diff --git a/src/backend/gpopt/translate/CTranslatorRelcacheToDXL.cpp b/src/backend/gpopt/translate/CTranslatorRelcacheToDXL.cpp index 6a5d679a11f..ee4b8888b19 100644 --- a/src/backend/gpopt/translate/CTranslatorRelcacheToDXL.cpp +++ b/src/backend/gpopt/translate/CTranslatorRelcacheToDXL.cpp @@ -3147,6 +3147,20 @@ CTranslatorRelcacheToDXL::RetrieveStorageTypeForPartitionedTable(Relation rel) "Queries with partitions of greenplum_fdw are not supported")); } GPOS_DELETE(fdw_name_str); + + // Check for mixed storage before continuing + // If we already encountered non-foreign partitions, mark as mixed + if (rel_storage_type != IMDRelation::ErelstorageSentinel && + rel_storage_type != IMDRelation::ErelstorageForeign) + { + // Already have non-foreign partition(s), now found foreign → mixed + rel_storage_type = IMDRelation::ErelstorageMixedPartitioned; + } + else if (rel_storage_type == IMDRelation::ErelstorageSentinel) + { + // First partition is foreign + rel_storage_type = IMDRelation::ErelstorageForeign; + } continue; } all_foreign = false; @@ -3154,11 +3168,15 @@ CTranslatorRelcacheToDXL::RetrieveStorageTypeForPartitionedTable(Relation rel) { rel_storage_type = child_storage; } - + else if (rel_storage_type == IMDRelation::ErelstorageForeign) + { + // Previously had foreign partition(s), now found non-foreign → mixed + rel_storage_type = IMDRelation::ErelstorageMixedPartitioned; + } // mark any partitioned table with supported partitions of mixed storage types, // this is more conservative for certain skans (eg: we can't do an index scan if any // partition is ao, we must only do a sequential or bitmap scan) - if (rel_storage_type != child_storage) + else if (rel_storage_type != child_storage) { rel_storage_type = IMDRelation::ErelstorageMixedPartitioned; } diff --git a/src/backend/gporca/data/dxl/minidump/MixedPartitioned-ForeignHeap-Test.mdp b/src/backend/gporca/data/dxl/minidump/MixedPartitioned-ForeignHeap-Test.mdp new file mode 100644 index 00000000000..181df7b0262 --- /dev/null +++ b/src/backend/gporca/data/dxl/minidump/MixedPartitioned-ForeignHeap-Test.mdp @@ -0,0 +1,17 @@ + + +Objective: Test RetrieveStorageTypeForPartitionedTable with Foreign + Heap partitions +Expected: StorageType="MixedPartitioned" + +Original query: +create table part (a int, b int) partition by range (b); +create external table p1_e (a int, b int) location ('file://...') format 'csv'; +create external table p2_e (a int, b int) location ('file://...') format 'csv'; +alter table part attach partition p1_e for values from (0) to (10); +alter table part attach partition p2_e for values from (10) to (19); +create table p3 (a int, b int) distributed by (a); +create table p4 (a int, b int) distributed by (a); +alter table part attach partition p3 for values from (20) to (30); +alter table part attach partition p4 for values from (30) to (40); +SELECT * FROM part; + \ No newline at end of file diff --git a/src/backend/gporca/server/CMakeLists.txt b/src/backend/gporca/server/CMakeLists.txt index 3c7b52cda91..7e6a4980479 100644 --- a/src/backend/gporca/server/CMakeLists.txt +++ b/src/backend/gporca/server/CMakeLists.txt @@ -420,7 +420,7 @@ Hint-Leading-Multiple Hint-Leading-Directed Hint-Leading-NonDirected Hint-FullHashJoin-JoinType Hint-FullMergeJoin-JoinType Hint-IndexHashJoin-JoinType Hint-IndexNestLoop-JoinType; CForeignPartTest: -ForeignPartUniform PartForeignMixed PartForeignDifferentServer PartForeignDifferentExecLocation PartForeignMixedDPE PartForeignMixedSPE PartForeignUniformSPE ForeignScanExecLocAnySimpleScan ForeignScanExecLocAnyJoin ForeignPartOneTimeFilterDPE; +ForeignPartUniform PartForeignMixed PartForeignDifferentServer PartForeignDifferentExecLocation PartForeignMixedDPE PartForeignMixedSPE PartForeignUniformSPE ForeignScanExecLocAnySimpleScan ForeignScanExecLocAnyJoin ForeignPartOneTimeFilterDPE MixedPartitioned-ForeignHeap-Test; CCardinalityTest: SystemColCtidStats SystemColSegIdStats