diff --git a/contrib/pax_storage/src/test/regress/expected/bfv_dd_optimizer.out b/contrib/pax_storage/src/test/regress/expected/bfv_dd_optimizer.out index deadff501d5..224d386ad0d 100644 --- a/contrib/pax_storage/src/test/regress/expected/bfv_dd_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/bfv_dd_optimizer.out @@ -88,7 +88,7 @@ INFO: (slice 1) Dispatch command to SINGLE content -- single column distr key select * from dd_singlecol_1 where a in (10,11,12); -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 2 1 a | b ----+---- 10 | 10 @@ -97,7 +97,7 @@ INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 (3 rows) select * from dd_singlecol_1 where a=10 or a=11 or a=12; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 2 1 a | b ----+---- 10 | 10 @@ -106,7 +106,7 @@ INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 (3 rows) select * from dd_singlecol_1 where a is null or a=1; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 1 0 a | b ---+--- 1 | 1 @@ -115,7 +115,7 @@ INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 -- projections and disjunction select b from dd_singlecol_1 where a=1 or a=2; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 1 0 b --- 1 @@ -175,7 +175,7 @@ INFO: (slice 0) Dispatch command to SINGLE content INFO: Distributed transaction command 'Distributed Commit (one-phase)' to SINGLE content -- disjunction with partitioned tables select * from dd_part_singlecol where a in (10,11,12); -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 2 1 a | b | c ----+----+---- 10 | 20 | 30 @@ -184,7 +184,7 @@ INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 (3 rows) select * from dd_part_singlecol where a=10 or a=11 or a=12; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 2 1 a | b | c ----+----+---- 10 | 20 | 30 @@ -193,7 +193,7 @@ INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 (3 rows) select * from dd_part_singlecol where a is null or a=1; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 1 0 a | b | c ---+---+--- | | @@ -321,21 +321,21 @@ analyze dd_singlecol_idx2; INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 -- disjunction with index scans select * from dd_singlecol_idx where (a=1 or a=2) and b<2; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 1 0 a | b | c ---+---+--- 1 | 1 | 1 (1 row) select 'one' from dd_singlecol_idx where (a=1 or a=2) and b=1; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 1 0 ?column? ---------- one (1 row) select a, count(*) from dd_singlecol_idx where (a=1 or a=2) and b=1 group by a; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 1 0 a | count ---+------- 1 | 1 @@ -369,21 +369,21 @@ analyze dd_singlecol_bitmap_idx; INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 -- disjunction with bitmap index scans select * from dd_singlecol_bitmap_idx where (a=1 or a=2) and b<2; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 1 0 a | b | c ---+---+--- 1 | 1 | 1 (1 row) select * from dd_singlecol_bitmap_idx where (a=1 or a=2) and b=2 and c=2; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 1 0 a | b | c ---+---+--- 2 | 2 | 2 (1 row) select * from dd_singlecol_bitmap_idx where (a=1 or a=2) and (b=2 or c=2); -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 1 0 a | b | c ---+---+--- 2 | 2 | 2 diff --git a/contrib/pax_storage/src/test/regress/expected/create_index_optimizer.out b/contrib/pax_storage/src/test/regress/expected/create_index_optimizer.out index 56b70e3175c..40b610bf773 100644 --- a/contrib/pax_storage/src/test/regress/expected/create_index_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/create_index_optimizer.out @@ -2013,7 +2013,7 @@ WHERE unique1 IN (1,42,7) ORDER BY unique1; QUERY PLAN ------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) Merge Key: unique1 -> Index Only Scan using tenk1_unique1 on tenk1 Index Cond: (unique1 = ANY ('{1,42,7}'::integer[])) diff --git a/contrib/pax_storage/src/test/regress/expected/direct_dispatch_optimizer.out b/contrib/pax_storage/src/test/regress/expected/direct_dispatch_optimizer.out index 8efc7ccfc0f..241b4101afe 100644 --- a/contrib/pax_storage/src/test/regress/expected/direct_dispatch_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/direct_dispatch_optimizer.out @@ -1120,14 +1120,14 @@ INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 explain (costs off) select gp_segment_id, * from t1_varchar where col1_varchar in ('a','b'); QUERY PLAN ---------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Seq Scan on t1_varchar Filter: ((col1_varchar)::text = ANY ('{a,b}'::text[])) Optimizer: Pivotal Optimizer (GPORCA) (4 rows) select gp_segment_id, * from t1_varchar where col1_varchar in ('a','b'); -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 2 1 gp_segment_id | col1_varchar | col2_int ---------------+--------------+---------- 1 | b | 2 @@ -1137,14 +1137,14 @@ INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 explain (costs off) select gp_segment_id, * from t1_varchar where col1_varchar = 'a' or col1_varchar = 'b'; QUERY PLAN -------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Seq Scan on t1_varchar Filter: (((col1_varchar)::text = 'a'::text) OR ((col1_varchar)::text = 'b'::text)) Optimizer: Pivotal Optimizer (GPORCA) (4 rows) select gp_segment_id, * from t1_varchar where col1_varchar = 'a' or col1_varchar = 'b'; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 2 1 gp_segment_id | col1_varchar | col2_int ---------------+--------------+---------- 1 | b | 2 @@ -1204,14 +1204,14 @@ INFO: (slice 1) Dispatch command to SINGLE content explain (costs off) select gp_segment_id, * from t1_varchar where col1_varchar in ('a', 'b') and col2_int=2; QUERY PLAN ------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Seq Scan on t1_varchar Filter: (((col1_varchar)::text = ANY ('{a,b}'::text[])) AND (col2_int = 2)) Optimizer: Pivotal Optimizer (GPORCA) (4 rows) select gp_segment_id, * from t1_varchar where col1_varchar in ('a', 'b') and col2_int=2; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 2 1 gp_segment_id | col1_varchar | col2_int ---------------+--------------+---------- 1 | b | 2 @@ -1220,14 +1220,14 @@ INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 explain (costs off) select gp_segment_id, * from t1_varchar where (col1_varchar = 'a' or col1_varchar = 'b') and col2_int=1; QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Seq Scan on t1_varchar Filter: ((((col1_varchar)::text = 'a'::text) OR ((col1_varchar)::text = 'b'::text)) AND (col2_int = 1)) Optimizer: Pivotal Optimizer (GPORCA) (4 rows) select gp_segment_id, * from t1_varchar where (col1_varchar = 'a' or col1_varchar = 'b') and col2_int=1; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 2 1 gp_segment_id | col1_varchar | col2_int ---------------+--------------+---------- 2 | a | 1 diff --git a/contrib/pax_storage/src/test/regress/expected/inherit_optimizer.out b/contrib/pax_storage/src/test/regress/expected/inherit_optimizer.out index 1b7799140e5..378eb8b7cb6 100644 --- a/contrib/pax_storage/src/test/regress/expected/inherit_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/inherit_optimizer.out @@ -2088,7 +2088,7 @@ explain (costs off) select * from list_parted where a is not null; explain (costs off) select * from list_parted where a in ('ab', 'cd', 'ef'); QUERY PLAN ---------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Dynamic Seq Scan on list_parted Number of partitions to scan: 2 (out of 3) Filter: ((a)::text = ANY ('{ab,cd,ef}'::text[])) @@ -2098,7 +2098,7 @@ explain (costs off) select * from list_parted where a in ('ab', 'cd', 'ef'); explain (costs off) select * from list_parted where a = 'ab' or a in (null, 'cd'); QUERY PLAN --------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Dynamic Seq Scan on list_parted Number of partitions to scan: 1 (out of 3) Filter: (((a)::text = 'ab'::text) OR ((a)::text = ANY ('{NULL,cd}'::text[]))) @@ -2548,7 +2548,7 @@ explain (costs off) select * from mclparted order by a; explain (costs off) select * from mclparted where a in(3,4,5) order by a; QUERY PLAN --------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) Merge Key: a -> Sort Sort Key: a @@ -2565,7 +2565,7 @@ create table mclparted_def partition of mclparted default; explain (costs off) select * from mclparted where a in(1,2,4) order by a; QUERY PLAN --------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) Merge Key: a -> Sort Sort Key: a @@ -2578,7 +2578,7 @@ explain (costs off) select * from mclparted where a in(1,2,4) order by a; explain (costs off) select * from mclparted where a in(1,2,4) or a is null order by a; QUERY PLAN ------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) Merge Key: a -> Sort Sort Key: a @@ -2595,7 +2595,7 @@ create table mclparted_0_null partition of mclparted for values in(0,null); explain (costs off) select * from mclparted where a in(1,2,4) or a is null order by a; QUERY PLAN ------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) Merge Key: a -> Sort Sort Key: a @@ -2608,7 +2608,7 @@ explain (costs off) select * from mclparted where a in(1,2,4) or a is null order explain (costs off) select * from mclparted where a in(0,1,2,4) order by a; QUERY PLAN --------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) Merge Key: a -> Sort Sort Key: a @@ -2622,7 +2622,7 @@ explain (costs off) select * from mclparted where a in(0,1,2,4) order by a; explain (costs off) select * from mclparted where a in(1,2,4) order by a; QUERY PLAN --------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) Merge Key: a -> Sort Sort Key: a diff --git a/contrib/pax_storage/src/test/regress/expected/partition_prune_optimizer.out b/contrib/pax_storage/src/test/regress/expected/partition_prune_optimizer.out index c8c35129b79..a020be227ec 100644 --- a/contrib/pax_storage/src/test/regress/expected/partition_prune_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/partition_prune_optimizer.out @@ -1600,7 +1600,7 @@ create table coercepart_cd partition of coercepart for values in ('cd'); explain (costs off) select * from coercepart where a in ('ab', to_char(125, '999')); QUERY PLAN ----------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Dynamic Seq Scan on coercepart Number of partitions to scan: 1 (out of 3) Filter: ((a)::text = ANY ('{ab," 125"}'::text[])) @@ -1650,7 +1650,7 @@ explain (costs off) select * from coercepart where a !~ all ('{ab,bc}'); explain (costs off) select * from coercepart where a = any ('{ab,bc}'); QUERY PLAN ------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Dynamic Seq Scan on coercepart Number of partitions to scan: 2 (out of 3) Filter: ((a)::text = ANY ('{ab,bc}'::text[])) @@ -1690,7 +1690,7 @@ explain (costs off) select * from coercepart where a = all ('{ab}'); explain (costs off) select * from coercepart where a = all ('{ab,bc}'); QUERY PLAN ------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Dynamic Seq Scan on coercepart Number of partitions to scan: 2 (out of 3) Filter: ((a)::text = ALL ('{ab,bc}'::text[])) @@ -3894,7 +3894,7 @@ explain (costs off) select * from pp_arrpart where a = '{1, 2}'; explain (costs off) select * from pp_arrpart where a in ('{4, 5}', '{1}'); QUERY PLAN ---------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Dynamic Seq Scan on pp_arrpart Number of partitions to scan: 2 (out of 2) Filter: ((a = '{4,5}'::integer[]) OR (a = '{1}'::integer[])) diff --git a/contrib/pax_storage/src/test/regress/expected/qp_misc_jiras_optimizer.out b/contrib/pax_storage/src/test/regress/expected/qp_misc_jiras_optimizer.out index 3cad459b8e7..e9e1dc84a64 100644 --- a/contrib/pax_storage/src/test/regress/expected/qp_misc_jiras_optimizer.out +++ b/contrib/pax_storage/src/test/regress/expected/qp_misc_jiras_optimizer.out @@ -5635,7 +5635,7 @@ explain select b from epsilon_test where b in (11,30) limit 30; QUERY PLAN -------------------------------------------------------------------------------------- Limit (cost=0.00..8771.18 rows=10 width=2) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..8771.18 rows=30 width=2) + -> Gather Motion 2:1 (slice1; segments: 2) (cost=0.00..8771.18 rows=30 width=2) -> Limit (cost=0.00..8771.18 rows=10 width=2) -> Seq Scan on epsilon_test (cost=0.00..8771.18 rows=10677 width=2) Filter: (b = ANY ('{11,30}'::integer[])) diff --git a/src/backend/gpopt/gpdbwrappers.cpp b/src/backend/gpopt/gpdbwrappers.cpp index 357417354e7..70abe6c72b9 100644 --- a/src/backend/gpopt/gpdbwrappers.cpp +++ b/src/backend/gpopt/gpdbwrappers.cpp @@ -1204,6 +1204,17 @@ gpdb::LAppendInt(List *list, int iDatum) return NIL; } +List * +gpdb::LAppendUniqueInt(List *list, int iDatum) +{ + GP_WRAP_START; + { + return list_append_unique_int(list, iDatum); + } + GP_WRAP_END; + return NIL; +} + List * gpdb::LAppendOid(List *list, Oid datum) { diff --git a/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp index 3abfd5fed5a..07f61a74c98 100644 --- a/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp +++ b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp @@ -5530,9 +5530,6 @@ CTranslatorDXLToPlStmt::TranslateDXLDirectDispatchInfo( return NIL; } - CDXLDatumArray *dxl_datum_array = (*dispatch_identifier_datum_arrays)[0]; - GPOS_ASSERT(0 < dxl_datum_array->Size()); - const ULONG length = dispatch_identifier_datum_arrays->Size(); if (dxl_direct_dispatch_info->FContainsRawValues()) @@ -5568,23 +5565,29 @@ CTranslatorDXLToPlStmt::TranslateDXLDirectDispatchInfo( return segids_list; } - ULONG hash_code = GetDXLDatumGPDBHash(dxl_datum_array, pRTEHashFuncCal); + // Each datum array is one value combination of the distribution key + // (e.g. one array per IN-list constant). Dispatch to the union of the + // segments they hash to, like the planner does. + List *segids_list = NIL; for (ULONG ul = 0; ul < length; ul++) { CDXLDatumArray *dispatch_identifier_datum_array = (*dispatch_identifier_datum_arrays)[ul]; GPOS_ASSERT(0 < dispatch_identifier_datum_array->Size()); - ULONG hash_code_new = GetDXLDatumGPDBHash( - dispatch_identifier_datum_array, pRTEHashFuncCal); + ULONG hash_code = GetDXLDatumGPDBHash(dispatch_identifier_datum_array, + pRTEHashFuncCal); - if (hash_code != hash_code_new) - { - // values don't hash to the same segment - return NIL; - } + segids_list = gpdb::LAppendUniqueInt(segids_list, hash_code); + } + + // a value set that spans every segment is equivalent to not direct + // dispatching at all + if (gpdb::ListLength(segids_list) == m_num_of_segments) + { + gpdb::ListFree(segids_list); + return NIL; } - List *segids_list = gpdb::LAppendInt(NIL, hash_code); return segids_list; } diff --git a/src/include/gpopt/gpdbwrappers.h b/src/include/gpopt/gpdbwrappers.h index 693fbdac678..760bd770265 100644 --- a/src/include/gpopt/gpdbwrappers.h +++ b/src/include/gpopt/gpdbwrappers.h @@ -456,6 +456,9 @@ List *LAppend(List *list, void *datum); // append an integer to a list List *LAppendInt(List *list, int datum); +// append an integer to a list if it is not already a member +List *LAppendUniqueInt(List *list, int datum); + // append an oid to a list List *LAppendOid(List *list, Oid datum); diff --git a/src/test/regress/expected/bfv_dd_optimizer.out b/src/test/regress/expected/bfv_dd_optimizer.out index deadff501d5..224d386ad0d 100644 --- a/src/test/regress/expected/bfv_dd_optimizer.out +++ b/src/test/regress/expected/bfv_dd_optimizer.out @@ -88,7 +88,7 @@ INFO: (slice 1) Dispatch command to SINGLE content -- single column distr key select * from dd_singlecol_1 where a in (10,11,12); -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 2 1 a | b ----+---- 10 | 10 @@ -97,7 +97,7 @@ INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 (3 rows) select * from dd_singlecol_1 where a=10 or a=11 or a=12; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 2 1 a | b ----+---- 10 | 10 @@ -106,7 +106,7 @@ INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 (3 rows) select * from dd_singlecol_1 where a is null or a=1; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 1 0 a | b ---+--- 1 | 1 @@ -115,7 +115,7 @@ INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 -- projections and disjunction select b from dd_singlecol_1 where a=1 or a=2; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 1 0 b --- 1 @@ -175,7 +175,7 @@ INFO: (slice 0) Dispatch command to SINGLE content INFO: Distributed transaction command 'Distributed Commit (one-phase)' to SINGLE content -- disjunction with partitioned tables select * from dd_part_singlecol where a in (10,11,12); -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 2 1 a | b | c ----+----+---- 10 | 20 | 30 @@ -184,7 +184,7 @@ INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 (3 rows) select * from dd_part_singlecol where a=10 or a=11 or a=12; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 2 1 a | b | c ----+----+---- 10 | 20 | 30 @@ -193,7 +193,7 @@ INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 (3 rows) select * from dd_part_singlecol where a is null or a=1; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 1 0 a | b | c ---+---+--- | | @@ -321,21 +321,21 @@ analyze dd_singlecol_idx2; INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 -- disjunction with index scans select * from dd_singlecol_idx where (a=1 or a=2) and b<2; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 1 0 a | b | c ---+---+--- 1 | 1 | 1 (1 row) select 'one' from dd_singlecol_idx where (a=1 or a=2) and b=1; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 1 0 ?column? ---------- one (1 row) select a, count(*) from dd_singlecol_idx where (a=1 or a=2) and b=1 group by a; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 1 0 a | count ---+------- 1 | 1 @@ -369,21 +369,21 @@ analyze dd_singlecol_bitmap_idx; INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 -- disjunction with bitmap index scans select * from dd_singlecol_bitmap_idx where (a=1 or a=2) and b<2; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 1 0 a | b | c ---+---+--- 1 | 1 | 1 (1 row) select * from dd_singlecol_bitmap_idx where (a=1 or a=2) and b=2 and c=2; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 1 0 a | b | c ---+---+--- 2 | 2 | 2 (1 row) select * from dd_singlecol_bitmap_idx where (a=1 or a=2) and (b=2 or c=2); -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 1 0 a | b | c ---+---+--- 2 | 2 | 2 diff --git a/src/test/regress/expected/create_index_optimizer.out b/src/test/regress/expected/create_index_optimizer.out index 7d95dd808ca..8e744326dbe 100644 --- a/src/test/regress/expected/create_index_optimizer.out +++ b/src/test/regress/expected/create_index_optimizer.out @@ -2017,7 +2017,7 @@ WHERE unique1 IN (1,42,7) ORDER BY unique1; QUERY PLAN ------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) Merge Key: unique1 -> Index Only Scan using tenk1_unique1 on tenk1 Index Cond: (unique1 = ANY ('{1,42,7}'::integer[])) diff --git a/src/test/regress/expected/direct_dispatch_optimizer.out b/src/test/regress/expected/direct_dispatch_optimizer.out index 2da45e7955a..ef3214de5bc 100644 --- a/src/test/regress/expected/direct_dispatch_optimizer.out +++ b/src/test/regress/expected/direct_dispatch_optimizer.out @@ -1130,14 +1130,14 @@ INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 explain (costs off) select gp_segment_id, * from t1_varchar where col1_varchar in ('a','b'); QUERY PLAN ---------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Seq Scan on t1_varchar Filter: ((col1_varchar)::text = ANY ('{a,b}'::text[])) Optimizer: Pivotal Optimizer (GPORCA) (4 rows) select gp_segment_id, * from t1_varchar where col1_varchar in ('a','b'); -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 2 1 gp_segment_id | col1_varchar | col2_int ---------------+--------------+---------- 1 | b | 2 @@ -1147,14 +1147,14 @@ INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 explain (costs off) select gp_segment_id, * from t1_varchar where col1_varchar = 'a' or col1_varchar = 'b'; QUERY PLAN -------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Seq Scan on t1_varchar Filter: (((col1_varchar)::text = 'a'::text) OR ((col1_varchar)::text = 'b'::text)) Optimizer: Pivotal Optimizer (GPORCA) (4 rows) select gp_segment_id, * from t1_varchar where col1_varchar = 'a' or col1_varchar = 'b'; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 2 1 gp_segment_id | col1_varchar | col2_int ---------------+--------------+---------- 1 | b | 2 @@ -1214,14 +1214,14 @@ INFO: (slice 1) Dispatch command to SINGLE content explain (costs off) select gp_segment_id, * from t1_varchar where col1_varchar in ('a', 'b') and col2_int=2; QUERY PLAN ------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Seq Scan on t1_varchar Filter: (((col1_varchar)::text = ANY ('{a,b}'::text[])) AND (col2_int = 2)) Optimizer: Pivotal Optimizer (GPORCA) (4 rows) select gp_segment_id, * from t1_varchar where col1_varchar in ('a', 'b') and col2_int=2; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 2 1 gp_segment_id | col1_varchar | col2_int ---------------+--------------+---------- 1 | b | 2 @@ -1230,14 +1230,14 @@ INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 explain (costs off) select gp_segment_id, * from t1_varchar where (col1_varchar = 'a' or col1_varchar = 'b') and col2_int=1; QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Seq Scan on t1_varchar Filter: ((((col1_varchar)::text = 'a'::text) OR ((col1_varchar)::text = 'b'::text)) AND (col2_int = 1)) Optimizer: Pivotal Optimizer (GPORCA) (4 rows) select gp_segment_id, * from t1_varchar where (col1_varchar = 'a' or col1_varchar = 'b') and col2_int=1; -INFO: (slice 1) Dispatch command to ALL contents: 0 1 2 +INFO: (slice 1) Dispatch command to PARTIAL contents: 2 1 gp_segment_id | col1_varchar | col2_int ---------------+--------------+---------- 2 | a | 1 diff --git a/src/test/regress/expected/inherit_optimizer.out b/src/test/regress/expected/inherit_optimizer.out index d30430b5519..63d6311e50b 100644 --- a/src/test/regress/expected/inherit_optimizer.out +++ b/src/test/regress/expected/inherit_optimizer.out @@ -2109,7 +2109,7 @@ explain (costs off) select * from list_parted where a is not null; explain (costs off) select * from list_parted where a in ('ab', 'cd', 'ef'); QUERY PLAN ---------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Dynamic Seq Scan on list_parted Number of partitions to scan: 2 (out of 3) Filter: ((a)::text = ANY ('{ab,cd,ef}'::text[])) @@ -2119,7 +2119,7 @@ explain (costs off) select * from list_parted where a in ('ab', 'cd', 'ef'); explain (costs off) select * from list_parted where a = 'ab' or a in (null, 'cd'); QUERY PLAN --------------------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Dynamic Seq Scan on list_parted Number of partitions to scan: 1 (out of 3) Filter: (((a)::text = 'ab'::text) OR ((a)::text = ANY ('{NULL,cd}'::text[]))) @@ -2569,7 +2569,7 @@ explain (costs off) select * from mclparted order by a; explain (costs off) select * from mclparted where a in(3,4,5) order by a; QUERY PLAN ---------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) Merge Key: a -> Sort Sort Key: a @@ -2586,7 +2586,7 @@ create table mclparted_def partition of mclparted default; explain (costs off) select * from mclparted where a in(1,2,4) order by a; QUERY PLAN ---------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) Merge Key: a -> Sort Sort Key: a @@ -2599,7 +2599,7 @@ explain (costs off) select * from mclparted where a in(1,2,4) order by a; explain (costs off) select * from mclparted where a in(1,2,4) or a is null order by a; QUERY PLAN ------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) Merge Key: a -> Sort Sort Key: a @@ -2616,7 +2616,7 @@ create table mclparted_0_null partition of mclparted for values in(0,null); explain (costs off) select * from mclparted where a in(1,2,4) or a is null order by a; QUERY PLAN ------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) Merge Key: a -> Sort Sort Key: a @@ -2629,7 +2629,7 @@ explain (costs off) select * from mclparted where a in(1,2,4) or a is null order explain (costs off) select * from mclparted where a in(0,1,2,4) order by a; QUERY PLAN ---------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) Merge Key: a -> Sort Sort Key: a @@ -2643,7 +2643,7 @@ explain (costs off) select * from mclparted where a in(0,1,2,4) order by a; explain (costs off) select * from mclparted where a in(1,2,4) order by a; QUERY PLAN ---------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) Merge Key: a -> Sort Sort Key: a diff --git a/src/test/regress/expected/partition_append.out b/src/test/regress/expected/partition_append.out index 9154c7d5a6b..8f7209bb950 100755 --- a/src/test/regress/expected/partition_append.out +++ b/src/test/regress/expected/partition_append.out @@ -6499,7 +6499,7 @@ HINT: For non-partitioned tables, run analyze (). For QUERY PLAN -------------------------------------------------------------------------------------------------------- Finalize Aggregate - -> Gather Motion 3:1 (slice1; segments: 3) + -> Gather Motion 2:1 (slice1; segments: 2) -> Partial Aggregate -> Append -> Seq Scan on test_rangepartition_1_prt_pn_20221022 diff --git a/src/test/regress/expected/partition_optimizer.out b/src/test/regress/expected/partition_optimizer.out index c237e41bcad..a69f46baa6a 100755 --- a/src/test/regress/expected/partition_optimizer.out +++ b/src/test/regress/expected/partition_optimizer.out @@ -6425,7 +6425,7 @@ HINT: For non-partitioned tables, run analyze (). For QUERY PLAN -------------------------------------------------------------------------------------------------- Finalize Aggregate - -> Gather Motion 3:1 (slice1; segments: 3) + -> Gather Motion 2:1 (slice1; segments: 2) -> Partial Aggregate -> Dynamic Seq Scan on test_rangepartition Number of partitions to scan: 2 (out of 3) diff --git a/src/test/regress/expected/partition_prune_append.out b/src/test/regress/expected/partition_prune_append.out index 20730d90d0f..e6e6a9a5746 100644 --- a/src/test/regress/expected/partition_prune_append.out +++ b/src/test/regress/expected/partition_prune_append.out @@ -1338,7 +1338,7 @@ create table coercepart_cd partition of coercepart for values in ('cd'); explain (costs off) select * from coercepart where a in ('ab', to_char(125, '999')); QUERY PLAN ----------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Append -> Seq Scan on coercepart_ab Filter: ((a)::text = ANY ('{ab," 125"}'::text[])) @@ -1404,7 +1404,7 @@ explain (costs off) select * from coercepart where a !~ all ('{ab,bc}'); explain (costs off) select * from coercepart where a = any ('{ab,bc}'); QUERY PLAN ------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Append -> Seq Scan on coercepart_ab Filter: ((a)::text = ANY ('{ab,bc}'::text[])) @@ -1450,7 +1450,7 @@ explain (costs off) select * from coercepart where a = all ('{ab}'); explain (costs off) select * from coercepart where a = all ('{ab,bc}'); QUERY PLAN ------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Append -> Seq Scan on coercepart_ab Filter: ((a)::text = ALL ('{ab,bc}'::text[])) @@ -3455,7 +3455,7 @@ explain (costs off) select * from pp_arrpart where a = '{1, 2}'; explain (costs off) select * from pp_arrpart where a in ('{4, 5}', '{1}'); QUERY PLAN ---------------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Append -> Seq Scan on pp_arrpart1 Filter: ((a = '{4,5}'::integer[]) OR (a = '{1}'::integer[])) diff --git a/src/test/regress/expected/partition_prune_optimizer.out b/src/test/regress/expected/partition_prune_optimizer.out index 72caa769ea3..befcc41a8d4 100644 --- a/src/test/regress/expected/partition_prune_optimizer.out +++ b/src/test/regress/expected/partition_prune_optimizer.out @@ -1610,7 +1610,7 @@ create table coercepart_cd partition of coercepart for values in ('cd'); explain (costs off) select * from coercepart where a in ('ab', to_char(125, '999')); QUERY PLAN ----------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Dynamic Seq Scan on coercepart Number of partitions to scan: 1 (out of 3) Filter: ((a)::text = ANY ('{ab," 125"}'::text[])) @@ -1660,7 +1660,7 @@ explain (costs off) select * from coercepart where a !~ all ('{ab,bc}'); explain (costs off) select * from coercepart where a = any ('{ab,bc}'); QUERY PLAN ------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Dynamic Seq Scan on coercepart Number of partitions to scan: 2 (out of 3) Filter: ((a)::text = ANY ('{ab,bc}'::text[])) @@ -1700,7 +1700,7 @@ explain (costs off) select * from coercepart where a = all ('{ab}'); explain (costs off) select * from coercepart where a = all ('{ab,bc}'); QUERY PLAN ------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Dynamic Seq Scan on coercepart Number of partitions to scan: 2 (out of 3) Filter: ((a)::text = ALL ('{ab,bc}'::text[])) @@ -3904,7 +3904,7 @@ explain (costs off) select * from pp_arrpart where a = '{1, 2}'; explain (costs off) select * from pp_arrpart where a in ('{4, 5}', '{1}'); QUERY PLAN ---------------------------------------------------------------------- - Gather Motion 3:1 (slice1; segments: 3) + Gather Motion 2:1 (slice1; segments: 2) -> Dynamic Seq Scan on pp_arrpart Number of partitions to scan: 2 (out of 2) Filter: ((a = '{4,5}'::integer[]) OR (a = '{1}'::integer[])) diff --git a/src/test/regress/expected/qp_misc_jiras_optimizer.out b/src/test/regress/expected/qp_misc_jiras_optimizer.out index 084c4ddb34b..fd70b270c54 100644 --- a/src/test/regress/expected/qp_misc_jiras_optimizer.out +++ b/src/test/regress/expected/qp_misc_jiras_optimizer.out @@ -5634,7 +5634,7 @@ explain select b from epsilon_test where b in (11,30) limit 30; QUERY PLAN -------------------------------------------------------------------------------------- Limit (cost=0.00..8771.18 rows=10 width=2) - -> Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..8771.18 rows=30 width=2) + -> Gather Motion 2:1 (slice1; segments: 2) (cost=0.00..8771.18 rows=30 width=2) -> Limit (cost=0.00..8771.18 rows=10 width=2) -> Seq Scan on epsilon_test (cost=0.00..8771.18 rows=10677 width=2) Filter: (b = ANY ('{11,30}'::integer[]))