mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-29 11:02:08 +00:00
Merge pull request #68881 from ClickHouse/backport/24.3/68323
Backport #68323 to 24.3: Fix small value DateTime64 constant folding in nested subquery for remote
This commit is contained in:
commit
515fd331e7
@ -11,6 +11,7 @@
|
|||||||
#include <IO/Operators.h>
|
#include <IO/Operators.h>
|
||||||
|
|
||||||
#include <DataTypes/FieldToDataType.h>
|
#include <DataTypes/FieldToDataType.h>
|
||||||
|
#include <DataTypes/DataTypeDateTime64.h>
|
||||||
|
|
||||||
#include <Parsers/ASTLiteral.h>
|
#include <Parsers/ASTLiteral.h>
|
||||||
#include <Parsers/ASTFunction.h>
|
#include <Parsers/ASTFunction.h>
|
||||||
@ -162,6 +163,7 @@ QueryTreeNodePtr ConstantNode::cloneImpl() const
|
|||||||
ASTPtr ConstantNode::toASTImpl(const ConvertToASTOptions & options) const
|
ASTPtr ConstantNode::toASTImpl(const ConvertToASTOptions & options) const
|
||||||
{
|
{
|
||||||
const auto & constant_value_literal = constant_value->getValue();
|
const auto & constant_value_literal = constant_value->getValue();
|
||||||
|
const auto & constant_value_type = constant_value->getType();
|
||||||
auto constant_value_ast = std::make_shared<ASTLiteral>(constant_value_literal);
|
auto constant_value_ast = std::make_shared<ASTLiteral>(constant_value_literal);
|
||||||
|
|
||||||
if (!options.add_cast_for_constants)
|
if (!options.add_cast_for_constants)
|
||||||
@ -169,7 +171,26 @@ ASTPtr ConstantNode::toASTImpl(const ConvertToASTOptions & options) const
|
|||||||
|
|
||||||
if (requiresCastCall())
|
if (requiresCastCall())
|
||||||
{
|
{
|
||||||
auto constant_type_name_ast = std::make_shared<ASTLiteral>(constant_value->getType()->getName());
|
/** Value for DateTime64 is Decimal64, which is serialized as a string literal.
|
||||||
|
* If we serialize it as is, DateTime64 would be parsed from that string literal, which can be incorrect.
|
||||||
|
* For example, DateTime64 cannot be parsed from the short value, like '1', while it's a valid Decimal64 value.
|
||||||
|
* It could also lead to ambiguous parsing because we don't know if the string literal represents a date or a Decimal64 literal.
|
||||||
|
* For this reason, we use a string literal representing a date instead of a Decimal64 literal.
|
||||||
|
*/
|
||||||
|
const auto & constant_value_end_type = removeNullable(constant_value_type); /// if Nullable
|
||||||
|
if (WhichDataType(constant_value_end_type->getTypeId()).isDateTime64())
|
||||||
|
{
|
||||||
|
const auto * date_time_type = typeid_cast<const DataTypeDateTime64 *>(constant_value_end_type.get());
|
||||||
|
DecimalField<Decimal64> decimal_value;
|
||||||
|
if (constant_value_literal.tryGet<DecimalField<Decimal64>>(decimal_value))
|
||||||
|
{
|
||||||
|
WriteBufferFromOwnString ostr;
|
||||||
|
writeDateTimeText(decimal_value.getValue(), date_time_type->getScale(), ostr, date_time_type->getTimeZone());
|
||||||
|
constant_value_ast = std::make_shared<ASTLiteral>(ostr.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto constant_type_name_ast = std::make_shared<ASTLiteral>(constant_value_type->getName());
|
||||||
return makeASTFunction("_CAST", std::move(constant_value_ast), std::move(constant_type_name_ast));
|
return makeASTFunction("_CAST", std::move(constant_value_ast), std::move(constant_type_name_ast));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
0 1970-01-01 00:00:00.000
|
||||||
|
0 1970-01-01 00:00:05.000
|
||||||
|
0 1970-01-01 00:45:25.456789
|
||||||
|
0 1970-01-01 00:53:25.456789123
|
||||||
|
0 \N
|
||||||
|
1 1970-01-01 00:00:00.000
|
||||||
|
5 1970-01-01 00:00:00.000
|
||||||
|
2 1970-01-01 00:00:02.456
|
||||||
|
3 1970-01-01 00:00:04.811
|
||||||
|
4 1970-01-01 00:10:05.000
|
||||||
|
4 1970-01-01 00:10:05.000
|
||||||
|
1 1970-01-01 00:00:00.000
|
||||||
|
2 1970-01-01 00:00:02.456
|
||||||
|
3 1970-01-01 00:00:04.811
|
||||||
|
5 1970-01-01 00:00:00.000
|
||||||
|
0
|
||||||
|
0
|
||||||
|
5
|
@ -0,0 +1,44 @@
|
|||||||
|
-- Tags: shard
|
||||||
|
set session_timezone = 'UTC'; -- don't randomize the session timezone
|
||||||
|
SET allow_experimental_analyzer = 1;
|
||||||
|
|
||||||
|
select *, (select toDateTime64(0, 3)) from remote('127.0.0.1', system.one) settings prefer_localhost_replica=0;
|
||||||
|
select *, (select toDateTime64(5, 3)) from remote('127.0.0.1', system.one) settings prefer_localhost_replica=0;
|
||||||
|
select *, (select toDateTime64('1970-01-01 00:45:25.456789', 6)) from remote('127.0.0.1', system.one) settings prefer_localhost_replica=0;
|
||||||
|
select *, (select toDateTime64('1970-01-01 00:53:25.456789123', 9)) from remote('127.0.0.1', system.one) settings prefer_localhost_replica=0;
|
||||||
|
select *, (select toDateTime64(null,3)) from remote('127.0.0.1', system.one) settings prefer_localhost_replica=0;
|
||||||
|
|
||||||
|
create database if not exists shard_0;
|
||||||
|
create database if not exists shard_1;
|
||||||
|
|
||||||
|
drop table if exists shard_0.dt64_03222;
|
||||||
|
drop table if exists shard_1.dt64_03222;
|
||||||
|
drop table if exists distr_03222_dt64;
|
||||||
|
|
||||||
|
create table shard_0.dt64_03222(id UInt64, dt DateTime64(3)) engine = MergeTree order by id;
|
||||||
|
create table shard_1.dt64_03222(id UInt64, dt DateTime64(3)) engine = MergeTree order by id;
|
||||||
|
create table distr_03222_dt64 (id UInt64, dt DateTime64(3)) engine = Distributed(test_cluster_two_shards_different_databases, '', dt64_03222);
|
||||||
|
|
||||||
|
insert into shard_0.dt64_03222 values(1, toDateTime64('1970-01-01 00:00:00.000',3));
|
||||||
|
insert into shard_0.dt64_03222 values(2, toDateTime64('1970-01-01 00:00:02.456',3));
|
||||||
|
insert into shard_1.dt64_03222 values(3, toDateTime64('1970-01-01 00:00:04.811',3));
|
||||||
|
insert into shard_1.dt64_03222 values(4, toDateTime64('1970-01-01 00:10:05',3));
|
||||||
|
insert into shard_1.dt64_03222 values(5, toDateTime64(0,3));
|
||||||
|
|
||||||
|
--Output : 1,5 2,3,4 4 1,2,3,5 0 0 5
|
||||||
|
select id, dt from distr_03222_dt64 where dt = (select toDateTime64(0,3)) order by id;
|
||||||
|
select id, dt from distr_03222_dt64 where dt > (select toDateTime64(0,3)) order by id;
|
||||||
|
select id, dt from distr_03222_dt64 where dt > (select toDateTime64('1970-01-01 00:10:00.000',3)) order by id;
|
||||||
|
select id, dt from distr_03222_dt64 where dt < (select toDateTime64(5,3)) order by id;
|
||||||
|
|
||||||
|
select count(*) from distr_03222_dt64 where dt > (select toDateTime64('2024-07-20 00:00:00',3));
|
||||||
|
select count(*) from distr_03222_dt64 where dt > (select now());
|
||||||
|
select count(*) from distr_03222_dt64 where dt < (select toDateTime64('2004-07-20 00:00:00',3));
|
||||||
|
|
||||||
|
|
||||||
|
drop table if exists shard_0.dt64_03222;
|
||||||
|
drop table if exists shard_1.dt64_03222;
|
||||||
|
drop table if exists distr_03222_dt64;
|
||||||
|
|
||||||
|
drop database shard_0;
|
||||||
|
drop database shard_1;
|
Loading…
Reference in New Issue
Block a user