diff --git a/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp index c8ad4cefd3ac..edfd676f78f0 100644 --- a/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp +++ b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp @@ -3608,6 +3608,13 @@ CTranslatorDXLToPlStmt::TranslateDXLCTEProducerToSharedScan( child_plan = materialize_plan; } + // Targetlist mismatch leads to different tuple bindings, see #12796. + // We assume targetlist's equivalence. In case of inequality one list + // is a subset of another, so it safe to compare only length. + if (list_length(child_plan->targetlist) != list_length(plan->targetlist)) + GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiDXL2PlStmtConversion, + GPOS_WSZ_LIT("Shared Scan and child plan targetlist mismatch.")); + InitializeSpoolingInfo(child_plan, cte_id); plan->lefttree = child_plan; diff --git a/src/backend/gporca/data/dxl/minidump/BitmapIndexScan.mdp b/src/backend/gporca/data/dxl/minidump/BitmapIndexScan.mdp index 9646bd7ecdb1..5227ad97c41f 100644 --- a/src/backend/gporca/data/dxl/minidump/BitmapIndexScan.mdp +++ b/src/backend/gporca/data/dxl/minidump/BitmapIndexScan.mdp @@ -556,14 +556,7 @@ see sql/BitmapIndexScan.sql - - - - - - - - + diff --git a/src/backend/gporca/data/dxl/minidump/BitmapTableScan-Basic.mdp b/src/backend/gporca/data/dxl/minidump/BitmapTableScan-Basic.mdp index aa84a4e622ac..8013f6d7096f 100644 --- a/src/backend/gporca/data/dxl/minidump/BitmapTableScan-Basic.mdp +++ b/src/backend/gporca/data/dxl/minidump/BitmapTableScan-Basic.mdp @@ -242,7 +242,7 @@ - + @@ -252,71 +252,53 @@ - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/src/backend/gporca/data/dxl/minidump/GinIndex.mdp b/src/backend/gporca/data/dxl/minidump/GinIndex.mdp index 00e82e4953df..2351608c7dc0 100644 --- a/src/backend/gporca/data/dxl/minidump/GinIndex.mdp +++ b/src/backend/gporca/data/dxl/minidump/GinIndex.mdp @@ -283,11 +283,7 @@ - - - - - + diff --git a/src/backend/gporca/data/dxl/minidump/GinIndexPathOpfamily.mdp b/src/backend/gporca/data/dxl/minidump/GinIndexPathOpfamily.mdp index 34b7e9047c84..b710e84e5071 100644 --- a/src/backend/gporca/data/dxl/minidump/GinIndexPathOpfamily.mdp +++ b/src/backend/gporca/data/dxl/minidump/GinIndexPathOpfamily.mdp @@ -283,11 +283,7 @@ - - - - - + diff --git a/src/backend/gporca/data/dxl/minidump/GinIndexSearchModeAll.mdp b/src/backend/gporca/data/dxl/minidump/GinIndexSearchModeAll.mdp index 3f4c74de1f5f..b419013c3b30 100644 --- a/src/backend/gporca/data/dxl/minidump/GinIndexSearchModeAll.mdp +++ b/src/backend/gporca/data/dxl/minidump/GinIndexSearchModeAll.mdp @@ -283,11 +283,7 @@ - - - - - + diff --git a/src/backend/gporca/data/dxl/minidump/Gist-AOCOTable-NonLossy-BitmapIndexPlan.mdp b/src/backend/gporca/data/dxl/minidump/Gist-AOCOTable-NonLossy-BitmapIndexPlan.mdp index 0383166b612b..55de927bb1cf 100644 --- a/src/backend/gporca/data/dxl/minidump/Gist-AOCOTable-NonLossy-BitmapIndexPlan.mdp +++ b/src/backend/gporca/data/dxl/minidump/Gist-AOCOTable-NonLossy-BitmapIndexPlan.mdp @@ -16,18 +16,17 @@ EXPLAIN SELECT id FROM aoco_gist_tbl WHERE b ~= '( (1,2), (3,4) )' ORDER BY id; - QUERY PLAN -Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..0.00 rows=1 width=4) + QUERY PLAN + Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..391.30 rows=1 width=4) Merge Key: id - -> Result (cost=0.00..0.00 rows=1 width=4) - -> Sort (cost=0.00..0.00 rows=1 width=4) - Sort Key: id - -> Bitmap Table Scan on aoco_gist_tbl (cost=0.00..0.00 rows=1 width=4) - Recheck Cond: b ~= '(3,4),(1,2)'::box - -> Bitmap Index Scan on boxindex (cost=0.00..0.00 rows=0 width=0) - Index Cond: b ~= '(3,4),(1,2)'::box - Optimizer status: PQO version 2.65.1 -(10 rows) + -> Sort (cost=0.00..391.30 rows=1 width=4) + Sort Key: id + -> Bitmap Heap Scan on aoco_gist_tbl (cost=0.00..391.30 rows=1 width=4) + Recheck Cond: (b ~= '(3,4),(1,2)'::box) + -> Bitmap Index Scan on boxindex (cost=0.00..0.00 rows=0 width=0) + Index Cond: (b ~= '(3,4),(1,2)'::box) + Optimizer: Pivotal Optimizer (GPORCA) +(9 rows) --> @@ -272,7 +271,7 @@ Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..0.00 rows=1 width=4) - + @@ -282,65 +281,47 @@ Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..0.00 rows=1 width=4) - - + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + diff --git a/src/backend/gporca/libgpopt/include/gpopt/translate/CTranslatorExprToDXL.h b/src/backend/gporca/libgpopt/include/gpopt/translate/CTranslatorExprToDXL.h index b14675ac38c7..e3c84b7a8612 100644 --- a/src/backend/gporca/libgpopt/include/gpopt/translate/CTranslatorExprToDXL.h +++ b/src/backend/gporca/libgpopt/include/gpopt/translate/CTranslatorExprToDXL.h @@ -785,14 +785,6 @@ class CTranslatorExprToDXL // helper to find subplan type from a correlated join expression static EdxlSubPlanType Edxlsubplantype(CExpression *pexprCorrelatedNLJoin); - // add used columns in the bitmap re-check and the remaining scalar filter condition to the - // required output column - static void AddBitmapFilterColumns( - CMemoryPool *mp, CPhysicalScan *pop, CExpression *pexprRecheckCond, - CExpression *pexprScalar, - CColRefSet *pcrsReqdOutput // append the required column reference - ); - public: // ctor CTranslatorExprToDXL(CMemoryPool *mp, CMDAccessor *md_accessor, diff --git a/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp b/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp index 9cadf9f02a89..f11824df674c 100644 --- a/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp +++ b/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp @@ -943,59 +943,6 @@ CTranslatorExprToDXL::PdxlnBitmapTableScan( ); } - -//--------------------------------------------------------------------------- -// @function: -// CTranslatorExprToDXL::AddBitmapFilterColumns -// -// @doc: -// Add used columns in the bitmap recheck and the remaining scalar filter -// condition to the required output column -//--------------------------------------------------------------------------- -void -CTranslatorExprToDXL::AddBitmapFilterColumns( - CMemoryPool *mp, CPhysicalScan *pop, CExpression *pexprRecheckCond, - CExpression *pexprScalar, - CColRefSet *pcrsReqdOutput // append the required column reference -) -{ - GPOS_ASSERT(NULL != pop); - GPOS_ASSERT(COperator::EopPhysicalDynamicBitmapTableScan == pop->Eopid() || - COperator::EopPhysicalBitmapTableScan == pop->Eopid()); - GPOS_ASSERT(NULL != pcrsReqdOutput); - - // compute what additional columns are required in the output of the (Dynamic) Bitmap Table Scan - CColRefSet *pcrsAdditional = GPOS_NEW(mp) CColRefSet(mp); - - if (NULL != pexprRecheckCond) - { - // add the columns used in the recheck condition - pcrsAdditional->Include(pexprRecheckCond->DeriveUsedColumns()); - } - - if (NULL != pexprScalar) - { - // add the columns used in the filter condition - pcrsAdditional->Include(pexprScalar->DeriveUsedColumns()); - } - - CColRefSet *pcrsBitmap = GPOS_NEW(mp) CColRefSet(mp); - pcrsBitmap->Include(pop->PdrgpcrOutput()); - - // only keep the columns that are in the table associated with the bitmap - pcrsAdditional->Intersection(pcrsBitmap); - - if (0 < pcrsAdditional->Size()) - { - pcrsReqdOutput->Include(pcrsAdditional); - } - - // clean up - pcrsAdditional->Release(); - pcrsBitmap->Release(); -} - - //--------------------------------------------------------------------------- // @function: // CTranslatorExprToDXL::PdxlnBitmapTableScan @@ -1056,9 +1003,6 @@ CTranslatorExprToDXL::PdxlnBitmapTableScan( CDXLNode(m_mp, GPOS_NEW(m_mp) CDXLScalarRecheckCondFilter(m_mp), pdxlnRecheckCond); - AddBitmapFilterColumns(m_mp, pop, pexprRecheckCond, pexprScalar, - pcrsOutput); - CDXLNode *proj_list_dxlnode = PdxlnProjList(pcrsOutput, colref_array); // translate bitmap access path @@ -1262,8 +1206,6 @@ CTranslatorExprToDXL::PdxlnDynamicBitmapTableScan( // build projection list CColRefSet *pcrsOutput = pexprScan->Prpp()->PcrsRequired(); - AddBitmapFilterColumns(m_mp, pop, pexprRecheckCond, pexprScalar, - pcrsOutput); CDXLNode *proj_list_dxlnode = PdxlnProjList(pcrsOutput, colref_array); pdxlnScan->AddChild(proj_list_dxlnode); diff --git a/src/test/regress/expected/gporca.out b/src/test/regress/expected/gporca.out index 8742a8849a3f..172a4d1af90e 100644 --- a/src/test/regress/expected/gporca.out +++ b/src/test/regress/expected/gporca.out @@ -14165,6 +14165,65 @@ select count(*) from (select trim(regexp_split_to_table((a)::text, ','::text)) f (1 row) reset optimizer_trace_fallback; +-- Test Bitmap Heap Scan's targetlist contains only necessary attrs, not +-- including ones from Recheck and Filter conditions. +create table material_bitmapscan(i int, j int, k timestamp, l timestamp) +with(appendonly=true) distributed replicated; +create index material_bitmapscan_idx on material_bitmapscan using btree(k); +insert into material_bitmapscan +select i, mod(i, 10), + timestamp '2021-06-01' + interval '1' day * mod(i, 30), + timestamp '2021-06-01' + interval '1' day * mod(i, 30) +from generate_series(1, 10000) i; +-- Bitmap Heap Scan should not contain 'material_bitmapscan.k' and +-- 'material_bitmapscan.l' at the Output list. +explain (costs off, verbose) with mat as( + select i, j from material_bitmapscan + where i = 2 and j = 2 + and k = timestamp '2021-06-03' and l = timestamp '2021-06-03' +) +select m1.i +from mat m1 join mat m2 on m1.j = m2.j; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Gather Motion 1:1 (slice1; segments: 1) + Output: material_bitmapscan.i + -> Hash Join + Output: material_bitmapscan.i + Hash Cond: (material_bitmapscan.j = m2.j) + -> Bitmap Heap Scan on orca.material_bitmapscan + Output: material_bitmapscan.i, material_bitmapscan.j + Recheck Cond: (material_bitmapscan.k = 'Thu Jun 03 00:00:00 2021'::timestamp without time zone) + Filter: ((material_bitmapscan.i = 2) AND (material_bitmapscan.j = 2) AND (material_bitmapscan.l = 'Thu Jun 03 00:00:00 2021'::timestamp without time zone)) + -> Bitmap Index Scan on material_bitmapscan_idx + Index Cond: (material_bitmapscan.k = 'Thu Jun 03 00:00:00 2021'::timestamp without time zone) + -> Hash + Output: m2.j + -> Subquery Scan on m2 + Output: m2.j + -> Bitmap Heap Scan on orca.material_bitmapscan material_bitmapscan_1 + Output: material_bitmapscan_1.i, material_bitmapscan_1.j + Recheck Cond: (material_bitmapscan_1.k = 'Thu Jun 03 00:00:00 2021'::timestamp without time zone) + Filter: ((material_bitmapscan_1.i = 2) AND (material_bitmapscan_1.j = 2) AND (material_bitmapscan_1.l = 'Thu Jun 03 00:00:00 2021'::timestamp without time zone)) + -> Bitmap Index Scan on material_bitmapscan_idx + Index Cond: (material_bitmapscan_1.k = 'Thu Jun 03 00:00:00 2021'::timestamp without time zone) + Optimizer: Postgres query optimizer + Settings: optimizer=off +(23 rows) + +-- There should be one row without any memory access errors. +with mat as( + select i, j from material_bitmapscan + where i = 2 and j = 2 + and k = timestamp '2021-06-03' and l = timestamp '2021-06-03' +) +select m1.i +from mat m1 join mat m2 on m1.j = m2.j; + i +--- + 2 +(1 row) + --- Test if orca can produce the correct plan for CTAS CREATE TABLE dist_tab_a (a varchar(15)) DISTRIBUTED BY(a); INSERT INTO dist_tab_a VALUES('1 '), ('2 '), ('3 '); diff --git a/src/test/regress/expected/gporca_optimizer.out b/src/test/regress/expected/gporca_optimizer.out index 1f2de7070b2d..ac20e72099de 100644 --- a/src/test/regress/expected/gporca_optimizer.out +++ b/src/test/regress/expected/gporca_optimizer.out @@ -13706,9 +13706,9 @@ and first_id in (select first_id from mat_w); -> Shared Scan (share slice:id 1:0) (cost=0.00..387.98 rows=4 width=1) Output: share0_ref1.first_id -> Materialize (cost=0.00..387.98 rows=4 width=1) - Output: material_test.first_id, material_test.second_id + Output: material_test.first_id -> Bitmap Heap Scan on orca.material_test (cost=0.00..387.98 rows=4 width=4) - Output: material_test.first_id, material_test.second_id + Output: material_test.first_id Recheck Cond: (material_test.second_id = ANY ('{1,2,3,4}'::integer[])) -> Bitmap Index Scan on material_test_idx (cost=0.00..0.00 rows=0 width=0) Index Cond: (material_test.second_id = ANY ('{1,2,3,4}'::integer[])) @@ -13729,7 +13729,7 @@ and first_id in (select first_id from mat_w); -> Shared Scan (share slice:id 1:0) (cost=0.00..431.00 rows=4 width=4) Output: share0_ref2.first_id Optimizer: Pivotal Optimizer (GPORCA) - Settings: enable_seqscan=on, optimizer=on + Settings: optimizer=on (31 rows) with mat_w as ( @@ -14419,6 +14419,72 @@ select count(*) from (select trim(regexp_split_to_table((a)::text, ','::text)) f (1 row) reset optimizer_trace_fallback; +-- Test Bitmap Heap Scan's targetlist contains only necessary attrs, not +-- including ones from Recheck and Filter conditions. +create table material_bitmapscan(i int, j int, k timestamp, l timestamp) +with(appendonly=true) distributed replicated; +create index material_bitmapscan_idx on material_bitmapscan using btree(k); +insert into material_bitmapscan +select i, mod(i, 10), + timestamp '2021-06-01' + interval '1' day * mod(i, 30), + timestamp '2021-06-01' + interval '1' day * mod(i, 30) +from generate_series(1, 10000) i; +-- Bitmap Heap Scan should not contain 'material_bitmapscan.k' and +-- 'material_bitmapscan.l' at the Output list. +explain (costs off, verbose) with mat as( + select i, j from material_bitmapscan + where i = 2 and j = 2 + and k = timestamp '2021-06-03' and l = timestamp '2021-06-03' +) +select m1.i +from mat m1 join mat m2 on m1.j = m2.j; + QUERY PLAN +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + Gather Motion 1:1 (slice1; segments: 1) + Output: share0_ref3.i + -> Sequence + Output: share0_ref3.i + -> Shared Scan (share slice:id 1:0) + Output: share0_ref1.i, share0_ref1.j + -> Materialize + Output: material_bitmapscan.i, material_bitmapscan.j + -> Bitmap Heap Scan on orca.material_bitmapscan + Output: material_bitmapscan.i, material_bitmapscan.j + Recheck Cond: (material_bitmapscan.k = 'Thu Jun 03 00:00:00 2021'::timestamp without time zone) + Filter: ((material_bitmapscan.i = 2) AND (material_bitmapscan.j = 2) AND (material_bitmapscan.l = 'Thu Jun 03 00:00:00 2021'::timestamp without time zone)) + -> Bitmap Index Scan on material_bitmapscan_idx + Index Cond: (material_bitmapscan.k = 'Thu Jun 03 00:00:00 2021'::timestamp without time zone) + -> Hash Join + Output: share0_ref3.i + Hash Cond: (share0_ref3.j = share0_ref2.j) + -> Result + Output: share0_ref3.i, share0_ref3.j + Filter: (share0_ref3.j = 2) + -> Shared Scan (share slice:id 1:0) + Output: share0_ref3.i, share0_ref3.j + -> Hash + Output: share0_ref2.j + -> Result + Output: share0_ref2.j + Filter: (share0_ref2.j = 2) + -> Shared Scan (share slice:id 1:0) + Output: share0_ref2.i, share0_ref2.j + Optimizer: Pivotal Optimizer (GPORCA) +(30 rows) + +-- There should be one row without any memory access errors. +with mat as( + select i, j from material_bitmapscan + where i = 2 and j = 2 + and k = timestamp '2021-06-03' and l = timestamp '2021-06-03' +) +select m1.i +from mat m1 join mat m2 on m1.j = m2.j; + i +--- + 2 +(1 row) + --- Test if orca can produce the correct plan for CTAS CREATE TABLE dist_tab_a (a varchar(15)) DISTRIBUTED BY(a); INSERT INTO dist_tab_a VALUES('1 '), ('2 '), ('3 '); diff --git a/src/test/regress/output/qp_gist_indexes2_optimizer.source b/src/test/regress/output/qp_gist_indexes2_optimizer.source index b44abee0e528..e0cea0868236 100644 --- a/src/test/regress/output/qp_gist_indexes2_optimizer.source +++ b/src/test/regress/output/qp_gist_indexes2_optimizer.source @@ -1286,19 +1286,18 @@ SELECT id FROM GistTable1 EXPLAIN (COSTS OFF) SELECT id FROM GistTable1 WHERE property ~= '( (1,2), (3,4) )' ORDER BY id; - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Merge Key: id - -> Result - -> Sort - Sort Key: id - -> Bitmap Heap Scan on gisttable1 - Recheck Cond: (property ~= '(3,4),(1,2)'::box) - -> Bitmap Index Scan on propertyboxindex - Index Cond: (property ~= '(3,4),(1,2)'::box) - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 -(10 rows) + -> Sort + Sort Key: id + -> Bitmap Heap Scan on gisttable1 + Recheck Cond: (property ~= '(3,4),(1,2)'::box) + -> Bitmap Index Scan on propertyboxindex + Index Cond: (property ~= '(3,4),(1,2)'::box) + Optimizer: Pivotal Optimizer (GPORCA) +(9 rows) REINDEX INDEX propertyBoxIndex; SELECT id FROM GistTable1 @@ -1314,19 +1313,18 @@ SELECT id FROM GistTable1 EXPLAIN (COSTS OFF) SELECT id FROM GistTable1 WHERE property ~= '( (1,2), (3,4) )' ORDER BY id; - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Merge Key: id - -> Result - -> Sort - Sort Key: id - -> Bitmap Heap Scan on gisttable1 - Recheck Cond: (property ~= '(3,4),(1,2)'::box) - -> Bitmap Index Scan on propertyboxindex - Index Cond: (property ~= '(3,4),(1,2)'::box) - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 -(10 rows) + -> Sort + Sort Key: id + -> Bitmap Heap Scan on gisttable1 + Recheck Cond: (property ~= '(3,4),(1,2)'::box) + -> Bitmap Index Scan on propertyboxindex + Index Cond: (property ~= '(3,4),(1,2)'::box) + Optimizer: Pivotal Optimizer (GPORCA) +(9 rows) DROP INDEX propertyBoxIndex; -- Obviously, this shouldn't use the index now that the index is gone. @@ -1912,19 +1910,18 @@ SELECT id FROM GistTable1 EXPLAIN (COSTS OFF) SELECT id FROM GistTable1 WHERE property ~= '( (1,2), (3,4) )' ORDER BY id; - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Merge Key: id - -> Result - -> Sort - Sort Key: id - -> Bitmap Heap Scan on gisttable1 - Recheck Cond: (property ~= '(3,4),(1,2)'::box) - -> Bitmap Index Scan on propertyboxindex - Index Cond: (property ~= '(3,4),(1,2)'::box) - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 -(10 rows) + -> Sort + Sort Key: id + -> Bitmap Heap Scan on gisttable1 + Recheck Cond: (property ~= '(3,4),(1,2)'::box) + -> Bitmap Index Scan on propertyboxindex + Index Cond: (property ~= '(3,4),(1,2)'::box) + Optimizer: Pivotal Optimizer (GPORCA) +(9 rows) REINDEX INDEX propertyBoxIndex; SELECT id FROM GistTable1 @@ -1940,19 +1937,18 @@ SELECT id FROM GistTable1 EXPLAIN (COSTS OFF) SELECT id FROM GistTable1 WHERE property ~= '( (1,2), (3,4) )' ORDER BY id; - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Merge Key: id - -> Result - -> Sort - Sort Key: id - -> Bitmap Heap Scan on gisttable1 - Recheck Cond: (property ~= '(3,4),(1,2)'::box) - -> Bitmap Index Scan on propertyboxindex - Index Cond: (property ~= '(3,4),(1,2)'::box) - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 -(10 rows) + -> Sort + Sort Key: id + -> Bitmap Heap Scan on gisttable1 + Recheck Cond: (property ~= '(3,4),(1,2)'::box) + -> Bitmap Index Scan on propertyboxindex + Index Cond: (property ~= '(3,4),(1,2)'::box) + Optimizer: Pivotal Optimizer (GPORCA) +(9 rows) DROP INDEX propertyBoxIndex; -- Obviously, this shouldn't use the index now that the index is gone. @@ -2538,19 +2534,18 @@ SELECT id FROM GistTable1 EXPLAIN (COSTS OFF) SELECT id FROM GistTable1 WHERE property ~= '( (1,2), (3,4) )' ORDER BY id; - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Merge Key: id - -> Result - -> Sort - Sort Key: id - -> Bitmap Heap Scan on gisttable1 - Recheck Cond: (property ~= '(3,4),(1,2)'::box) - -> Bitmap Index Scan on propertyboxindex - Index Cond: (property ~= '(3,4),(1,2)'::box) - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 -(10 rows) + -> Sort + Sort Key: id + -> Bitmap Heap Scan on gisttable1 + Recheck Cond: (property ~= '(3,4),(1,2)'::box) + -> Bitmap Index Scan on propertyboxindex + Index Cond: (property ~= '(3,4),(1,2)'::box) + Optimizer: Pivotal Optimizer (GPORCA) +(9 rows) REINDEX INDEX propertyBoxIndex; SELECT id FROM GistTable1 @@ -2566,19 +2561,18 @@ SELECT id FROM GistTable1 EXPLAIN (COSTS OFF) SELECT id FROM GistTable1 WHERE property ~= '( (1,2), (3,4) )' ORDER BY id; - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Merge Key: id - -> Result - -> Sort - Sort Key: id - -> Bitmap Heap Scan on gisttable1 - Recheck Cond: (property ~= '(3,4),(1,2)'::box) - -> Bitmap Index Scan on propertyboxindex - Index Cond: (property ~= '(3,4),(1,2)'::box) - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 -(10 rows) + -> Sort + Sort Key: id + -> Bitmap Heap Scan on gisttable1 + Recheck Cond: (property ~= '(3,4),(1,2)'::box) + -> Bitmap Index Scan on propertyboxindex + Index Cond: (property ~= '(3,4),(1,2)'::box) + Optimizer: Pivotal Optimizer (GPORCA) +(9 rows) DROP INDEX propertyBoxIndex; -- Obviously, this shouldn't use the index now that the index is gone. @@ -3164,19 +3158,18 @@ SELECT id FROM GistTable1 EXPLAIN (COSTS OFF) SELECT id FROM GistTable1 WHERE property ~= '( (1,2), (3,4) )' ORDER BY id; - QUERY PLAN ----------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Merge Key: id - -> Result - -> Sort - Sort Key: id - -> Bitmap Heap Scan on gisttable1 - Recheck Cond: (property ~= '(3,4),(1,2)'::box) - -> Bitmap Index Scan on propertyboxindex - Index Cond: (property ~= '(3,4),(1,2)'::box) - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 -(10 rows) + -> Sort + Sort Key: id + -> Bitmap Heap Scan on gisttable1 + Recheck Cond: (property ~= '(3,4),(1,2)'::box) + -> Bitmap Index Scan on propertyboxindex + Index Cond: (property ~= '(3,4),(1,2)'::box) + Optimizer: Pivotal Optimizer (GPORCA) +(9 rows) REINDEX INDEX propertyBoxIndex; SELECT id FROM GistTable1 @@ -3192,19 +3185,18 @@ SELECT id FROM GistTable1 EXPLAIN (COSTS OFF) SELECT id FROM GistTable1 WHERE property ~= '( (1,2), (3,4) )' ORDER BY id; - QUERY PLAN ------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------ Gather Motion 3:1 (slice1; segments: 3) Merge Key: id - -> Result - -> Sort - Sort Key: id - -> Bitmap Heap Scan on gisttable1 - Recheck Cond: (property ~= '(3,4),(1,2)'::box) - -> Bitmap Index Scan on propertyboxindex - Index Cond: (property ~= '(3,4),(1,2)'::box) - Optimizer: Pivotal Optimizer (GPORCA) version 2.74.0 -(10 rows) + -> Sort + Sort Key: id + -> Bitmap Heap Scan on gisttable1 + Recheck Cond: (property ~= '(3,4),(1,2)'::box) + -> Bitmap Index Scan on propertyboxindex + Index Cond: (property ~= '(3,4),(1,2)'::box) + Optimizer: Pivotal Optimizer (GPORCA) +(9 rows) DROP INDEX propertyBoxIndex; -- Obviously, this shouldn't use the index now that the index is gone. diff --git a/src/test/regress/sql/gporca.sql b/src/test/regress/sql/gporca.sql index 69a654ea0a9d..3b709b3ba819 100644 --- a/src/test/regress/sql/gporca.sql +++ b/src/test/regress/sql/gporca.sql @@ -3171,6 +3171,34 @@ select count(*) from (select trim(regexp_split_to_table((a)::text, ','::text)) f reset optimizer_trace_fallback; +-- Test Bitmap Heap Scan's targetlist contains only necessary attrs, not +-- including ones from Recheck and Filter conditions. +create table material_bitmapscan(i int, j int, k timestamp, l timestamp) +with(appendonly=true) distributed replicated; +create index material_bitmapscan_idx on material_bitmapscan using btree(k); +insert into material_bitmapscan +select i, mod(i, 10), + timestamp '2021-06-01' + interval '1' day * mod(i, 30), + timestamp '2021-06-01' + interval '1' day * mod(i, 30) +from generate_series(1, 10000) i; +-- Bitmap Heap Scan should not contain 'material_bitmapscan.k' and +-- 'material_bitmapscan.l' at the Output list. +explain (costs off, verbose) with mat as( + select i, j from material_bitmapscan + where i = 2 and j = 2 + and k = timestamp '2021-06-03' and l = timestamp '2021-06-03' +) +select m1.i +from mat m1 join mat m2 on m1.j = m2.j; +-- There should be one row without any memory access errors. +with mat as( + select i, j from material_bitmapscan + where i = 2 and j = 2 + and k = timestamp '2021-06-03' and l = timestamp '2021-06-03' +) +select m1.i +from mat m1 join mat m2 on m1.j = m2.j; + --- Test if orca can produce the correct plan for CTAS CREATE TABLE dist_tab_a (a varchar(15)) DISTRIBUTED BY(a); INSERT INTO dist_tab_a VALUES('1 '), ('2 '), ('3 ');