mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-26 09:32:01 +00:00
support nested column names
This commit is contained in:
parent
d70904d7ee
commit
31028b8f3b
@ -132,6 +132,15 @@ std::pair<String, String> IdentifierSemantic::extractDatabaseAndTable(const ASTI
|
||||
return { "", identifier.name };
|
||||
}
|
||||
|
||||
std::optional<String> IdentifierSemantic::extractNestedName(const ASTIdentifier & identifier, const String & table_name)
|
||||
{
|
||||
if (identifier.name_parts.size() == 3 && table_name == identifier.name_parts[0])
|
||||
return identifier.name_parts[1] + '.' + identifier.name_parts[2];
|
||||
else if (identifier.name_parts.size() == 2)
|
||||
return identifier.name_parts[0] + '.' + identifier.name_parts[1];
|
||||
return {};
|
||||
}
|
||||
|
||||
bool IdentifierSemantic::doesIdentifierBelongTo(const ASTIdentifier & identifier, const String & database, const String & table)
|
||||
{
|
||||
size_t num_components = identifier.name_parts.size();
|
||||
|
@ -36,6 +36,7 @@ struct IdentifierSemantic
|
||||
static std::optional<String> getTableName(const ASTIdentifier & node);
|
||||
static std::optional<String> getTableName(const ASTPtr & ast);
|
||||
static std::pair<String, String> extractDatabaseAndTable(const ASTIdentifier & identifier);
|
||||
static std::optional<String> extractNestedName(const ASTIdentifier & identifier, const String & table_name);
|
||||
|
||||
static ColumnMatch canReferColumnToTable(const ASTIdentifier & identifier, const DatabaseAndTableWithAlias & db_and_table);
|
||||
static void setColumnShortName(ASTIdentifier & identifier, const DatabaseAndTableWithAlias & db_and_table);
|
||||
|
@ -29,6 +29,26 @@ namespace ErrorCodes
|
||||
extern const int LOGICAL_ERROR;
|
||||
}
|
||||
|
||||
bool TranslateQualifiedNamesMatcher::Data::unknownColumn(size_t table_pos, const ASTIdentifier & identifier) const
|
||||
{
|
||||
const auto & table = tables[table_pos].first;
|
||||
auto nested1 = IdentifierSemantic::extractNestedName(identifier, table.table);
|
||||
auto nested2 = IdentifierSemantic::extractNestedName(identifier, table.alias);
|
||||
|
||||
String short_name = identifier.shortName();
|
||||
const Names & column_names = tables[table_pos].second;
|
||||
for (auto & known_name : column_names)
|
||||
{
|
||||
if (short_name == known_name)
|
||||
return false;
|
||||
if (nested1 && *nested1 == known_name)
|
||||
return false;
|
||||
if (nested2 && *nested2 == known_name)
|
||||
return false;
|
||||
}
|
||||
return !column_names.empty();
|
||||
}
|
||||
|
||||
bool TranslateQualifiedNamesMatcher::needChildVisit(ASTPtr & node, const ASTPtr & child)
|
||||
{
|
||||
/// Do not go to FROM, JOIN, subqueries.
|
||||
@ -66,7 +86,7 @@ void TranslateQualifiedNamesMatcher::visit(ASTIdentifier & identifier, ASTPtr &,
|
||||
bool allow_ambiguous = data.join_using_columns.count(short_name);
|
||||
if (IdentifierSemantic::chooseTable(identifier, data.tables, table_pos, allow_ambiguous))
|
||||
{
|
||||
if (data.unknownColumn(table_pos, short_name))
|
||||
if (data.unknownColumn(table_pos, identifier))
|
||||
{
|
||||
String table_name = data.tables[table_pos].first.getQualifiedNamePrefix(false);
|
||||
throw Exception("There's no column '" + identifier.name + "' in table '" + table_name + "'",
|
||||
|
@ -38,15 +38,7 @@ public:
|
||||
bool hasColumn(const String & name) const { return source_columns.count(name); }
|
||||
bool hasTable() const { return !tables.empty(); }
|
||||
bool processAsterisks() const { return hasTable() && has_columns; }
|
||||
|
||||
bool unknownColumn(size_t table_pos, const String & name) const
|
||||
{
|
||||
const Names & names = tables[table_pos].second;
|
||||
for (auto & known_name : names)
|
||||
if (name == known_name)
|
||||
return false;
|
||||
return !names.empty();
|
||||
}
|
||||
bool unknownColumn(size_t table_pos, const ASTIdentifier & node) const;
|
||||
|
||||
static std::vector<TableWithColumnNames> tablesOnly(const std::vector<DatabaseAndTableWithAlias> & tables)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user