1 | #pragma once |
2 | |
3 | #include <optional> |
4 | |
5 | #include <Parsers/ASTIdentifier.h> |
6 | #include <Interpreters/DatabaseAndTableWithAlias.h> |
7 | |
8 | namespace DB |
9 | { |
10 | |
11 | struct 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 |
20 | struct 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> (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 | |
55 | private: |
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 | |