| 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 | |