2019-01-25 15:42:24 +00:00
|
|
|
#pragma once
|
|
|
|
|
2021-04-01 11:21:36 +00:00
|
|
|
#include <Interpreters/Aliases.h>
|
2019-01-25 15:42:24 +00:00
|
|
|
#include <Interpreters/DatabaseAndTableWithAlias.h>
|
2021-04-01 11:21:36 +00:00
|
|
|
#include <Interpreters/InDepthNodeVisitor.h>
|
|
|
|
#include <Interpreters/QueryAliasesVisitor.h>
|
|
|
|
#include <Interpreters/getHeaderForProcessingStage.h>
|
|
|
|
#include <Interpreters/getTableExpressions.h>
|
2019-01-25 15:42:24 +00:00
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2021-11-26 15:49:40 +00:00
|
|
|
class ASTIdentifier;
|
2021-11-26 17:35:24 +00:00
|
|
|
class ASTSelectQuery;
|
2021-11-26 15:49:40 +00:00
|
|
|
|
2019-01-25 15:42:24 +00:00
|
|
|
struct IdentifierSemanticImpl
|
|
|
|
{
|
2020-10-24 18:46:10 +00:00
|
|
|
bool special = false; /// for now it's 'not a column': tables, subselects and some special stuff like FORMAT
|
|
|
|
bool can_be_alias = true; /// if it's a cropped name it could not be an alias
|
|
|
|
bool covered = false; /// real (compound) name is hidden by an alias (short name)
|
|
|
|
std::optional<size_t> membership; /// table position in join
|
|
|
|
String table = {}; /// store table name for columns just to support legacy logic.
|
|
|
|
bool legacy_compound = false; /// true if identifier supposed to be comply for legacy |compound()| behavior
|
2019-01-25 15:42:24 +00:00
|
|
|
};
|
|
|
|
|
2020-08-08 01:01:47 +00:00
|
|
|
/// Static class to manipulate IdentifierSemanticImpl via ASTIdentifier
|
2019-01-25 15:42:24 +00:00
|
|
|
struct IdentifierSemantic
|
|
|
|
{
|
2019-10-17 21:08:28 +00:00
|
|
|
enum class ColumnMatch
|
|
|
|
{
|
|
|
|
NoMatch,
|
2020-03-08 11:07:05 +00:00
|
|
|
ColumnName, /// column qualified with column names list
|
2019-10-18 16:16:57 +00:00
|
|
|
AliasedTableName, /// column qualified with table name (but table has an alias so its priority is lower than TableName)
|
2019-10-17 21:08:28 +00:00
|
|
|
TableName, /// column qualified with table name
|
2021-09-25 02:48:24 +00:00
|
|
|
DBAndTable, /// column qualified with database and table name
|
2019-10-17 21:08:28 +00:00
|
|
|
TableAlias, /// column qualified with table alias
|
|
|
|
Ambiguous,
|
|
|
|
};
|
|
|
|
|
2019-01-25 15:42:24 +00:00
|
|
|
/// @returns name for column identifiers
|
|
|
|
static std::optional<String> getColumnName(const ASTIdentifier & node);
|
|
|
|
static std::optional<String> getColumnName(const ASTPtr & ast);
|
|
|
|
|
|
|
|
/// @returns name for 'not a column' identifiers
|
2019-11-13 16:49:29 +00:00
|
|
|
static std::optional<String> extractNestedName(const ASTIdentifier & identifier, const String & table_name);
|
2019-01-25 15:42:24 +00:00
|
|
|
|
2022-06-17 07:13:31 +00:00
|
|
|
static String extractNestedName(const ASTIdentifier & identifier, const DatabaseAndTableWithAlias & table);
|
|
|
|
|
2019-10-17 21:08:28 +00:00
|
|
|
static ColumnMatch canReferColumnToTable(const ASTIdentifier & identifier, const DatabaseAndTableWithAlias & db_and_table);
|
2020-06-15 12:36:10 +00:00
|
|
|
static ColumnMatch canReferColumnToTable(const ASTIdentifier & identifier, const TableWithColumnNamesAndTypes & table_with_columns);
|
2020-03-08 11:07:05 +00:00
|
|
|
|
2019-10-18 16:16:57 +00:00
|
|
|
static void setColumnShortName(ASTIdentifier & identifier, const DatabaseAndTableWithAlias & db_and_table);
|
2019-02-20 12:12:36 +00:00
|
|
|
static void setColumnLongName(ASTIdentifier & identifier, const DatabaseAndTableWithAlias & db_and_table);
|
2019-02-11 19:14:57 +00:00
|
|
|
static bool canBeAlias(const ASTIdentifier & identifier);
|
2020-03-09 00:08:02 +00:00
|
|
|
static void setMembership(ASTIdentifier &, size_t table_pos);
|
2019-12-24 18:51:37 +00:00
|
|
|
static void coverName(ASTIdentifier &, const String & alias);
|
|
|
|
static std::optional<ASTIdentifier> uncover(const ASTIdentifier & identifier);
|
2019-10-18 16:16:57 +00:00
|
|
|
static std::optional<size_t> getMembership(const ASTIdentifier & identifier);
|
2020-03-08 11:07:05 +00:00
|
|
|
static std::optional<size_t> chooseTable(const ASTIdentifier &, const std::vector<DatabaseAndTableWithAlias> & tables,
|
|
|
|
bool allow_ambiguous = false);
|
2020-06-15 12:36:10 +00:00
|
|
|
static std::optional<size_t> chooseTable(const ASTIdentifier &, const TablesWithColumns & tables,
|
|
|
|
bool allow_ambiguous = false);
|
|
|
|
static std::optional<size_t> chooseTableColumnMatch(const ASTIdentifier &, const TablesWithColumns & tables,
|
2020-03-08 11:07:05 +00:00
|
|
|
bool allow_ambiguous = false);
|
2019-01-25 15:42:24 +00:00
|
|
|
|
2021-04-01 11:21:36 +00:00
|
|
|
static std::optional<size_t> getIdentMembership(const ASTIdentifier & ident, const std::vector<TableWithColumnNamesAndTypes> & tables);
|
|
|
|
|
|
|
|
/// Collect common table membership for identifiers in expression
|
|
|
|
/// If membership cannot be established or there are several identifies from different tables, return empty optional
|
|
|
|
static std::optional<size_t>
|
|
|
|
getIdentsMembership(ASTPtr ast, const std::vector<TableWithColumnNamesAndTypes> & tables, const Aliases & aliases);
|
|
|
|
|
2019-01-25 15:42:24 +00:00
|
|
|
private:
|
|
|
|
static bool doesIdentifierBelongTo(const ASTIdentifier & identifier, const String & database, const String & table);
|
|
|
|
static bool doesIdentifierBelongTo(const ASTIdentifier & identifier, const String & table);
|
|
|
|
};
|
|
|
|
|
2021-04-01 11:21:36 +00:00
|
|
|
|
|
|
|
/// Collect all identifies from AST recursively
|
|
|
|
class IdentifiersCollector
|
|
|
|
{
|
|
|
|
public:
|
2021-04-09 14:56:15 +00:00
|
|
|
using ASTIdentifierPtr = const ASTIdentifier *;
|
|
|
|
using ASTIdentifiers = std::vector<ASTIdentifierPtr>;
|
2021-04-01 11:21:36 +00:00
|
|
|
struct Data
|
|
|
|
{
|
|
|
|
ASTIdentifiers idents;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void visit(const ASTPtr & node, Data & data);
|
|
|
|
static bool needChildVisit(const ASTPtr &, const ASTPtr &);
|
|
|
|
static ASTIdentifiers collect(const ASTPtr & node);
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Collect identifier table membership considering aliases
|
|
|
|
class IdentifierMembershipCollector
|
|
|
|
{
|
|
|
|
public:
|
2021-04-10 23:33:54 +00:00
|
|
|
IdentifierMembershipCollector(const ASTSelectQuery & select, ContextPtr context);
|
2021-04-01 11:21:36 +00:00
|
|
|
std::optional<size_t> getIdentsMembership(ASTPtr ast) const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
std::vector<TableWithColumnNamesAndTypes> tables;
|
|
|
|
Aliases aliases;
|
|
|
|
};
|
|
|
|
|
2021-04-06 09:29:29 +00:00
|
|
|
/// Split expression `expr_1 AND expr_2 AND ... AND expr_n` into vector `[expr_1, expr_2, ..., expr_n]`
|
|
|
|
std::vector<ASTPtr> collectConjunctions(const ASTPtr & node);
|
|
|
|
|
2019-01-25 15:42:24 +00:00
|
|
|
}
|