mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 08:40:50 +00:00
Merge pull request #7758 from 4ertus2/ast
Check if table has qualified column
This commit is contained in:
commit
3735a7e210
@ -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,6 +86,13 @@ 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, identifier))
|
||||
{
|
||||
String table_name = data.tables[table_pos].first.getQualifiedNamePrefix(false);
|
||||
throw Exception("There's no column '" + identifier.name + "' in table '" + table_name + "'",
|
||||
ErrorCodes::UNKNOWN_IDENTIFIER);
|
||||
}
|
||||
|
||||
IdentifierSemantic::setMembership(identifier, table_pos);
|
||||
|
||||
/// In case if column from the joined table are in source columns, change it's name to qualified.
|
||||
|
@ -38,6 +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 ASTIdentifier & node) const;
|
||||
|
||||
static std::vector<TableWithColumnNames> tablesOnly(const std::vector<DatabaseAndTableWithAlias> & tables)
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
SELECT
|
||||
q0.dt,
|
||||
q0.cnt,
|
||||
q0.cnt2
|
||||
q1.cnt2
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
|
@ -0,0 +1 @@
|
||||
1 3
|
@ -0,0 +1,3 @@
|
||||
SELECT l.c FROM (SELECT 1 AS a, 2 AS b) AS l join (SELECT 2 AS b, 3 AS c) AS r USING b; -- { serverError 47 }
|
||||
SELECT r.a FROM (SELECT 1 AS a, 2 AS b) AS l join (SELECT 2 AS b, 3 AS c) AS r USING b; -- { serverError 47 }
|
||||
SELECT l.a, r.c FROM (SELECT 1 AS a, 2 AS b) AS l join (SELECT 2 AS b, 3 AS c) AS r USING b;
|
Loading…
Reference in New Issue
Block a user