diff --git a/contrib/pax_storage/expected/delete_sum_stats.out b/contrib/pax_storage/expected/delete_sum_stats.out new file mode 100644 index 00000000000..8b4b200cd26 --- /dev/null +++ b/contrib/pax_storage/expected/delete_sum_stats.out @@ -0,0 +1,53 @@ +-- Verify that DELETE statistics refresh uses the SUM result type when +-- deserializing and merging stats. In particular, sum(bigint) returns numeric. +set pax.max_tuples_per_group = 25; +create table pax_delete_sum_stats ( + dist_key int, + id bigint, + int_amount int, + bigint_amount bigint, + numeric_amount numeric +) +using pax +with (minmax_columns = 'int_amount,bigint_amount,numeric_amount') +distributed by (dist_key); +insert into pax_delete_sum_stats +select 1, i, i, i, i::numeric * 2 +from generate_series(1, 1000) i; +select count(*) as rows, + sum(int_amount) as int_sum, + sum(bigint_amount) as bigint_sum, + sum(numeric_amount) as numeric_sum +from pax_delete_sum_stats; + rows | int_sum | bigint_sum | numeric_sum +------+---------+------------+------------- + 1000 | 500500 | 500500 | 1001000 +(1 row) + +delete from pax_delete_sum_stats where id between 1 and 100; +select count(*) as rows, + sum(int_amount) as int_sum, + sum(bigint_amount) as bigint_sum, + sum(numeric_amount) as numeric_sum +from pax_delete_sum_stats; + rows | int_sum | bigint_sum | numeric_sum +------+---------+------------+------------- + 900 | 495450 | 495450 | 990900 +(1 row) + +insert into pax_delete_sum_stats +select 1, i, i, i, i::numeric * 2 +from generate_series(1001, 1100) i; +delete from pax_delete_sum_stats where id between 301 and 400; +select count(*) as rows, + sum(int_amount) as int_sum, + sum(bigint_amount) as bigint_sum, + sum(numeric_amount) as numeric_sum +from pax_delete_sum_stats; + rows | int_sum | bigint_sum | numeric_sum +------+---------+------------+------------- + 900 | 565450 | 565450 | 1130900 +(1 row) + +drop table pax_delete_sum_stats; +reset pax.max_tuples_per_group; diff --git a/contrib/pax_storage/pax_schedule b/contrib/pax_storage/pax_schedule index f9818f8e0b7..5f7ef41d2d8 100644 --- a/contrib/pax_storage/pax_schedule +++ b/contrib/pax_storage/pax_schedule @@ -10,6 +10,7 @@ test: statistics_bloom_filter test: filter_tree filter_tree_arithmetic test: filter_tree_root_quals test: statistics/statistics +test: delete_sum_stats test: statistics/min_max_time_types statistics/min_max_text_types statistics/min_max_other_types statistics/min_max_net_types statistics/min_max_int_types statistics/min_max_geo_types statistics/min_max_float_types statistics/min_max_bit_byte_types diff --git a/contrib/pax_storage/sql/delete_sum_stats.sql b/contrib/pax_storage/sql/delete_sum_stats.sql new file mode 100644 index 00000000000..dce2c9eba18 --- /dev/null +++ b/contrib/pax_storage/sql/delete_sum_stats.sql @@ -0,0 +1,47 @@ +-- Verify that DELETE statistics refresh uses the SUM result type when +-- deserializing and merging stats. In particular, sum(bigint) returns numeric. +set pax.max_tuples_per_group = 25; + +create table pax_delete_sum_stats ( + dist_key int, + id bigint, + int_amount int, + bigint_amount bigint, + numeric_amount numeric +) +using pax +with (minmax_columns = 'int_amount,bigint_amount,numeric_amount') +distributed by (dist_key); + +insert into pax_delete_sum_stats +select 1, i, i, i, i::numeric * 2 +from generate_series(1, 1000) i; + +select count(*) as rows, + sum(int_amount) as int_sum, + sum(bigint_amount) as bigint_sum, + sum(numeric_amount) as numeric_sum +from pax_delete_sum_stats; + +delete from pax_delete_sum_stats where id between 1 and 100; + +select count(*) as rows, + sum(int_amount) as int_sum, + sum(bigint_amount) as bigint_sum, + sum(numeric_amount) as numeric_sum +from pax_delete_sum_stats; + +insert into pax_delete_sum_stats +select 1, i, i, i, i::numeric * 2 +from generate_series(1001, 1100) i; + +delete from pax_delete_sum_stats where id between 301 and 400; + +select count(*) as rows, + sum(int_amount) as int_sum, + sum(bigint_amount) as bigint_sum, + sum(numeric_amount) as numeric_sum +from pax_delete_sum_stats; + +drop table pax_delete_sum_stats; +reset pax.max_tuples_per_group; diff --git a/contrib/pax_storage/src/cpp/storage/micro_partition_stats.cc b/contrib/pax_storage/src/cpp/storage/micro_partition_stats.cc index 53342ad0e2a..d307ed49431 100644 --- a/contrib/pax_storage/src/cpp/storage/micro_partition_stats.cc +++ b/contrib/pax_storage/src/cpp/storage/micro_partition_stats.cc @@ -758,7 +758,7 @@ void MicroPartitionStats::MergeRawInfo( } else if (sum_stat->status == STATUS_NEED_UPDATE) { sum_result = FromValue(stats_info->columnstats(column_index).datastats().sum(), - typlen, typbyval, column_index); + sum_stat->rettyplen, sum_stat->rettypbyval, column_index); Datum newval = cbdb::FunctionCall2Coll(&sum_stat->add_func, InvalidOid, sum_stat->result, sum_result); if (!sum_stat->rettypbyval && newval != sum_stat->result && @@ -766,11 +766,11 @@ void MicroPartitionStats::MergeRawInfo( cbdb::Pfree(cbdb::DatumToPointer(sum_stat->result)); } sum_stat->result = - cbdb::datumCopy(newval, sum_stat->rettyplen, sum_stat->rettypbyval); + cbdb::datumCopy(newval, sum_stat->rettypbyval, sum_stat->rettyplen); } else if (sum_stat->status == STATUS_MISSING_INIT_VAL) { sum_result = FromValue(stats_info->columnstats(column_index).datastats().sum(), - typlen, typbyval, column_index); + sum_stat->rettyplen, sum_stat->rettypbyval, column_index); sum_stat->result = cbdb::datumCopy(sum_result, sum_stat->rettypbyval, sum_stat->rettyplen); sum_stat->status = STATUS_NEED_UPDATE; @@ -966,8 +966,8 @@ void MicroPartitionStats::MergeTo(MicroPartitionStats *stats) { left_sum_stat->result) { cbdb::Pfree(cbdb::DatumToPointer(left_sum_stat->result)); } - left_sum_stat->result = cbdb::datumCopy(newval, left_sum_stat->rettyplen, - left_sum_stat->rettypbyval); + left_sum_stat->result = cbdb::datumCopy( + newval, left_sum_stat->rettypbyval, left_sum_stat->rettyplen); } else if (left_sum_stat->status == STATUS_MISSING_INIT_VAL) { left_sum_stat->result = cbdb::datumCopy(right_sum_stat->result, left_sum_stat->rettypbyval,