1#pragma once
2
3#include <optional>
4
5#include <Parsers/ASTIdentifier.h>
6#include <Interpreters/DatabaseAndTableWithAlias.h>
7
8namespace DB
9{
10
11struct IdentifierSemanticImpl
12{
13 bool special = false; /// for now it's 'not a column': tables, subselects and some special stuff like FORMAT
14 bool can_be_alias = true; /// if it's a cropped name it could not be an alias
15 bool covered = false; /// real (compound) name is hidden by an alias (short name)
16 std::optional<size_t> membership; /// table position in join
17};
18
19/// Static calss to manipulate IdentifierSemanticImpl via ASTIdentifier
20struct IdentifierSemantic
21{
22 enum class ColumnMatch
23 {
24 NoMatch,
25 AliasedTableName, /// column qualified with table name (but table has an alias so its priority is lower than TableName)
26 TableName, /// column qualified with table name
27 DbAndTable, /// column qualified with database and table name
28 TableAlias, /// column qualified with table alias
29 Ambiguous,
30 };
31
32 /// @returns name for column identifiers
33 static std::optional<String> getColumnName(const ASTIdentifier & node);
34 static std::optional<String> getColumnName(const ASTPtr & ast);
35
36 /// @returns name for 'not a column' identifiers
37 static std::optional<String> getTableName(const ASTIdentifier & node);
38 static std::optional<String> getTableName(const ASTPtr & ast);
39 static std::pair<String, String> extractDatabaseAndTable(const ASTIdentifier & identifier);
40 static std::optional<String> extractNestedName(const ASTIdentifier & identifier, const String & table_name);
41
42 static ColumnMatch canReferColumnToTable(const ASTIdentifier & identifier, const DatabaseAndTableWithAlias & db_and_table);
43 static void setColumnShortName(ASTIdentifier & identifier, const DatabaseAndTableWithAlias & db_and_table);
44 static void setColumnLongName(ASTIdentifier & identifier, const DatabaseAndTableWithAlias & db_and_table);
45 static bool canBeAlias(const ASTIdentifier & identifier);
46 static void setMembership(ASTIdentifier &, size_t table_no);
47 static void coverName(ASTIdentifier &, const String & alias);
48 static std::optional<ASTIdentifier> uncover(const ASTIdentifier & identifier);
49 static std::optional<size_t> getMembership(const ASTIdentifier & identifier);
50 static bool chooseTable(const ASTIdentifier &, const std::vector<DatabaseAndTableWithAlias> & tables, size_t & best_table_pos,
51 bool ambiguous = false);
52 static bool chooseTable(const ASTIdentifier &, const std::vector<TableWithColumnNames> & tables, size_t & best_table_pos,
53 bool ambiguous = false);
54
55private:
56 static bool doesIdentifierBelongTo(const ASTIdentifier & identifier, const String & database, const String & table);
57 static bool doesIdentifierBelongTo(const ASTIdentifier & identifier, const String & table);
58};
59
60}
61