This is an automated email from the ASF dual-hosted git repository. reshke pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/cloudberry.git
commit 7e59649b4027f495f2b99cbc5854aef54765f1bc Author: David Kimura <[email protected]> AuthorDate: Mon Oct 16 11:31:25 2023 -0700 [ORCA] Fix bug checking index_can_return() (#16575) ORCA uses index_can_return() to check whether an index can return a given column's data. The result determines whether an index-only-scan plan is allowed. The function uses attno, however ORCA erroneously passed the column number instead. This caused ORCA to incorrectly allow an index-only-scan plan. See get_relation_info() usage of index_can_return() attno for PLANNER. --- .../gpopt/translate/CTranslatorRelcacheToDXL.cpp | 2 +- src/test/regress/expected/gp_covering_index.out | 32 +++++++++++++++++++ .../expected/gp_covering_index_optimizer.out | 36 ++++++++++++++++++++++ src/test/regress/sql/gp_covering_index.sql | 21 +++++++++++++ 4 files changed, 90 insertions(+), 1 deletion(-) diff --git a/src/backend/gpopt/translate/CTranslatorRelcacheToDXL.cpp b/src/backend/gpopt/translate/CTranslatorRelcacheToDXL.cpp index a2d7b2608e..26915d7c27 100644 --- a/src/backend/gpopt/translate/CTranslatorRelcacheToDXL.cpp +++ b/src/backend/gpopt/translate/CTranslatorRelcacheToDXL.cpp @@ -1063,7 +1063,7 @@ CTranslatorRelcacheToDXL::RetrieveIndex(CMemoryPool *mp, } // check if index can return column for index-only scans - if (gpdb::IndexCanReturn(index_rel.get(), attno)) + if (gpdb::IndexCanReturn(index_rel.get(), i + 1)) { returnable_cols->Append( GPOS_NEW(mp) ULONG(GetAttributePosition(attno, attno_mapping))); diff --git a/src/test/regress/expected/gp_covering_index.out b/src/test/regress/expected/gp_covering_index.out index 357101464e..e642677ea2 100644 --- a/src/test/regress/expected/gp_covering_index.out +++ b/src/test/regress/expected/gp_covering_index.out @@ -707,6 +707,38 @@ SELECT a, b FROM test_index_types WHERE a<@ box '(0,0,3,3)'; Optimizer: Postgres query optimizer (5 rows) +-- KEYS: [a] INCLUDED: [] +CREATE TABLE tsvector_table(t text, a tsvector) DISTRIBUTED BY (t); +INSERT INTO tsvector_table values('\n', ''); +CREATE INDEX a_gist_index ON tsvector_table USING GIST (a); +-- Check index-only-scan is not used when index can not return column +SET optimizer_enable_indexscan=off; +SET optimizer_enable_bitmapscan=off; +SET optimizer_enable_tablescan=off; +-- expect fallback +EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF, SUMMARY OFF) +SELECT count(*) FROM tsvector_table WHERE a @@ 'w:*|q:*'; + QUERY PLAN +----------------------------------------------------------------------------------- + Finalize Aggregate (actual rows=1 loops=1) + -> Gather Motion 3:1 (slice1; segments: 3) (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Bitmap Heap Scan on tsvector_table (actual rows=0 loops=1) + Recheck Cond: (a @@ '''w'':* | ''q'':*'::tsquery) + -> Bitmap Index Scan on a_gist_index (actual rows=1 loops=1) + Index Cond: (a @@ '''w'':* | ''q'':*'::tsquery) + Optimizer: Postgres-based planner +(8 rows) + +SELECT count(*) FROM tsvector_table WHERE a @@ 'w:*|q:*'; + count +------- + 0 +(1 row) + +RESET optimizer_enable_indexscan; +RESET optimizer_enable_bitmapscan; +RESET optimizer_enable_tablescan; -- KEYS: [a] INCLUDED: [b] -- Check support dynamic-index-only-scan on GIST indexes CREATE TABLE test_partition_table_with_gist_index(a int, b_box box) diff --git a/src/test/regress/expected/gp_covering_index_optimizer.out b/src/test/regress/expected/gp_covering_index_optimizer.out index db1ebcf468..b02ee1d954 100644 --- a/src/test/regress/expected/gp_covering_index_optimizer.out +++ b/src/test/regress/expected/gp_covering_index_optimizer.out @@ -678,6 +678,42 @@ SELECT a, b FROM test_index_types WHERE a<@ box '(0,0,3,3)'; Optimizer: Pivotal Optimizer (GPORCA) (5 rows) +-- KEYS: [a] INCLUDED: [] +CREATE TABLE tsvector_table(t text, a tsvector) DISTRIBUTED BY (t); +INSERT INTO tsvector_table values('\n', ''); +CREATE INDEX a_gist_index ON tsvector_table USING GIST (a); +-- Check index-only-scan is not used when index can not return column +SET optimizer_enable_indexscan=off; +SET optimizer_enable_bitmapscan=off; +SET optimizer_enable_tablescan=off; +-- expect fallback +EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF, SUMMARY OFF) +SELECT count(*) FROM tsvector_table WHERE a @@ 'w:*|q:*'; +INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner +DETAIL: Falling back to Postgres-based planner because no plan has been computed for required properties in GPORCA + QUERY PLAN +----------------------------------------------------------------------------------- + Finalize Aggregate (actual rows=1 loops=1) + -> Gather Motion 3:1 (slice1; segments: 3) (actual rows=3 loops=1) + -> Partial Aggregate (actual rows=1 loops=1) + -> Bitmap Heap Scan on tsvector_table (actual rows=0 loops=1) + Recheck Cond: (a @@ '''w'':* | ''q'':*'::tsquery) + -> Bitmap Index Scan on a_gist_index (actual rows=1 loops=1) + Index Cond: (a @@ '''w'':* | ''q'':*'::tsquery) + Optimizer: Postgres-based planner +(8 rows) + +SELECT count(*) FROM tsvector_table WHERE a @@ 'w:*|q:*'; +INFO: GPORCA failed to produce a plan, falling back to Postgres-based planner +DETAIL: Falling back to Postgres-based planner because no plan has been computed for required properties in GPORCA + count +------- + 0 +(1 row) + +RESET optimizer_enable_indexscan; +RESET optimizer_enable_bitmapscan; +RESET optimizer_enable_tablescan; -- KEYS: [a] INCLUDED: [b] -- Check support dynamic-index-only-scan on GIST indexes CREATE TABLE test_partition_table_with_gist_index(a int, b_box box) diff --git a/src/test/regress/sql/gp_covering_index.sql b/src/test/regress/sql/gp_covering_index.sql index 7e61c136cf..2bcdce6500 100644 --- a/src/test/regress/sql/gp_covering_index.sql +++ b/src/test/regress/sql/gp_covering_index.sql @@ -361,6 +361,27 @@ VACUUM ANALYZE test_index_types; EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF, SUMMARY OFF) SELECT a, b FROM test_index_types WHERE a<@ box '(0,0,3,3)'; +-- KEYS: [a] INCLUDED: [] +CREATE TABLE tsvector_table(t text, a tsvector) DISTRIBUTED BY (t); +INSERT INTO tsvector_table values('\n', ''); +CREATE INDEX a_gist_index ON tsvector_table USING GIST (a); + +-- Check index-only-scan is not used when index can not return column +SET optimizer_enable_indexscan=off; +SET optimizer_enable_bitmapscan=off; +SET optimizer_enable_tablescan=off; + +-- expect fallback +EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF, SUMMARY OFF) +SELECT count(*) FROM tsvector_table WHERE a @@ 'w:*|q:*'; +SELECT count(*) FROM tsvector_table WHERE a @@ 'w:*|q:*'; + +RESET optimizer_enable_indexscan; +RESET optimizer_enable_bitmapscan; +RESET optimizer_enable_tablescan; + + + -- KEYS: [a] INCLUDED: [b] -- Check support dynamic-index-only-scan on GIST indexes CREATE TABLE test_partition_table_with_gist_index(a int, b_box box) --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
