1 | #include <Interpreters/DatabaseAndTableWithAlias.h> |
2 | #include <Interpreters/IdentifierSemantic.h> |
3 | #include <Interpreters/Context.h> |
4 | #include <Interpreters/getTableExpressions.h> |
5 | |
6 | #include <Common/typeid_cast.h> |
7 | |
8 | #include <Parsers/IAST.h> |
9 | #include <Parsers/ASTIdentifier.h> |
10 | #include <Parsers/ASTTablesInSelectQuery.h> |
11 | #include <Parsers/ASTSelectQuery.h> |
12 | #include <Parsers/ASTSubquery.h> |
13 | |
14 | namespace DB |
15 | { |
16 | |
17 | DatabaseAndTableWithAlias::DatabaseAndTableWithAlias(const ASTIdentifier & identifier, const String & current_database) |
18 | { |
19 | alias = identifier.tryGetAlias(); |
20 | |
21 | std::tie(database, table) = IdentifierSemantic::extractDatabaseAndTable(identifier); |
22 | if (database.empty()) |
23 | database = current_database; |
24 | } |
25 | |
26 | DatabaseAndTableWithAlias::DatabaseAndTableWithAlias(const ASTPtr & node, const String & current_database) |
27 | { |
28 | const auto * identifier = node->as<ASTIdentifier>(); |
29 | if (!identifier) |
30 | throw Exception("Logical error: identifier expected" , ErrorCodes::LOGICAL_ERROR); |
31 | |
32 | *this = DatabaseAndTableWithAlias(*identifier, current_database); |
33 | } |
34 | |
35 | DatabaseAndTableWithAlias::DatabaseAndTableWithAlias(const ASTTableExpression & table_expression, const String & current_database) |
36 | { |
37 | if (table_expression.database_and_table_name) |
38 | *this = DatabaseAndTableWithAlias(table_expression.database_and_table_name, current_database); |
39 | else if (table_expression.table_function) |
40 | alias = table_expression.table_function->tryGetAlias(); |
41 | else if (table_expression.subquery) |
42 | alias = table_expression.subquery->tryGetAlias(); |
43 | else |
44 | throw Exception("Logical error: no known elements in ASTTableExpression" , ErrorCodes::LOGICAL_ERROR); |
45 | } |
46 | |
47 | bool DatabaseAndTableWithAlias::satisfies(const DatabaseAndTableWithAlias & db_table, bool table_may_be_an_alias) |
48 | { |
49 | /// table.*, alias.* or database.table.* |
50 | |
51 | if (database.empty()) |
52 | { |
53 | if (!db_table.table.empty() && table == db_table.table) |
54 | return true; |
55 | |
56 | if (!db_table.alias.empty()) |
57 | return (alias == db_table.alias) || (table_may_be_an_alias && table == db_table.alias); |
58 | } |
59 | |
60 | return database == db_table.database && table == db_table.table; |
61 | } |
62 | |
63 | String DatabaseAndTableWithAlias::getQualifiedNamePrefix(bool with_dot) const |
64 | { |
65 | if (alias.empty() && table.empty()) |
66 | return "" ; |
67 | return (!alias.empty() ? alias : table) + (with_dot ? "." : "" ); |
68 | } |
69 | |
70 | std::vector<DatabaseAndTableWithAlias> getDatabaseAndTables(const ASTSelectQuery & select_query, const String & current_database) |
71 | { |
72 | std::vector<const ASTTableExpression *> tables_expression = getTableExpressions(select_query); |
73 | |
74 | std::vector<DatabaseAndTableWithAlias> database_and_table_with_aliases; |
75 | database_and_table_with_aliases.reserve(tables_expression.size()); |
76 | |
77 | for (const auto & table_expression : tables_expression) |
78 | database_and_table_with_aliases.emplace_back(DatabaseAndTableWithAlias(*table_expression, current_database)); |
79 | |
80 | return database_and_table_with_aliases; |
81 | } |
82 | |
83 | std::optional<DatabaseAndTableWithAlias> getDatabaseAndTable(const ASTSelectQuery & select, size_t table_number) |
84 | { |
85 | const ASTTableExpression * table_expression = getTableExpression(select, table_number); |
86 | if (!table_expression) |
87 | return {}; |
88 | |
89 | ASTPtr database_and_table_name = table_expression->database_and_table_name; |
90 | if (!database_and_table_name || !database_and_table_name->as<ASTIdentifier>()) |
91 | return {}; |
92 | |
93 | return DatabaseAndTableWithAlias(database_and_table_name); |
94 | } |
95 | |
96 | } |
97 | |