From f283719d89034ae50f76942a13148ee0fcfc5e6c Mon Sep 17 00:00:00 2001 From: Andrey Mironov Date: Tue, 23 Dec 2014 03:31:11 +0300 Subject: [PATCH] dbms: fix in/join identifier subquery [#METR-14402] --- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 34 ++++++++++++------- .../00100_subquery_table_identifier.reference | 5 +++ .../00100_subquery_table_identifier.sh | 7 ++++ 3 files changed, 33 insertions(+), 13 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/00100_subquery_table_identifier.reference create mode 100755 dbms/tests/queries/0_stateless/00100_subquery_table_identifier.sh diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index 34fe41eda1..e60d75b117 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -583,19 +583,27 @@ static SharedPtr interpretSubquery( ASTPtr query; if (table) { - String query_str = "SELECT * FROM " + backQuoteIfNeed(table->name); - const char * begin = query_str.data(); - const char * end = begin + query_str.size(); - const char * pos = begin; - Expected expected = ""; - - bool parse_res = ParserSelectQuery().parse(pos, end, query, expected); - if (!parse_res) - throw Exception("Error in parsing SELECT query while creating set or join for table " + table->name + ".", - ErrorCodes::LOGICAL_ERROR); - - /// @note it may be more appropriate to manually replace ASTAsterisk with table's columns - ExpressionAnalyzer{query, context, subquery_depth}; + /// create ASTSelectQuery for "SELECT * FROM table" as if written by hand + const auto select_query = new ASTSelectQuery; + query = select_query; + + const auto select_expression_list = new ASTExpressionList; + select_query->select_expression_list = select_expression_list; + select_query->children.emplace_back(select_query->select_expression_list); + + /// get columns list for target table + const auto & storage = context.getTable("", table->name); + const auto & columns = storage->getColumnsListNonMaterialized(); + select_expression_list->children.reserve(columns.size()); + + /// manually substitute column names in place of asterisk + for (const auto & column : columns) + select_expression_list->children.emplace_back(new ASTIdentifier{ + StringRange{}, column.name + }); + + select_query->table = subquery_or_table_name; + select_query->children.emplace_back(select_query->table); } else query = subquery->children.at(0); diff --git a/dbms/tests/queries/0_stateless/00100_subquery_table_identifier.reference b/dbms/tests/queries/0_stateless/00100_subquery_table_identifier.reference new file mode 100644 index 0000000000..9864cf5dad --- /dev/null +++ b/dbms/tests/queries/0_stateless/00100_subquery_table_identifier.reference @@ -0,0 +1,5 @@ +0 +1 +1 +0 +0 diff --git a/dbms/tests/queries/0_stateless/00100_subquery_table_identifier.sh b/dbms/tests/queries/0_stateless/00100_subquery_table_identifier.sh new file mode 100755 index 0000000000..e14e3afa61 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00100_subquery_table_identifier.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +clickhouse-client --query="SELECT sum(dummy) FROM remote('[::]:9000', system, one) WHERE 1 GLOBAL IN (SELECT 1)" +echo '1' | clickhouse-client --external --file=- --types=UInt8 --query="SELECT 1 IN _data" +echo '1' | clickhouse-client --external --file=- --types=UInt8 --query="SELECT 1 IN (SELECT * FROM _data)" +echo '1' | clickhouse-client --external --file=- --types=UInt8 --query="SELECT dummy FROM remote('[::]:9000', system, one) WHERE 1 GLOBAL IN _data" +echo '1' | clickhouse-client --external --file=- --types=UInt8 --query="SELECT dummy FROM remote('[::]:9000', system, one) WHERE 1 IN _data" -- GitLab