mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-26 01:22:04 +00:00
Merge pull request #32232 from Vxider/fix-window-view-parser
Fix window view parser
This commit is contained in:
commit
e2cf5c6075
@ -238,12 +238,18 @@ struct WindowImpl<TUMBLE_START>
|
||||
|
||||
[[maybe_unused]] static ColumnPtr dispatchForColumns(const ColumnsWithTypeAndName & arguments, const String & function_name)
|
||||
{
|
||||
const auto which_type = WhichDataType(arguments[0].type);
|
||||
const auto & time_column = arguments[0];
|
||||
const auto which_type = WhichDataType(time_column.type);
|
||||
ColumnPtr result_column;
|
||||
if (which_type.isDateTime())
|
||||
result_column= WindowImpl<TUMBLE>::dispatchForColumns(arguments, function_name);
|
||||
if (arguments.size() == 1)
|
||||
{
|
||||
if (which_type.isUInt32())
|
||||
return time_column.column;
|
||||
else //isTuple
|
||||
result_column = time_column.column;
|
||||
}
|
||||
else
|
||||
result_column = arguments[0].column;
|
||||
result_column = WindowImpl<TUMBLE>::dispatchForColumns(arguments, function_name);
|
||||
return executeWindowBound(result_column, 0, function_name);
|
||||
}
|
||||
};
|
||||
@ -260,12 +266,18 @@ struct WindowImpl<TUMBLE_END>
|
||||
|
||||
[[maybe_unused]] static ColumnPtr dispatchForColumns(const ColumnsWithTypeAndName & arguments, const String& function_name)
|
||||
{
|
||||
const auto which_type = WhichDataType(arguments[0].type);
|
||||
const auto & time_column = arguments[0];
|
||||
const auto which_type = WhichDataType(time_column.type);
|
||||
ColumnPtr result_column;
|
||||
if (which_type.isDateTime())
|
||||
result_column = WindowImpl<TUMBLE>::dispatchForColumns(arguments, function_name);
|
||||
if (arguments.size() == 1)
|
||||
{
|
||||
if (which_type.isUInt32())
|
||||
return time_column.column;
|
||||
else //isTuple
|
||||
result_column = time_column.column;
|
||||
}
|
||||
else
|
||||
result_column = arguments[0].column;
|
||||
result_column = WindowImpl<TUMBLE>::dispatchForColumns(arguments, function_name);
|
||||
return executeWindowBound(result_column, 1, function_name);
|
||||
}
|
||||
};
|
||||
|
@ -89,22 +89,27 @@ namespace
|
||||
{
|
||||
data.is_tumble = t->name == "TUMBLE";
|
||||
data.is_hop = t->name == "HOP";
|
||||
auto temp_node = t->clone();
|
||||
temp_node->setAlias("");
|
||||
if (startsWith(t->arguments->children[0]->getColumnName(), "toDateTime"))
|
||||
throw Exception(
|
||||
"The first argument of window function should not be a constant value.",
|
||||
ErrorCodes::QUERY_IS_NOT_SUPPORTED_IN_WINDOW_VIEW);
|
||||
if (!data.window_function)
|
||||
{
|
||||
data.serialized_window_function = serializeAST(*temp_node);
|
||||
t->name = "WINDOW_ID";
|
||||
data.window_id_name = t->getColumnName();
|
||||
data.window_id_alias = t->alias;
|
||||
data.window_function = t->clone();
|
||||
data.window_function->setAlias("");
|
||||
data.serialized_window_function = serializeAST(*data.window_function);
|
||||
data.timestamp_column_name = t->arguments->children[0]->getColumnName();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto temp_node = t->clone();
|
||||
temp_node->setAlias("");
|
||||
if (serializeAST(*temp_node) != data.serialized_window_function)
|
||||
throw Exception("WINDOW VIEW only support ONE WINDOW FUNCTION", ErrorCodes::QUERY_IS_NOT_SUPPORTED_IN_WINDOW_VIEW);
|
||||
t->name = "WINDOW_ID";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -146,7 +151,7 @@ namespace
|
||||
|
||||
void visit(ASTFunction & node, ASTPtr & node_ptr)
|
||||
{
|
||||
if (node.name == "WINDOW_ID")
|
||||
if (node.name == "WINDOW_ID" || node.name == "TUMBLE" || node.name == "HOP")
|
||||
{
|
||||
if (const auto * t = node.arguments->children[0]->as<ASTFunction>();
|
||||
t && t->name == "now")
|
||||
@ -302,10 +307,12 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
static void extractDependentTable(ContextPtr context, ASTSelectQuery & query, String & select_database_name, String & select_table_name)
|
||||
static void extractDependentTable(ContextPtr context, ASTPtr & query, String & select_database_name, String & select_table_name)
|
||||
{
|
||||
auto db_and_table = getDatabaseAndTable(query, 0);
|
||||
ASTPtr subquery = extractTableExpression(query, 0);
|
||||
ASTSelectQuery & select_query = typeid_cast<ASTSelectQuery &>(*query);
|
||||
|
||||
auto db_and_table = getDatabaseAndTable(select_query, 0);
|
||||
ASTPtr subquery = extractTableExpression(select_query, 0);
|
||||
|
||||
if (!db_and_table && !subquery)
|
||||
return;
|
||||
@ -318,7 +325,7 @@ static void extractDependentTable(ContextPtr context, ASTSelectQuery & query, St
|
||||
{
|
||||
db_and_table->database = select_database_name;
|
||||
AddDefaultDatabaseVisitor visitor(context, select_database_name);
|
||||
visitor.visit(query);
|
||||
visitor.visit(select_query);
|
||||
}
|
||||
else
|
||||
select_database_name = db_and_table->database;
|
||||
@ -330,7 +337,7 @@ static void extractDependentTable(ContextPtr context, ASTSelectQuery & query, St
|
||||
|
||||
auto & inner_select_query = ast_select->list_of_selects->children.at(0);
|
||||
|
||||
extractDependentTable(context, inner_select_query->as<ASTSelectQuery &>(), select_database_name, select_table_name);
|
||||
extractDependentTable(context, inner_select_query, select_database_name, select_table_name);
|
||||
}
|
||||
else
|
||||
throw Exception(
|
||||
@ -938,10 +945,11 @@ StorageWindowView::StorageWindowView(
|
||||
ErrorCodes::QUERY_IS_NOT_SUPPORTED_IN_WINDOW_VIEW,
|
||||
"UNION is not supported for {}", getName());
|
||||
|
||||
ASTSelectQuery & select_query = typeid_cast<ASTSelectQuery &>(*query.select->list_of_selects->children.at(0));
|
||||
select_query = query.select->list_of_selects->children.at(0)->clone();
|
||||
String select_database_name = getContext()->getCurrentDatabase();
|
||||
String select_table_name;
|
||||
extractDependentTable(getContext(), select_query, select_database_name, select_table_name);
|
||||
auto select_query_tmp = select_query->clone();
|
||||
extractDependentTable(getContext(), select_query_tmp, select_database_name, select_table_name);
|
||||
|
||||
/// If the table is not specified - use the table `system.one`
|
||||
if (select_table_name.empty())
|
||||
@ -953,7 +961,7 @@ StorageWindowView::StorageWindowView(
|
||||
DatabaseCatalog::instance().addDependency(select_table_id, table_id_);
|
||||
|
||||
/// Extract all info from query; substitute Function_TUMPLE and Function_HOP with Function_WINDOW_ID.
|
||||
auto inner_query = innerQueryParser(select_query);
|
||||
auto inner_query = innerQueryParser(select_query->as<ASTSelectQuery &>());
|
||||
|
||||
// Parse mergeable query
|
||||
mergeable_query = inner_query->clone();
|
||||
@ -1022,7 +1030,7 @@ StorageWindowView::StorageWindowView(
|
||||
}
|
||||
|
||||
|
||||
ASTPtr StorageWindowView::innerQueryParser(ASTSelectQuery & query)
|
||||
ASTPtr StorageWindowView::innerQueryParser(const ASTSelectQuery & query)
|
||||
{
|
||||
if (!query.groupBy())
|
||||
throw Exception(ErrorCodes::INCORRECT_QUERY, "GROUP BY query is required for {}", getName());
|
||||
@ -1344,7 +1352,7 @@ Block & StorageWindowView::getHeader() const
|
||||
if (!sample_block)
|
||||
{
|
||||
sample_block = InterpreterSelectQuery(
|
||||
getFinalQuery(), window_view_context, getParentStorage(), nullptr,
|
||||
select_query->clone(), window_view_context, getParentStorage(), nullptr,
|
||||
SelectQueryOptions(QueryProcessingStage::Complete)).getSampleBlock();
|
||||
|
||||
for (size_t i = 0; i < sample_block.columns(); ++i)
|
||||
|
@ -150,7 +150,11 @@ public:
|
||||
private:
|
||||
Poco::Logger * log;
|
||||
|
||||
/// Stored query, e.g. SELECT * FROM * GROUP BY TUMBLE(now(), *)
|
||||
ASTPtr select_query;
|
||||
/// Used to generate the mergeable state of select_query, e.g. SELECT * FROM * GROUP BY WINDOW_ID(____timestamp, *)
|
||||
ASTPtr mergeable_query;
|
||||
/// Used to fetch the mergeable state and generate the final result. e.g. SELECT * FROM * GROUP BY TUMBLE(____timestamp, *)
|
||||
ASTPtr final_query;
|
||||
|
||||
ContextMutablePtr window_view_context;
|
||||
@ -208,7 +212,7 @@ private:
|
||||
|
||||
String function_now_timezone;
|
||||
|
||||
ASTPtr innerQueryParser(ASTSelectQuery & inner_query);
|
||||
ASTPtr innerQueryParser(const ASTSelectQuery & query);
|
||||
void eventTimeParser(const ASTCreateQuery & query);
|
||||
|
||||
std::shared_ptr<ASTCreateQuery> getInnerTableCreateQuery(
|
||||
|
@ -4,3 +4,4 @@
|
||||
---WITH---
|
||||
---WHERE---
|
||||
---ORDER_BY---
|
||||
---With now---
|
||||
|
@ -1,5 +1,3 @@
|
||||
-- Tags: disabled
|
||||
|
||||
SET allow_experimental_window_view = 1;
|
||||
|
||||
DROP TABLE IF EXISTS mt;
|
||||
@ -12,7 +10,7 @@ CREATE WINDOW VIEW wv WATERMARK=INTERVAL '1' SECOND AS SELECT count(a), TUMBLE_S
|
||||
|
||||
SELECT '---With w_end---';
|
||||
DROP TABLE IF EXISTS wv NO DELAY;
|
||||
CREATE WINDOW VIEW wv AS SELECT count(a), TUMBLE_START(wid) AS w_start, TUMBLE_END(wid) AS w_end FROM mt GROUP BY TUMBLE(timestamp, INTERVAL '3' SECOND) AS wid;
|
||||
CREATE WINDOW VIEW wv AS SELECT count(a), TUMBLE_START(TUMBLE(timestamp, INTERVAL '3' SECOND)) AS w_start, TUMBLE_END(wid) AS w_end FROM mt GROUP BY TUMBLE(timestamp, INTERVAL '3' SECOND) AS wid;
|
||||
|
||||
SELECT '---WithOut w_end---';
|
||||
DROP TABLE IF EXISTS wv NO DELAY;
|
||||
@ -29,3 +27,7 @@ CREATE WINDOW VIEW wv AS SELECT count(a), TUMBLE_START(wid) AS w_start FROM mt W
|
||||
SELECT '---ORDER_BY---';
|
||||
DROP TABLE IF EXISTS wv NO DELAY;
|
||||
CREATE WINDOW VIEW wv AS SELECT count(a), TUMBLE_START(wid) AS w_start FROM mt WHERE a != 1 GROUP BY TUMBLE(timestamp, INTERVAL '3' SECOND) AS wid ORDER BY w_start;
|
||||
|
||||
SELECT '---With now---';
|
||||
DROP TABLE IF EXISTS wv NO DELAY;
|
||||
CREATE WINDOW VIEW wv AS SELECT count(a), TUMBLE_START(wid) AS w_start, TUMBLE_END(TUMBLE(now(), INTERVAL '3' SECOND)) AS w_end FROM mt GROUP BY TUMBLE(now(), INTERVAL '3' SECOND) AS wid;
|
||||
|
@ -4,3 +4,4 @@
|
||||
---WITH---
|
||||
---WHERE---
|
||||
---ORDER_BY---
|
||||
---With now---
|
||||
|
@ -1,5 +1,3 @@
|
||||
-- Tags: disabled
|
||||
|
||||
SET allow_experimental_window_view = 1;
|
||||
|
||||
DROP TABLE IF EXISTS mt;
|
||||
@ -29,3 +27,7 @@ CREATE WINDOW VIEW wv AS SELECT count(a), HOP_START(wid) AS w_start FROM mt WHER
|
||||
SELECT '---ORDER_BY---';
|
||||
DROP TABLE IF EXISTS wv NO DELAY;
|
||||
CREATE WINDOW VIEW wv AS SELECT count(a), HOP_START(wid) AS w_start FROM mt WHERE a != 1 GROUP BY HOP(timestamp, INTERVAL '3' SECOND, INTERVAL '5' SECOND) AS wid ORDER BY w_start;
|
||||
|
||||
SELECT '---With now---';
|
||||
DROP TABLE IF EXISTS wv NO DELAY;
|
||||
CREATE WINDOW VIEW wv AS SELECT count(a), HOP_START(wid) AS w_start, HOP_END(HOP(now(), INTERVAL '1' SECOND, INTERVAL '3' SECOND)) as w_end FROM mt GROUP BY HOP(now(), INTERVAL '1' SECOND, INTERVAL '3' SECOND) AS wid;
|
||||
|
@ -1,5 +1,3 @@
|
||||
-- Tags: disabled
|
||||
|
||||
SET allow_experimental_window_view = 1;
|
||||
|
||||
DROP TABLE IF EXISTS mt;
|
||||
@ -11,7 +9,7 @@ CREATE TABLE mt(a Int32) ENGINE=MergeTree ORDER BY tuple();
|
||||
CREATE WINDOW VIEW wv TO dst AS SELECT count(a) AS count FROM mt GROUP BY TUMBLE(now('US/Samoa'), INTERVAL '1' SECOND, 'US/Samoa') AS wid;
|
||||
|
||||
INSERT INTO mt VALUES (1);
|
||||
SELECT sleep(2);
|
||||
SELECT sleep(3);
|
||||
SELECT count from dst;
|
||||
|
||||
DROP TABLE wv;
|
||||
|
@ -1,5 +1,3 @@
|
||||
-- Tags: disabled
|
||||
|
||||
SET allow_experimental_window_view = 1;
|
||||
|
||||
DROP TABLE IF EXISTS mt;
|
||||
@ -11,7 +9,7 @@ CREATE TABLE mt(a Int32) ENGINE=MergeTree ORDER BY tuple();
|
||||
CREATE WINDOW VIEW wv TO dst AS SELECT count(a) AS count FROM mt GROUP BY HOP(now('US/Samoa'), INTERVAL '1' SECOND, INTERVAL '1' SECOND, 'US/Samoa') AS wid;
|
||||
|
||||
INSERT INTO mt VALUES (1);
|
||||
SELECT sleep(2);
|
||||
SELECT sleep(3);
|
||||
SELECT count from dst;
|
||||
|
||||
DROP TABLE wv;
|
||||
|
@ -1,5 +1,3 @@
|
||||
-- Tags: disabled
|
||||
|
||||
SET allow_experimental_window_view = 1;
|
||||
|
||||
DROP TABLE IF EXISTS mt;
|
||||
|
@ -1,5 +1,3 @@
|
||||
-- Tags: disabled
|
||||
|
||||
SET allow_experimental_window_view = 1;
|
||||
|
||||
DROP TABLE IF EXISTS mt;
|
||||
|
@ -1,5 +1,3 @@
|
||||
-- Tags: disabled
|
||||
|
||||
SET allow_experimental_window_view = 1;
|
||||
|
||||
DROP TABLE IF EXISTS mt;
|
||||
@ -19,7 +17,7 @@ INSERT INTO mt VALUES (1, '1990/01/01 12:00:10');
|
||||
INSERT INTO mt VALUES (1, '1990/01/01 12:00:11');
|
||||
INSERT INTO mt VALUES (1, '1990/01/01 12:00:30');
|
||||
|
||||
SELECT sleep(1);
|
||||
SELECT sleep(3);
|
||||
SELECT * from dst order by w_end;
|
||||
|
||||
DROP TABLE wv;
|
||||
|
@ -1,5 +1,3 @@
|
||||
-- Tags: disabled
|
||||
|
||||
SET allow_experimental_window_view = 1;
|
||||
|
||||
DROP TABLE IF EXISTS mt;
|
||||
@ -19,7 +17,7 @@ INSERT INTO mt VALUES (1, '1990/01/01 12:00:10');
|
||||
INSERT INTO mt VALUES (1, '1990/01/01 12:00:11');
|
||||
INSERT INTO mt VALUES (1, '1990/01/01 12:00:30');
|
||||
|
||||
SELECT sleep(1);
|
||||
SELECT sleep(3);
|
||||
SELECT * from dst order by w_end;
|
||||
|
||||
DROP TABLE wv;
|
||||
|
@ -1,5 +1,3 @@
|
||||
-- Tags: disabled
|
||||
|
||||
SET allow_experimental_window_view = 1;
|
||||
|
||||
DROP TABLE IF EXISTS mt;
|
||||
@ -20,7 +18,7 @@ INSERT INTO mt VALUES (1, '1990/01/01 12:00:10');
|
||||
INSERT INTO mt VALUES (1, '1990/01/01 12:00:11');
|
||||
INSERT INTO mt VALUES (1, '1990/01/01 12:00:30');
|
||||
|
||||
SELECT sleep(1);
|
||||
SELECT sleep(3);
|
||||
SELECT * from dst order by w_end;
|
||||
|
||||
DROP TABLE wv;
|
||||
|
@ -1,5 +1,3 @@
|
||||
-- Tags: disabled
|
||||
|
||||
SET allow_experimental_window_view = 1;
|
||||
|
||||
DROP TABLE IF EXISTS mt;
|
||||
@ -20,7 +18,7 @@ INSERT INTO mt VALUES (1, '1990/01/01 12:00:10');
|
||||
INSERT INTO mt VALUES (1, '1990/01/01 12:00:11');
|
||||
INSERT INTO mt VALUES (1, '1990/01/01 12:00:30');
|
||||
|
||||
SELECT sleep(1);
|
||||
SELECT sleep(3);
|
||||
SELECT * from dst order by w_end;
|
||||
|
||||
DROP TABLE wv;
|
||||
|
@ -1,5 +1,3 @@
|
||||
-- Tags: disabled
|
||||
|
||||
SET allow_experimental_window_view = 1;
|
||||
|
||||
DROP TABLE IF EXISTS mt;
|
||||
@ -20,7 +18,7 @@ INSERT INTO mt VALUES (1, '1990/01/01 12:00:10');
|
||||
INSERT INTO mt VALUES (1, '1990/01/01 12:00:11');
|
||||
INSERT INTO mt VALUES (1, '1990/01/01 12:00:30');
|
||||
|
||||
SELECT sleep(1);
|
||||
SELECT sleep(3);
|
||||
SELECT * from dst order by w_end;
|
||||
|
||||
DROP TABLE wv;
|
||||
|
@ -1,5 +1,3 @@
|
||||
-- Tags: disabled
|
||||
|
||||
SET allow_experimental_window_view = 1;
|
||||
|
||||
DROP TABLE IF EXISTS mt;
|
||||
@ -19,7 +17,7 @@ INSERT INTO mt VALUES (1, '1990/01/01 12:00:10');
|
||||
INSERT INTO mt VALUES (1, '1990/01/01 12:00:11');
|
||||
INSERT INTO mt VALUES (1, '1990/01/01 12:00:30');
|
||||
|
||||
SELECT sleep(1);
|
||||
SELECT sleep(3);
|
||||
SELECT * from dst order by w_end;
|
||||
|
||||
DROP TABLE wv NO DELAY;
|
||||
|
@ -1,5 +1,3 @@
|
||||
-- Tags: disabled
|
||||
|
||||
SET allow_experimental_window_view = 1;
|
||||
|
||||
DROP TABLE IF EXISTS mt;
|
||||
@ -23,7 +21,7 @@ INSERT INTO mt VALUES (1, '1990/01/01 12:00:07');
|
||||
INSERT INTO mt VALUES (1, '1990/01/01 12:00:10');
|
||||
INSERT INTO mt VALUES (1, '1990/01/01 12:00:11');
|
||||
|
||||
SELECT sleep(1);
|
||||
SELECT sleep(3);
|
||||
SELECT * from dst order by w_end, count;
|
||||
|
||||
DROP TABLE wv;
|
||||
|
@ -1,5 +1,3 @@
|
||||
-- Tags: disabled
|
||||
|
||||
SET allow_experimental_window_view = 1;
|
||||
|
||||
DROP TABLE IF EXISTS mt;
|
||||
@ -23,7 +21,7 @@ INSERT INTO mt VALUES (1, '1990/01/01 12:00:07');
|
||||
INSERT INTO mt VALUES (1, '1990/01/01 12:00:10');
|
||||
INSERT INTO mt VALUES (1, '1990/01/01 12:00:11');
|
||||
|
||||
SELECT sleep(1);
|
||||
SELECT sleep(3);
|
||||
SELECT * from dst order by w_end, count;
|
||||
|
||||
DROP TABLE wv;
|
||||
|
@ -1,5 +1,3 @@
|
||||
-- Tags: disabled
|
||||
|
||||
SET allow_experimental_window_view = 1;
|
||||
|
||||
DROP TABLE IF EXISTS mt;
|
||||
@ -24,7 +22,7 @@ INSERT INTO mt VALUES (1, '1990/01/01 12:00:10');
|
||||
INSERT INTO mt VALUES (1, '1990/01/01 12:00:11');
|
||||
INSERT INTO mt VALUES (1, '1990/01/01 12:00:12');
|
||||
|
||||
SELECT sleep(1);
|
||||
SELECT sleep(3);
|
||||
SELECT * from dst order by w_end, count;
|
||||
|
||||
DROP TABLE wv;
|
||||
|
Loading…
Reference in New Issue
Block a user