Merge pull request #37849 from ClickHouse/bug-with-fill-date

Enforce equality of WITH FILL type with ORDER BY column's type for date/time types.
This commit is contained in:
Nikolai Kochetov 2022-07-27 12:27:53 +02:00 committed by GitHub
commit 873432fb53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 7 deletions

View File

@ -28,7 +28,9 @@ struct FillColumnDescription
/// All missed values in range [FROM, TO) will be filled
/// Range [FROM, TO) respects sorting direction
Field fill_from; /// Fill value >= FILL_FROM
DataTypePtr fill_from_type;
Field fill_to; /// Fill value + STEP < FILL_TO
DataTypePtr fill_to_type;
Field fill_step; /// Default = +1 or -1 according to direction
std::optional<IntervalKind> step_kind;

View File

@ -873,14 +873,15 @@ Block InterpreterSelectQuery::getSampleBlockImpl()
return analysis_result.final_projection->getResultColumns();
}
static Field getWithFillFieldValue(const ASTPtr & node, const ContextPtr & context)
static std::pair<Field, DataTypePtr> getWithFillFieldValue(const ASTPtr & node, ContextPtr context)
{
auto [field, type] = evaluateConstantExpression(node, context);
auto field_type = evaluateConstantExpression(node, context);
if (!isColumnedAsNumber(type))
throw Exception("Illegal type " + type->getName() + " of WITH FILL expression, must be numeric type", ErrorCodes::INVALID_WITH_FILL_EXPRESSION);
if (!isColumnedAsNumber(field_type.second))
throw Exception("Illegal type " + field_type.second->getName() + " of WITH FILL expression, must be numeric type", ErrorCodes::INVALID_WITH_FILL_EXPRESSION);
return field;
return field_type;
}
static std::pair<Field, std::optional<IntervalKind>> getWithFillStep(const ASTPtr & node, const ContextPtr & context)
@ -901,9 +902,9 @@ static FillColumnDescription getWithFillDescription(const ASTOrderByElement & or
FillColumnDescription descr;
if (order_by_elem.fill_from)
descr.fill_from = getWithFillFieldValue(order_by_elem.fill_from, context);
std::tie(descr.fill_from, descr.fill_from_type) = getWithFillFieldValue(order_by_elem.fill_from, context);
if (order_by_elem.fill_to)
descr.fill_to = getWithFillFieldValue(order_by_elem.fill_to, context);
std::tie(descr.fill_to, descr.fill_to_type) = getWithFillFieldValue(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);

View File

@ -54,6 +54,23 @@ static bool tryConvertFields(FillColumnDescription & descr, const DataTypePtr &
WhichDataType which(type);
DataTypePtr to_type;
/// For Date/DateTime types TO/FROM type should match column type
if (descr.fill_from_type)
{
WhichDataType which_from(descr.fill_from_type);
if ((which_from.isDateOrDate32() || which_from.isDateTime() || which_from.isDateTime64()) &&
!descr.fill_from_type->equals(*type))
return false;
}
if (descr.fill_to_type)
{
WhichDataType which_to(descr.fill_to_type);
if ((which_to.isDateOrDate32() || which_to.isDateTime() || which_to.isDateTime64()) &&
!descr.fill_to_type->equals(*type))
return false;
}
/// TODO Wrong results for big integers.
if (isInteger(type) || which.isDate() || which.isDate32() || which.isDateTime())
{

View File

@ -0,0 +1,6 @@
-- Tags: no-backward-compatibility-check
SELECT toDate('2022-02-01') AS d1
FROM numbers(18) AS number
ORDER BY d1 ASC WITH FILL FROM toDateTime('2022-02-01') TO toDateTime('2022-07-01') STEP toIntervalMonth(1); -- { serverError 475 }