Skip to content

Commit b71dbbf

Browse files
authored
fix(query): add partition write regression tests (#20426)
* test(query): add partition write regression coverage * test(query): fix computed partition column type
1 parent cccb76e commit b71dbbf

3 files changed

Lines changed: 162 additions & 0 deletions

File tree

tests/sqllogictests/suites/base/09_fuse_engine/09_0054_partition_by.test

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,13 @@ SELECT id, p FROM merge_partitioned
372372
2 0
373373
3 1
374374

375+
# MERGE moves id 1 across the physical partition boundary. The rewritten blocks
376+
# must retain exact partition metadata for pruning.
377+
query T
378+
EXPLAIN SELECT id, p FROM merge_partitioned WHERE p % 2 = 0
379+
----
380+
<slt:ignore>partitions total: 3<slt:ignore>partitions scanned: 1<slt:ignore>range pruning: 3 to 1<slt:ignore>
381+
375382
statement ok
376383
OPTIMIZE TABLE merge_partitioned COMPACT
377384

@@ -654,5 +661,57 @@ SELECT p, length(v) FROM ctas_partitioned
654661
2 1
655662
3 1
656663

664+
# Missing DEFAULT columns must be materialized before the hash write layout
665+
# evaluates the partition expression. Reversing those pipeline stages makes the
666+
# insert fail because p is absent from the input block.
667+
statement ok
668+
CREATE TABLE default_partitioned(id INT, p INT DEFAULT 7)
669+
PARTITION BY (p)
670+
WRITE_DISTRIBUTION_MODE='hash'
671+
ROW_PER_BLOCK=100000 BLOCK_PER_SEGMENT=1000
672+
673+
statement ok
674+
INSERT INTO default_partitioned(id) SELECT number::INT FROM numbers(4)
675+
676+
query III
677+
SELECT count(*), min(p), max(p) FROM default_partitioned
678+
----
679+
4 7 7
680+
681+
# Nullable partition values must survive serialization as exact metadata so
682+
# that IS NULL can prune every non-NULL partition.
683+
statement ok
684+
CREATE TABLE nullable_partitioned(p INT NULL, id BIGINT)
685+
PARTITION BY (p)
686+
WRITE_DISTRIBUTION_MODE='hash'
687+
ROW_PER_BLOCK=100000 BLOCK_PER_SEGMENT=1000
688+
689+
statement ok
690+
INSERT INTO nullable_partitioned
691+
SELECT if(number % 4 = 0, NULL, (number % 3)::INT), number FROM numbers(16)
692+
693+
query II
694+
SELECT count(*), count_if(p IS NULL) FROM nullable_partitioned
695+
----
696+
16 4
697+
698+
# NULL is a physical partition value too: no serialized block may mix it with
699+
# a non-NULL value or another non-NULL partition.
700+
query I
701+
SELECT count_if(partition_values != 1)
702+
FROM (
703+
SELECT _block_name,
704+
count(DISTINCT if(p IS NULL, '<NULL>', to_string(p))) AS partition_values
705+
FROM nullable_partitioned
706+
GROUP BY _block_name
707+
)
708+
----
709+
0
710+
711+
query T
712+
EXPLAIN SELECT id FROM nullable_partitioned WHERE p IS NULL
713+
----
714+
<slt:ignore>partitions total: 4<slt:ignore>partitions scanned: 1<slt:ignore>range pruning: 4 to 1<slt:ignore>
715+
657716
statement ok
658717
DROP DATABASE db_09_0054

tests/sqllogictests/suites/base/09_fuse_engine/09_0100_insert_multi_table.test

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,3 +779,57 @@ drop table dst1_19716;
779779

780780
statement ok
781781
drop table dst2_19716;
782+
783+
# ChunkAppendData builds each target's partition transforms independently.
784+
# Different target expressions must not share or misalign partition metadata.
785+
statement ok
786+
CREATE TABLE multi_partitioned_a(p INT, id INT)
787+
PARTITION BY (p % 2)
788+
ROW_PER_BLOCK=100000 BLOCK_PER_SEGMENT=1000
789+
790+
statement ok
791+
CREATE TABLE multi_partitioned_b(id INT)
792+
PARTITION BY (id % 3)
793+
ROW_PER_BLOCK=100000 BLOCK_PER_SEGMENT=1000
794+
795+
statement ok
796+
INSERT ALL
797+
WHEN true THEN INTO multi_partitioned_a VALUES(p, id)
798+
WHEN id % 2 = 0 THEN INTO multi_partitioned_b VALUES(id)
799+
SELECT (number % 4)::INT AS p, number::INT AS id FROM numbers(16)
800+
801+
query I
802+
SELECT count(*) FROM multi_partitioned_a
803+
----
804+
16
805+
806+
query I
807+
SELECT count(*) FROM multi_partitioned_b
808+
----
809+
8
810+
811+
query I
812+
SELECT count_if(partition_values != 1)
813+
FROM (
814+
SELECT _block_name, count(DISTINCT p % 2) AS partition_values
815+
FROM multi_partitioned_a
816+
GROUP BY _block_name
817+
)
818+
----
819+
0
820+
821+
query I
822+
SELECT count_if(partition_values != 1)
823+
FROM (
824+
SELECT _block_name, count(DISTINCT id % 3) AS partition_values
825+
FROM multi_partitioned_b
826+
GROUP BY _block_name
827+
)
828+
----
829+
0
830+
831+
statement ok
832+
DROP TABLE multi_partitioned_a
833+
834+
statement ok
835+
DROP TABLE multi_partitioned_b
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
## Copyright 2026 Databend Cloud
2+
##
3+
## Licensed under the Elastic License, Version 2.0 (the "License");
4+
## you may not use this file except in compliance with the License.
5+
## You may obtain a copy of the License at
6+
##
7+
## https://www.elastic.co/licensing/elastic-license
8+
##
9+
## Unless required by applicable law or agreed to in writing, software
10+
## distributed under the License is distributed on an "AS IS" BASIS,
11+
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
## See the License for the specific language governing permissions and
13+
## limitations under the License.
14+
15+
statement ok
16+
DROP DATABASE IF EXISTS computed_partition_by
17+
18+
statement ok
19+
CREATE DATABASE computed_partition_by
20+
21+
statement ok
22+
USE computed_partition_by
23+
24+
# Stored computed partition columns must be generated before hash routing and
25+
# physical partition layout.
26+
statement ok
27+
CREATE TABLE computed_partitioned(
28+
id INT,
29+
p SMALLINT AS (id % 2) STORED
30+
)
31+
PARTITION BY (p)
32+
WRITE_DISTRIBUTION_MODE='hash'
33+
ROW_PER_BLOCK=100000 BLOCK_PER_SEGMENT=1000
34+
35+
statement ok
36+
INSERT INTO computed_partitioned(id) SELECT number::INT FROM numbers(4)
37+
38+
query III
39+
SELECT count(*), min(p), max(p) FROM computed_partitioned
40+
----
41+
4 0 1
42+
43+
query T
44+
EXPLAIN SELECT id FROM computed_partitioned WHERE p = 0
45+
----
46+
<slt:ignore>partitions total: 2<slt:ignore>partitions scanned: 1<slt:ignore>range pruning: 2 to 1<slt:ignore>
47+
48+
statement ok
49+
DROP DATABASE computed_partition_by

0 commit comments

Comments
 (0)