diff --git a/src/Interpreters/RequiredSourceColumnsData.h b/src/Interpreters/RequiredSourceColumnsData.h index 3334cea5565..94c3294c8b7 100644 --- a/src/Interpreters/RequiredSourceColumnsData.h +++ b/src/Interpreters/RequiredSourceColumnsData.h @@ -51,6 +51,21 @@ struct RequiredSourceColumnsData NameSet requiredColumns() const; size_t nameInclusion(const String & name) const; + + /// proton: starts + bool needsScanAgain() const + { + if (complex_aliases.empty()) + return false; + + for (const auto & alias : complex_aliases) + { + if (!masked_columns.contains(alias) && required_names.contains(alias)) + return true; + } + return false; + } + /// proton: ends }; std::ostream & operator << (std::ostream & os, const RequiredSourceColumnsData & cols); diff --git a/src/Interpreters/RequiredSourceColumnsVisitor.cpp b/src/Interpreters/RequiredSourceColumnsVisitor.cpp index f86adc46cd9..cff0e1da2a5 100644 --- a/src/Interpreters/RequiredSourceColumnsVisitor.cpp +++ b/src/Interpreters/RequiredSourceColumnsVisitor.cpp @@ -144,6 +144,12 @@ void RequiredSourceColumnsMatcher::visit(const ASTSelectQuery & select, const AS /// revisit select_expression_list (with children) when all the aliases are set Visitor(data).visit(select.select()); + + /// proton: starts + /// revisit select_expression_list again (see issue https://github.com/timeplus-io/proton/issues/356 ) + if (data.needsScanAgain()) + Visitor(data).visit(select.select()); + /// proton: ends } void RequiredSourceColumnsMatcher::visit(const ASTIdentifier & node, const ASTPtr &, Data & data) diff --git a/tests/stream/test_stream_smoke/0099_fixed_issues.json b/tests/stream/test_stream_smoke/0099_fixed_issues.json index 54711c352c0..2733335e0bc 100644 --- a/tests/stream/test_stream_smoke/0099_fixed_issues.json +++ b/tests/stream/test_stream_smoke/0099_fixed_issues.json @@ -597,6 +597,38 @@ [3, 2] ]} ] - } + }, + { + "id": 21, + "tags": ["parser", "tree-rewriter"], + "name": "#356", + "description": "Fix parser opt bug. below 2 select query only change the order.", + "steps":[ + { + "statements": [ + {"client":"python", "query_type": "table", "query": "drop stream if exists cte1"}, + {"client":"python", "query_type": "table", "query": "drop stream if exists cte2"}, + {"client":"python", "query_type": "table", "exist": "cte1", "wait":1, "query": "create stream if not exists cte1(`Id` int32, `OrderQty` float, `LastQty` float);"}, + {"client":"python", "query_type": "table", "exist": "cte2", "wait":1, "query": "create stream if not exists cte2(`Id` int32, `OrderQty` float, `LastQty` float);"}, + {"client":"python", "query_type": "stream", "depends_on_stream":"cte1", "query_id":"9921_1", "query_end_timer":"3", "query":" SELECT least(cte1.LastQty, cte2.LastQty) AS OrderQty, cte1.LastQty + cte1.OrderQty AS LastQty FROM cte1 INNER JOIN cte2 ON cte1.Id = cte2.Id;"}, + {"client":"python", "query_type": "stream", "depends_on_stream":"cte1", "query_id":"9921_2", "query_end_timer":"3", "query":" SELECT cte1.LastQty + cte1.OrderQty AS LastQty, least(cte1.LastQty, cte2.LastQty) AS OrderQty FROM cte1 INNER JOIN cte2 ON cte1.Id = cte2.Id;"}, + {"client":"python", "query_type": "table", "depends_on_stream": "cte1", "wait":1, "query": "insert into cte1(Id, OrderQty, LastQty) values(1, 10, 2)(2, 15, 3)(3,20,4)"}, + {"client":"python", "query_type": "table", "depends_on_stream": "cte2", "wait":1, "query": "insert into cte2(Id, OrderQty, LastQty) values(1, 10, 2)(2, 15, 3)(3,20,4)"} + ] + } + ], + "expected_results": [ + {"query_id":"9921_1", "expected_results":[ + [2.0, 12.0], + [3.0, 18.0], + [4.0, 24.0] + ]}, + {"query_id":"9921_2", "expected_results":[ + [12.0, 2.0], + [18.0, 3.0], + [24.0, 4.0] + ]} + ] + } ] } \ No newline at end of file