-- -- MULTI_NULL_MINMAX_VALUE_PRUNING -- -- This test checks that we can handle null min/max values in shard statistics -- and that we don't partition or join prune shards that have null values. CREATE SCHEMA multi_null_minmax_value_pruning; SET search_path TO multi_null_minmax_value_pruning; SET citus.explain_all_tasks TO on; SET citus.log_multi_join_order to true; SET citus.enable_repartition_joins to ON; SET citus.next_shard_id = 290000; CREATE TABLE lineitem (LIKE public.lineitem); SELECT create_distributed_table('lineitem', 'l_orderkey', 'range'); create_distributed_table --------------------------------------------------------------------- (1 row) SELECT master_create_empty_shard('lineitem') as lineitem_shardid1 \gset SELECT master_create_empty_shard('lineitem') as lineitem_shardid2 \gset CREATE TABLE orders (LIKE public.orders); SELECT create_distributed_table('orders', 'o_orderkey', 'range'); create_distributed_table --------------------------------------------------------------------- (1 row) SELECT master_create_empty_shard('orders') as orders_shardid1 \gset SELECT master_create_empty_shard('orders') as orders_shardid2 \gset SET client_min_messages TO DEBUG2; UPDATE pg_dist_shard SET shardminvalue = '1', shardmaxvalue = '6000' WHERE shardid = :lineitem_shardid1 OR shardid = :orders_shardid1; UPDATE pg_dist_shard SET shardminvalue = '6001', shardmaxvalue = '20000' WHERE shardid = :lineitem_shardid2 OR shardid = :orders_shardid2; UPDATE pg_dist_partition SET colocationid = 87091 WHERE logicalrelid = 'orders'::regclass OR logicalrelid = 'lineitem'::regclass; -- Check that partition and join pruning works when min/max values exist -- Adding l_orderkey = 1 to make the query not router executable SELECT public.coordinator_plan($Q$ EXPLAIN (COSTS FALSE) SELECT l_orderkey, l_linenumber, l_shipdate FROM lineitem WHERE l_orderkey = 9030 or l_orderkey = 1; $Q$); DEBUG: Router planner cannot handle multi-shard select queries CONTEXT: PL/pgSQL function public.coordinator_plan(text) line XX at FOR over EXECUTE statement LOG: join order: [ "lineitem" ] CONTEXT: PL/pgSQL function public.coordinator_plan(text) line XX at FOR over EXECUTE statement coordinator_plan --------------------------------------------------------------------- Custom Scan (Citus Adaptive) Task Count: 2 (2 rows) EXPLAIN (COSTS FALSE) SELECT sum(l_linenumber), avg(l_linenumber) FROM lineitem, orders WHERE l_orderkey = o_orderkey; DEBUG: Router planner cannot handle multi-shard select queries LOG: join order: [ "lineitem" ][ local partition join "orders" ] DEBUG: join prunable for intervals [1,6000] and [6001,20000] DEBUG: join prunable for intervals [6001,20000] and [1,6000] QUERY PLAN --------------------------------------------------------------------- Aggregate -> Custom Scan (Citus Adaptive) Task Count: 2 Tasks Shown: All -> Task Node: host=localhost port=xxxxx dbname=regression -> Aggregate -> Hash Join Hash Cond: (orders.o_orderkey = lineitem.l_orderkey) -> Seq Scan on orders_290002 orders -> Hash -> Seq Scan on lineitem_290000 lineitem -> Task Node: host=localhost port=xxxxx dbname=regression -> Aggregate -> Hash Join Hash Cond: (orders.o_orderkey = lineitem.l_orderkey) -> Seq Scan on orders_290003 orders -> Hash -> Seq Scan on lineitem_290001 lineitem (20 rows) -- Now set the minimum value for a shard to null. Then check that we don't apply -- partition or join pruning for the shard with null min value. Since it is not -- supported with single-repartition join, dual-repartition has been used. UPDATE pg_dist_shard SET shardminvalue = NULL WHERE shardid = :lineitem_shardid1; SELECT public.coordinator_plan($Q$ EXPLAIN (COSTS FALSE) SELECT l_orderkey, l_linenumber, l_shipdate FROM lineitem WHERE l_orderkey = 9030; $Q$); DEBUG: Router planner cannot handle multi-shard select queries CONTEXT: PL/pgSQL function public.coordinator_plan(text) line XX at FOR over EXECUTE statement LOG: join order: [ "lineitem" ] CONTEXT: PL/pgSQL function public.coordinator_plan(text) line XX at FOR over EXECUTE statement coordinator_plan --------------------------------------------------------------------- Custom Scan (Citus Adaptive) Task Count: 2 (2 rows) EXPLAIN (COSTS FALSE) SELECT sum(l_linenumber), avg(l_linenumber) FROM lineitem, orders WHERE l_partkey = o_custkey; DEBUG: Router planner cannot handle multi-shard select queries LOG: join order: [ "lineitem" ][ dual partition join "orders" ] DEBUG: join prunable for task partitionId 0 and 1 DEBUG: join prunable for task partitionId 0 and 2 DEBUG: join prunable for task partitionId 0 and 3 DEBUG: join prunable for task partitionId 0 and 4 DEBUG: join prunable for task partitionId 0 and 5 DEBUG: join prunable for task partitionId 1 and 0 DEBUG: join prunable for task partitionId 1 and 2 DEBUG: join prunable for task partitionId 1 and 3 DEBUG: join prunable for task partitionId 1 and 4 DEBUG: join prunable for task partitionId 1 and 5 DEBUG: join prunable for task partitionId 2 and 0 DEBUG: join prunable for task partitionId 2 and 1 DEBUG: join prunable for task partitionId 2 and 3 DEBUG: join prunable for task partitionId 2 and 4 DEBUG: join prunable for task partitionId 2 and 5 DEBUG: join prunable for task partitionId 3 and 0 DEBUG: join prunable for task partitionId 3 and 1 DEBUG: join prunable for task partitionId 3 and 2 DEBUG: join prunable for task partitionId 3 and 4 DEBUG: join prunable for task partitionId 3 and 5 DEBUG: join prunable for task partitionId 4 and 0 DEBUG: join prunable for task partitionId 4 and 1 DEBUG: join prunable for task partitionId 4 and 2 DEBUG: join prunable for task partitionId 4 and 3 DEBUG: join prunable for task partitionId 4 and 5 DEBUG: join prunable for task partitionId 5 and 0 DEBUG: join prunable for task partitionId 5 and 1 DEBUG: join prunable for task partitionId 5 and 2 DEBUG: join prunable for task partitionId 5 and 3 DEBUG: join prunable for task partitionId 5 and 4 DEBUG: pruning merge fetch taskId 1 DETAIL: Creating dependency on merge taskId 3 DEBUG: pruning merge fetch taskId 2 DETAIL: Creating dependency on merge taskId 3 DEBUG: pruning merge fetch taskId 4 DETAIL: Creating dependency on merge taskId 6 DEBUG: pruning merge fetch taskId 5 DETAIL: Creating dependency on merge taskId 6 DEBUG: pruning merge fetch taskId 7 DETAIL: Creating dependency on merge taskId 9 DEBUG: pruning merge fetch taskId 8 DETAIL: Creating dependency on merge taskId 9 DEBUG: pruning merge fetch taskId 10 DETAIL: Creating dependency on merge taskId 12 DEBUG: pruning merge fetch taskId 11 DETAIL: Creating dependency on merge taskId 12 DEBUG: pruning merge fetch taskId 13 DETAIL: Creating dependency on merge taskId 15 DEBUG: pruning merge fetch taskId 14 DETAIL: Creating dependency on merge taskId 15 DEBUG: pruning merge fetch taskId 16 DETAIL: Creating dependency on merge taskId 18 DEBUG: pruning merge fetch taskId 17 DETAIL: Creating dependency on merge taskId 18 QUERY PLAN --------------------------------------------------------------------- Aggregate -> Custom Scan (Citus Adaptive) Task Count: 6 Tasks Shown: None, not supported for re-partition queries -> MapMergeJob Map Task Count: 2 Merge Task Count: 6 -> MapMergeJob Map Task Count: 2 Merge Task Count: 6 (10 rows) -- Next, set the maximum value for another shard to null. Then check that we -- don't apply partition or join pruning for this other shard either. Since it -- is not supported with single-repartition join, dual-repartition has been used. UPDATE pg_dist_shard SET shardmaxvalue = NULL WHERE shardid = :lineitem_shardid2; SELECT public.coordinator_plan($Q$ EXPLAIN (COSTS FALSE) SELECT l_orderkey, l_linenumber, l_shipdate FROM lineitem WHERE l_orderkey = 9030; $Q$); DEBUG: Router planner cannot handle multi-shard select queries CONTEXT: PL/pgSQL function public.coordinator_plan(text) line XX at FOR over EXECUTE statement LOG: join order: [ "lineitem" ] CONTEXT: PL/pgSQL function public.coordinator_plan(text) line XX at FOR over EXECUTE statement coordinator_plan --------------------------------------------------------------------- Custom Scan (Citus Adaptive) Task Count: 2 (2 rows) EXPLAIN (COSTS FALSE) SELECT sum(l_linenumber), avg(l_linenumber) FROM lineitem, orders WHERE l_partkey = o_custkey; DEBUG: Router planner cannot handle multi-shard select queries LOG: join order: [ "lineitem" ][ dual partition join "orders" ] DEBUG: join prunable for task partitionId 0 and 1 DEBUG: join prunable for task partitionId 0 and 2 DEBUG: join prunable for task partitionId 0 and 3 DEBUG: join prunable for task partitionId 0 and 4 DEBUG: join prunable for task partitionId 0 and 5 DEBUG: join prunable for task partitionId 1 and 0 DEBUG: join prunable for task partitionId 1 and 2 DEBUG: join prunable for task partitionId 1 and 3 DEBUG: join prunable for task partitionId 1 and 4 DEBUG: join prunable for task partitionId 1 and 5 DEBUG: join prunable for task partitionId 2 and 0 DEBUG: join prunable for task partitionId 2 and 1 DEBUG: join prunable for task partitionId 2 and 3 DEBUG: join prunable for task partitionId 2 and 4 DEBUG: join prunable for task partitionId 2 and 5 DEBUG: join prunable for task partitionId 3 and 0 DEBUG: join prunable for task partitionId 3 and 1 DEBUG: join prunable for task partitionId 3 and 2 DEBUG: join prunable for task partitionId 3 and 4 DEBUG: join prunable for task partitionId 3 and 5 DEBUG: join prunable for task partitionId 4 and 0 DEBUG: join prunable for task partitionId 4 and 1 DEBUG: join prunable for task partitionId 4 and 2 DEBUG: join prunable for task partitionId 4 and 3 DEBUG: join prunable for task partitionId 4 and 5 DEBUG: join prunable for task partitionId 5 and 0 DEBUG: join prunable for task partitionId 5 and 1 DEBUG: join prunable for task partitionId 5 and 2 DEBUG: join prunable for task partitionId 5 and 3 DEBUG: join prunable for task partitionId 5 and 4 DEBUG: pruning merge fetch taskId 1 DETAIL: Creating dependency on merge taskId 3 DEBUG: pruning merge fetch taskId 2 DETAIL: Creating dependency on merge taskId 3 DEBUG: pruning merge fetch taskId 4 DETAIL: Creating dependency on merge taskId 6 DEBUG: pruning merge fetch taskId 5 DETAIL: Creating dependency on merge taskId 6 DEBUG: pruning merge fetch taskId 7 DETAIL: Creating dependency on merge taskId 9 DEBUG: pruning merge fetch taskId 8 DETAIL: Creating dependency on merge taskId 9 DEBUG: pruning merge fetch taskId 10 DETAIL: Creating dependency on merge taskId 12 DEBUG: pruning merge fetch taskId 11 DETAIL: Creating dependency on merge taskId 12 DEBUG: pruning merge fetch taskId 13 DETAIL: Creating dependency on merge taskId 15 DEBUG: pruning merge fetch taskId 14 DETAIL: Creating dependency on merge taskId 15 DEBUG: pruning merge fetch taskId 16 DETAIL: Creating dependency on merge taskId 18 DEBUG: pruning merge fetch taskId 17 DETAIL: Creating dependency on merge taskId 18 QUERY PLAN --------------------------------------------------------------------- Aggregate -> Custom Scan (Citus Adaptive) Task Count: 6 Tasks Shown: None, not supported for re-partition queries -> MapMergeJob Map Task Count: 2 Merge Task Count: 6 -> MapMergeJob Map Task Count: 2 Merge Task Count: 6 (10 rows) -- Last, set the minimum value to 0 and check that we don't treat it as null. We -- should apply partition and join pruning for this shard now. Since it is not -- supported with single-repartition join, dual-repartition has been used. UPDATE pg_dist_shard SET shardminvalue = '0' WHERE shardid = :lineitem_shardid1; SELECT public.coordinator_plan($Q$ EXPLAIN (COSTS FALSE) SELECT l_orderkey, l_linenumber, l_shipdate FROM lineitem WHERE l_orderkey = 9030; $Q$); DEBUG: Creating router plan CONTEXT: PL/pgSQL function public.coordinator_plan(text) line XX at FOR over EXECUTE statement coordinator_plan --------------------------------------------------------------------- Custom Scan (Citus Adaptive) Task Count: 1 (2 rows) EXPLAIN (COSTS FALSE) SELECT sum(l_linenumber), avg(l_linenumber) FROM lineitem, orders WHERE l_partkey = o_custkey; DEBUG: Router planner cannot handle multi-shard select queries LOG: join order: [ "lineitem" ][ dual partition join "orders" ] DEBUG: join prunable for task partitionId 0 and 1 DEBUG: join prunable for task partitionId 0 and 2 DEBUG: join prunable for task partitionId 0 and 3 DEBUG: join prunable for task partitionId 0 and 4 DEBUG: join prunable for task partitionId 0 and 5 DEBUG: join prunable for task partitionId 1 and 0 DEBUG: join prunable for task partitionId 1 and 2 DEBUG: join prunable for task partitionId 1 and 3 DEBUG: join prunable for task partitionId 1 and 4 DEBUG: join prunable for task partitionId 1 and 5 DEBUG: join prunable for task partitionId 2 and 0 DEBUG: join prunable for task partitionId 2 and 1 DEBUG: join prunable for task partitionId 2 and 3 DEBUG: join prunable for task partitionId 2 and 4 DEBUG: join prunable for task partitionId 2 and 5 DEBUG: join prunable for task partitionId 3 and 0 DEBUG: join prunable for task partitionId 3 and 1 DEBUG: join prunable for task partitionId 3 and 2 DEBUG: join prunable for task partitionId 3 and 4 DEBUG: join prunable for task partitionId 3 and 5 DEBUG: join prunable for task partitionId 4 and 0 DEBUG: join prunable for task partitionId 4 and 1 DEBUG: join prunable for task partitionId 4 and 2 DEBUG: join prunable for task partitionId 4 and 3 DEBUG: join prunable for task partitionId 4 and 5 DEBUG: join prunable for task partitionId 5 and 0 DEBUG: join prunable for task partitionId 5 and 1 DEBUG: join prunable for task partitionId 5 and 2 DEBUG: join prunable for task partitionId 5 and 3 DEBUG: join prunable for task partitionId 5 and 4 DEBUG: pruning merge fetch taskId 1 DETAIL: Creating dependency on merge taskId 3 DEBUG: pruning merge fetch taskId 2 DETAIL: Creating dependency on merge taskId 3 DEBUG: pruning merge fetch taskId 4 DETAIL: Creating dependency on merge taskId 6 DEBUG: pruning merge fetch taskId 5 DETAIL: Creating dependency on merge taskId 6 DEBUG: pruning merge fetch taskId 7 DETAIL: Creating dependency on merge taskId 9 DEBUG: pruning merge fetch taskId 8 DETAIL: Creating dependency on merge taskId 9 DEBUG: pruning merge fetch taskId 10 DETAIL: Creating dependency on merge taskId 12 DEBUG: pruning merge fetch taskId 11 DETAIL: Creating dependency on merge taskId 12 DEBUG: pruning merge fetch taskId 13 DETAIL: Creating dependency on merge taskId 15 DEBUG: pruning merge fetch taskId 14 DETAIL: Creating dependency on merge taskId 15 DEBUG: pruning merge fetch taskId 16 DETAIL: Creating dependency on merge taskId 18 DEBUG: pruning merge fetch taskId 17 DETAIL: Creating dependency on merge taskId 18 QUERY PLAN --------------------------------------------------------------------- Aggregate -> Custom Scan (Citus Adaptive) Task Count: 6 Tasks Shown: None, not supported for re-partition queries -> MapMergeJob Map Task Count: 2 Merge Task Count: 6 -> MapMergeJob Map Task Count: 2 Merge Task Count: 6 (10 rows) RESET client_min_messages; DROP SCHEMA multi_null_minmax_value_pruning CASCADE; NOTICE: drop cascades to 2 other objects DETAIL: drop cascades to table lineitem drop cascades to table orders