UNION ALL: mismatch size #1444 (#1446)

* UNION ALL: mismatch size #1444

* Fix test reference

* restore InterpreterSelectQuery::initQueryAnalyzer
This commit is contained in:
proller 2017-12-22 21:30:42 +03:00 committed by alexey-milovidov
parent daab7adf6f
commit 4f2b4efa25
4 changed files with 87 additions and 4 deletions

View File

@ -100,11 +100,30 @@ void InterpreterSelectQuery::init(const BlockInputStreamPtr & input, const Names
}
}
renameColumns();
if (!required_column_names.empty())
rewriteExpressionList(required_column_names);
if (is_first_select_inside_union_all && (hasAsterisk()))
{
basicInit(input);
basicInit(input);
// We execute this code here, because otherwise the following kind of query would not work
// SELECT X FROM (SELECT * FROM (SELECT 1 AS X, 2 AS Y) UNION ALL SELECT 3, 4)
// because the asterisk is replaced with columns only when query_analyzer objects are created in basicInit().
renameColumns();
if (!required_column_names.empty() && (table_column_names.size() != required_column_names.size()))
{
rewriteExpressionList(required_column_names);
/// Now there is obsolete information to execute the query. We update this information.
initQueryAnalyzer();
}
}
else
{
renameColumns();
if (!required_column_names.empty())
rewriteExpressionList(required_column_names);
basicInit(input);
}
}
bool InterpreterSelectQuery::hasAggregation(const ASTSelectQuery & query_ptr)
@ -188,6 +207,16 @@ void InterpreterSelectQuery::basicInit(const BlockInputStreamPtr & input)
}
}
void InterpreterSelectQuery::initQueryAnalyzer()
{
query_analyzer.reset(
new ExpressionAnalyzer(query_ptr, context, storage, table_column_names, subquery_depth, !only_analyze));
for (auto p = next_select_in_union_all.get(); p != nullptr; p = p->next_select_in_union_all.get())
p->query_analyzer.reset(
new ExpressionAnalyzer(p->query_ptr, p->context, p->storage, p->table_column_names, p->subquery_depth, !only_analyze));
}
InterpreterSelectQuery::InterpreterSelectQuery(const ASTPtr & query_ptr_, const Context & context_, QueryProcessingStage::Enum to_stage_,
size_t subquery_depth_, BlockInputStreamPtr input)
: query_ptr(query_ptr_)

View File

@ -100,6 +100,7 @@ private:
void init(const BlockInputStreamPtr & input, const Names & required_column_names = Names{});
void basicInit(const BlockInputStreamPtr & input);
void initQueryAnalyzer();
bool hasAggregation(const ASTSelectQuery & query_ptr);
/// Execute one SELECT query from the UNION ALL chain.

View File

@ -8,3 +8,15 @@ NOW BAD ==========================:
34
34
finish ===========================;
* A UNION * B:
A 1970-01-01 03:00:01
B 1970-01-01 03:00:02
Event, Datetime A UNION * B:
A 1970-01-01 03:00:01
B 1970-01-01 03:00:02
* A UNION Event, Datetime B:
A 1970-01-01 03:00:01
B 1970-01-01 03:00:02
Event, Datetime A UNION Event, Datetime B:
A 1970-01-01 03:00:01
B 1970-01-01 03:00:02

View File

@ -15,3 +15,44 @@ SELECT * FROM ( SELECT CounterID FROM remote('localhost', 'test', 'globalin') WH
SELECT 'finish ===========================;';
DROP TABLE test.globalin;
DROP TABLE IF EXISTS test.union_bug;
CREATE TABLE test.union_bug (
Event String,
Datetime DateTime
) Engine = Memory;
INSERT INTO test.union_bug VALUES ('A', 1), ('B', 2);
SELECT ' * A UNION * B:';
SELECT * FROM (
SELECT * FROM test.union_bug WHERE Event = 'A'
UNION ALL
SELECT * FROM test.union_bug WHERE Event = 'B'
) ORDER BY Datetime;
SELECT ' Event, Datetime A UNION * B:';
SELECT * FROM (
SELECT Event, Datetime FROM test.union_bug WHERE Event = 'A'
UNION ALL
SELECT * FROM test.union_bug WHERE Event = 'B'
) ORDER BY Datetime;
SELECT ' * A UNION Event, Datetime B:';
SELECT * FROM (
SELECT * FROM test.union_bug WHERE Event = 'A'
UNION ALL
SELECT Event, Datetime FROM test.union_bug WHERE Event = 'B'
) ORDER BY Datetime;
SELECT ' Event, Datetime A UNION Event, Datetime B:';
SELECT * FROM (
SELECT Event, Datetime FROM test.union_bug WHERE Event = 'A'
UNION ALL
SELECT Event, Datetime FROM test.union_bug WHERE Event = 'B'
) ORDER BY Datetime;
DROP TABLE test.union_bug;