Fix GLOBAL IN evaluation

This commit is contained in:
Ivan Lezhankin 2020-11-13 17:13:27 +03:00
parent 9250d5c4e9
commit d69b6307b5
6 changed files with 33 additions and 17 deletions

View File

@ -526,6 +526,7 @@ bool ActionsMatcher::needChildVisit(const ASTPtr & node, const ASTPtr & child)
{
/// Visit children themself
if (node->as<ASTIdentifier>() ||
node->as<ASTTableIdentifier>() ||
node->as<ASTFunction>() ||
node->as<ASTLiteral>() ||
node->as<ASTExpressionList>())
@ -543,6 +544,8 @@ void ActionsMatcher::visit(const ASTPtr & ast, Data & data)
{
if (const auto * identifier = ast->as<ASTIdentifier>())
visit(*identifier, ast, data);
else if (const auto * table = ast->as<ASTTableIdentifier>())
visit(*table, ast, data);
else if (const auto * node = ast->as<ASTFunction>())
visit(*node, ast, data);
else if (const auto * literal = ast->as<ASTLiteral>())
@ -659,9 +662,9 @@ void ActionsMatcher::visit(ASTExpressionList & expression_list, const ASTPtr &,
}
}
void ActionsMatcher::visit(const ASTIdentifier & identifier, const ASTPtr & ast, Data & data)
void ActionsMatcher::visit(const ASTIdentifier & identifier, const ASTPtr &, Data & data)
{
auto column_name = ast->getColumnName();
auto column_name = identifier.getColumnName();
if (data.hasColumn(column_name))
return;
@ -1004,7 +1007,7 @@ SetPtr ActionsMatcher::makeSet(const ASTFunction & node, Data & data, bool no_su
const ASTPtr & right_in_operand = args.children.at(1);
/// If the subquery or table name for SELECT.
const auto * identifier = right_in_operand->as<ASTIdentifier>();
const auto * identifier = right_in_operand->as<ASTTableIdentifier>();
if (right_in_operand->as<ASTSubquery>() || identifier)
{
if (no_subqueries)

View File

@ -158,9 +158,7 @@ public:
static bool needChildVisit(ASTPtr &, const ASTPtr & child)
{
/// We do not go into subqueries.
if (child->as<ASTSelectQuery>())
return false;
return true;
return !child->as<ASTSelectQuery>();
}
private:

View File

@ -1,4 +1,5 @@
#include <Poco/String.h>
#include <IO/WriteBufferFromOStream.h>
#include <Interpreters/misc.h>
#include <Interpreters/MarkTableIdentifiersVisitor.h>
#include <Interpreters/IdentifierSemantic.h>
@ -24,29 +25,35 @@ void MarkTableIdentifiersMatcher::visit(ASTPtr & ast, Data & data)
visit(*node_func, ast, data);
}
void MarkTableIdentifiersMatcher::visit(const ASTFunction & func, ASTPtr &, Data & data)
void MarkTableIdentifiersMatcher::visit(const ASTFunction & func, ASTPtr & ptr, Data & data)
{
/// `IN t` can be specified, where t is a table, which is equivalent to `IN (SELECT * FROM t)`.
if (checkFunctionIsInOrGlobalInOperator(func))
{
auto & ast = func.arguments->children.at(1);
auto ast = func.arguments->children.at(1);
auto opt_name = tryGetIdentifierName(ast);
if (opt_name && !data.aliases.count(*opt_name))
setIdentifierSpecial(ast);
{
ptr = func.clone();
ptr->as<ASTFunction>()->arguments->children[1] = ast->as<ASTIdentifier>()->createTable();
assert(ptr->as<ASTFunction>()->arguments->children[1]);
}
}
// First argument of joinGet can be a table name, perhaps with a database.
// First argument of dictGet can be a dictionary name, perhaps with a database.
if (functionIsJoinGet(func.name) || functionIsDictGet(func.name))
else if (functionIsJoinGet(func.name) || functionIsDictGet(func.name))
{
if (func.arguments->children.empty())
{
return;
}
auto & ast = func.arguments->children.at(0);
auto opt_name = tryGetIdentifierName(ast);
if (opt_name && !data.aliases.count(*opt_name))
setIdentifierSpecial(ast);
{
ptr = func.clone();
ptr->as<ASTFunction>()->arguments->children[0] = ast->as<ASTIdentifier>()->createTable();
assert(ptr->as<ASTFunction>()->arguments->children[0]);
}
}
}

View File

@ -142,6 +142,13 @@ void ASTIdentifier::restoreTable()
}
}
std::shared_ptr<ASTTableIdentifier> ASTIdentifier::createTable() const
{
if (name_parts.size() == 1) return std::make_shared<ASTTableIdentifier>(name_parts[0]);
if (name_parts.size() == 2) return std::make_shared<ASTTableIdentifier>(name_parts[0], name_parts[1]);
return nullptr;
}
void ASTIdentifier::resetFullName()
{
full_name = name_parts[0];

View File

@ -14,10 +14,11 @@ struct IdentifierSemantic;
struct IdentifierSemanticImpl;
struct StorageID;
class ASTTableIdentifier;
/// Generic identifier. ASTTableIdentifier - for table identifier.
class ASTIdentifier : public ASTWithAlias
{
friend class ReplaceQueryParameterVisitor;
public:
explicit ASTIdentifier(const String & short_name, ASTPtr && name_param = {});
explicit ASTIdentifier(std::vector<String> && name_parts, bool special = false, std::vector<ASTPtr> && name_params = {});
@ -44,6 +45,7 @@ public:
const String & name() const;
void restoreTable(); // TODO(ilezhankin): get rid of this
std::shared_ptr<ASTTableIdentifier> createTable() const; // return |nullptr| if identifier is not table.
protected:
String full_name;
@ -56,10 +58,9 @@ protected:
private:
using ASTWithAlias::children; /// ASTIdentifier is child free
friend class ReplaceQueryParameterVisitor;
friend struct IdentifierSemantic;
friend ASTPtr createTableIdentifier(const StorageID & table_id);
friend void setIdentifierSpecial(ASTPtr & ast);
friend StorageID getTableIdentifier(const ASTPtr & ast);
void resetFullName();
};

View File

@ -1,4 +1,4 @@
#!/usr/bin/python3.8
#!/usr/bin/python3
import argparse
import collections