fix scalar subquery hash conflicts

This commit is contained in:
Amos Bird 2020-08-20 10:01:40 +08:00
parent 5928eab2c4
commit 333ec2e496
No known key found for this signature in database
GPG Key ID: 80D430DCBECFEDB4
19 changed files with 123 additions and 39 deletions

View File

@ -2,6 +2,7 @@
#include <IO/WriteHelpers.h>
#include <Common/quoteString.h>
#include <re2/re2.h>
#include <Common/SipHash.h>
namespace DB
@ -20,6 +21,13 @@ ASTPtr ASTColumnsMatcher::clone() const
void ASTColumnsMatcher::appendColumnName(WriteBuffer & ostr) const { writeString(original_pattern, ostr); }
void ASTColumnsMatcher::updateTreeHashImpl(SipHash & hash_state) const
{
hash_state.update(original_pattern.size());
hash_state.update(original_pattern);
IAST::updateTreeHashImpl(hash_state);
}
void ASTColumnsMatcher::formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const
{
settings.ostr << (settings.hilite ? hilite_keyword : "") << "COLUMNS" << (settings.hilite ? hilite_none : "") << "("

View File

@ -33,6 +33,7 @@ public:
void appendColumnName(WriteBuffer & ostr) const override;
void setPattern(String pattern);
bool isColumnMatching(const String & column_name) const;
void updateTreeHashImpl(SipHash & hash_state) const override;
protected:
void formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const override;

View File

@ -1,39 +0,0 @@
#pragma once
#include "IAST.h"
#include <Core/Field.h>
#include <Common/FieldVisitors.h>
namespace DB
{
class ASTEnumElement : public IAST
{
public:
String name;
Field value;
ASTEnumElement(const String & name, const Field & value)
: name{name}, value {value} {}
String getID(char) const override { return "EnumElement"; }
ASTPtr clone() const override
{
return std::make_shared<ASTEnumElement>(name, value);
}
protected:
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override
{
frame.need_parens = false;
const std::string indent_str = settings.one_line ? "" : std::string(4 * frame.indent, ' ');
settings.ostr << settings.nl_or_ws << indent_str << '\'' << name << "' = " << applyVisitor(FieldVisitorToString{}, value);
}
};
}

View File

@ -5,6 +5,7 @@
#include <Parsers/ASTSubquery.h>
#include <IO/WriteHelpers.h>
#include <IO/WriteBufferFromString.h>
#include <Common/SipHash.h>
namespace DB
@ -54,6 +55,14 @@ ASTPtr ASTFunction::clone() const
}
void ASTFunction::updateTreeHashImpl(SipHash & hash_state) const
{
hash_state.update(name.size());
hash_state.update(name);
IAST::updateTreeHashImpl(hash_state);
}
/** A special hack. If it's [I]LIKE or NOT [I]LIKE expression and the right hand side is a string literal,
* we will highlight unescaped metacharacters % and _ in string literal for convenience.
* Motivation: most people are unaware that _ is a metacharacter and forgot to properly escape it with two backslashes.

View File

@ -23,6 +23,8 @@ public:
ASTPtr clone() const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
protected:
void formatImplWithoutAlias(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
void appendColumnNameImpl(WriteBuffer & ostr) const override;

View File

@ -1,6 +1,7 @@
#include <Parsers/ASTFunctionWithKeyValueArguments.h>
#include <Poco/String.h>
#include <Common/SipHash.h>
namespace DB
{
@ -35,6 +36,16 @@ void ASTPair::formatImpl(const FormatSettings & settings, FormatState & state, F
settings.ostr << (settings.hilite ? hilite_none : "");
}
void ASTPair::updateTreeHashImpl(SipHash & hash_state) const
{
hash_state.update(first.size());
hash_state.update(first);
hash_state.update(second_with_brackets);
IAST::updateTreeHashImpl(hash_state);
}
String ASTFunctionWithKeyValueArguments::getID(char delim) const
{
return "FunctionWithKeyValueArguments " + (delim + name);
@ -64,4 +75,13 @@ void ASTFunctionWithKeyValueArguments::formatImpl(const FormatSettings & setting
settings.ostr << (settings.hilite ? hilite_none : "");
}
void ASTFunctionWithKeyValueArguments::updateTreeHashImpl(SipHash & hash_state) const
{
hash_state.update(name.size());
hash_state.update(name);
hash_state.update(has_brackets);
IAST::updateTreeHashImpl(hash_state);
}
}

View File

@ -30,6 +30,8 @@ public:
ASTPtr clone() const override;
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
};
@ -58,6 +60,8 @@ public:
ASTPtr clone() const override;
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
};
}

View File

@ -111,6 +111,12 @@ void ASTIdentifier::resetTable(const String & database_name, const String & tabl
uuid = ident.uuid;
}
void ASTIdentifier::updateTreeHashImpl(SipHash & hash_state) const
{
hash_state.update(uuid);
IAST::updateTreeHashImpl(hash_state);
}
ASTPtr createTableIdentifier(const String & database_name, const String & table_name)
{
assert(database_name != "_temporary_and_external_tables");

View File

@ -53,6 +53,8 @@ public:
void resetTable(const String & database_name, const String & table_name);
void updateTreeHashImpl(SipHash & hash_state) const override;
protected:
void formatImplWithoutAlias(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
void appendColumnNameImpl(WriteBuffer & ostr) const override;

View File

@ -1,10 +1,20 @@
#include <Columns/Collator.h>
#include <Parsers/ASTOrderByElement.h>
#include <Common/SipHash.h>
namespace DB
{
void ASTOrderByElement::updateTreeHashImpl(SipHash & hash_state) const
{
hash_state.update(direction);
hash_state.update(nulls_direction);
hash_state.update(nulls_direction_was_explicitly_specified);
hash_state.update(with_fill);
IAST::updateTreeHashImpl(hash_state);
}
void ASTOrderByElement::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const
{
children.front()->formatImpl(settings, state, frame);

View File

@ -46,6 +46,8 @@ public:
return clone;
}
void updateTreeHashImpl(SipHash & hash_state) const override;
protected:
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
};

View File

@ -57,6 +57,17 @@ ASTPtr ASTSelectQuery::clone() const
}
void ASTSelectQuery::updateTreeHashImpl(SipHash & hash_state) const
{
hash_state.update(distinct);
hash_state.update(group_by_with_totals);
hash_state.update(group_by_with_rollup);
hash_state.update(group_by_with_cube);
hash_state.update(limit_with_ties);
IAST::updateTreeHashImpl(hash_state);
}
void ASTSelectQuery::formatImpl(const FormatSettings & s, FormatState & state, FormatStateStacked frame) const
{
frame.current_select = this;

View File

@ -88,6 +88,7 @@ public:
void replaceDatabaseAndTable(const String & database_name, const String & table_name);
void replaceDatabaseAndTable(const StorageID & table_id);
void addTableFunction(ASTPtr & table_function_ptr);
void updateTreeHashImpl(SipHash & hash_state) const override;
protected:
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;

View File

@ -1,9 +1,21 @@
#include <Parsers/ASTSetQuery.h>
#include <Parsers/formatSettingName.h>
#include <Common/SipHash.h>
namespace DB
{
void ASTSetQuery::updateTreeHashImpl(SipHash & hash_state) const
{
for (const auto & change : changes)
{
hash_state.update(change.name.size());
hash_state.update(change.name);
applyVisitor(FieldVisitorHash(hash_state), change.value);
}
}
void ASTSetQuery::formatImpl(const FormatSettings & format, FormatState &, FormatStateStacked) const
{
if (is_standalone)

View File

@ -23,6 +23,8 @@ public:
ASTPtr clone() const override { return std::make_shared<ASTSetQuery>(*this); }
void formatImpl(const FormatSettings & format, FormatState &, FormatStateStacked) const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
};
}

View File

@ -1,6 +1,7 @@
#include <Common/typeid_cast.h>
#include <Parsers/ASTExpressionList.h>
#include <Parsers/ASTTablesInSelectQuery.h>
#include <Common/SipHash.h>
namespace DB
@ -18,6 +19,13 @@ do \
while (false)
void ASTTableExpression::updateTreeHashImpl(SipHash & hash_state) const
{
hash_state.update(final);
IAST::updateTreeHashImpl(hash_state);
}
ASTPtr ASTTableExpression::clone() const
{
auto res = std::make_shared<ASTTableExpression>(*this);
@ -32,6 +40,14 @@ ASTPtr ASTTableExpression::clone() const
return res;
}
void ASTTableJoin::updateTreeHashImpl(SipHash & hash_state) const
{
hash_state.update(locality);
hash_state.update(strictness);
hash_state.update(kind);
IAST::updateTreeHashImpl(hash_state);
}
ASTPtr ASTTableJoin::clone() const
{
auto res = std::make_shared<ASTTableJoin>(*this);
@ -43,6 +59,12 @@ ASTPtr ASTTableJoin::clone() const
return res;
}
void ASTArrayJoin::updateTreeHashImpl(SipHash & hash_state) const
{
hash_state.update(kind);
IAST::updateTreeHashImpl(hash_state);
}
ASTPtr ASTArrayJoin::clone() const
{
auto res = std::make_shared<ASTArrayJoin>(*this);

View File

@ -56,6 +56,7 @@ struct ASTTableExpression : public IAST
String getID(char) const override { return "TableExpression"; }
ASTPtr clone() const override;
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
};
@ -108,6 +109,7 @@ struct ASTTableJoin : public IAST
void formatImplBeforeTable(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const;
void formatImplAfterTable(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const;
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
};
inline bool isLeft(ASTTableJoin::Kind kind) { return kind == ASTTableJoin::Kind::Left; }
@ -139,6 +141,7 @@ struct ASTArrayJoin : public IAST
String getID(char) const override { return "ArrayJoin"; }
ASTPtr clone() const override;
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
void updateTreeHashImpl(SipHash & hash_state) const override;
};

View File

@ -0,0 +1,2 @@
0 99
1

View File

@ -0,0 +1,6 @@
SELECT (SELECT number FROM numbers(100) ORDER BY number LIMIT 1),
(SELECT number FROM numbers(100) ORDER BY number DESC LIMIT 1);
SELECT 1
WHERE 0=(SELECT number FROM numbers(2) ORDER BY number LIMIT 1)
AND 1=(SELECT number FROM numbers(2) ORDER BY number DESC LIMIT 1);