2019-10-23 13:59:03 +00:00
|
|
|
#include <Interpreters/MarkTableIdentifiersVisitor.h>
|
2021-04-14 15:35:52 +00:00
|
|
|
|
|
|
|
#include <IO/WriteBufferFromOStream.h>
|
2019-10-23 13:59:03 +00:00
|
|
|
#include <Interpreters/IdentifierSemantic.h>
|
2021-04-14 15:35:52 +00:00
|
|
|
#include <Interpreters/misc.h>
|
2019-10-23 13:59:03 +00:00
|
|
|
#include <Parsers/ASTFunction.h>
|
2021-11-26 15:49:40 +00:00
|
|
|
#include <Parsers/ASTIdentifier.h>
|
2019-10-23 13:59:03 +00:00
|
|
|
#include <Parsers/ASTSelectQuery.h>
|
|
|
|
#include <Parsers/ASTTablesInSelectQuery.h>
|
|
|
|
|
2021-04-14 15:35:52 +00:00
|
|
|
|
2019-10-23 13:59:03 +00:00
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2021-07-02 11:20:41 +00:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
void replaceArgumentWithTableIdentifierIfNotAlias(ASTFunction & func, size_t argument_pos, const Aliases & aliases)
|
|
|
|
{
|
|
|
|
if (!func.arguments || (func.arguments->children.size() <= argument_pos))
|
|
|
|
return;
|
|
|
|
auto arg = func.arguments->children[argument_pos];
|
2021-07-03 10:16:55 +00:00
|
|
|
auto * identifier = arg->as<ASTIdentifier>();
|
2021-07-02 11:20:41 +00:00
|
|
|
if (!identifier)
|
|
|
|
return;
|
|
|
|
if (aliases.contains(identifier->name()))
|
|
|
|
return;
|
|
|
|
auto table_identifier = identifier->createTable();
|
|
|
|
if (!table_identifier)
|
|
|
|
return;
|
|
|
|
func.arguments->children[argument_pos] = table_identifier;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-10-23 13:59:03 +00:00
|
|
|
bool MarkTableIdentifiersMatcher::needChildVisit(ASTPtr & node, const ASTPtr & child)
|
|
|
|
{
|
|
|
|
if (child->as<ASTSelectQuery>())
|
|
|
|
return false;
|
|
|
|
if (node->as<ASTTableExpression>())
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MarkTableIdentifiersMatcher::visit(ASTPtr & ast, Data & data)
|
|
|
|
{
|
|
|
|
if (auto * node_func = ast->as<ASTFunction>())
|
2021-07-02 11:20:41 +00:00
|
|
|
visit(*node_func, data);
|
2019-10-23 13:59:03 +00:00
|
|
|
}
|
|
|
|
|
2021-07-02 11:20:41 +00:00
|
|
|
void MarkTableIdentifiersMatcher::visit(ASTFunction & func, const Data & data)
|
2019-10-23 13:59:03 +00:00
|
|
|
{
|
|
|
|
/// `IN t` can be specified, where t is a table, which is equivalent to `IN (SELECT * FROM t)`.
|
2020-07-15 14:22:54 +00:00
|
|
|
if (checkFunctionIsInOrGlobalInOperator(func))
|
2019-10-23 13:59:03 +00:00
|
|
|
{
|
2021-07-02 11:20:41 +00:00
|
|
|
replaceArgumentWithTableIdentifierIfNotAlias(func, 1, data.aliases);
|
2019-10-23 13:59:03 +00:00
|
|
|
}
|
2019-12-18 20:36:51 +00:00
|
|
|
|
2020-05-19 18:12:30 +00:00
|
|
|
// 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.
|
2020-11-13 14:13:27 +00:00
|
|
|
else if (functionIsJoinGet(func.name) || functionIsDictGet(func.name))
|
2019-12-18 20:36:51 +00:00
|
|
|
{
|
2021-07-02 11:20:41 +00:00
|
|
|
replaceArgumentWithTableIdentifierIfNotAlias(func, 0, data.aliases);
|
2019-12-18 20:36:51 +00:00
|
|
|
}
|
2019-10-23 13:59:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|