From 0a063820c7980005920bcbf713d1fe170d5ffaf5 Mon Sep 17 00:00:00 2001 From: Yakov Olkhovskiy Date: Sat, 4 Jun 2022 01:35:41 -0400 Subject: [PATCH] WITH FILL of date/time type must be equal to type of ORDER BY column --- src/Interpreters/InterpreterSelectQuery.cpp | 38 ++++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/src/Interpreters/InterpreterSelectQuery.cpp b/src/Interpreters/InterpreterSelectQuery.cpp index fbafb98e0d8..5d9baadbfdf 100644 --- a/src/Interpreters/InterpreterSelectQuery.cpp +++ b/src/Interpreters/InterpreterSelectQuery.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -802,10 +803,14 @@ Block InterpreterSelectQuery::getSampleBlockImpl() return analysis_result.final_projection->getResultColumns(); } -static Field getWithFillFieldValue(const ASTPtr & node, ContextPtr context) +static Field getWithFillFieldValue(DataTypePtr col_type, const ASTPtr & node, ContextPtr context) { auto [field, type] = evaluateConstantExpression(node, context); + WhichDataType which(col_type); + if ((which.isDateOrDate32() || which.isDateTime() || which.isDateTime64()) && !col_type->equals(*type)) + throw Exception("Illegal type " + type->getName() + " of WITH FILL expression, must be same as column " + col_type->getName(), ErrorCodes::INVALID_WITH_FILL_EXPRESSION); + if (!isColumnedAsNumber(type)) throw Exception("Illegal type " + type->getName() + " of WITH FILL expression, must be numeric type", ErrorCodes::INVALID_WITH_FILL_EXPRESSION); @@ -825,14 +830,14 @@ static std::pair> getWithFillStep(const ASTPt throw Exception("Illegal type " + type->getName() + " of WITH FILL expression, must be numeric type", ErrorCodes::INVALID_WITH_FILL_EXPRESSION); } -static FillColumnDescription getWithFillDescription(const ASTOrderByElement & order_by_elem, ContextPtr context) +static FillColumnDescription getWithFillDescription(DataTypePtr type, const ASTOrderByElement & order_by_elem, ContextPtr context) { FillColumnDescription descr; if (order_by_elem.fill_from) - descr.fill_from = getWithFillFieldValue(order_by_elem.fill_from, context); + descr.fill_from = getWithFillFieldValue(type, order_by_elem.fill_from, context); if (order_by_elem.fill_to) - descr.fill_to = getWithFillFieldValue(order_by_elem.fill_to, context); + descr.fill_to = getWithFillFieldValue(type, order_by_elem.fill_to, context); if (order_by_elem.fill_step) std::tie(descr.fill_step, descr.step_kind) = getWithFillStep(order_by_elem.fill_step, context); @@ -872,7 +877,7 @@ static FillColumnDescription getWithFillDescription(const ASTOrderByElement & or return descr; } -static SortDescription getSortDescription(const ASTSelectQuery & query, ContextPtr context) +static SortDescription getSortDescription(const ASTSelectQuery & query, const Block & result_block, const Aliases & aliases, ContextPtr context) { SortDescription order_descr; order_descr.reserve(query.orderBy()->children.size()); @@ -886,7 +891,14 @@ static SortDescription getSortDescription(const ASTSelectQuery & query, ContextP collator = std::make_shared(order_by_elem.collation->as().value.get()); if (order_by_elem.with_fill) { - FillColumnDescription fill_desc = getWithFillDescription(order_by_elem, context); + auto column = result_block.findByName(name); + if (!column) + for (auto &[alias, ast] : aliases) + if (name == ast->getColumnName()) + if ((column = result_block.findByName(alias))) + break; + + FillColumnDescription fill_desc = getWithFillDescription(column->type, order_by_elem, context); order_descr.emplace_back(name, order_by_elem.direction, order_by_elem.nulls_direction, collator, true, fill_desc); } else @@ -1492,7 +1504,7 @@ void InterpreterSelectQuery::executeImpl(QueryPlan & query_plan, std::optional

aliases, context); for (auto & desc : order_descr) if (desc.with_fill) { @@ -2105,7 +2117,7 @@ void InterpreterSelectQuery::executeFetchColumns(QueryProcessingStage::Enum proc // TODO Do we need a projection variant for this field? query, analysis_result.order_by_elements_actions, - getSortDescription(query, context), + getSortDescription(query, result_header, syntax_analyzer_result->aliases, context), query_info.syntax_analyzer_result); } else @@ -2113,7 +2125,7 @@ void InterpreterSelectQuery::executeFetchColumns(QueryProcessingStage::Enum proc query_info.order_optimizer = std::make_shared( query, analysis_result.order_by_elements_actions, - getSortDescription(query, context), + getSortDescription(query, result_header, syntax_analyzer_result->aliases, context), query_info.syntax_analyzer_result); } } @@ -2542,7 +2554,7 @@ void InterpreterSelectQuery::executeOrderOptimized(QueryPlan & query_plan, Input void InterpreterSelectQuery::executeOrder(QueryPlan & query_plan, InputOrderInfoPtr input_sorting_info) { auto & query = getSelectQuery(); - SortDescription output_order_descr = getSortDescription(query, context); + SortDescription output_order_descr = getSortDescription(query, result_header, syntax_analyzer_result->aliases, context); UInt64 limit = getLimitForSorting(query, context); if (input_sorting_info) @@ -2580,7 +2592,7 @@ void InterpreterSelectQuery::executeOrder(QueryPlan & query_plan, InputOrderInfo void InterpreterSelectQuery::executeMergeSorted(QueryPlan & query_plan, const std::string & description) { auto & query = getSelectQuery(); - SortDescription order_descr = getSortDescription(query, context); + SortDescription order_descr = getSortDescription(query, result_header, syntax_analyzer_result->aliases, context); UInt64 limit = getLimitForSorting(query, context); executeMergeSorted(query_plan, order_descr, limit, description); @@ -2683,7 +2695,7 @@ void InterpreterSelectQuery::executeWithFill(QueryPlan & query_plan) auto & query = getSelectQuery(); if (query.orderBy()) { - SortDescription order_descr = getSortDescription(query, context); + SortDescription order_descr = getSortDescription(query, result_header, syntax_analyzer_result->aliases, context); SortDescription fill_descr; for (auto & desc : order_descr) { @@ -2734,7 +2746,7 @@ void InterpreterSelectQuery::executeLimit(QueryPlan & query_plan) { if (!query.orderBy()) throw Exception("LIMIT WITH TIES without ORDER BY", ErrorCodes::LOGICAL_ERROR); - order_descr = getSortDescription(query, context); + order_descr = getSortDescription(query, result_header, syntax_analyzer_result->aliases, context); } auto limit = std::make_unique(