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
14namespace DB
15{
16
17DatabaseAndTableWithAlias::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
26DatabaseAndTableWithAlias::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
35DatabaseAndTableWithAlias::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
47bool 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
63String 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
70std::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
83std::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