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]

Reply via email to