mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-14 18:32:29 +00:00
WITH FILL of date/time type must be equal to type of ORDER BY column
This commit is contained in:
parent
b7e8bbb154
commit
0a063820c7
@ -1,5 +1,6 @@
|
|||||||
#include <DataTypes/DataTypeAggregateFunction.h>
|
#include <DataTypes/DataTypeAggregateFunction.h>
|
||||||
#include <DataTypes/DataTypeInterval.h>
|
#include <DataTypes/DataTypeInterval.h>
|
||||||
|
#include <DataTypes/DataTypeDate.h>
|
||||||
|
|
||||||
#include <Parsers/ASTFunction.h>
|
#include <Parsers/ASTFunction.h>
|
||||||
#include <Parsers/ASTIdentifier.h>
|
#include <Parsers/ASTIdentifier.h>
|
||||||
@ -802,10 +803,14 @@ Block InterpreterSelectQuery::getSampleBlockImpl()
|
|||||||
return analysis_result.final_projection->getResultColumns();
|
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);
|
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))
|
if (!isColumnedAsNumber(type))
|
||||||
throw Exception("Illegal type " + type->getName() + " of WITH FILL expression, must be numeric type", ErrorCodes::INVALID_WITH_FILL_EXPRESSION);
|
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<Field, std::optional<IntervalKind>> getWithFillStep(const ASTPt
|
|||||||
throw Exception("Illegal type " + type->getName() + " of WITH FILL expression, must be numeric type", ErrorCodes::INVALID_WITH_FILL_EXPRESSION);
|
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;
|
FillColumnDescription descr;
|
||||||
|
|
||||||
if (order_by_elem.fill_from)
|
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)
|
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)
|
if (order_by_elem.fill_step)
|
||||||
std::tie(descr.fill_step, descr.step_kind) = getWithFillStep(order_by_elem.fill_step, context);
|
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;
|
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;
|
SortDescription order_descr;
|
||||||
order_descr.reserve(query.orderBy()->children.size());
|
order_descr.reserve(query.orderBy()->children.size());
|
||||||
@ -886,7 +891,14 @@ static SortDescription getSortDescription(const ASTSelectQuery & query, ContextP
|
|||||||
collator = std::make_shared<Collator>(order_by_elem.collation->as<ASTLiteral &>().value.get<String>());
|
collator = std::make_shared<Collator>(order_by_elem.collation->as<ASTLiteral &>().value.get<String>());
|
||||||
if (order_by_elem.with_fill)
|
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);
|
order_descr.emplace_back(name, order_by_elem.direction, order_by_elem.nulls_direction, collator, true, fill_desc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1492,7 +1504,7 @@ void InterpreterSelectQuery::executeImpl(QueryPlan & query_plan, std::optional<P
|
|||||||
bool has_withfill = false;
|
bool has_withfill = false;
|
||||||
if (query.orderBy())
|
if (query.orderBy())
|
||||||
{
|
{
|
||||||
SortDescription order_descr = getSortDescription(query, context);
|
SortDescription order_descr = getSortDescription(query, result_header, syntax_analyzer_result->aliases, context);
|
||||||
for (auto & desc : order_descr)
|
for (auto & desc : order_descr)
|
||||||
if (desc.with_fill)
|
if (desc.with_fill)
|
||||||
{
|
{
|
||||||
@ -2105,7 +2117,7 @@ void InterpreterSelectQuery::executeFetchColumns(QueryProcessingStage::Enum proc
|
|||||||
// TODO Do we need a projection variant for this field?
|
// TODO Do we need a projection variant for this field?
|
||||||
query,
|
query,
|
||||||
analysis_result.order_by_elements_actions,
|
analysis_result.order_by_elements_actions,
|
||||||
getSortDescription(query, context),
|
getSortDescription(query, result_header, syntax_analyzer_result->aliases, context),
|
||||||
query_info.syntax_analyzer_result);
|
query_info.syntax_analyzer_result);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2113,7 +2125,7 @@ void InterpreterSelectQuery::executeFetchColumns(QueryProcessingStage::Enum proc
|
|||||||
query_info.order_optimizer = std::make_shared<ReadInOrderOptimizer>(
|
query_info.order_optimizer = std::make_shared<ReadInOrderOptimizer>(
|
||||||
query,
|
query,
|
||||||
analysis_result.order_by_elements_actions,
|
analysis_result.order_by_elements_actions,
|
||||||
getSortDescription(query, context),
|
getSortDescription(query, result_header, syntax_analyzer_result->aliases, context),
|
||||||
query_info.syntax_analyzer_result);
|
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)
|
void InterpreterSelectQuery::executeOrder(QueryPlan & query_plan, InputOrderInfoPtr input_sorting_info)
|
||||||
{
|
{
|
||||||
auto & query = getSelectQuery();
|
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);
|
UInt64 limit = getLimitForSorting(query, context);
|
||||||
|
|
||||||
if (input_sorting_info)
|
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)
|
void InterpreterSelectQuery::executeMergeSorted(QueryPlan & query_plan, const std::string & description)
|
||||||
{
|
{
|
||||||
auto & query = getSelectQuery();
|
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);
|
UInt64 limit = getLimitForSorting(query, context);
|
||||||
|
|
||||||
executeMergeSorted(query_plan, order_descr, limit, description);
|
executeMergeSorted(query_plan, order_descr, limit, description);
|
||||||
@ -2683,7 +2695,7 @@ void InterpreterSelectQuery::executeWithFill(QueryPlan & query_plan)
|
|||||||
auto & query = getSelectQuery();
|
auto & query = getSelectQuery();
|
||||||
if (query.orderBy())
|
if (query.orderBy())
|
||||||
{
|
{
|
||||||
SortDescription order_descr = getSortDescription(query, context);
|
SortDescription order_descr = getSortDescription(query, result_header, syntax_analyzer_result->aliases, context);
|
||||||
SortDescription fill_descr;
|
SortDescription fill_descr;
|
||||||
for (auto & desc : order_descr)
|
for (auto & desc : order_descr)
|
||||||
{
|
{
|
||||||
@ -2734,7 +2746,7 @@ void InterpreterSelectQuery::executeLimit(QueryPlan & query_plan)
|
|||||||
{
|
{
|
||||||
if (!query.orderBy())
|
if (!query.orderBy())
|
||||||
throw Exception("LIMIT WITH TIES without ORDER BY", ErrorCodes::LOGICAL_ERROR);
|
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<LimitStep>(
|
auto limit = std::make_unique<LimitStep>(
|
||||||
|
Loading…
Reference in New Issue
Block a user