This is an automated email from the ASF dual-hosted git repository.

maxyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git

commit 9178c9f6dc0708bfcfd7dde45aa49104ab3eeb55
Author: Alexey Gordeev <[email protected]>
AuthorDate: Fri Jun 24 23:36:16 2022 +0500

    Fallback to Postgres optimizer on empty target list in CTE producer
    
    greenplum-db/gpdb-postgres-merge@98154a8f6c47fc6007638ffe84e7ae8999b19f2a 
and
    a8bb542fb8de88682bbfb18de0dbab0200674307 started a small refactoring, which
    pointed that we have a lot of `NULL != target_list` asserts to be 
appropriately
    replaced. There is a new case which cause SIGSEGV on builds without asserts 
-
    empty target list in CTE producer. From now, we fallback to Postgres 
optimizer
    in such case.
---
 .../gpopt/translate/CTranslatorQueryToDXL.cpp       | 10 ++++++++--
 src/test/regress/expected/gporca.out                | 19 +++++++++++++++++++
 src/test/regress/expected/gporca_optimizer.out      | 21 +++++++++++++++++++++
 src/test/regress/sql/gporca.sql                     | 14 ++++++++++++++
 4 files changed, 62 insertions(+), 2 deletions(-)

diff --git a/src/backend/gpopt/translate/CTranslatorQueryToDXL.cpp 
b/src/backend/gpopt/translate/CTranslatorQueryToDXL.cpp
index d4b9052b30..d959f85b21 100644
--- a/src/backend/gpopt/translate/CTranslatorQueryToDXL.cpp
+++ b/src/backend/gpopt/translate/CTranslatorQueryToDXL.cpp
@@ -3800,8 +3800,14 @@ CTranslatorQueryToDXL::TranslateCTEToDXL(const 
RangeTblEntry *rte,
        const List *cte_producer_target_list =
                cte_list_entry->GetCTEProducerTargetList(rte->ctename);
 
-       GPOS_ASSERT(nullptr != cte_producer_dxlnode &&
-                               nullptr != cte_producer_target_list);
+       // fallback to Postgres optimizer in case of empty target list
+       if (NIL == cte_producer_target_list)
+       {
+               GPOS_RAISE(gpdxl::ExmaDXL, 
gpdxl::ExmiQuery2DXLUnsupportedFeature,
+                                  GPOS_WSZ_LIT("Empty target list"));
+       }
+
+       GPOS_ASSERT(nullptr != cte_producer_dxlnode);
 
        CDXLLogicalCTEProducer *cte_producer_dxlop =
                
CDXLLogicalCTEProducer::Cast(cte_producer_dxlnode->GetOperator());
diff --git a/src/test/regress/expected/gporca.out 
b/src/test/regress/expected/gporca.out
index 3202b8c186..619eda6cca 100644
--- a/src/test/regress/expected/gporca.out
+++ b/src/test/regress/expected/gporca.out
@@ -14614,3 +14614,22 @@ select c from mix_func_cast();
  t
 (1 row)
 
+-- the query with empty CTE producer target list should fall back to Postgres
+-- optimizer without any error on build without asserts
+drop table if exists empty_cte_tl_test;
+NOTICE:  table "empty_cte_tl_test" does not exist, skipping
+create table empty_cte_tl_test(id int);
+NOTICE:  Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' 
as the Greenplum Database data distribution key for this table.
+HINT:  The 'DISTRIBUTED BY' clause determines the distribution of data. Make 
sure column(s) chosen are the optimal data distribution key to minimize skew.
+set optimizer_trace_fallback = on;
+with cte as (
+  select from empty_cte_tl_test
+)
+select * 
+from empty_cte_tl_test
+where id in(select id from cte);
+ id 
+----
+(0 rows)
+
+reset optimizer_trace_fallback;
diff --git a/src/test/regress/expected/gporca_optimizer.out 
b/src/test/regress/expected/gporca_optimizer.out
index 1a679609e4..db42c71fca 100644
--- a/src/test/regress/expected/gporca_optimizer.out
+++ b/src/test/regress/expected/gporca_optimizer.out
@@ -14849,3 +14849,24 @@ select c from mix_func_cast();
  t
 (1 row)
 
+-- the query with empty CTE producer target list should fall back to Postgres
+-- optimizer without any error on build without asserts
+drop table if exists empty_cte_tl_test;
+NOTICE:  table "empty_cte_tl_test" does not exist, skipping
+create table empty_cte_tl_test(id int);
+NOTICE:  Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' 
as the Greenplum Database data distribution key for this table.
+HINT:  The 'DISTRIBUTED BY' clause determines the distribution of data. Make 
sure column(s) chosen are the optimal data distribution key to minimize skew.
+set optimizer_trace_fallback = on;
+with cte as (
+  select from empty_cte_tl_test
+)
+select * 
+from empty_cte_tl_test
+where id in(select id from cte);
+INFO:  GPORCA failed to produce a plan, falling back to planner
+DETAIL:  Feature not supported: Empty target list
+ id 
+----
+(0 rows)
+
+reset optimizer_trace_fallback;
diff --git a/src/test/regress/sql/gporca.sql b/src/test/regress/sql/gporca.sql
index 100ba7a4e0..c87d9929de 100644
--- a/src/test/regress/sql/gporca.sql
+++ b/src/test/regress/sql/gporca.sql
@@ -3592,6 +3592,20 @@ select a from mix_func_cast();
 select b from mix_func_cast();
 select c from mix_func_cast();
 
+-- the query with empty CTE producer target list should fall back to Postgres
+-- optimizer without any error on build without asserts
+drop table if exists empty_cte_tl_test;
+create table empty_cte_tl_test(id int);
+
+set optimizer_trace_fallback = on;
+with cte as (
+  select from empty_cte_tl_test
+)
+select * 
+from empty_cte_tl_test
+where id in(select id from cte);
+reset optimizer_trace_fallback;
+
 -- start_ignore
 DROP SCHEMA orca CASCADE;
 -- end_ignore


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to