From 3fbb61cbad1428c887f89a38c83026e58eb94d2a Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sat, 15 Aug 2015 00:07:17 +0300 Subject: [PATCH] dbms: fixed error with multiple GLOBAL subqueries [#METR-17622]. --- dbms/src/Interpreters/ExpressionAnalyzer.cpp | 18 +++++++++++------- .../00213_multiple_global_in.reference | 1 + .../0_stateless/00213_multiple_global_in.sql | 1 + 3 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/00213_multiple_global_in.reference create mode 100644 dbms/tests/queries/0_stateless/00213_multiple_global_in.sql diff --git a/dbms/src/Interpreters/ExpressionAnalyzer.cpp b/dbms/src/Interpreters/ExpressionAnalyzer.cpp index 37bd9cc15a3..c02ee22684a 100644 --- a/dbms/src/Interpreters/ExpressionAnalyzer.cpp +++ b/dbms/src/Interpreters/ExpressionAnalyzer.cpp @@ -239,9 +239,10 @@ void ExpressionAnalyzer::analyzeAggregation() void ExpressionAnalyzer::initGlobalSubqueriesAndExternalTables() { + /// Преобразует GLOBAL-подзапросы во внешние таблицы; кладёт их в словарь external_tables: name -> StoragePtr. initGlobalSubqueries(ast); - /// Создаёт словарь external_tables: name -> StoragePtr. + /// Добавляет уже существующие внешние таблицы (не подзапросы) в словарь external_tables. findExternalTables(ast); } @@ -896,10 +897,6 @@ static SharedPtr interpretSubquery( void ExpressionAnalyzer::addExternalStorage(ASTPtr & subquery_or_table_name) { - /// Сгенерируем имя для внешней таблицы. - while (context.tryGetExternalTable("_data" + toString(external_table_id))) - ++external_table_id; - if (const ASTIdentifier * table = typeid_cast(&*subquery_or_table_name)) { /// Если это уже внешняя таблица, ничего заполять не нужно. Просто запоминаем ее наличие. @@ -910,13 +907,20 @@ void ExpressionAnalyzer::addExternalStorage(ASTPtr & subquery_or_table_name) } } + /// Сгенерируем имя для внешней таблицы. + String external_table_name = "_data" + toString(external_table_id); + while (context.tryGetExternalTable(external_table_name) + || external_tables.count(external_table_name)) + { + ++external_table_id; + external_table_name = "_data" + toString(external_table_id); + } + SharedPtr interpreter = interpretSubquery(subquery_or_table_name, context, subquery_depth + 1); Block sample = interpreter->getSampleBlock(); NamesAndTypesListPtr columns = new NamesAndTypesList(sample.getColumnsList()); - String external_table_name = "_data" + toString(external_table_id); - /** Заменяем подзапрос на имя временной таблицы. * Именно в таком виде, запрос отправится на удалённый сервер. * На удалённый сервер отправится эта временная таблица, и на его стороне, diff --git a/dbms/tests/queries/0_stateless/00213_multiple_global_in.reference b/dbms/tests/queries/0_stateless/00213_multiple_global_in.reference new file mode 100644 index 00000000000..9972842f982 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00213_multiple_global_in.reference @@ -0,0 +1 @@ +1 1 diff --git a/dbms/tests/queries/0_stateless/00213_multiple_global_in.sql b/dbms/tests/queries/0_stateless/00213_multiple_global_in.sql new file mode 100644 index 00000000000..b93c2bec722 --- /dev/null +++ b/dbms/tests/queries/0_stateless/00213_multiple_global_in.sql @@ -0,0 +1 @@ +SELECT 1 GLOBAL IN (SELECT 1), 2 GLOBAL IN (SELECT 2) FROM remote('127.0.0.2', system.one);