diff --git a/src/test/regress/expected/multi_complex_count_distinct_1.out b/src/test/regress/expected/multi_complex_count_distinct_1.out deleted file mode 100644 index b14e9c7e8..000000000 --- a/src/test/regress/expected/multi_complex_count_distinct_1.out +++ /dev/null @@ -1,1128 +0,0 @@ --- --- COMPLEX_COUNT_DISTINCT --- -SET citus.next_shard_id TO 240000; -SET citus.shard_count TO 8; -SET citus.shard_replication_factor TO 1; -SET citus.coordinator_aggregation_strategy TO 'disabled'; -CREATE TABLE lineitem_hash ( - l_orderkey bigint not null, - l_partkey integer not null, - l_suppkey integer not null, - l_linenumber integer not null, - l_quantity decimal(15, 2) not null, - l_extendedprice decimal(15, 2) not null, - l_discount decimal(15, 2) not null, - l_tax decimal(15, 2) not null, - l_returnflag char(1) not null, - l_linestatus char(1) not null, - l_shipdate date not null, - l_commitdate date not null, - l_receiptdate date not null, - l_shipinstruct char(25) not null, - l_shipmode char(10) not null, - l_comment varchar(44) not null, - PRIMARY KEY(l_orderkey, l_linenumber) ); -SELECT create_distributed_table('lineitem_hash', 'l_orderkey', 'hash'); - create_distributed_table ---------------------------------------------------------------------- - -(1 row) - -\copy lineitem_hash FROM '/home/talha/citus/src/test/regress/data/lineitem.1.data' with delimiter '|' -\copy lineitem_hash FROM '/home/talha/citus/src/test/regress/data/lineitem.2.data' with delimiter '|' -ANALYZE lineitem_hash; -SET citus.task_executor_type to "task-tracker"; --- count(distinct) is supported on top level query if there --- is a grouping on the partition key -SELECT - l_orderkey, count(DISTINCT l_partkey) - FROM lineitem_hash - GROUP BY l_orderkey - ORDER BY 2 DESC, 1 DESC - LIMIT 10; - l_orderkey | count ---------------------------------------------------------------------- - 14885 | 7 - 14884 | 7 - 14821 | 7 - 14790 | 7 - 14785 | 7 - 14755 | 7 - 14725 | 7 - 14694 | 7 - 14627 | 7 - 14624 | 7 -(10 rows) - -EXPLAIN (COSTS false, VERBOSE true) -SELECT - l_orderkey, count(DISTINCT l_partkey) - FROM lineitem_hash - GROUP BY l_orderkey - ORDER BY 2 DESC, 1 DESC - LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------- - Limit - Output: remote_scan.l_orderkey, remote_scan.count - -> Sort - Output: remote_scan.l_orderkey, remote_scan.count - Sort Key: remote_scan.count DESC, remote_scan.l_orderkey DESC - -> Custom Scan (Citus Task-Tracker) - Output: remote_scan.l_orderkey, remote_scan.count - Task Count: 8 - Tasks Shown: One of 8 - -> Task - Node: host=localhost port=xxxxx dbname=regression - -> Limit - Output: l_orderkey, (count(DISTINCT l_partkey)) - -> Sort - Output: l_orderkey, (count(DISTINCT l_partkey)) - Sort Key: (count(DISTINCT lineitem_hash.l_partkey)) DESC, lineitem_hash.l_orderkey DESC - -> GroupAggregate - Output: l_orderkey, count(DISTINCT l_partkey) - Group Key: lineitem_hash.l_orderkey - -> Index Scan Backward using lineitem_hash_pkey_240000 on public.lineitem_hash_240000 lineitem_hash - Output: l_orderkey, l_partkey, l_suppkey, l_linenumber, l_quantity, l_extendedprice, l_discount, l_tax, l_returnflag, l_linestatus, l_shipdate, l_commitdate, l_receiptdate, l_shipinstruct, l_shipmode, l_comment -(21 rows) - --- it is also supported if there is no grouping or grouping is on non-partition field -SELECT - count(DISTINCT l_partkey) - FROM lineitem_hash - ORDER BY 1 DESC - LIMIT 10; - count ---------------------------------------------------------------------- - 11661 -(1 row) - -EXPLAIN (COSTS false, VERBOSE true) -SELECT - count(DISTINCT l_partkey) - FROM lineitem_hash - ORDER BY 1 DESC - LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------- - Limit - Output: (count(DISTINCT remote_scan.count)) - -> Sort - Output: (count(DISTINCT remote_scan.count)) - Sort Key: (count(DISTINCT remote_scan.count)) DESC - -> Aggregate - Output: count(DISTINCT remote_scan.count) - -> Custom Scan (Citus Task-Tracker) - Output: remote_scan.count - Task Count: 8 - Tasks Shown: One of 8 - -> Task - Node: host=localhost port=xxxxx dbname=regression - -> HashAggregate - Output: l_partkey - Group Key: lineitem_hash.l_partkey - -> Seq Scan on public.lineitem_hash_240000 lineitem_hash - Output: l_orderkey, l_partkey, l_suppkey, l_linenumber, l_quantity, l_extendedprice, l_discount, l_tax, l_returnflag, l_linestatus, l_shipdate, l_commitdate, l_receiptdate, l_shipinstruct, l_shipmode, l_comment -(18 rows) - -SELECT - l_shipmode, count(DISTINCT l_partkey) - FROM lineitem_hash - GROUP BY l_shipmode - ORDER BY 2 DESC, 1 DESC - LIMIT 10; - l_shipmode | count ---------------------------------------------------------------------- - TRUCK | 1757 - MAIL | 1730 - AIR | 1702 - FOB | 1700 - RAIL | 1696 - SHIP | 1684 - REG AIR | 1676 -(7 rows) - -EXPLAIN (COSTS false, VERBOSE true) -SELECT - l_shipmode, count(DISTINCT l_partkey) - FROM lineitem_hash - GROUP BY l_shipmode - ORDER BY 2 DESC, 1 DESC - LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------- - Limit - Output: remote_scan.l_shipmode, (count(DISTINCT remote_scan.count)) - -> Sort - Output: remote_scan.l_shipmode, (count(DISTINCT remote_scan.count)) - Sort Key: (count(DISTINCT remote_scan.count)) DESC, remote_scan.l_shipmode DESC - -> GroupAggregate - Output: remote_scan.l_shipmode, count(DISTINCT remote_scan.count) - Group Key: remote_scan.l_shipmode - -> Sort - Output: remote_scan.l_shipmode, remote_scan.count - Sort Key: remote_scan.l_shipmode DESC - -> Custom Scan (Citus Task-Tracker) - Output: remote_scan.l_shipmode, remote_scan.count - Task Count: 8 - Tasks Shown: One of 8 - -> Task - Node: host=localhost port=xxxxx dbname=regression - -> HashAggregate - Output: l_shipmode, l_partkey - Group Key: lineitem_hash.l_shipmode, lineitem_hash.l_partkey - -> Seq Scan on public.lineitem_hash_240000 lineitem_hash - Output: l_orderkey, l_partkey, l_suppkey, l_linenumber, l_quantity, l_extendedprice, l_discount, l_tax, l_returnflag, l_linestatus, l_shipdate, l_commitdate, l_receiptdate, l_shipinstruct, l_shipmode, l_comment -(22 rows) - --- mixed mode count distinct, grouped by partition column -SELECT - l_orderkey, count(distinct l_partkey), count(distinct l_shipmode) - FROM lineitem_hash - GROUP BY l_orderkey - ORDER BY 3 DESC, 2 DESC, 1 - LIMIT 10; - l_orderkey | count | count ---------------------------------------------------------------------- - 226 | 7 | 7 - 1316 | 7 | 7 - 1477 | 7 | 7 - 3555 | 7 | 7 - 12258 | 7 | 7 - 12835 | 7 | 7 - 768 | 7 | 6 - 1121 | 7 | 6 - 1153 | 7 | 6 - 1281 | 7 | 6 -(10 rows) - -EXPLAIN (COSTS false, VERBOSE true) -SELECT - l_orderkey, count(distinct l_partkey), count(distinct l_shipmode) - FROM lineitem_hash - GROUP BY l_orderkey - ORDER BY 3 DESC, 2 DESC, 1 - LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------- - Limit - Output: remote_scan.l_orderkey, remote_scan.count, remote_scan.count_1 - -> Sort - Output: remote_scan.l_orderkey, remote_scan.count, remote_scan.count_1 - Sort Key: remote_scan.count_1 DESC, remote_scan.count DESC, remote_scan.l_orderkey - -> Custom Scan (Citus Task-Tracker) - Output: remote_scan.l_orderkey, remote_scan.count, remote_scan.count_1 - Task Count: 8 - Tasks Shown: One of 8 - -> Task - Node: host=localhost port=xxxxx dbname=regression - -> Limit - Output: l_orderkey, (count(DISTINCT l_partkey)), (count(DISTINCT l_shipmode)) - -> Sort - Output: l_orderkey, (count(DISTINCT l_partkey)), (count(DISTINCT l_shipmode)) - Sort Key: (count(DISTINCT lineitem_hash.l_shipmode)) DESC, (count(DISTINCT lineitem_hash.l_partkey)) DESC, lineitem_hash.l_orderkey - -> GroupAggregate - Output: l_orderkey, count(DISTINCT l_partkey), count(DISTINCT l_shipmode) - Group Key: lineitem_hash.l_orderkey - -> Index Scan using lineitem_hash_pkey_240000 on public.lineitem_hash_240000 lineitem_hash - Output: l_orderkey, l_partkey, l_suppkey, l_linenumber, l_quantity, l_extendedprice, l_discount, l_tax, l_returnflag, l_linestatus, l_shipdate, l_commitdate, l_receiptdate, l_shipinstruct, l_shipmode, l_comment -(21 rows) - --- partition/non-partition column count distinct no grouping -SELECT - count(distinct l_orderkey), count(distinct l_partkey), count(distinct l_shipmode) - FROM lineitem_hash; - count | count | count ---------------------------------------------------------------------- - 2985 | 11661 | 7 -(1 row) - -EXPLAIN (COSTS false, VERBOSE true) -SELECT - count(distinct l_orderkey), count(distinct l_partkey), count(distinct l_shipmode) - FROM lineitem_hash; - QUERY PLAN ---------------------------------------------------------------------- - Aggregate - Output: count(DISTINCT remote_scan.count), count(DISTINCT remote_scan.count_1), count(DISTINCT remote_scan.count_2) - -> Custom Scan (Citus Task-Tracker) - Output: remote_scan.count, remote_scan.count_1, remote_scan.count_2 - Task Count: 8 - Tasks Shown: One of 8 - -> Task - Node: host=localhost port=xxxxx dbname=regression - -> HashAggregate - Output: l_orderkey, l_partkey, l_shipmode - Group Key: lineitem_hash.l_orderkey, lineitem_hash.l_partkey, lineitem_hash.l_shipmode - -> Seq Scan on public.lineitem_hash_240000 lineitem_hash - Output: l_orderkey, l_partkey, l_suppkey, l_linenumber, l_quantity, l_extendedprice, l_discount, l_tax, l_returnflag, l_linestatus, l_shipdate, l_commitdate, l_receiptdate, l_shipinstruct, l_shipmode, l_comment -(13 rows) - --- distinct/non-distinct on partition and non-partition columns -SELECT - count(distinct l_orderkey), count(l_orderkey), - count(distinct l_partkey), count(l_partkey), - count(distinct l_shipmode), count(l_shipmode) - FROM lineitem_hash; - count | count | count | count | count | count ---------------------------------------------------------------------- - 2985 | 12000 | 11661 | 12000 | 7 | 12000 -(1 row) - --- mixed mode count distinct, grouped by non-partition column -SELECT - l_shipmode, count(distinct l_partkey), count(distinct l_orderkey) - FROM lineitem_hash - GROUP BY l_shipmode - ORDER BY 1, 2 DESC, 3 DESC; - l_shipmode | count | count ---------------------------------------------------------------------- - AIR | 1702 | 1327 - FOB | 1700 | 1276 - MAIL | 1730 | 1299 - RAIL | 1696 | 1265 - REG AIR | 1676 | 1275 - SHIP | 1684 | 1289 - TRUCK | 1757 | 1333 -(7 rows) - --- mixed mode count distinct, grouped by non-partition column --- having on partition column -SELECT - l_shipmode, count(distinct l_partkey), count(distinct l_orderkey) - FROM lineitem_hash - GROUP BY l_shipmode - HAVING count(distinct l_orderkey) > 1300 - ORDER BY 1, 2 DESC; - l_shipmode | count | count ---------------------------------------------------------------------- - AIR | 1702 | 1327 - TRUCK | 1757 | 1333 -(2 rows) - --- same but having clause is not on target list -SELECT - l_shipmode, count(distinct l_partkey) - FROM lineitem_hash - GROUP BY l_shipmode - HAVING count(distinct l_orderkey) > 1300 - ORDER BY 1, 2 DESC; - l_shipmode | count ---------------------------------------------------------------------- - AIR | 1702 - TRUCK | 1757 -(2 rows) - --- mixed mode count distinct, grouped by non-partition column --- having on non-partition column -SELECT - l_shipmode, count(distinct l_partkey), count(distinct l_suppkey) - FROM lineitem_hash - GROUP BY l_shipmode - HAVING count(distinct l_suppkey) > 1550 - ORDER BY 1, 2 DESC; - l_shipmode | count | count ---------------------------------------------------------------------- - AIR | 1702 | 1564 - FOB | 1700 | 1571 - MAIL | 1730 | 1573 - RAIL | 1696 | 1581 - REG AIR | 1676 | 1557 - SHIP | 1684 | 1554 - TRUCK | 1757 | 1602 -(7 rows) - --- same but having clause is not on target list -SELECT - l_shipmode, count(distinct l_partkey) - FROM lineitem_hash - GROUP BY l_shipmode - HAVING count(distinct l_suppkey) > 1550 - ORDER BY 1, 2 DESC; - l_shipmode | count ---------------------------------------------------------------------- - AIR | 1702 - FOB | 1700 - MAIL | 1730 - RAIL | 1696 - REG AIR | 1676 - SHIP | 1684 - TRUCK | 1757 -(7 rows) - -EXPLAIN (COSTS false, VERBOSE true) -SELECT - l_shipmode, count(distinct l_partkey) - FROM lineitem_hash - GROUP BY l_shipmode - HAVING count(distinct l_suppkey) > 1550 - ORDER BY 1, 2 DESC; - QUERY PLAN ---------------------------------------------------------------------- - Sort - Output: remote_scan.l_shipmode, (count(DISTINCT remote_scan.count)) - Sort Key: remote_scan.l_shipmode, (count(DISTINCT remote_scan.count)) DESC - -> GroupAggregate - Output: remote_scan.l_shipmode, count(DISTINCT remote_scan.count) - Group Key: remote_scan.l_shipmode - Filter: (count(DISTINCT remote_scan.worker_column_3) > 1550) - -> Sort - Output: remote_scan.l_shipmode, remote_scan.count, remote_scan.worker_column_3 - Sort Key: remote_scan.l_shipmode - -> Custom Scan (Citus Task-Tracker) - Output: remote_scan.l_shipmode, remote_scan.count, remote_scan.worker_column_3 - Task Count: 8 - Tasks Shown: One of 8 - -> Task - Node: host=localhost port=xxxxx dbname=regression - -> HashAggregate - Output: l_shipmode, l_partkey, l_suppkey - Group Key: lineitem_hash.l_shipmode, lineitem_hash.l_partkey, lineitem_hash.l_suppkey - -> Seq Scan on public.lineitem_hash_240000 lineitem_hash - Output: l_orderkey, l_partkey, l_suppkey, l_linenumber, l_quantity, l_extendedprice, l_discount, l_tax, l_returnflag, l_linestatus, l_shipdate, l_commitdate, l_receiptdate, l_shipinstruct, l_shipmode, l_comment -(21 rows) - --- count distinct is supported on single table subqueries -SELECT * - FROM ( - SELECT - l_orderkey, count(DISTINCT l_partkey) - FROM lineitem_hash - GROUP BY l_orderkey) sub - ORDER BY 2 DESC, 1 DESC - LIMIT 10; - l_orderkey | count ---------------------------------------------------------------------- - 14885 | 7 - 14884 | 7 - 14821 | 7 - 14790 | 7 - 14785 | 7 - 14755 | 7 - 14725 | 7 - 14694 | 7 - 14627 | 7 - 14624 | 7 -(10 rows) - -SELECT * - FROM ( - SELECT - l_partkey, count(DISTINCT l_orderkey) - FROM lineitem_hash - GROUP BY l_partkey) sub - ORDER BY 2 DESC, 1 DESC - LIMIT 10; - l_partkey | count ---------------------------------------------------------------------- - 199146 | 3 - 188804 | 3 - 177771 | 3 - 160895 | 3 - 149926 | 3 - 136884 | 3 - 87761 | 3 - 15283 | 3 - 6983 | 3 - 1927 | 3 -(10 rows) - -EXPLAIN (COSTS false, VERBOSE true) -SELECT * - FROM ( - SELECT - l_partkey, count(DISTINCT l_orderkey) - FROM lineitem_hash - GROUP BY l_partkey) sub - ORDER BY 2 DESC, 1 DESC - LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------- - Limit - Output: remote_scan.l_partkey, remote_scan.count - -> Sort - Output: remote_scan.l_partkey, remote_scan.count - Sort Key: remote_scan.count DESC, remote_scan.l_partkey DESC - -> Custom Scan (Citus Task-Tracker) - Output: remote_scan.l_partkey, remote_scan.count - Task Count: 4 - Tasks Shown: None, not supported for re-partition queries - -> MapMergeJob - Map Task Count: 8 - Merge Task Count: 4 -(12 rows) - --- count distinct with filters -SELECT - l_orderkey, - count(DISTINCT l_suppkey) FILTER (WHERE l_shipmode = 'AIR'), - count(DISTINCT l_suppkey) - FROM lineitem_hash - GROUP BY l_orderkey - ORDER BY 2 DESC, 3 DESC, 1 - LIMIT 10; - l_orderkey | count | count ---------------------------------------------------------------------- - 4964 | 4 | 7 - 12005 | 4 | 7 - 5409 | 4 | 6 - 164 | 3 | 7 - 322 | 3 | 7 - 871 | 3 | 7 - 1156 | 3 | 7 - 1574 | 3 | 7 - 2054 | 3 | 7 - 2309 | 3 | 7 -(10 rows) - -EXPLAIN (COSTS false, VERBOSE true) -SELECT - l_orderkey, - count(DISTINCT l_suppkey) FILTER (WHERE l_shipmode = 'AIR'), - count(DISTINCT l_suppkey) - FROM lineitem_hash - GROUP BY l_orderkey - ORDER BY 2 DESC, 3 DESC, 1 - LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------- - Limit - Output: remote_scan.l_orderkey, remote_scan.count, remote_scan.count_1 - -> Sort - Output: remote_scan.l_orderkey, remote_scan.count, remote_scan.count_1 - Sort Key: remote_scan.count DESC, remote_scan.count_1 DESC, remote_scan.l_orderkey - -> Custom Scan (Citus Task-Tracker) - Output: remote_scan.l_orderkey, remote_scan.count, remote_scan.count_1 - Task Count: 8 - Tasks Shown: One of 8 - -> Task - Node: host=localhost port=xxxxx dbname=regression - -> Limit - Output: l_orderkey, (count(DISTINCT l_suppkey) FILTER (WHERE (l_shipmode = 'AIR'::bpchar))), (count(DISTINCT l_suppkey)) - -> Sort - Output: l_orderkey, (count(DISTINCT l_suppkey) FILTER (WHERE (l_shipmode = 'AIR'::bpchar))), (count(DISTINCT l_suppkey)) - Sort Key: (count(DISTINCT lineitem_hash.l_suppkey) FILTER (WHERE (lineitem_hash.l_shipmode = 'AIR'::bpchar))) DESC, (count(DISTINCT lineitem_hash.l_suppkey)) DESC, lineitem_hash.l_orderkey - -> GroupAggregate - Output: l_orderkey, count(DISTINCT l_suppkey) FILTER (WHERE (l_shipmode = 'AIR'::bpchar)), count(DISTINCT l_suppkey) - Group Key: lineitem_hash.l_orderkey - -> Index Scan using lineitem_hash_pkey_240000 on public.lineitem_hash_240000 lineitem_hash - Output: l_orderkey, l_partkey, l_suppkey, l_linenumber, l_quantity, l_extendedprice, l_discount, l_tax, l_returnflag, l_linestatus, l_shipdate, l_commitdate, l_receiptdate, l_shipinstruct, l_shipmode, l_comment -(21 rows) - --- group by on non-partition column -SELECT - l_suppkey, count(DISTINCT l_partkey) FILTER (WHERE l_shipmode = 'AIR') - FROM lineitem_hash - GROUP BY l_suppkey - ORDER BY 2 DESC, 1 DESC - LIMIT 10; - l_suppkey | count ---------------------------------------------------------------------- - 7680 | 4 - 7703 | 3 - 7542 | 3 - 7072 | 3 - 6335 | 3 - 5873 | 3 - 1318 | 3 - 1042 | 3 - 160 | 3 - 9872 | 2 -(10 rows) - --- explaining the same query fails -EXPLAIN (COSTS false, VERBOSE true) -SELECT - l_suppkey, count(DISTINCT l_partkey) FILTER (WHERE l_shipmode = 'AIR') - FROM lineitem_hash - GROUP BY l_suppkey - ORDER BY 2 DESC, 1 DESC - LIMIT 10; - QUERY PLAN ---------------------------------------------------------------------- - Limit - Output: remote_scan.l_suppkey, (count(DISTINCT remote_scan.count) FILTER (WHERE (remote_scan.count_1 = 'AIR'::bpchar))) - -> Sort - Output: remote_scan.l_suppkey, (count(DISTINCT remote_scan.count) FILTER (WHERE (remote_scan.count_1 = 'AIR'::bpchar))) - Sort Key: (count(DISTINCT remote_scan.count) FILTER (WHERE (remote_scan.count_1 = 'AIR'::bpchar))) DESC, remote_scan.l_suppkey DESC - -> GroupAggregate - Output: remote_scan.l_suppkey, count(DISTINCT remote_scan.count) FILTER (WHERE (remote_scan.count_1 = 'AIR'::bpchar)) - Group Key: remote_scan.l_suppkey - -> Sort - Output: remote_scan.l_suppkey, remote_scan.count, remote_scan.count_1 - Sort Key: remote_scan.l_suppkey DESC - -> Custom Scan (Citus Task-Tracker) - Output: remote_scan.l_suppkey, remote_scan.count, remote_scan.count_1 - Task Count: 8 - Tasks Shown: One of 8 - -> Task - Node: host=localhost port=xxxxx dbname=regression - -> HashAggregate - Output: l_suppkey, l_partkey, l_shipmode - Group Key: lineitem_hash.l_suppkey, lineitem_hash.l_partkey, lineitem_hash.l_shipmode - -> Seq Scan on public.lineitem_hash_240000 lineitem_hash - Output: l_orderkey, l_partkey, l_suppkey, l_linenumber, l_quantity, l_extendedprice, l_discount, l_tax, l_returnflag, l_linestatus, l_shipdate, l_commitdate, l_receiptdate, l_shipinstruct, l_shipmode, l_comment -(22 rows) - --- without group by, on partition column -SELECT - count(DISTINCT l_orderkey) FILTER (WHERE l_shipmode = 'AIR') - FROM lineitem_hash; - count ---------------------------------------------------------------------- - 1327 -(1 row) - --- without group by, on non-partition column -SELECT - count(DISTINCT l_partkey) FILTER (WHERE l_shipmode = 'AIR') - FROM lineitem_hash; - count ---------------------------------------------------------------------- - 1702 -(1 row) - -SELECT - count(DISTINCT l_partkey) FILTER (WHERE l_shipmode = 'AIR'), - count(DISTINCT l_partkey), - count(DISTINCT l_shipdate) - FROM lineitem_hash; - count | count | count ---------------------------------------------------------------------- - 1702 | 11661 | 2470 -(1 row) - --- filter column already exists in target list -SELECT * - FROM ( - SELECT - l_orderkey, count(DISTINCT l_partkey) FILTER (WHERE l_orderkey > 100) - FROM lineitem_hash - GROUP BY l_orderkey) sub - ORDER BY 2 DESC, 1 DESC - LIMIT 10; - l_orderkey | count ---------------------------------------------------------------------- - 14885 | 7 - 14884 | 7 - 14821 | 7 - 14790 | 7 - 14785 | 7 - 14755 | 7 - 14725 | 7 - 14694 | 7 - 14627 | 7 - 14624 | 7 -(10 rows) - --- filter column does not exist in target list -SELECT * - FROM ( - SELECT - l_orderkey, count(DISTINCT l_partkey) FILTER (WHERE l_shipmode = 'AIR') - FROM lineitem_hash - GROUP BY l_orderkey) sub - ORDER BY 2 DESC, 1 DESC - LIMIT 10; - l_orderkey | count ---------------------------------------------------------------------- - 12005 | 4 - 5409 | 4 - 4964 | 4 - 14848 | 3 - 14496 | 3 - 13473 | 3 - 13122 | 3 - 12929 | 3 - 12645 | 3 - 12417 | 3 -(10 rows) - --- case expr in count distinct is supported. --- count orders partkeys if l_shipmode is air -SELECT * - FROM ( - SELECT - l_orderkey, count(DISTINCT CASE WHEN l_shipmode = 'AIR' THEN l_partkey ELSE NULL END) as count - FROM lineitem_hash - GROUP BY l_orderkey) sub - WHERE count > 0 - ORDER BY 2 DESC, 1 DESC - LIMIT 10; - l_orderkey | count ---------------------------------------------------------------------- - 12005 | 4 - 5409 | 4 - 4964 | 4 - 14848 | 3 - 14496 | 3 - 13473 | 3 - 13122 | 3 - 12929 | 3 - 12645 | 3 - 12417 | 3 -(10 rows) - --- text like operator is also supported -SELECT * - FROM ( - SELECT - l_orderkey, count(DISTINCT CASE WHEN l_shipmode like '%A%' THEN l_partkey ELSE NULL END) as count - FROM lineitem_hash - GROUP BY l_orderkey) sub - WHERE count > 0 - ORDER BY 2 DESC, 1 DESC - LIMIT 10; - l_orderkey | count ---------------------------------------------------------------------- - 14275 | 7 - 14181 | 7 - 13605 | 7 - 12707 | 7 - 12384 | 7 - 11746 | 7 - 10727 | 7 - 10467 | 7 - 5636 | 7 - 4614 | 7 -(10 rows) - --- count distinct is rejected if it does not reference any columns -SELECT * - FROM ( - SELECT - l_linenumber, count(DISTINCT 1) - FROM lineitem_hash - GROUP BY l_linenumber) sub - ORDER BY 2 DESC, 1 DESC - LIMIT 10; -ERROR: cannot compute aggregate (distinct) -DETAIL: aggregate (distinct) with no columns is unsupported -HINT: You can load the hll extension from contrib packages and enable distinct approximations. --- count distinct is rejected if it does not reference any columns -SELECT * - FROM ( - SELECT - l_linenumber, count(DISTINCT (random() * 5)::int) - FROM lineitem_hash - GROUP BY l_linenumber) sub - ORDER BY 2 DESC, 1 DESC - LIMIT 10; -ERROR: cannot compute aggregate (distinct) -DETAIL: aggregate (distinct) with no columns is unsupported -HINT: You can load the hll extension from contrib packages and enable distinct approximations. --- even non-const function calls are supported within count distinct -SELECT * - FROM ( - SELECT - l_orderkey, count(DISTINCT (random() * 5)::int = l_linenumber) - FROM lineitem_hash - GROUP BY l_orderkey) sub - ORDER BY 2 DESC, 1 DESC - LIMIT 0; - l_orderkey | count ---------------------------------------------------------------------- -(0 rows) - --- multiple nested subquery -SELECT - total, - avg(avg_count) as total_avg_count - FROM ( - SELECT - number_sum, - count(DISTINCT l_suppkey) as total, - avg(total_count) avg_count - FROM ( - SELECT - l_suppkey, - sum(l_linenumber) as number_sum, - count(DISTINCT l_shipmode) as total_count - FROM - lineitem_hash - WHERE - l_partkey > 100 and - l_quantity > 2 and - l_orderkey < 10000 - GROUP BY - l_suppkey) as distributed_table - WHERE - number_sum >= 10 - GROUP BY - number_sum) as distributed_table_2 - GROUP BY - total - ORDER BY - total_avg_count DESC; - total | total_avg_count ---------------------------------------------------------------------- - 1 | 3.6000000000000000 - 6 | 2.8333333333333333 - 10 | 2.6000000000000000 - 27 | 2.5555555555555556 - 32 | 2.4687500000000000 - 77 | 2.1948051948051948 - 57 | 2.1754385964912281 -(7 rows) - --- multiple cases query -SELECT * - FROM ( - SELECT - count(DISTINCT - CASE - WHEN l_shipmode = 'TRUCK' THEN l_partkey - WHEN l_shipmode = 'AIR' THEN l_quantity - WHEN l_shipmode = 'SHIP' THEN l_discount - ELSE l_suppkey - END) as count, - l_shipdate - FROM - lineitem_hash - GROUP BY - l_shipdate) sub - WHERE - count > 0 - ORDER BY - 1 DESC, 2 DESC - LIMIT 10; - count | l_shipdate ---------------------------------------------------------------------- - 14 | 07-30-1997 - 13 | 05-26-1998 - 13 | 08-08-1997 - 13 | 11-17-1995 - 13 | 01-09-1993 - 12 | 01-15-1998 - 12 | 10-15-1997 - 12 | 09-07-1997 - 12 | 06-02-1997 - 12 | 03-14-1997 -(10 rows) - --- count DISTINCT expression -SELECT * - FROM ( - SELECT - l_quantity, count(DISTINCT ((l_orderkey / 1000) * 1000 )) as count - FROM - lineitem_hash - GROUP BY - l_quantity) sub - WHERE - count > 0 - ORDER BY - 2 DESC, 1 DESC - LIMIT 10; - l_quantity | count ---------------------------------------------------------------------- - 48.00 | 13 - 47.00 | 13 - 37.00 | 13 - 33.00 | 13 - 26.00 | 13 - 25.00 | 13 - 23.00 | 13 - 21.00 | 13 - 15.00 | 13 - 12.00 | 13 -(10 rows) - --- count DISTINCT is part of an expression which includes another aggregate -SELECT * - FROM ( - SELECT - sum(((l_partkey * l_tax) / 100)) / - count(DISTINCT - CASE - WHEN l_shipmode = 'TRUCK' THEN l_partkey - ELSE l_suppkey - END) as avg, - l_shipmode - FROM - lineitem_hash - GROUP BY - l_shipmode) sub - ORDER BY - 1 DESC, 2 DESC - LIMIT 10; - avg | l_shipmode ---------------------------------------------------------------------- - 44.82904609027336300064 | MAIL - 44.80704536679536679537 | SHIP - 44.68891732736572890026 | AIR - 44.34106724470134874759 | REG AIR - 43.12739987269255251432 | FOB - 43.07299253636938646426 | RAIL - 40.50298377916903813318 | TRUCK -(7 rows) - --- count DISTINCT CASE WHEN expression -SELECT * - FROM ( - SELECT - count(DISTINCT - CASE - WHEN l_shipmode = 'TRUCK' THEN l_linenumber - WHEN l_shipmode = 'AIR' THEN l_linenumber + 10 - ELSE 2 - END) as avg - FROM - lineitem_hash - GROUP BY l_shipdate) sub - ORDER BY 1 DESC - LIMIT 10; - avg ---------------------------------------------------------------------- - 7 - 6 - 6 - 6 - 6 - 6 - 6 - 6 - 5 - 5 -(10 rows) - --- COUNT DISTINCT (c1, c2) -SELECT * - FROM - (SELECT - l_shipmode, - count(DISTINCT (l_shipdate, l_tax)) - FROM - lineitem_hash - GROUP BY - l_shipmode) t - ORDER BY - 2 DESC,1 DESC - LIMIT 10; - l_shipmode | count ---------------------------------------------------------------------- - TRUCK | 1689 - MAIL | 1683 - FOB | 1655 - AIR | 1650 - SHIP | 1644 - RAIL | 1636 - REG AIR | 1607 -(7 rows) - --- distinct on non-var (type cast/field select) columns are also --- supported if grouped on distribution column --- random is added to prevent flattening by postgresql -SELECT - l_orderkey, count(a::int), count(distinct a::int) - FROM ( - SELECT l_orderkey, l_orderkey * 1.5 a, random() b - FROM lineitem_hash) sub - GROUP BY 1 - ORDER BY 1 DESC - LIMIT 5; - l_orderkey | count | count ---------------------------------------------------------------------- - 14947 | 2 | 1 - 14946 | 2 | 1 - 14945 | 6 | 1 - 14944 | 2 | 1 - 14919 | 1 | 1 -(5 rows) - -SELECT user_id, - count(sub.a::int), - count(DISTINCT sub.a::int), - count(DISTINCT (sub).a) -FROM - (SELECT user_id, - unnest(ARRAY[user_id * 1.5])a, - random() b - FROM users_table - ) sub -GROUP BY 1 -ORDER BY 1 DESC -LIMIT 5; - user_id | count | count | count ---------------------------------------------------------------------- - 6 | 11 | 1 | 1 - 5 | 27 | 1 | 1 - 4 | 24 | 1 | 1 - 3 | 18 | 1 | 1 - 2 | 19 | 1 | 1 -(5 rows) - -CREATE TYPE test_item AS -( - id INTEGER, - duration INTEGER -); -CREATE TABLE test_count_distinct_array (key int, value int , value_arr test_item[]); -SELECT create_distributed_table('test_count_distinct_array', 'key'); - create_distributed_table ---------------------------------------------------------------------- - -(1 row) - -INSERT INTO test_count_distinct_array SELECT i, i, ARRAY[(i,i)::test_item] FROM generate_Series(0, 1000) i; -SELECT - key, - count(DISTINCT value), - count(DISTINCT (item)."id"), - count(DISTINCT (item)."id" * 3) -FROM - ( - SELECT key, unnest(value_arr) as item, value FROM test_count_distinct_array - ) as sub -GROUP BY 1 -ORDER BY 1 DESC -LIMIT 5; - key | count | count | count ---------------------------------------------------------------------- - 1000 | 1 | 1 | 1 - 999 | 1 | 1 | 1 - 998 | 1 | 1 | 1 - 997 | 1 | 1 | 1 - 996 | 1 | 1 | 1 -(5 rows) - -DROP TABLE test_count_distinct_array; -DROP TYPE test_item; --- other distinct aggregate are not supported -SELECT * - FROM ( - SELECT - l_linenumber, sum(DISTINCT l_partkey) - FROM lineitem_hash - GROUP BY l_linenumber) sub - ORDER BY 2 DESC, 1 DESC - LIMIT 10; -ERROR: cannot compute aggregate (distinct) -DETAIL: Only count(distinct) aggregate is supported in subqueries -SELECT * - FROM ( - SELECT - l_linenumber, avg(DISTINCT l_partkey) - FROM lineitem_hash - GROUP BY l_linenumber) sub - ORDER BY 2 DESC, 1 DESC - LIMIT 10; -ERROR: cannot compute aggregate (distinct) -DETAIL: Only count(distinct) aggregate is supported in subqueries --- whole row references, oid, and ctid are not supported in count distinct --- test table does not have oid or ctid enabled, so tests for them are skipped -SELECT * - FROM ( - SELECT - l_linenumber, count(DISTINCT lineitem_hash) - FROM lineitem_hash - GROUP BY l_linenumber) sub - ORDER BY 2 DESC, 1 DESC - LIMIT 10; -ERROR: cannot compute count (distinct) -DETAIL: Non-column references are not supported yet -SELECT * - FROM ( - SELECT - l_linenumber, count(DISTINCT lineitem_hash.*) - FROM lineitem_hash - GROUP BY l_linenumber) sub - ORDER BY 2 DESC, 1 DESC - LIMIT 10; -ERROR: cannot compute count (distinct) -DETAIL: Non-column references are not supported yet --- count distinct pushdown is enabled -SELECT * - FROM ( - SELECT - l_shipdate, - count(DISTINCT - CASE - WHEN l_shipmode = 'TRUCK' THEN l_partkey - ELSE NULL - END) as distinct_part, - extract(year from l_shipdate) as year - FROM - lineitem_hash - GROUP BY l_shipdate, year) sub - WHERE year = 1995 - ORDER BY 2 DESC, 1 - LIMIT 10; - l_shipdate | distinct_part | year ---------------------------------------------------------------------- - 11-29-1995 | 5 | 1995 - 03-24-1995 | 4 | 1995 - 09-18-1995 | 4 | 1995 - 01-17-1995 | 3 | 1995 - 04-02-1995 | 3 | 1995 - 05-23-1995 | 3 | 1995 - 08-11-1995 | 3 | 1995 - 09-27-1995 | 3 | 1995 - 10-27-1995 | 3 | 1995 - 10-30-1995 | 3 | 1995 -(10 rows) - -RESET citus.task_executor_type; --- count distinct pushdown is enabled -SELECT * - FROM ( - SELECT - l_shipdate, - count(DISTINCT - CASE - WHEN l_shipmode = 'TRUCK' THEN l_partkey - ELSE NULL - END) as distinct_part, - extract(year from l_shipdate) as year - FROM - lineitem_hash - GROUP BY l_shipdate, year) sub - WHERE year = 1995 - ORDER BY 2 DESC, 1 - LIMIT 10; - l_shipdate | distinct_part | year ---------------------------------------------------------------------- - 11-29-1995 | 5 | 1995 - 03-24-1995 | 4 | 1995 - 09-18-1995 | 4 | 1995 - 01-17-1995 | 3 | 1995 - 04-02-1995 | 3 | 1995 - 05-23-1995 | 3 | 1995 - 08-11-1995 | 3 | 1995 - 09-27-1995 | 3 | 1995 - 10-27-1995 | 3 | 1995 - 10-30-1995 | 3 | 1995 -(10 rows) - -SELECT * - FROM ( - SELECT - l_shipdate, - count(DISTINCT - CASE - WHEN l_shipmode = 'TRUCK' THEN l_partkey - ELSE NULL - END) as distinct_part, - extract(year from l_shipdate) as year - FROM - lineitem_hash - GROUP BY l_shipdate) sub - WHERE year = 1995 - ORDER BY 2 DESC, 1 - LIMIT 10; - l_shipdate | distinct_part | year ---------------------------------------------------------------------- - 11-29-1995 | 5 | 1995 - 03-24-1995 | 4 | 1995 - 09-18-1995 | 4 | 1995 - 01-17-1995 | 3 | 1995 - 04-02-1995 | 3 | 1995 - 05-23-1995 | 3 | 1995 - 08-11-1995 | 3 | 1995 - 09-27-1995 | 3 | 1995 - 10-27-1995 | 3 | 1995 - 10-30-1995 | 3 | 1995 -(10 rows) - -DROP TABLE lineitem_hash; diff --git a/src/test/regress/expected/multi_partitioning.out b/src/test/regress/expected/multi_partitioning.out index e85a4a2a9..66dbcfc94 100644 --- a/src/test/regress/expected/multi_partitioning.out +++ b/src/test/regress/expected/multi_partitioning.out @@ -1613,14 +1613,14 @@ SELECT * FROM partitioning_hash_test JOIN partitioning_hash_join_test USING (id, -> Hash Join Hash Cond: ((partitioning_hash_join_test.id = partitioning_hash_test.id) AND (partitioning_hash_join_test.subid = partitioning_hash_test.subid)) -> Append - -> Seq Scan on partitioning_hash_join_test_0_1660133 partitioning_hash_join_test - -> Seq Scan on partitioning_hash_join_test_1_1660137 partitioning_hash_join_test_1 - -> Seq Scan on partitioning_hash_join_test_2_1660141 partitioning_hash_join_test_2 + -> Seq Scan on partitioning_hash_join_test_0_1660133 partitioning_hash_join_test_1 + -> Seq Scan on partitioning_hash_join_test_1_1660137 partitioning_hash_join_test_2 + -> Seq Scan on partitioning_hash_join_test_2_1660141 partitioning_hash_join_test_3 -> Hash -> Append - -> Seq Scan on partitioning_hash_test_0_1660016 partitioning_hash_test - -> Seq Scan on partitioning_hash_test_1_1660020 partitioning_hash_test_1 - -> Seq Scan on partitioning_hash_test_2_1660032 partitioning_hash_test_2 + -> Seq Scan on partitioning_hash_test_0_1660016 partitioning_hash_test_1 + -> Seq Scan on partitioning_hash_test_1_1660020 partitioning_hash_test_2 + -> Seq Scan on partitioning_hash_test_2_1660032 partitioning_hash_test_3 (16 rows) -- set partition-wise join on and parallel to off @@ -1651,20 +1651,20 @@ SELECT * FROM partitioning_hash_test JOIN partitioning_hash_join_test USING (id, Node: host=localhost port=xxxxx dbname=regression -> Append -> Hash Join - Hash Cond: ((partitioning_hash_join_test.id = partitioning_hash_test.id) AND (partitioning_hash_join_test.subid = partitioning_hash_test.subid)) - -> Seq Scan on partitioning_hash_join_test_0_1660133 partitioning_hash_join_test + Hash Cond: ((partitioning_hash_join_test_1.id = partitioning_hash_test_1.id) AND (partitioning_hash_join_test_1.subid = partitioning_hash_test_1.subid)) + -> Seq Scan on partitioning_hash_join_test_0_1660133 partitioning_hash_join_test_1 -> Hash - -> Seq Scan on partitioning_hash_test_0_1660016 partitioning_hash_test + -> Seq Scan on partitioning_hash_test_0_1660016 partitioning_hash_test_1 -> Hash Join - Hash Cond: ((partitioning_hash_test_1.id = partitioning_hash_join_test_1.id) AND (partitioning_hash_test_1.subid = partitioning_hash_join_test_1.subid)) - -> Seq Scan on partitioning_hash_test_1_1660020 partitioning_hash_test_1 + Hash Cond: ((partitioning_hash_test_2.id = partitioning_hash_join_test_2.id) AND (partitioning_hash_test_2.subid = partitioning_hash_join_test_2.subid)) + -> Seq Scan on partitioning_hash_test_1_1660020 partitioning_hash_test_2 -> Hash - -> Seq Scan on partitioning_hash_join_test_1_1660137 partitioning_hash_join_test_1 + -> Seq Scan on partitioning_hash_join_test_1_1660137 partitioning_hash_join_test_2 -> Hash Join - Hash Cond: ((partitioning_hash_join_test_2.id = partitioning_hash_test_2.id) AND (partitioning_hash_join_test_2.subid = partitioning_hash_test_2.subid)) - -> Seq Scan on partitioning_hash_join_test_2_1660141 partitioning_hash_join_test_2 + Hash Cond: ((partitioning_hash_join_test_3.id = partitioning_hash_test_3.id) AND (partitioning_hash_join_test_3.subid = partitioning_hash_test_3.subid)) + -> Seq Scan on partitioning_hash_join_test_2_1660141 partitioning_hash_join_test_3 -> Hash - -> Seq Scan on partitioning_hash_test_2_1660032 partitioning_hash_test_2 + -> Seq Scan on partitioning_hash_test_2_1660032 partitioning_hash_test_3 (21 rows) -- note that partition-wise joins only work when partition key is in the join @@ -1682,14 +1682,14 @@ SELECT * FROM partitioning_hash_test JOIN partitioning_hash_join_test USING (id) -> Hash Join Hash Cond: (partitioning_hash_join_test.id = partitioning_hash_test.id) -> Append - -> Seq Scan on partitioning_hash_join_test_0_1660133 partitioning_hash_join_test - -> Seq Scan on partitioning_hash_join_test_1_1660137 partitioning_hash_join_test_1 - -> Seq Scan on partitioning_hash_join_test_2_1660141 partitioning_hash_join_test_2 + -> Seq Scan on partitioning_hash_join_test_0_1660133 partitioning_hash_join_test_1 + -> Seq Scan on partitioning_hash_join_test_1_1660137 partitioning_hash_join_test_2 + -> Seq Scan on partitioning_hash_join_test_2_1660141 partitioning_hash_join_test_3 -> Hash -> Append - -> Seq Scan on partitioning_hash_test_0_1660016 partitioning_hash_test - -> Seq Scan on partitioning_hash_test_1_1660020 partitioning_hash_test_1 - -> Seq Scan on partitioning_hash_test_2_1660032 partitioning_hash_test_2 + -> Seq Scan on partitioning_hash_test_0_1660016 partitioning_hash_test_1 + -> Seq Scan on partitioning_hash_test_1_1660020 partitioning_hash_test_2 + -> Seq Scan on partitioning_hash_test_2_1660032 partitioning_hash_test_3 (16 rows) -- reset partition-wise join diff --git a/src/test/regress/expected/multi_partitioning_1.out b/src/test/regress/expected/multi_partitioning_1.out new file mode 100644 index 000000000..18691286c --- /dev/null +++ b/src/test/regress/expected/multi_partitioning_1.out @@ -0,0 +1,1967 @@ +-- +-- Distributed Partitioned Table Tests +-- +SET citus.next_shard_id TO 1660000; +SET citus.shard_count TO 4; +SET citus.shard_replication_factor TO 1; +-- +-- Distributed Partitioned Table Creation Tests +-- +-- 1-) Distributing partitioned table +-- create partitioned table +CREATE TABLE partitioning_test(id int, time date) PARTITION BY RANGE (time); +CREATE TABLE partitioning_hash_test(id int, subid int) PARTITION BY HASH(subid); +-- create its partitions +CREATE TABLE partitioning_test_2009 PARTITION OF partitioning_test FOR VALUES FROM ('2009-01-01') TO ('2010-01-01'); +CREATE TABLE partitioning_test_2010 PARTITION OF partitioning_test FOR VALUES FROM ('2010-01-01') TO ('2011-01-01'); +CREATE TABLE partitioning_hash_test_0 PARTITION OF partitioning_hash_test FOR VALUES WITH (MODULUS 3, REMAINDER 0); +CREATE TABLE partitioning_hash_test_1 PARTITION OF partitioning_hash_test FOR VALUES WITH (MODULUS 3, REMAINDER 1); +-- load some data and distribute tables +INSERT INTO partitioning_test VALUES (1, '2009-06-06'); +INSERT INTO partitioning_test VALUES (2, '2010-07-07'); +INSERT INTO partitioning_test_2009 VALUES (3, '2009-09-09'); +INSERT INTO partitioning_test_2010 VALUES (4, '2010-03-03'); +INSERT INTO partitioning_hash_test VALUES (1, 2); +INSERT INTO partitioning_hash_test VALUES (2, 13); +INSERT INTO partitioning_hash_test VALUES (3, 7); +INSERT INTO partitioning_hash_test VALUES (4, 4); +-- distribute partitioned table +SELECT create_distributed_table('partitioning_test', 'id'); +NOTICE: Copying data from local table... +NOTICE: copying the data has completed +DETAIL: The local data in the table is no longer visible, but is still on disk. +HINT: To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$public.partitioning_test_2009$$) +NOTICE: Copying data from local table... +NOTICE: copying the data has completed +DETAIL: The local data in the table is no longer visible, but is still on disk. +HINT: To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$public.partitioning_test_2010$$) + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +SELECT create_distributed_table('partitioning_hash_test', 'id'); +NOTICE: Copying data from local table... +NOTICE: copying the data has completed +DETAIL: The local data in the table is no longer visible, but is still on disk. +HINT: To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$public.partitioning_hash_test_0$$) +NOTICE: Copying data from local table... +NOTICE: copying the data has completed +DETAIL: The local data in the table is no longer visible, but is still on disk. +HINT: To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$public.partitioning_hash_test_1$$) + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +-- see the data is loaded to shards +SELECT * FROM partitioning_test ORDER BY 1; + id | time +--------------------------------------------------------------------- + 1 | 06-06-2009 + 2 | 07-07-2010 + 3 | 09-09-2009 + 4 | 03-03-2010 +(4 rows) + +SELECT * FROM partitioning_hash_test ORDER BY 1; + id | subid +--------------------------------------------------------------------- + 1 | 2 + 2 | 13 + 3 | 7 + 4 | 4 +(4 rows) + +-- see partitioned table and its partitions are distributed +SELECT + logicalrelid +FROM + pg_dist_partition +WHERE + logicalrelid IN ('partitioning_test', 'partitioning_test_2009', 'partitioning_test_2010') +ORDER BY 1; + logicalrelid +--------------------------------------------------------------------- + partitioning_test + partitioning_test_2009 + partitioning_test_2010 +(3 rows) + +SELECT + logicalrelid, count(*) +FROM pg_dist_shard + WHERE logicalrelid IN ('partitioning_test', 'partitioning_test_2009', 'partitioning_test_2010') +GROUP BY + logicalrelid +ORDER BY + 1,2; + logicalrelid | count +--------------------------------------------------------------------- + partitioning_test | 4 + partitioning_test_2009 | 4 + partitioning_test_2010 | 4 +(3 rows) + +SELECT + logicalrelid +FROM + pg_dist_partition +WHERE + logicalrelid IN ('partitioning_hash_test', 'partitioning_hash_test_0', 'partitioning_hash_test_1') +ORDER BY 1; + logicalrelid +--------------------------------------------------------------------- + partitioning_hash_test + partitioning_hash_test_0 + partitioning_hash_test_1 +(3 rows) + +SELECT + logicalrelid, count(*) +FROM pg_dist_shard + WHERE logicalrelid IN ('partitioning_hash_test', 'partitioning_hash_test_0', 'partitioning_hash_test_1') +GROUP BY + logicalrelid +ORDER BY + 1,2; + logicalrelid | count +--------------------------------------------------------------------- + partitioning_hash_test | 4 + partitioning_hash_test_0 | 4 + partitioning_hash_test_1 | 4 +(3 rows) + +-- 2-) Creating partition of a distributed table +CREATE TABLE partitioning_test_2011 PARTITION OF partitioning_test FOR VALUES FROM ('2011-01-01') TO ('2012-01-01'); +-- new partition is automatically distributed as well +SELECT + logicalrelid +FROM + pg_dist_partition +WHERE + logicalrelid IN ('partitioning_test', 'partitioning_test_2011') +ORDER BY 1; + logicalrelid +--------------------------------------------------------------------- + partitioning_test + partitioning_test_2011 +(2 rows) + +SELECT + logicalrelid, count(*) +FROM pg_dist_shard + WHERE logicalrelid IN ('partitioning_test', 'partitioning_test_2011') +GROUP BY + logicalrelid +ORDER BY + 1,2; + logicalrelid | count +--------------------------------------------------------------------- + partitioning_test | 4 + partitioning_test_2011 | 4 +(2 rows) + +-- 3-) Attaching non distributed table to a distributed table +CREATE TABLE partitioning_test_2012(id int, time date); +-- load some data +INSERT INTO partitioning_test_2012 VALUES (5, '2012-06-06'); +INSERT INTO partitioning_test_2012 VALUES (6, '2012-07-07'); +ALTER TABLE partitioning_test ATTACH PARTITION partitioning_test_2012 FOR VALUES FROM ('2012-01-01') TO ('2013-01-01'); +NOTICE: Copying data from local table... +NOTICE: copying the data has completed +DETAIL: The local data in the table is no longer visible, but is still on disk. +HINT: To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$public.partitioning_test_2012$$) +-- attached partition is distributed as well +SELECT + logicalrelid +FROM + pg_dist_partition +WHERE + logicalrelid IN ('partitioning_test', 'partitioning_test_2012') +ORDER BY 1; + logicalrelid +--------------------------------------------------------------------- + partitioning_test + partitioning_test_2012 +(2 rows) + +SELECT + logicalrelid, count(*) +FROM pg_dist_shard + WHERE logicalrelid IN ('partitioning_test', 'partitioning_test_2012') +GROUP BY + logicalrelid +ORDER BY + 1,2; + logicalrelid | count +--------------------------------------------------------------------- + partitioning_test | 4 + partitioning_test_2012 | 4 +(2 rows) + +-- try to insert a new data to hash partitioned table +-- no partition is defined for value 5 +INSERT INTO partitioning_hash_test VALUES (8, 5); +ERROR: no partition of relation "partitioning_hash_test_1660012" found for row +DETAIL: Partition key of the failing row contains (subid) = (5). +CONTEXT: while executing command on localhost:xxxxx +INSERT INTO partitioning_hash_test VALUES (9, 12); +ERROR: no partition of relation "partitioning_hash_test_1660015" found for row +DETAIL: Partition key of the failing row contains (subid) = (12). +CONTEXT: while executing command on localhost:xxxxx +CREATE TABLE partitioning_hash_test_2 (id int, subid int); +INSERT INTO partitioning_hash_test_2 VALUES (8, 5); +ALTER TABLE partitioning_hash_test ATTACH PARTITION partitioning_hash_test_2 FOR VALUES WITH (MODULUS 3, REMAINDER 2); +NOTICE: Copying data from local table... +NOTICE: copying the data has completed +DETAIL: The local data in the table is no longer visible, but is still on disk. +HINT: To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$public.partitioning_hash_test_2$$) +INSERT INTO partitioning_hash_test VALUES (9, 12); +-- see the data is loaded to shards +SELECT * FROM partitioning_test ORDER BY 1; + id | time +--------------------------------------------------------------------- + 1 | 06-06-2009 + 2 | 07-07-2010 + 3 | 09-09-2009 + 4 | 03-03-2010 + 5 | 06-06-2012 + 6 | 07-07-2012 +(6 rows) + +SELECT * FROM partitioning_hash_test ORDER BY 1; + id | subid +--------------------------------------------------------------------- + 1 | 2 + 2 | 13 + 3 | 7 + 4 | 4 + 8 | 5 + 9 | 12 +(6 rows) + +-- 4-) Attaching distributed table to distributed table +CREATE TABLE partitioning_test_2013(id int, time date); +SELECT create_distributed_table('partitioning_test_2013', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +-- load some data +INSERT INTO partitioning_test_2013 VALUES (7, '2013-06-06'); +INSERT INTO partitioning_test_2013 VALUES (8, '2013-07-07'); +ALTER TABLE partitioning_test ATTACH PARTITION partitioning_test_2013 FOR VALUES FROM ('2013-01-01') TO ('2014-01-01'); +-- see the data is loaded to shards +SELECT * FROM partitioning_test ORDER BY 1; + id | time +--------------------------------------------------------------------- + 1 | 06-06-2009 + 2 | 07-07-2010 + 3 | 09-09-2009 + 4 | 03-03-2010 + 5 | 06-06-2012 + 6 | 07-07-2012 + 7 | 06-06-2013 + 8 | 07-07-2013 +(8 rows) + +-- 5-) Failure cases while creating distributed partitioned tables +-- cannot distribute a partition if its parent is not distributed +CREATE TABLE partitioning_test_failure(id int, time date) PARTITION BY RANGE (time); +CREATE TABLE partitioning_test_failure_2009 PARTITION OF partitioning_test_failure FOR VALUES FROM ('2009-01-01') TO ('2010-01-01'); +SELECT create_distributed_table('partitioning_test_failure_2009', 'id'); +ERROR: cannot distribute relation "partitioning_test_failure_2009" which is partition of "partitioning_test_failure" +DETAIL: Citus does not support distributing partitions if their parent is not distributed table. +HINT: Distribute the partitioned table "partitioning_test_failure" instead. +-- only hash distributed tables can have partitions +SELECT create_distributed_table('partitioning_test_failure', 'id', 'append'); +ERROR: distributing partitioned tables in only supported for hash-distributed tables +SELECT create_distributed_table('partitioning_test_failure', 'id', 'range'); +ERROR: distributing partitioned tables in only supported for hash-distributed tables +SELECT create_reference_table('partitioning_test_failure'); +ERROR: distributing partitioned tables in only supported for hash-distributed tables +SET citus.shard_replication_factor TO 1; +-- non-distributed tables cannot have distributed partitions; +DROP TABLE partitioning_test_failure_2009; +CREATE TABLE partitioning_test_failure_2009(id int, time date); +SELECT create_distributed_table('partitioning_test_failure_2009', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +ALTER TABLE partitioning_test_failure ATTACH PARTITION partitioning_test_failure_2009 FOR VALUES FROM ('2009-01-01') TO ('2010-01-01'); +ERROR: non-distributed tables cannot have distributed partitions +HINT: Distribute the partitioned table "partitioning_test_failure_2009" instead +-- multi-level partitioning is not allowed +DROP TABLE partitioning_test_failure_2009; +CREATE TABLE partitioning_test_failure_2009 PARTITION OF partitioning_test_failure FOR VALUES FROM ('2009-01-01') TO ('2010-01-01') PARTITION BY RANGE (time); +SELECT create_distributed_table('partitioning_test_failure', 'id'); +ERROR: distributing multi-level partitioned tables is not supported +DETAIL: Relation "partitioning_test_failure_2009" is partitioned table itself and it is also partition of relation "partitioning_test_failure". +-- multi-level partitioning is not allowed in different order +DROP TABLE partitioning_test_failure_2009; +SELECT create_distributed_table('partitioning_test_failure', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE TABLE partitioning_test_failure_2009 PARTITION OF partitioning_test_failure FOR VALUES FROM ('2009-01-01') TO ('2010-01-01') PARTITION BY RANGE (time); +ERROR: distributing multi-level partitioned tables is not supported +DETAIL: Relation "partitioning_test_failure_2009" is partitioned table itself and it is also partition of relation "partitioning_test_failure". +-- +-- DMLs in distributed partitioned tables +-- +-- test COPY +-- COPY data to partitioned table +COPY partitioning_test FROM STDIN WITH CSV; +-- COPY data to partition directly +COPY partitioning_test_2009 FROM STDIN WITH CSV; +-- see the data is loaded to shards +SELECT * FROM partitioning_test WHERE id >= 9 ORDER BY 1; + id | time +--------------------------------------------------------------------- + 9 | 01-01-2009 + 10 | 01-01-2010 + 11 | 01-01-2011 + 12 | 01-01-2012 + 13 | 01-02-2009 + 14 | 01-03-2009 +(6 rows) + +-- test INSERT +-- INSERT INTO the partitioned table +INSERT INTO partitioning_test VALUES(15, '2009-02-01'); +INSERT INTO partitioning_test VALUES(16, '2010-02-01'); +INSERT INTO partitioning_test VALUES(17, '2011-02-01'); +INSERT INTO partitioning_test VALUES(18, '2012-02-01'); +-- INSERT INTO the partitions directly table +INSERT INTO partitioning_test VALUES(19, '2009-02-02'); +INSERT INTO partitioning_test VALUES(20, '2010-02-02'); +-- see the data is loaded to shards +SELECT * FROM partitioning_test WHERE id >= 15 ORDER BY 1; + id | time +--------------------------------------------------------------------- + 15 | 02-01-2009 + 16 | 02-01-2010 + 17 | 02-01-2011 + 18 | 02-01-2012 + 19 | 02-02-2009 + 20 | 02-02-2010 +(6 rows) + +-- test INSERT/SELECT +-- INSERT/SELECT from partition to partitioned table +INSERT INTO partitioning_test SELECT * FROM partitioning_test_2011; +-- INSERT/SELECT from partitioned table to partition +INSERT INTO partitioning_test_2012 SELECT * FROM partitioning_test WHERE time >= '2012-01-01' AND time < '2013-01-01'; +-- see the data is loaded to shards (rows in the given range should be duplicated) +SELECT * FROM partitioning_test WHERE time >= '2011-01-01' AND time < '2013-01-01' ORDER BY 1; + id | time +--------------------------------------------------------------------- + 5 | 06-06-2012 + 5 | 06-06-2012 + 6 | 07-07-2012 + 6 | 07-07-2012 + 11 | 01-01-2011 + 11 | 01-01-2011 + 12 | 01-01-2012 + 12 | 01-01-2012 + 17 | 02-01-2011 + 17 | 02-01-2011 + 18 | 02-01-2012 + 18 | 02-01-2012 +(12 rows) + +-- test UPDATE +-- UPDATE partitioned table +UPDATE partitioning_test SET time = '2013-07-07' WHERE id = 7; +-- UPDATE partition directly +UPDATE partitioning_test_2013 SET time = '2013-08-08' WHERE id = 8; +-- see the data is updated +SELECT * FROM partitioning_test WHERE id = 7 OR id = 8 ORDER BY 1; + id | time +--------------------------------------------------------------------- + 7 | 07-07-2013 + 8 | 08-08-2013 +(2 rows) + +-- UPDATE that tries to move a row to a non-existing partition (this should fail) +UPDATE partitioning_test SET time = '2020-07-07' WHERE id = 7; +ERROR: no partition of relation "partitioning_test_1660001" found for row +DETAIL: Partition key of the failing row contains ("time") = (2020-07-07). +CONTEXT: while executing command on localhost:xxxxx +-- UPDATE with subqueries on partitioned table +UPDATE + partitioning_test +SET + time = time + INTERVAL '1 day' +WHERE + id IN (SELECT id FROM partitioning_test WHERE id = 1); +-- UPDATE with subqueries on partition +UPDATE + partitioning_test_2009 +SET + time = time + INTERVAL '1 month' +WHERE + id IN (SELECT id FROM partitioning_test WHERE id = 2); +-- see the data is updated +SELECT * FROM partitioning_test WHERE id = 1 OR id = 2 ORDER BY 1; + id | time +--------------------------------------------------------------------- + 1 | 06-07-2009 + 2 | 07-07-2010 +(2 rows) + +-- test DELETE +-- DELETE from partitioned table +DELETE FROM partitioning_test WHERE id = 9; +-- DELETE from partition directly +DELETE FROM partitioning_test_2010 WHERE id = 10; +-- see the data is deleted +SELECT * FROM partitioning_test WHERE id = 9 OR id = 10 ORDER BY 1; + id | time +--------------------------------------------------------------------- +(0 rows) + +-- create default partition +CREATE TABLE partitioning_test_default PARTITION OF partitioning_test DEFAULT; +\d+ partitioning_test + Table "public.partitioning_test" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------------------------------------------------------------------- + id | integer | | | | plain | | + time | date | | | | plain | | +Partition key: RANGE ("time") +Partitions: partitioning_test_2009 FOR VALUES FROM ('01-01-2009') TO ('01-01-2010'), + partitioning_test_2010 FOR VALUES FROM ('01-01-2010') TO ('01-01-2011'), + partitioning_test_2011 FOR VALUES FROM ('01-01-2011') TO ('01-01-2012'), + partitioning_test_2012 FOR VALUES FROM ('01-01-2012') TO ('01-01-2013'), + partitioning_test_2013 FOR VALUES FROM ('01-01-2013') TO ('01-01-2014'), + partitioning_test_default DEFAULT + +INSERT INTO partitioning_test VALUES(21, '2014-02-02'); +INSERT INTO partitioning_test VALUES(22, '2015-04-02'); +-- see they are inserted into default partition +SELECT * FROM partitioning_test WHERE id > 20 ORDER BY 1, 2; + id | time +--------------------------------------------------------------------- + 21 | 02-02-2014 + 22 | 04-02-2015 +(2 rows) + +SELECT * FROM partitioning_test_default ORDER BY 1, 2; + id | time +--------------------------------------------------------------------- + 21 | 02-02-2014 + 22 | 04-02-2015 +(2 rows) + +-- create a new partition (will fail) +CREATE TABLE partitioning_test_2014 PARTITION OF partitioning_test FOR VALUES FROM ('2014-01-01') TO ('2015-01-01'); +ERROR: updated partition constraint for default partition would be violated by some row +CONTEXT: while executing command on localhost:xxxxx +BEGIN; +ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_default; +CREATE TABLE partitioning_test_2014 PARTITION OF partitioning_test FOR VALUES FROM ('2014-01-01') TO ('2015-01-01'); +INSERT INTO partitioning_test SELECT * FROM partitioning_test_default WHERE time >= '2014-01-01' AND time < '2015-01-01'; +DELETE FROM partitioning_test_default WHERE time >= '2014-01-01' AND time < '2015-01-01'; +ALTER TABLE partitioning_test ATTACH PARTITION partitioning_test_default DEFAULT; +END; +-- see data is in the table, but some moved out from default partition +SELECT * FROM partitioning_test WHERE id > 20 ORDER BY 1, 2; + id | time +--------------------------------------------------------------------- + 21 | 02-02-2014 + 22 | 04-02-2015 +(2 rows) + +SELECT * FROM partitioning_test_default ORDER BY 1, 2; + id | time +--------------------------------------------------------------------- + 22 | 04-02-2015 +(1 row) + +-- multi-shard UPDATE on partitioned table +UPDATE partitioning_test SET time = time + INTERVAL '1 day'; +-- see rows are UPDATED +SELECT * FROM partitioning_test ORDER BY 1; + id | time +--------------------------------------------------------------------- + 1 | 06-08-2009 + 2 | 07-08-2010 + 3 | 09-10-2009 + 4 | 03-04-2010 + 5 | 06-07-2012 + 5 | 06-07-2012 + 6 | 07-08-2012 + 6 | 07-08-2012 + 7 | 07-08-2013 + 8 | 08-09-2013 + 11 | 01-02-2011 + 11 | 01-02-2011 + 12 | 01-02-2012 + 12 | 01-02-2012 + 13 | 01-03-2009 + 14 | 01-04-2009 + 15 | 02-02-2009 + 16 | 02-02-2010 + 17 | 02-02-2011 + 17 | 02-02-2011 + 18 | 02-02-2012 + 18 | 02-02-2012 + 19 | 02-03-2009 + 20 | 02-03-2010 + 21 | 02-03-2014 + 22 | 04-03-2015 +(26 rows) + +-- multi-shard UPDATE on partition directly +UPDATE partitioning_test_2009 SET time = time + INTERVAL '1 day'; +-- see rows are UPDATED +SELECT * FROM partitioning_test_2009 ORDER BY 1; + id | time +--------------------------------------------------------------------- + 1 | 06-09-2009 + 3 | 09-11-2009 + 13 | 01-04-2009 + 14 | 01-05-2009 + 15 | 02-03-2009 + 19 | 02-04-2009 +(6 rows) + +-- test multi-shard UPDATE which fails in workers (updated value is outside of partition bounds) +UPDATE partitioning_test_2009 SET time = time + INTERVAL '6 month'; +ERROR: new row for relation "partitioning_test_2009_1660005" violates partition constraint +DETAIL: Failing row contains (3, 2010-03-11). +CONTEXT: while executing command on localhost:xxxxx +-- +-- DDL in distributed partitioned tables +-- +-- test CREATE INDEX +-- CREATE INDEX on partitioned table - this will error out +-- on earlier versions of postgres earlier than 11. +CREATE INDEX partitioning_index ON partitioning_test(id); +-- CREATE INDEX on partition +CREATE INDEX partitioning_2009_index ON partitioning_test_2009(id); +-- CREATE INDEX CONCURRENTLY on partition +CREATE INDEX CONCURRENTLY partitioned_2010_index ON partitioning_test_2010(id); +-- see index is created +SELECT tablename, indexname FROM pg_indexes WHERE tablename LIKE 'partitioning_test_%' ORDER BY indexname; + tablename | indexname +--------------------------------------------------------------------- + partitioning_test_2010 | partitioned_2010_index + partitioning_test_2009 | partitioning_2009_index + partitioning_test_2009 | partitioning_test_2009_id_idx + partitioning_test_2010 | partitioning_test_2010_id_idx + partitioning_test_2011 | partitioning_test_2011_id_idx + partitioning_test_2012 | partitioning_test_2012_id_idx + partitioning_test_2013 | partitioning_test_2013_id_idx + partitioning_test_2014 | partitioning_test_2014_id_idx + partitioning_test_default | partitioning_test_default_id_idx +(9 rows) + +-- test drop +-- indexes created on parent table can only be dropped on parent table +-- ie using the same index name +-- following will fail +DROP INDEX partitioning_test_2009_id_idx; +ERROR: cannot drop index partitioning_test_2009_id_idx because index partitioning_index requires it +HINT: You can drop index partitioning_index instead. +-- but dropping index on parent table will succeed +DROP INDEX partitioning_index; +-- this index was already created on partition table +DROP INDEX partitioning_2009_index; +-- test drop index on non-distributed, partitioned table +CREATE TABLE non_distributed_partitioned_table(a int, b int) PARTITION BY RANGE (a); +CREATE TABLE non_distributed_partitioned_table_1 PARTITION OF non_distributed_partitioned_table +FOR VALUES FROM (0) TO (10); +CREATE INDEX non_distributed_partitioned_table_index ON non_distributed_partitioned_table(a); +-- see index is created +SELECT tablename, indexname FROM pg_indexes WHERE tablename LIKE 'non_distributed_partitioned_table_%' ORDER BY indexname; + tablename | indexname +--------------------------------------------------------------------- + non_distributed_partitioned_table_1 | non_distributed_partitioned_table_1_a_idx +(1 row) + +-- drop the index and see it is dropped +DROP INDEX non_distributed_partitioned_table_index; +SELECT tablename, indexname FROM pg_indexes WHERE tablename LIKE 'non_distributed%' ORDER BY indexname; + tablename | indexname +--------------------------------------------------------------------- +(0 rows) + +-- test add COLUMN +-- add COLUMN to partitioned table +ALTER TABLE partitioning_test ADD new_column int; +-- add COLUMN to partition - this will error out +ALTER TABLE partitioning_test_2010 ADD new_column_2 int; +ERROR: cannot add column to a partition +-- see additional column is created +SELECT name, type FROM table_attrs WHERE relid = 'partitioning_test'::regclass ORDER BY 1; + name | type +--------------------------------------------------------------------- + id | integer + new_column | integer + time | date +(3 rows) + +SELECT name, type FROM table_attrs WHERE relid = 'partitioning_test_2010'::regclass ORDER BY 1; + name | type +--------------------------------------------------------------------- + id | integer + new_column | integer + time | date +(3 rows) + +-- test add PRIMARY KEY +-- add PRIMARY KEY to partitioned table - this will error out +ALTER TABLE partitioning_test ADD CONSTRAINT partitioning_primary PRIMARY KEY (id); +ERROR: insufficient columns in PRIMARY KEY constraint definition +DETAIL: PRIMARY KEY constraint on table "partitioning_test" lacks column "time" which is part of the partition key. +-- ADD PRIMARY KEY to partition +ALTER TABLE partitioning_test_2009 ADD CONSTRAINT partitioning_2009_primary PRIMARY KEY (id); +-- see PRIMARY KEY is created +SELECT + table_name, + constraint_name, + constraint_type +FROM + information_schema.table_constraints +WHERE + table_name = 'partitioning_test_2009' AND + constraint_name = 'partitioning_2009_primary'; + table_name | constraint_name | constraint_type +--------------------------------------------------------------------- + partitioning_test_2009 | partitioning_2009_primary | PRIMARY KEY +(1 row) + +-- however, you can add primary key if it contains both distribution and partition key +ALTER TABLE partitioning_hash_test ADD CONSTRAINT partitioning_hash_primary PRIMARY KEY (id, subid); +-- see PRIMARY KEY is created +SELECT + table_name, + constraint_name, + constraint_type +FROM + information_schema.table_constraints +WHERE + table_name LIKE 'partitioning_hash_test%' AND + constraint_type = 'PRIMARY KEY' +ORDER BY 1; + table_name | constraint_name | constraint_type +--------------------------------------------------------------------- + partitioning_hash_test | partitioning_hash_primary | PRIMARY KEY + partitioning_hash_test_0 | partitioning_hash_test_0_pkey | PRIMARY KEY + partitioning_hash_test_1 | partitioning_hash_test_1_pkey | PRIMARY KEY + partitioning_hash_test_2 | partitioning_hash_test_2_pkey | PRIMARY KEY +(4 rows) + +-- test ADD FOREIGN CONSTRAINT +-- add FOREIGN CONSTRAINT to partitioned table -- this will error out (it is a self reference) +ALTER TABLE partitioning_test ADD CONSTRAINT partitioning_foreign FOREIGN KEY (id) REFERENCES partitioning_test_2009 (id); +ERROR: cannot ALTER TABLE "partitioning_test_2009" because it is being used by active queries in this session +-- add FOREIGN CONSTRAINT to partition +INSERT INTO partitioning_test_2009 VALUES (5, '2009-06-06'); +INSERT INTO partitioning_test_2009 VALUES (6, '2009-07-07'); +INSERT INTO partitioning_test_2009 VALUES(12, '2009-02-01'); +INSERT INTO partitioning_test_2009 VALUES(18, '2009-02-01'); +ALTER TABLE partitioning_test_2012 ADD CONSTRAINT partitioning_2012_foreign FOREIGN KEY (id) REFERENCES partitioning_test_2009 (id) ON DELETE CASCADE; +-- see FOREIGN KEY is created +SELECT "Constraint" FROM table_fkeys WHERE relid = 'partitioning_test_2012'::regclass ORDER BY 1; + Constraint +--------------------------------------------------------------------- + partitioning_2012_foreign +(1 row) + +-- test ON DELETE CASCADE works +DELETE FROM partitioning_test_2009 WHERE id = 5; +-- see that element is deleted from both partitions +SELECT * FROM partitioning_test_2009 WHERE id = 5 ORDER BY 1; + id | time | new_column +--------------------------------------------------------------------- +(0 rows) + +SELECT * FROM partitioning_test_2012 WHERE id = 5 ORDER BY 1; + id | time | new_column +--------------------------------------------------------------------- +(0 rows) + +-- test DETACH partition +ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2009; +-- see DETACHed partitions content is not accessible from partitioning_test; +SELECT * FROM partitioning_test WHERE time >= '2009-01-01' AND time < '2010-01-01' ORDER BY 1; + id | time | new_column +--------------------------------------------------------------------- +(0 rows) + +-- delete from default partition +DELETE FROM partitioning_test WHERE time >= '2015-01-01'; +SELECT * FROM partitioning_test_default; + id | time | new_column +--------------------------------------------------------------------- +(0 rows) + +-- create a reference table for foreign key test +CREATE TABLE partitioning_test_reference(id int PRIMARY KEY, subid int); +INSERT INTO partitioning_test_reference SELECT a, a FROM generate_series(1, 50) a; +SELECT create_reference_table('partitioning_test_reference'); +NOTICE: Copying data from local table... +NOTICE: copying the data has completed +DETAIL: The local data in the table is no longer visible, but is still on disk. +HINT: To remove the local data, run: SELECT truncate_local_data_after_distributing_table($$public.partitioning_test_reference$$) + create_reference_table +--------------------------------------------------------------------- + +(1 row) + +ALTER TABLE partitioning_test ADD CONSTRAINT partitioning_reference_fkey FOREIGN KEY (id) REFERENCES partitioning_test_reference(id) ON DELETE CASCADE; +CREATE TABLE partitioning_test_foreign_key(id int PRIMARY KEY, value int); +SELECT create_distributed_table('partitioning_test_foreign_key', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +INSERT INTO partitioning_test_foreign_key SELECT * FROM partitioning_test_reference; +ALTER TABLE partitioning_hash_test ADD CONSTRAINT partitioning_reference_fk_test FOREIGN KEY (id) REFERENCES partitioning_test_foreign_key(id) ON DELETE CASCADE; +-- check foreign keys on partitions +SELECT + table_name, constraint_name, constraint_type FROm information_schema.table_constraints +WHERE + table_name LIKE 'partitioning_hash_test%' AND + constraint_type = 'FOREIGN KEY' +ORDER BY + 1,2; + table_name | constraint_name | constraint_type +--------------------------------------------------------------------- + partitioning_hash_test | partitioning_reference_fk_test | FOREIGN KEY + partitioning_hash_test_0 | partitioning_reference_fk_test | FOREIGN KEY + partitioning_hash_test_1 | partitioning_reference_fk_test | FOREIGN KEY + partitioning_hash_test_2 | partitioning_reference_fk_test | FOREIGN KEY +(4 rows) + +-- check foreign keys on partition shards +-- there is some text ordering issue regarding table name +-- forcing integer sort by extracting shardid +CREATE TYPE foreign_key_details AS (table_name text, constraint_name text, constraint_type text); +SELECT right(table_name, 7)::int as shardid, * FROM ( + SELECT (json_populate_record(NULL::foreign_key_details, + json_array_elements_text(result::json)::json )).* + FROM run_command_on_workers($$ + SELECT + COALESCE(json_agg(row_to_json(q)), '[]'::json) + FROM ( + SELECT + table_name, constraint_name, constraint_type + FROM information_schema.table_constraints + WHERE + table_name LIKE 'partitioning_hash_test%' AND + constraint_type = 'FOREIGN KEY' + ORDER BY 1, 2, 3 + ) q + $$) ) w +ORDER BY 1, 2, 3, 4; + shardid | table_name | constraint_name | constraint_type +--------------------------------------------------------------------- + 1660012 | partitioning_hash_test_1660012 | partitioning_reference_fk_test_1660012 | FOREIGN KEY + 1660013 | partitioning_hash_test_1660013 | partitioning_reference_fk_test_1660013 | FOREIGN KEY + 1660014 | partitioning_hash_test_1660014 | partitioning_reference_fk_test_1660014 | FOREIGN KEY + 1660015 | partitioning_hash_test_1660015 | partitioning_reference_fk_test_1660015 | FOREIGN KEY + 1660016 | partitioning_hash_test_0_1660016 | partitioning_reference_fk_test_1660012 | FOREIGN KEY + 1660017 | partitioning_hash_test_0_1660017 | partitioning_reference_fk_test_1660013 | FOREIGN KEY + 1660018 | partitioning_hash_test_0_1660018 | partitioning_reference_fk_test_1660014 | FOREIGN KEY + 1660019 | partitioning_hash_test_0_1660019 | partitioning_reference_fk_test_1660015 | FOREIGN KEY + 1660020 | partitioning_hash_test_1_1660020 | partitioning_reference_fk_test_1660012 | FOREIGN KEY + 1660021 | partitioning_hash_test_1_1660021 | partitioning_reference_fk_test_1660013 | FOREIGN KEY + 1660022 | partitioning_hash_test_1_1660022 | partitioning_reference_fk_test_1660014 | FOREIGN KEY + 1660023 | partitioning_hash_test_1_1660023 | partitioning_reference_fk_test_1660015 | FOREIGN KEY + 1660032 | partitioning_hash_test_2_1660032 | partitioning_reference_fk_test_1660012 | FOREIGN KEY + 1660033 | partitioning_hash_test_2_1660033 | partitioning_reference_fk_test_1660013 | FOREIGN KEY + 1660034 | partitioning_hash_test_2_1660034 | partitioning_reference_fk_test_1660014 | FOREIGN KEY + 1660035 | partitioning_hash_test_2_1660035 | partitioning_reference_fk_test_1660015 | FOREIGN KEY +(16 rows) + +DROP TYPE foreign_key_details; +-- set replication factor back to 1 since it gots reset +-- after connection re-establishment +SET citus.shard_replication_factor TO 1; +SELECT * FROM partitioning_test WHERE id = 11 or id = 12; + id | time | new_column +--------------------------------------------------------------------- + 11 | 01-02-2011 | + 11 | 01-02-2011 | + 12 | 01-02-2012 | + 12 | 01-02-2012 | +(4 rows) + +DELETE FROM partitioning_test_reference WHERE id = 11 or id = 12; +SELECT * FROM partitioning_hash_test ORDER BY 1, 2; + id | subid +--------------------------------------------------------------------- + 1 | 2 + 2 | 13 + 3 | 7 + 4 | 4 + 8 | 5 + 9 | 12 +(6 rows) + +DELETE FROM partitioning_test_foreign_key WHERE id = 2 OR id = 9; +-- see data is deleted from referencing table +SELECT * FROM partitioning_test WHERE id = 11 or id = 12; + id | time | new_column +--------------------------------------------------------------------- +(0 rows) + +SELECT * FROM partitioning_hash_test ORDER BY 1, 2; + id | subid +--------------------------------------------------------------------- + 1 | 2 + 3 | 7 + 4 | 4 + 8 | 5 +(4 rows) + +-- +-- Transaction tests +-- +-- DDL in transaction +BEGIN; +ALTER TABLE partitioning_test ADD newer_column int; +-- see additional column is created +SELECT name, type FROM table_attrs WHERE relid = 'partitioning_test'::regclass ORDER BY 1; + name | type +--------------------------------------------------------------------- + id | integer + new_column | integer + newer_column | integer + time | date +(4 rows) + +ROLLBACK; +-- see rollback is successful +SELECT name, type FROM table_attrs WHERE relid = 'partitioning_test'::regclass ORDER BY 1; + name | type +--------------------------------------------------------------------- + id | integer + new_column | integer + time | date +(3 rows) + +-- COPY in transaction +BEGIN; +COPY partitioning_test FROM STDIN WITH CSV; +-- see the data is loaded to shards +SELECT * FROM partitioning_test WHERE id = 22 ORDER BY 1; + id | time | new_column +--------------------------------------------------------------------- + 22 | 01-01-2010 | 22 +(1 row) + +SELECT * FROM partitioning_test WHERE id = 23 ORDER BY 1; + id | time | new_column +--------------------------------------------------------------------- + 23 | 01-01-2011 | 23 +(1 row) + +SELECT * FROM partitioning_test WHERE id = 24 ORDER BY 1; + id | time | new_column +--------------------------------------------------------------------- + 24 | 01-01-2013 | 24 +(1 row) + +ROLLBACK; +-- see rollback is successful +SELECT * FROM partitioning_test WHERE id >= 22 ORDER BY 1; + id | time | new_column +--------------------------------------------------------------------- +(0 rows) + +-- DML in transaction +BEGIN; +-- INSERT in transaction +INSERT INTO partitioning_test VALUES(25, '2010-02-02'); +-- see the data is loaded to shards +SELECT * FROM partitioning_test WHERE id = 25 ORDER BY 1; + id | time | new_column +--------------------------------------------------------------------- + 25 | 02-02-2010 | +(1 row) + +-- INSERT/SELECT in transaction +INSERT INTO partitioning_test SELECT * FROM partitioning_test WHERE id = 25; +-- see the data is loaded to shards +SELECT * FROM partitioning_test WHERE id = 25 ORDER BY 1; + id | time | new_column +--------------------------------------------------------------------- + 25 | 02-02-2010 | + 25 | 02-02-2010 | +(2 rows) + +-- UPDATE in transaction +UPDATE partitioning_test SET time = '2010-10-10' WHERE id = 25; +-- see the data is updated +SELECT * FROM partitioning_test WHERE id = 25 ORDER BY 1; + id | time | new_column +--------------------------------------------------------------------- + 25 | 10-10-2010 | + 25 | 10-10-2010 | +(2 rows) + +-- perform operations on partition and partioned tables together +INSERT INTO partitioning_test VALUES(26, '2010-02-02', 26); +INSERT INTO partitioning_test_2010 VALUES(26, '2010-02-02', 26); +COPY partitioning_test FROM STDIN WITH CSV; +COPY partitioning_test_2010 FROM STDIN WITH CSV; +-- see the data is loaded to shards (we should see 4 rows with same content) +SELECT * FROM partitioning_test WHERE id = 26 ORDER BY 1; + id | time | new_column +--------------------------------------------------------------------- + 26 | 02-02-2010 | 26 + 26 | 02-02-2010 | 26 + 26 | 02-02-2010 | 26 + 26 | 02-02-2010 | 26 +(4 rows) + +ROLLBACK; +-- see rollback is successful +SELECT * FROM partitioning_test WHERE id = 26 ORDER BY 1; + id | time | new_column +--------------------------------------------------------------------- +(0 rows) + +-- DETACH and DROP in a transaction +BEGIN; +ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2011; +DROP TABLE partitioning_test_2011; +COMMIT; +-- see DROPed partitions content is not accessible +SELECT * FROM partitioning_test WHERE time >= '2011-01-01' AND time < '2012-01-01' ORDER BY 1; + id | time | new_column +--------------------------------------------------------------------- +(0 rows) + +-- +-- Misc tests +-- +-- test TRUNCATE +-- test TRUNCATE partition +TRUNCATE partitioning_test_2012; +-- see partition is TRUNCATEd +SELECT * FROM partitioning_test_2012 ORDER BY 1; + id | time | new_column +--------------------------------------------------------------------- +(0 rows) + +-- test TRUNCATE partitioned table +TRUNCATE partitioning_test; +-- see partitioned table is TRUNCATEd +SELECT * FROM partitioning_test ORDER BY 1; + id | time | new_column +--------------------------------------------------------------------- +(0 rows) + +-- test DROP +-- test DROP partition +INSERT INTO partitioning_test_2010 VALUES(27, '2010-02-01'); +DROP TABLE partitioning_test_2010; +-- see DROPped partitions content is not accessible from partitioning_test; +SELECT * FROM partitioning_test WHERE time >= '2010-01-01' AND time < '2011-01-01' ORDER BY 1; + id | time | new_column +--------------------------------------------------------------------- +(0 rows) + +-- test DROP partitioned table +DROP TABLE partitioning_test; +DROP TABLE partitioning_test_reference; +-- dropping the parent should CASCADE to the children as well +SELECT table_name FROM information_schema.tables WHERE table_name LIKE 'partitioning_test%' ORDER BY 1; + table_name +--------------------------------------------------------------------- + partitioning_test_2009 + partitioning_test_failure + partitioning_test_foreign_key +(3 rows) + +-- test distributing partitioned table colocated with non-partitioned table +CREATE TABLE partitioned_users_table (user_id int, time timestamp, value_1 int, value_2 int, value_3 float, value_4 bigint) PARTITION BY RANGE (time); +CREATE TABLE partitioned_events_table (user_id int, time timestamp, event_type int, value_2 int, value_3 float, value_4 bigint) PARTITION BY RANGE (time); +SELECT create_distributed_table('partitioned_users_table', 'user_id', colocate_with => 'users_table'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +SELECT create_distributed_table('partitioned_events_table', 'user_id', colocate_with => 'events_table'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +-- INSERT/SELECT from regular table to partitioned table +CREATE TABLE partitioned_users_table_2009 PARTITION OF partitioned_users_table FOR VALUES FROM ('2017-01-01') TO ('2018-01-01'); +CREATE TABLE partitioned_events_table_2009 PARTITION OF partitioned_events_table FOR VALUES FROM ('2017-01-01') TO ('2018-01-01'); +INSERT INTO partitioned_events_table SELECT * FROM events_table; +INSERT INTO partitioned_users_table_2009 SELECT * FROM users_table; +-- +-- Complex JOINs, subqueries, UNIONs etc... +-- +-- subquery with UNIONs on partitioned table +SELECT ("final_query"."event_types") as types, count(*) AS sumOfEventType +FROM + (SELECT *, random() + FROM + (SELECT + "t"."user_id", "t"."time", unnest("t"."collected_events") AS "event_types" + FROM + (SELECT + "t1"."user_id", min("t1"."time") AS "time", array_agg(("t1"."event") ORDER BY TIME ASC, event DESC) AS collected_events + FROM( + (SELECT + "events"."user_id", "events"."time", 0 AS event + FROM + partitioned_events_table as "events" + WHERE + event_type IN (1, 2) ) + UNION + (SELECT + "events"."user_id", "events"."time", 1 AS event + FROM + partitioned_events_table as "events" + WHERE + event_type IN (3, 4) ) + UNION + (SELECT + "events"."user_id", "events"."time", 2 AS event + FROM + partitioned_events_table as "events" + WHERE + event_type IN (5, 6) ) + UNION + (SELECT + "events"."user_id", "events"."time", 3 AS event + FROM + partitioned_events_table as "events" + WHERE + event_type IN (1, 6))) t1 + GROUP BY "t1"."user_id") AS t) "q" +) AS final_query +GROUP BY types +ORDER BY types; + types | sumofeventtype +--------------------------------------------------------------------- + 0 | 43 + 1 | 44 + 2 | 8 + 3 | 25 +(4 rows) + +-- UNION and JOIN on both partitioned and regular tables +SELECT ("final_query"."event_types") as types, count(*) AS sumOfEventType +FROM + (SELECT + *, random() + FROM + (SELECT + "t"."user_id", "t"."time", unnest("t"."collected_events") AS "event_types" + FROM + (SELECT + "t1"."user_id", min("t1"."time") AS "time", array_agg(("t1"."event") ORDER BY TIME ASC, event DESC) AS collected_events + FROM ( + (SELECT + * + FROM + (SELECT + "events"."time", 0 AS event, "events"."user_id" + FROM + partitioned_events_table as "events" + WHERE + event_type IN (1, 2)) events_subquery_1) + UNION + (SELECT * + FROM + ( + SELECT * FROM + ( + SELECT + max("events"."time"), + 0 AS event, + "events"."user_id" + FROM + events_table as "events", users_table as "users" + WHERE + events.user_id = users.user_id AND + event_type IN (1, 2) + GROUP BY "events"."user_id" + ) as events_subquery_5 + ) events_subquery_2) + UNION + (SELECT * + FROM + (SELECT + "events"."time", 2 AS event, "events"."user_id" + FROM + partitioned_events_table as "events" + WHERE + event_type IN (3, 4)) events_subquery_3) + UNION + (SELECT * + FROM + (SELECT + "events"."time", 3 AS event, "events"."user_id" + FROM + events_table as "events" + WHERE + event_type IN (5, 6)) events_subquery_4) + ) t1 + GROUP BY "t1"."user_id") AS t) "q" +INNER JOIN + (SELECT + "users"."user_id" + FROM + partitioned_users_table as "users" + WHERE + value_1 > 2 and value_1 < 5) AS t + ON (t.user_id = q.user_id)) as final_query +GROUP BY + types +ORDER BY + types; + types | sumofeventtype +--------------------------------------------------------------------- + 0 | 367 + 2 | 360 + 3 | 57 +(3 rows) + +-- test LIST partitioning +CREATE TABLE list_partitioned_events_table (user_id int, time date, event_type int, value_2 int, value_3 float, value_4 bigint) PARTITION BY LIST (time); +CREATE TABLE list_partitioned_events_table_2014_01_01_05 PARTITION OF list_partitioned_events_table FOR VALUES IN ('2017-11-21', '2017-11-22', '2017-11-23', '2017-11-24', '2017-11-25'); +CREATE TABLE list_partitioned_events_table_2014_01_06_10 PARTITION OF list_partitioned_events_table FOR VALUES IN ('2017-11-26', '2017-11-27', '2017-11-28', '2017-11-29', '2017-11-30'); +CREATE TABLE list_partitioned_events_table_2014_01_11_15 PARTITION OF list_partitioned_events_table FOR VALUES IN ('2017-12-01', '2017-12-02', '2017-12-03', '2017-12-04', '2017-12-05'); +-- test distributing partitioned table colocated with another partitioned table +SELECT create_distributed_table('list_partitioned_events_table', 'user_id', colocate_with => 'partitioned_events_table'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +-- INSERT/SELECT from partitioned table to partitioned table +INSERT INTO + list_partitioned_events_table +SELECT + user_id, + date_trunc('day', time) as time, + event_type, + value_2, + value_3, + value_4 +FROM + events_table +WHERE + time >= '2017-11-21' AND + time <= '2017-12-01'; +-- LEFT JOINs used with INNER JOINs on range partitioned table, list partitioned table and non-partitioned table +SELECT +count(*) AS cnt, "generated_group_field" + FROM + (SELECT + "eventQuery"."user_id", random(), generated_group_field + FROM + (SELECT + "multi_group_wrapper_1".*, generated_group_field, random() + FROM + (SELECT * + FROM + (SELECT + "list_partitioned_events_table"."time", "list_partitioned_events_table"."user_id" as event_user_id + FROM + list_partitioned_events_table as "list_partitioned_events_table" + WHERE + user_id > 2) "temp_data_queries" + INNER JOIN + (SELECT + "users"."user_id" + FROM + partitioned_users_table as "users" + WHERE + user_id > 2 and value_2 = 1) "user_filters_1" + ON ("temp_data_queries".event_user_id = "user_filters_1".user_id)) AS "multi_group_wrapper_1" + LEFT JOIN + (SELECT + "users"."user_id" AS "user_id", value_2 AS "generated_group_field" + FROM + partitioned_users_table as "users") "left_group_by_1" + ON ("left_group_by_1".user_id = "multi_group_wrapper_1".event_user_id)) "eventQuery") "pushedDownQuery" + GROUP BY + "generated_group_field" + ORDER BY + cnt DESC, generated_group_field ASC + LIMIT 10; + cnt | generated_group_field +--------------------------------------------------------------------- + 1851 | 1 + 1077 | 4 + 963 | 2 + 955 | 3 + 768 | 5 + 639 | 0 +(6 rows) + +-- +-- Additional partitioning features +-- +-- test multi column partitioning +CREATE TABLE multi_column_partitioning(c1 int, c2 int) PARTITION BY RANGE (c1, c2); +CREATE TABLE multi_column_partitioning_0_0_10_0 PARTITION OF multi_column_partitioning FOR VALUES FROM (0, 0) TO (10, 0); +SELECT create_distributed_table('multi_column_partitioning', 'c1'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +-- test INSERT to multi-column partitioned table +INSERT INTO multi_column_partitioning VALUES(1, 1); +INSERT INTO multi_column_partitioning_0_0_10_0 VALUES(5, -5); +-- test INSERT to multi-column partitioned table where no suitable partition exists +INSERT INTO multi_column_partitioning VALUES(10, 1); +ERROR: no partition of relation "multi_column_partitioning_1660101" found for row +DETAIL: Partition key of the failing row contains (c1, c2) = (10, 1). +CONTEXT: while executing command on localhost:xxxxx +-- test with MINVALUE/MAXVALUE +CREATE TABLE multi_column_partitioning_10_max_20_min PARTITION OF multi_column_partitioning FOR VALUES FROM (10, MAXVALUE) TO (20, MINVALUE); +-- test INSERT to partition with MINVALUE/MAXVALUE bounds +INSERT INTO multi_column_partitioning VALUES(11, -11); +INSERT INTO multi_column_partitioning_10_max_20_min VALUES(19, -19); +-- test INSERT to multi-column partitioned table where no suitable partition exists +INSERT INTO multi_column_partitioning VALUES(20, -20); +ERROR: no partition of relation "multi_column_partitioning_1660101" found for row +DETAIL: Partition key of the failing row contains (c1, c2) = (20, -20). +CONTEXT: while executing command on localhost:xxxxx +-- see data is loaded to multi-column partitioned table +SELECT * FROM multi_column_partitioning ORDER BY 1, 2; + c1 | c2 +--------------------------------------------------------------------- + 1 | 1 + 5 | -5 + 11 | -11 + 19 | -19 +(4 rows) + +-- +-- Tests for locks on partitioned tables +-- +CREATE TABLE partitioning_locks(id int, ref_id int, time date) PARTITION BY RANGE (time); +-- create its partitions +CREATE TABLE partitioning_locks_2009 PARTITION OF partitioning_locks FOR VALUES FROM ('2009-01-01') TO ('2010-01-01'); +CREATE TABLE partitioning_locks_2010 PARTITION OF partitioning_locks FOR VALUES FROM ('2010-01-01') TO ('2011-01-01'); +-- distribute partitioned table +SELECT create_distributed_table('partitioning_locks', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +-- test locks on router SELECT +BEGIN; +SELECT * FROM partitioning_locks WHERE id = 1 ORDER BY 1, 2; + id | ref_id | time +--------------------------------------------------------------------- +(0 rows) + +SELECT relation::regclass, locktype, mode FROM pg_locks WHERE relation::regclass::text LIKE 'partitioning_locks%' AND pid = pg_backend_pid() ORDER BY 1, 2, 3; + relation | locktype | mode +--------------------------------------------------------------------- + partitioning_locks | relation | AccessShareLock + partitioning_locks_2009 | relation | AccessShareLock + partitioning_locks_2010 | relation | AccessShareLock +(3 rows) + +COMMIT; +-- test locks on real-time SELECT +BEGIN; +SELECT * FROM partitioning_locks ORDER BY 1, 2; + id | ref_id | time +--------------------------------------------------------------------- +(0 rows) + +SELECT relation::regclass, locktype, mode FROM pg_locks WHERE relation::regclass::text LIKE 'partitioning_locks%' AND pid = pg_backend_pid() ORDER BY 1, 2, 3; + relation | locktype | mode +--------------------------------------------------------------------- + partitioning_locks | relation | AccessShareLock + partitioning_locks_2009 | relation | AccessShareLock + partitioning_locks_2010 | relation | AccessShareLock +(3 rows) + +COMMIT; +-- test locks on task-tracker SELECT +SET citus.task_executor_type TO 'task-tracker'; +BEGIN; +SELECT * FROM partitioning_locks AS pl1 JOIN partitioning_locks AS pl2 ON pl1.id = pl2.ref_id ORDER BY 1, 2; + id | ref_id | time | id | ref_id | time +--------------------------------------------------------------------- +(0 rows) + +SELECT relation::regclass, locktype, mode FROM pg_locks WHERE relation::regclass::text LIKE 'partitioning_locks%' AND pid = pg_backend_pid() ORDER BY 1, 2, 3; + relation | locktype | mode +--------------------------------------------------------------------- + partitioning_locks | relation | AccessShareLock + partitioning_locks_2009 | relation | AccessShareLock + partitioning_locks_2010 | relation | AccessShareLock +(3 rows) + +COMMIT; +RESET citus.task_executor_type; +-- test locks on INSERT +BEGIN; +INSERT INTO partitioning_locks VALUES(1, 1, '2009-01-01'); +SELECT relation::regclass, locktype, mode FROM pg_locks WHERE relation::regclass::text LIKE 'partitioning_locks%' AND pid = pg_backend_pid() ORDER BY 1, 2, 3; + relation | locktype | mode +--------------------------------------------------------------------- + partitioning_locks | relation | AccessShareLock + partitioning_locks | relation | RowExclusiveLock + partitioning_locks_2009 | relation | AccessShareLock + partitioning_locks_2009 | relation | RowExclusiveLock + partitioning_locks_2010 | relation | AccessShareLock + partitioning_locks_2010 | relation | RowExclusiveLock +(6 rows) + +COMMIT; +-- test locks on UPDATE +BEGIN; +UPDATE partitioning_locks SET time = '2009-02-01' WHERE id = 1; +SELECT relation::regclass, locktype, mode FROM pg_locks WHERE relation::regclass::text LIKE 'partitioning_locks%' AND pid = pg_backend_pid() ORDER BY 1, 2, 3; + relation | locktype | mode +--------------------------------------------------------------------- + partitioning_locks | relation | AccessShareLock + partitioning_locks | relation | RowExclusiveLock + partitioning_locks_2009 | relation | AccessShareLock + partitioning_locks_2009 | relation | RowExclusiveLock + partitioning_locks_2010 | relation | AccessShareLock + partitioning_locks_2010 | relation | RowExclusiveLock +(6 rows) + +COMMIT; +-- test locks on DELETE +BEGIN; +DELETE FROM partitioning_locks WHERE id = 1; +SELECT relation::regclass, locktype, mode FROM pg_locks WHERE relation::regclass::text LIKE 'partitioning_locks%' AND pid = pg_backend_pid() ORDER BY 1, 2, 3; + relation | locktype | mode +--------------------------------------------------------------------- + partitioning_locks | relation | AccessShareLock + partitioning_locks | relation | RowExclusiveLock + partitioning_locks_2009 | relation | AccessShareLock + partitioning_locks_2009 | relation | RowExclusiveLock + partitioning_locks_2010 | relation | AccessShareLock + partitioning_locks_2010 | relation | RowExclusiveLock +(6 rows) + +COMMIT; +-- test locks on INSERT/SELECT +CREATE TABLE partitioning_locks_for_select(id int, ref_id int, time date); +SELECT create_distributed_table('partitioning_locks_for_select', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +BEGIN; +INSERT INTO partitioning_locks SELECT * FROM partitioning_locks_for_select; +SELECT relation::regclass, locktype, mode FROM pg_locks WHERE relation::regclass::text LIKE 'partitioning_locks%' AND pid = pg_backend_pid() ORDER BY 1, 2, 3; + relation | locktype | mode +--------------------------------------------------------------------- + partitioning_locks | relation | AccessShareLock + partitioning_locks | relation | RowExclusiveLock + partitioning_locks_2009 | relation | AccessShareLock + partitioning_locks_2009 | relation | RowExclusiveLock + partitioning_locks_2010 | relation | AccessShareLock + partitioning_locks_2010 | relation | RowExclusiveLock + partitioning_locks_for_select | relation | AccessShareLock +(7 rows) + +COMMIT; +-- test locks on coordinator INSERT/SELECT +BEGIN; +INSERT INTO partitioning_locks SELECT * FROM partitioning_locks_for_select LIMIT 5; +SELECT relation::regclass, locktype, mode FROM pg_locks WHERE relation::regclass::text LIKE 'partitioning_locks%' AND pid = pg_backend_pid() ORDER BY 1, 2, 3; + relation | locktype | mode +--------------------------------------------------------------------- + partitioning_locks | relation | AccessShareLock + partitioning_locks | relation | RowExclusiveLock + partitioning_locks_2009 | relation | RowExclusiveLock + partitioning_locks_2010 | relation | RowExclusiveLock + partitioning_locks_for_select | relation | AccessShareLock +(5 rows) + +COMMIT; +-- test locks on multi-shard UPDATE +BEGIN; +UPDATE partitioning_locks SET time = '2009-03-01'; +SELECT relation::regclass, locktype, mode FROM pg_locks WHERE relation::regclass::text LIKE 'partitioning_locks%' AND pid = pg_backend_pid() ORDER BY 1, 2, 3; + relation | locktype | mode +--------------------------------------------------------------------- + partitioning_locks | relation | AccessShareLock + partitioning_locks | relation | RowExclusiveLock + partitioning_locks_2009 | relation | AccessShareLock + partitioning_locks_2009 | relation | RowExclusiveLock + partitioning_locks_2010 | relation | AccessShareLock + partitioning_locks_2010 | relation | RowExclusiveLock +(6 rows) + +COMMIT; +-- test locks on DDL +BEGIN; +ALTER TABLE partitioning_locks ADD COLUMN new_column int; +SELECT relation::regclass, locktype, mode FROM pg_locks WHERE relation::regclass::text LIKE 'partitioning_locks%' AND pid = pg_backend_pid() ORDER BY 1, 2, 3; + relation | locktype | mode +--------------------------------------------------------------------- + partitioning_locks | relation | AccessExclusiveLock + partitioning_locks | relation | AccessShareLock + partitioning_locks_2009 | relation | AccessExclusiveLock + partitioning_locks_2009 | relation | AccessShareLock + partitioning_locks_2010 | relation | AccessExclusiveLock + partitioning_locks_2010 | relation | AccessShareLock +(6 rows) + +COMMIT; +-- test locks on TRUNCATE +BEGIN; +TRUNCATE partitioning_locks; +SELECT relation::regclass, locktype, mode FROM pg_locks WHERE relation::regclass::text LIKE 'partitioning_locks%' AND pid = pg_backend_pid() ORDER BY 1, 2, 3; + relation | locktype | mode +--------------------------------------------------------------------- + partitioning_locks | relation | AccessExclusiveLock + partitioning_locks | relation | AccessShareLock + partitioning_locks_2009 | relation | AccessExclusiveLock + partitioning_locks_2009 | relation | AccessShareLock + partitioning_locks_2009 | relation | ShareLock + partitioning_locks_2010 | relation | AccessExclusiveLock + partitioning_locks_2010 | relation | AccessShareLock + partitioning_locks_2010 | relation | ShareLock +(8 rows) + +COMMIT; +CREATE VIEW lockinfo AS + SELECT + logicalrelid, + CASE + WHEN l.objsubid = 5 THEN 'shard' + WHEN l.objsubid = 4 THEN 'shard_metadata' + ELSE 'colocated_shards_metadata' + END AS locktype, + mode + FROM + pg_locks AS l JOIN (select row_number() over (partition by logicalrelid order by shardminvalue) -1 as shardintervalindex, * from pg_dist_shard) AS s + ON + (l.objsubid IN (4, 5) AND l.objid = s.shardid ) + OR (l.objsubid = 8 + AND l.objid IN (select colocationid from pg_dist_partition AS p where p.logicalrelid = s.logicalrelid) + AND l.classid = shardintervalindex + ) + WHERE + logicalrelid IN ('partitioning_locks', 'partitioning_locks_2009', 'partitioning_locks_2010') + AND pid = pg_backend_pid() + AND l.locktype = 'advisory' + ORDER BY + 1, 2, 3; +-- test shard resource locks with multi-shard UPDATE +BEGIN; +UPDATE partitioning_locks_2009 SET time = '2009-03-01'; +-- see the locks on parent table +SELECT * FROM lockinfo; + logicalrelid | locktype | mode +--------------------------------------------------------------------- + partitioning_locks | colocated_shards_metadata | ShareLock + partitioning_locks | colocated_shards_metadata | ShareLock + partitioning_locks | colocated_shards_metadata | ShareLock + partitioning_locks | colocated_shards_metadata | ShareLock + partitioning_locks | shard | ShareUpdateExclusiveLock + partitioning_locks | shard | ShareUpdateExclusiveLock + partitioning_locks | shard | ShareUpdateExclusiveLock + partitioning_locks | shard | ShareUpdateExclusiveLock + partitioning_locks_2009 | colocated_shards_metadata | ShareLock + partitioning_locks_2009 | colocated_shards_metadata | ShareLock + partitioning_locks_2009 | colocated_shards_metadata | ShareLock + partitioning_locks_2009 | colocated_shards_metadata | ShareLock + partitioning_locks_2009 | shard | ShareUpdateExclusiveLock + partitioning_locks_2009 | shard | ShareUpdateExclusiveLock + partitioning_locks_2009 | shard | ShareUpdateExclusiveLock + partitioning_locks_2009 | shard | ShareUpdateExclusiveLock + partitioning_locks_2010 | colocated_shards_metadata | ShareLock + partitioning_locks_2010 | colocated_shards_metadata | ShareLock + partitioning_locks_2010 | colocated_shards_metadata | ShareLock + partitioning_locks_2010 | colocated_shards_metadata | ShareLock +(20 rows) + +COMMIT; +-- test shard resource locks with TRUNCATE +BEGIN; +TRUNCATE partitioning_locks_2009; +-- see the locks on parent table +SELECT * FROM lockinfo; + logicalrelid | locktype | mode +--------------------------------------------------------------------- + partitioning_locks | colocated_shards_metadata | ShareLock + partitioning_locks | colocated_shards_metadata | ShareLock + partitioning_locks | colocated_shards_metadata | ShareLock + partitioning_locks | colocated_shards_metadata | ShareLock + partitioning_locks_2009 | colocated_shards_metadata | ShareLock + partitioning_locks_2009 | colocated_shards_metadata | ShareLock + partitioning_locks_2009 | colocated_shards_metadata | ShareLock + partitioning_locks_2009 | colocated_shards_metadata | ShareLock + partitioning_locks_2010 | colocated_shards_metadata | ShareLock + partitioning_locks_2010 | colocated_shards_metadata | ShareLock + partitioning_locks_2010 | colocated_shards_metadata | ShareLock + partitioning_locks_2010 | colocated_shards_metadata | ShareLock +(12 rows) + +COMMIT; +-- test shard resource locks with INSERT/SELECT +BEGIN; +INSERT INTO partitioning_locks_2009 SELECT * FROM partitioning_locks WHERE time >= '2009-01-01' AND time < '2010-01-01'; +-- see the locks on parent table +SELECT * FROM lockinfo; + logicalrelid | locktype | mode +--------------------------------------------------------------------- + partitioning_locks | colocated_shards_metadata | ShareLock + partitioning_locks | colocated_shards_metadata | ShareLock + partitioning_locks | colocated_shards_metadata | ShareLock + partitioning_locks | colocated_shards_metadata | ShareLock + partitioning_locks | shard | ShareUpdateExclusiveLock + partitioning_locks | shard | ShareUpdateExclusiveLock + partitioning_locks | shard | ShareUpdateExclusiveLock + partitioning_locks | shard | ShareUpdateExclusiveLock + partitioning_locks_2009 | colocated_shards_metadata | ShareLock + partitioning_locks_2009 | colocated_shards_metadata | ShareLock + partitioning_locks_2009 | colocated_shards_metadata | ShareLock + partitioning_locks_2009 | colocated_shards_metadata | ShareLock + partitioning_locks_2009 | shard | ShareUpdateExclusiveLock + partitioning_locks_2009 | shard | ShareUpdateExclusiveLock + partitioning_locks_2009 | shard | ShareUpdateExclusiveLock + partitioning_locks_2009 | shard | ShareUpdateExclusiveLock + partitioning_locks_2010 | colocated_shards_metadata | ShareLock + partitioning_locks_2010 | colocated_shards_metadata | ShareLock + partitioning_locks_2010 | colocated_shards_metadata | ShareLock + partitioning_locks_2010 | colocated_shards_metadata | ShareLock +(20 rows) + +COMMIT; +-- test partition-wise join +CREATE TABLE partitioning_hash_join_test(id int, subid int) PARTITION BY HASH(subid); +CREATE TABLE partitioning_hash_join_test_0 PARTITION OF partitioning_hash_join_test FOR VALUES WITH (MODULUS 3, REMAINDER 0); +CREATE TABLE partitioning_hash_join_test_1 PARTITION OF partitioning_hash_join_test FOR VALUES WITH (MODULUS 3, REMAINDER 1); +CREATE TABLE partitioning_hash_join_test_2 PARTITION OF partitioning_hash_join_test FOR VALUES WITH (MODULUS 3, REMAINDER 2); +SELECT create_distributed_table('partitioning_hash_join_test', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +SELECT success FROM run_command_on_workers('alter system set enable_mergejoin to off'); + success +--------------------------------------------------------------------- + t + t +(2 rows) + +SELECT success FROM run_command_on_workers('alter system set enable_nestloop to off'); + success +--------------------------------------------------------------------- + t + t +(2 rows) + +SELECT success FROM run_command_on_workers('alter system set enable_indexscan to off'); + success +--------------------------------------------------------------------- + t + t +(2 rows) + +SELECT success FROM run_command_on_workers('alter system set enable_indexonlyscan to off'); + success +--------------------------------------------------------------------- + t + t +(2 rows) + +SELECT success FROM run_command_on_workers('alter system set enable_partitionwise_join to off'); + success +--------------------------------------------------------------------- + t + t +(2 rows) + +SELECT success FROM run_command_on_workers('select pg_reload_conf()'); + success +--------------------------------------------------------------------- + t + t +(2 rows) + +EXPLAIN (COSTS OFF) +SELECT * FROM partitioning_hash_test JOIN partitioning_hash_join_test USING (id, subid); + QUERY PLAN +--------------------------------------------------------------------- + Custom Scan (Citus Adaptive) + Task Count: 4 + Tasks Shown: One of 4 + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> Hash Join + Hash Cond: ((partitioning_hash_join_test.id = partitioning_hash_test.id) AND (partitioning_hash_join_test.subid = partitioning_hash_test.subid)) + -> Append + -> Seq Scan on partitioning_hash_join_test_0_1660133 partitioning_hash_join_test + -> Seq Scan on partitioning_hash_join_test_1_1660137 partitioning_hash_join_test_1 + -> Seq Scan on partitioning_hash_join_test_2_1660141 partitioning_hash_join_test_2 + -> Hash + -> Append + -> Seq Scan on partitioning_hash_test_0_1660016 partitioning_hash_test + -> Seq Scan on partitioning_hash_test_1_1660020 partitioning_hash_test_1 + -> Seq Scan on partitioning_hash_test_2_1660032 partitioning_hash_test_2 +(16 rows) + +-- set partition-wise join on and parallel to off +SELECT success FROM run_command_on_workers('alter system set enable_partitionwise_join to on'); + success +--------------------------------------------------------------------- + t + t +(2 rows) + +SELECT success FROM run_command_on_workers('select pg_reload_conf()'); + success +--------------------------------------------------------------------- + t + t +(2 rows) + +SET enable_partitionwise_join TO on; +ANALYZE partitioning_hash_test, partitioning_hash_join_test; +EXPLAIN (COSTS OFF) +SELECT * FROM partitioning_hash_test JOIN partitioning_hash_join_test USING (id, subid); + QUERY PLAN +--------------------------------------------------------------------- + Custom Scan (Citus Adaptive) + Task Count: 4 + Tasks Shown: One of 4 + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> Append + -> Hash Join + Hash Cond: ((partitioning_hash_join_test.id = partitioning_hash_test.id) AND (partitioning_hash_join_test.subid = partitioning_hash_test.subid)) + -> Seq Scan on partitioning_hash_join_test_0_1660133 partitioning_hash_join_test + -> Hash + -> Seq Scan on partitioning_hash_test_0_1660016 partitioning_hash_test + -> Hash Join + Hash Cond: ((partitioning_hash_test_1.id = partitioning_hash_join_test_1.id) AND (partitioning_hash_test_1.subid = partitioning_hash_join_test_1.subid)) + -> Seq Scan on partitioning_hash_test_1_1660020 partitioning_hash_test_1 + -> Hash + -> Seq Scan on partitioning_hash_join_test_1_1660137 partitioning_hash_join_test_1 + -> Hash Join + Hash Cond: ((partitioning_hash_join_test_2.id = partitioning_hash_test_2.id) AND (partitioning_hash_join_test_2.subid = partitioning_hash_test_2.subid)) + -> Seq Scan on partitioning_hash_join_test_2_1660141 partitioning_hash_join_test_2 + -> Hash + -> Seq Scan on partitioning_hash_test_2_1660032 partitioning_hash_test_2 +(21 rows) + +-- note that partition-wise joins only work when partition key is in the join +-- following join does not have that, therefore join will not be pushed down to +-- partitions +EXPLAIN (COSTS OFF) +SELECT * FROM partitioning_hash_test JOIN partitioning_hash_join_test USING (id); + QUERY PLAN +--------------------------------------------------------------------- + Custom Scan (Citus Adaptive) + Task Count: 4 + Tasks Shown: One of 4 + -> Task + Node: host=localhost port=xxxxx dbname=regression + -> Hash Join + Hash Cond: (partitioning_hash_join_test.id = partitioning_hash_test.id) + -> Append + -> Seq Scan on partitioning_hash_join_test_0_1660133 partitioning_hash_join_test + -> Seq Scan on partitioning_hash_join_test_1_1660137 partitioning_hash_join_test_1 + -> Seq Scan on partitioning_hash_join_test_2_1660141 partitioning_hash_join_test_2 + -> Hash + -> Append + -> Seq Scan on partitioning_hash_test_0_1660016 partitioning_hash_test + -> Seq Scan on partitioning_hash_test_1_1660020 partitioning_hash_test_1 + -> Seq Scan on partitioning_hash_test_2_1660032 partitioning_hash_test_2 +(16 rows) + +-- reset partition-wise join +SELECT success FROM run_command_on_workers('alter system reset enable_partitionwise_join'); + success +--------------------------------------------------------------------- + t + t +(2 rows) + +SELECT success FROM run_command_on_workers('alter system reset enable_mergejoin'); + success +--------------------------------------------------------------------- + t + t +(2 rows) + +SELECT success FROM run_command_on_workers('alter system reset enable_nestloop'); + success +--------------------------------------------------------------------- + t + t +(2 rows) + +SELECT success FROM run_command_on_workers('alter system reset enable_indexscan'); + success +--------------------------------------------------------------------- + t + t +(2 rows) + +SELECT success FROM run_command_on_workers('alter system reset enable_indexonlyscan'); + success +--------------------------------------------------------------------- + t + t +(2 rows) + +SELECT success FROM run_command_on_workers('select pg_reload_conf()'); + success +--------------------------------------------------------------------- + t + t +(2 rows) + +RESET enable_partitionwise_join; +DROP VIEW lockinfo; +DROP TABLE +IF EXISTS + partitioning_test_2009, + partitioned_events_table, + partitioned_users_table, + list_partitioned_events_table, + multi_column_partitioning, + partitioning_locks, + partitioning_locks_for_select; +-- make sure we can create a partitioned table with streaming replication +SET citus.replication_model TO 'streaming'; +CREATE TABLE partitioning_test(id int, time date) PARTITION BY RANGE (time); +CREATE TABLE partitioning_test_2009 PARTITION OF partitioning_test FOR VALUES FROM ('2009-01-01') TO ('2010-01-01'); +SELECT create_distributed_table('partitioning_test', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +DROP TABLE partitioning_test; +-- make sure we can attach partitions to a distributed table in a schema +CREATE SCHEMA partitioning_schema; +CREATE TABLE partitioning_schema."schema-test"(id int, time date) PARTITION BY RANGE (time); +SELECT create_distributed_table('partitioning_schema."schema-test"', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE TABLE partitioning_schema."schema-test_2009"(id int, time date); +ALTER TABLE partitioning_schema."schema-test" ATTACH PARTITION partitioning_schema."schema-test_2009" FOR VALUES FROM ('2009-01-01') TO ('2010-01-01'); +-- attached partition is distributed as well +SELECT + logicalrelid +FROM + pg_dist_partition +WHERE + logicalrelid IN ('partitioning_schema."schema-test"'::regclass, 'partitioning_schema."schema-test_2009"'::regclass) +ORDER BY 1; + logicalrelid +--------------------------------------------------------------------- + partitioning_schema."schema-test" + partitioning_schema."schema-test_2009" +(2 rows) + +SELECT + logicalrelid, count(*) +FROM + pg_dist_shard +WHERE + logicalrelid IN ('partitioning_schema."schema-test"'::regclass, 'partitioning_schema."schema-test_2009"'::regclass) +GROUP BY + logicalrelid +ORDER BY + 1,2; + logicalrelid | count +--------------------------------------------------------------------- + partitioning_schema."schema-test" | 4 + partitioning_schema."schema-test_2009" | 4 +(2 rows) + +DROP TABLE partitioning_schema."schema-test"; +-- make sure we can create partition of a distributed table in a schema +CREATE TABLE partitioning_schema."schema-test"(id int, time date) PARTITION BY RANGE (time); +SELECT create_distributed_table('partitioning_schema."schema-test"', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE TABLE partitioning_schema."schema-test_2009" PARTITION OF partitioning_schema."schema-test" FOR VALUES FROM ('2009-01-01') TO ('2010-01-01'); +-- newly created partition is distributed as well +SELECT + logicalrelid +FROM + pg_dist_partition +WHERE + logicalrelid IN ('partitioning_schema."schema-test"'::regclass, 'partitioning_schema."schema-test_2009"'::regclass) +ORDER BY 1; + logicalrelid +--------------------------------------------------------------------- + partitioning_schema."schema-test" + partitioning_schema."schema-test_2009" +(2 rows) + +SELECT + logicalrelid, count(*) +FROM + pg_dist_shard +WHERE + logicalrelid IN ('partitioning_schema."schema-test"'::regclass, 'partitioning_schema."schema-test_2009"'::regclass) +GROUP BY + logicalrelid +ORDER BY + 1,2; + logicalrelid | count +--------------------------------------------------------------------- + partitioning_schema."schema-test" | 4 + partitioning_schema."schema-test_2009" | 4 +(2 rows) + +DROP TABLE partitioning_schema."schema-test"; +-- make sure creating partitioned tables works while search_path is set +CREATE TABLE partitioning_schema."schema-test"(id int, time date) PARTITION BY RANGE (time); +SET search_path = partitioning_schema; +SELECT create_distributed_table('"schema-test"', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +CREATE TABLE partitioning_schema."schema-test_2009" PARTITION OF "schema-test" FOR VALUES FROM ('2009-01-01') TO ('2010-01-01'); +-- newly created partition is distributed as well +SELECT + logicalrelid +FROM + pg_dist_partition +WHERE + logicalrelid IN ('partitioning_schema."schema-test"'::regclass, 'partitioning_schema."schema-test_2009"'::regclass) +ORDER BY 1; + logicalrelid +--------------------------------------------------------------------- + "schema-test" + "schema-test_2009" +(2 rows) + +SELECT + logicalrelid, count(*) +FROM + pg_dist_shard +WHERE + logicalrelid IN ('partitioning_schema."schema-test"'::regclass, 'partitioning_schema."schema-test_2009"'::regclass) +GROUP BY + logicalrelid +ORDER BY + 1,2; + logicalrelid | count +--------------------------------------------------------------------- + "schema-test" | 4 + "schema-test_2009" | 4 +(2 rows) + +-- test we don't deadlock when attaching and detaching partitions from partitioned +-- tables with foreign keys +CREATE TABLE reference_table(id int PRIMARY KEY); +SELECT create_reference_table('reference_table'); + create_reference_table +--------------------------------------------------------------------- + +(1 row) + +CREATE TABLE reference_table_2(id int PRIMARY KEY); +SELECT create_reference_table('reference_table_2'); + create_reference_table +--------------------------------------------------------------------- + +(1 row) + +CREATE TABLE partitioning_test(id int, time date) PARTITION BY RANGE (time); +CREATE TABLE partitioning_test_2008 PARTITION OF partitioning_test FOR VALUES FROM ('2008-01-01') TO ('2009-01-01'); +CREATE TABLE partitioning_test_2009 (LIKE partitioning_test); +CREATE TABLE partitioning_test_2010 (LIKE partitioning_test); +CREATE TABLE partitioning_test_2011 (LIKE partitioning_test); +-- distributing partitioning_test will also distribute partitioning_test_2008 +SELECT create_distributed_table('partitioning_test', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +SELECT create_distributed_table('partitioning_test_2009', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +SELECT create_distributed_table('partitioning_test_2010', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +SELECT create_distributed_table('partitioning_test_2011', 'id'); + create_distributed_table +--------------------------------------------------------------------- + +(1 row) + +ALTER TABLE partitioning_test ADD CONSTRAINT partitioning_reference_fkey + FOREIGN KEY (id) REFERENCES reference_table(id) ON DELETE CASCADE; +ALTER TABLE partitioning_test_2009 ADD CONSTRAINT partitioning_reference_fkey_2009 + FOREIGN KEY (id) REFERENCES reference_table(id) ON DELETE CASCADE; +INSERT INTO partitioning_test_2010 VALUES (1, '2010-02-01'); +-- This should fail because of foreign key constraint violation +ALTER TABLE partitioning_test ATTACH PARTITION partitioning_test_2010 + FOR VALUES FROM ('2010-01-01') TO ('2011-01-01'); +ERROR: insert or update on table "partitioning_test_2010_1660191" violates foreign key constraint "partitioning_reference_fkey_1660179" +DETAIL: Key (id)=(X) is not present in table "reference_table_1660177". +CONTEXT: while executing command on localhost:xxxxx +-- Truncate, so attaching again won't fail +TRUNCATE partitioning_test_2010; +-- Attach a table which already has the same constraint +ALTER TABLE partitioning_test ATTACH PARTITION partitioning_test_2009 + FOR VALUES FROM ('2009-01-01') TO ('2010-01-01'); +-- Attach a table which doesn't have the constraint +ALTER TABLE partitioning_test ATTACH PARTITION partitioning_test_2010 + FOR VALUES FROM ('2010-01-01') TO ('2011-01-01'); +-- Attach a table which has a different constraint +ALTER TABLE partitioning_test ATTACH PARTITION partitioning_test_2011 + FOR VALUES FROM ('2011-01-01') TO ('2012-01-01'); +ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2008; +ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2009; +ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2010; +ALTER TABLE partitioning_test DETACH PARTITION partitioning_test_2011; +DROP TABLE partitioning_test, partitioning_test_2008, partitioning_test_2009, + partitioning_test_2010, partitioning_test_2011, + reference_table, reference_table_2; +DROP SCHEMA partitioning_schema CASCADE; +NOTICE: drop cascades to table "schema-test" +RESET SEARCH_PATH; +DROP TABLE IF EXISTS + partitioning_hash_test, + partitioning_hash_join_test, + partitioning_test_failure, + non_distributed_partitioned_table, + partitioning_test_foreign_key; diff --git a/src/test/regress/input/multi_complex_count_distinct.source b/src/test/regress/input/multi_complex_count_distinct.source index a30cb119c..13b25e0d3 100644 --- a/src/test/regress/input/multi_complex_count_distinct.source +++ b/src/test/regress/input/multi_complex_count_distinct.source @@ -154,14 +154,6 @@ SELECT HAVING count(distinct l_suppkey) > 1550 ORDER BY 1, 2 DESC; -EXPLAIN (COSTS false, VERBOSE true) -SELECT - l_shipmode, count(distinct l_partkey) - FROM lineitem_hash - GROUP BY l_shipmode - HAVING count(distinct l_suppkey) > 1550 - ORDER BY 1, 2 DESC; - -- count distinct is supported on single table subqueries SELECT * FROM (