diff --git a/src/Functions/FunctionsComparison.h b/src/Functions/FunctionsComparison.h index 389b150e381..b9c7c211b74 100644 --- a/src/Functions/FunctionsComparison.h +++ b/src/Functions/FunctionsComparison.h @@ -1218,17 +1218,36 @@ public: { return res; } - else if ((isColumnedAsDecimal(left_type) || isColumnedAsDecimal(right_type)) - // Comparing Date and DateTime64 requires implicit conversion, - // otherwise Date is treated as number. - && !(date_and_datetime && (isDate(left_type) || isDate(right_type)))) + else if ((isColumnedAsDecimal(left_type) || isColumnedAsDecimal(right_type))) { - // compare - if (!allowDecimalComparison(left_type, right_type) && !date_and_datetime) - throw Exception("No operation " + getName() + " between " + left_type->getName() + " and " + right_type->getName(), - ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); + // Comparing Date and DateTime64 requires implicit conversion, + if (date_and_datetime && (isDate(left_type) || isDate(right_type))) + { + DataTypePtr common_type = getLeastSupertype({left_type, right_type}); + ColumnPtr c0_converted = castColumn(col_with_type_and_name_left, common_type); + ColumnPtr c1_converted = castColumn(col_with_type_and_name_right, common_type); + return executeDecimal({c0_converted, common_type, "left"}, {c1_converted, common_type, "right"}); + } + else + { + // compare + if (!allowDecimalComparison(left_type, right_type) && !date_and_datetime) + throw Exception( + "No operation " + getName() + " between " + left_type->getName() + " and " + right_type->getName(), + ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); + return executeDecimal(col_with_type_and_name_left, col_with_type_and_name_right); + } - return executeDecimal(col_with_type_and_name_left, col_with_type_and_name_right); + } + else if (date_and_datetime) + { + DataTypePtr common_type = getLeastSupertype({left_type, right_type}); + ColumnPtr c0_converted = castColumn(col_with_type_and_name_left, common_type); + ColumnPtr c1_converted = castColumn(col_with_type_and_name_right, common_type); + if (!((res = executeNumLeftType(c0_converted.get(), c1_converted.get())) + || (res = executeNumLeftType(c0_converted.get(), c1_converted.get())))) + throw Exception("Date related common types can only be UInt32 or UInt64", ErrorCodes::LOGICAL_ERROR); + return res; } else if (left_type->equals(*right_type)) { diff --git a/tests/performance/datetime_comparison.xml b/tests/performance/datetime_comparison.xml index 2d47ded0b1a..8d7b0c8c4de 100644 --- a/tests/performance/datetime_comparison.xml +++ b/tests/performance/datetime_comparison.xml @@ -2,4 +2,5 @@ SELECT count() FROM numbers(1000000000) WHERE materialize(now()) > toString(toDateTime('2020-09-30 00:00:00')) SELECT count() FROM numbers(1000000000) WHERE materialize(now()) > toUInt32(toDateTime('2020-09-30 00:00:00')) SELECT count() FROM numbers(1000000000) WHERE materialize(now()) > toDateTime('2020-09-30 00:00:00') + SELECT count() FROM numbers(1000000000) WHERE materialize(now()) > toDate('2020-09-30 00:00:00')