From 6b1ceda8c5064486171f7689e7e3edc6499a23ee Mon Sep 17 00:00:00 2001 From: Hao Wu Date: Wed, 3 Jun 2026 09:40:40 +0000 Subject: [PATCH] PAX/toast: aux's TOAST goes to pg_toast, aux itself clamped to PERMANENT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two related changes that together make PAX aux toasting match the rest of the Cloudberry / Postgres tree: 1. src/backend/catalog/toasting.c Drop the Cloudberry-only branch that routed TOAST for pg_ext_aux parents back into pg_ext_aux: else if (IsExtAuxNamespace(rel->rd_rel->relnamespace)) namespaceid = PG_EXTAUX_NAMESPACE; PAX aux tables (pg_pax_blocks_) now get a normal TOAST companion in pg_toast, the same as every other heap. 2. contrib/pax_storage/.../pax_aux_table.cc Aux inherits the parent's persistence for PERMANENT / UNLOGGED verbatim, but TEMP is clamped down to PERMANENT. Background: the aux always lives in pg_ext_aux (not in pg_temp_), so a TEMP-persistence row in pg_ext_aux ends up mis-classified by RELATION_IS_OTHER_TEMP — relcache.c sets rd_islocaltemp=false because pg_ext_aux is not a temp namespace, and then reindex_index() (or any catalog walk that touches the aux) bails with "cannot reindex temporary tables of other sessions". Clamping TEMP→PERMANENT avoids the mis-trigger; the trade-off is that the aux of a TEMP PAX table outlives the session, which is acceptable given the long-standing FIXME in the same file ("temporary table in aux namespace is not supported yet"). Resulting layout: PERMANENT pax_tab aux in pg_ext_aux (p) toast in pg_toast (p) idx in pg_toast (p) UNLOGGED u_pax aux in pg_ext_aux (u) toast in pg_toast (u) idx in pg_toast (u) TEMP pax_tmp parent in pg_temp_ (t) aux in pg_ext_aux (p) <-- clamped toast in pg_toast (p) idx in pg_toast (p) Verified: - CREATE TABLE / UNLOGGED / TEMP USING pax all produce the layout above. - INSERT round-trip works for all three persistence modes. --- .../src/cpp/catalog/pax_aux_table.cc | 25 ++++++++++++++++--- src/backend/catalog/toasting.c | 9 +++++-- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/contrib/pax_storage/src/cpp/catalog/pax_aux_table.cc b/contrib/pax_storage/src/cpp/catalog/pax_aux_table.cc index c01d046c3b8..eb274d9ee8d 100644 --- a/contrib/pax_storage/src/cpp/catalog/pax_aux_table.cc +++ b/contrib/pax_storage/src/cpp/catalog/pax_aux_table.cc @@ -89,6 +89,11 @@ void CPaxCreateMicroPartitionTable(Relation rel) { pax_relid = RelationGetRelid(rel); // 1. create blocks table. + // + // The aux relation always lives in pg_ext_aux, regardless of the + // parent's persistence. See the persistence selection comment on + // the heap_create_with_catalog call below for why TEMP parents' + // aux is clamped to PERMANENT rather than passed through. snprintf(aux_relname, sizeof(aux_relname), "pg_pax_blocks_%u", pax_relid); aux_namespace_id = PG_EXTAUX_NAMESPACE; aux_relid = GetNewOidForRelation(pg_class_desc, ClassOidIndexId, @@ -121,14 +126,26 @@ void CPaxCreateMicroPartitionTable(Relation rel) { attr->attnotnull = true; } - // FIXME: temporary table in aux namespace is not supported yet. + /* + * Aux inherits the parent's persistence for PERMANENT / UNLOGGED. + * TEMP is clamped down to PERMANENT: the aux lives in pg_ext_aux + * (NOT in pg_temp_), so a TEMP-persistence row there would + * mis-trigger RELATION_IS_OTHER_TEMP — relcache sets + * rd_islocaltemp=false because pg_ext_aux is not a temp namespace, + * and any reindex_index() path on the aux (or anything that walks + * the catalog and stumbles on it) bails with "cannot reindex + * temporary tables of other sessions". Clamping to PERMANENT + * avoids that mis-classification; the trade-off is that the aux + * of a TEMP PAX table outlives the session (already a known + * limitation — see the long-standing FIXME further up the file). + */ relid = heap_create_with_catalog( aux_relname, aux_namespace_id, InvalidOid, aux_relid, InvalidOid, InvalidOid, rel->rd_rel->relowner, HEAP_TABLE_AM_OID, tupdesc, NIL, RELKIND_RELATION, - rel->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED - ? RELPERSISTENCE_UNLOGGED - : RELPERSISTENCE_PERMANENT, + rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP + ? RELPERSISTENCE_PERMANENT + : rel->rd_rel->relpersistence, rel->rd_rel->relisshared, RelationIsMapped(rel), ONCOMMIT_NOOP, NULL, /* GP Policy */ (Datum)0, false, /* use _user_acl */ diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c index 9814aa4eb63..17d87f49360 100644 --- a/src/backend/catalog/toasting.c +++ b/src/backend/catalog/toasting.c @@ -167,11 +167,16 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, /* * Toast tables for regular relations go in pg_toast; those for temp * relations go into the per-backend temp-toast-table namespace. + * + * Cloudberry used to have a third branch here that routed TOAST + * for relations whose parent namespace was pg_ext_aux back into + * pg_ext_aux too — this was inconsistent with how every other + * Cloudberry / Postgres relation handles toasting. Treat + * pg_ext_aux parents like any other regular schema; their TOAST + * lands in pg_toast. */ if (isTempOrTempToastNamespace(rel->rd_rel->relnamespace)) namespaceid = GetTempToastNamespace(); - else if (IsExtAuxNamespace(rel->rd_rel->relnamespace)) - namespaceid = PG_EXTAUX_NAMESPACE; else namespaceid = PG_TOAST_NAMESPACE;