From d3578205eff16b8493e2039db0d5e6ce4cf80e5a Mon Sep 17 00:00:00 2001 From: Maksim Melnikov Date: Fri, 31 Oct 2025 13:08:36 +0300 Subject: [PATCH] Columnar temp tables cannot be accessed(#8235). After PG vanilla commit ab874faaa1f, RelidByRelfilenumber logic was changed, now for temp objects its return O oid. For such cases we can use alternative approach with keeping temp relations oids directly. --- src/backend/columnar/columnar_customscan.c | 6 +-- src/backend/columnar/columnar_metadata.c | 48 ++++++++++++------- src/backend/columnar/columnar_reader.c | 6 +-- src/backend/columnar/columnar_tableam.c | 20 ++++---- src/backend/columnar/columnar_writer.c | 26 +++++----- src/backend/columnar/write_state_management.c | 3 +- src/include/columnar/columnar.h | 13 ++--- src/include/columnar/columnar_metadata.h | 2 +- src/include/pg_version_compat.h | 3 +- 9 files changed, 68 insertions(+), 59 deletions(-) diff --git a/src/backend/columnar/columnar_customscan.c b/src/backend/columnar/columnar_customscan.c index 5e5410116..d97f4cdeb 100644 --- a/src/backend/columnar/columnar_customscan.c +++ b/src/backend/columnar/columnar_customscan.c @@ -1556,8 +1556,7 @@ ColumnarPerStripeScanCost(RelOptInfo *rel, Oid relationId, int numberOfColumnsRe ereport(ERROR, (errmsg("could not open relation with OID %u", relationId))); } - List *stripeList = StripesForRelfilelocator(RelationPhysicalIdentifier_compat( - relation)); + List *stripeList = StripesForRelfilelocator(relation); RelationClose(relation); uint32 maxColumnCount = 0; @@ -1614,8 +1613,7 @@ ColumnarTableStripeCount(Oid relationId) ereport(ERROR, (errmsg("could not open relation with OID %u", relationId))); } - List *stripeList = StripesForRelfilelocator(RelationPhysicalIdentifier_compat( - relation)); + List *stripeList = StripesForRelfilelocator(relation); int stripeCount = list_length(stripeList); RelationClose(relation); diff --git a/src/backend/columnar/columnar_metadata.c b/src/backend/columnar/columnar_metadata.c index 52b1082d7..fb62cbfcb 100644 --- a/src/backend/columnar/columnar_metadata.c +++ b/src/backend/columnar/columnar_metadata.c @@ -125,7 +125,7 @@ static Oid ColumnarChunkGroupRelationId(void); static Oid ColumnarChunkIndexRelationId(void); static Oid ColumnarChunkGroupIndexRelationId(void); static Oid ColumnarNamespaceId(void); -static uint64 LookupStorageId(RelFileLocator relfilelocator); +static uint64 LookupStorageId(Oid relationId, RelFileLocator relfilelocator); static uint64 GetHighestUsedRowNumber(uint64 storageId); static void DeleteStorageFromColumnarMetadataTable(Oid metadataTableId, AttrNumber storageIdAtrrNumber, @@ -606,7 +606,7 @@ ReadColumnarOptions(Oid regclass, ColumnarOptions *options) * of columnar.chunk. */ void -SaveStripeSkipList(RelFileLocator relfilelocator, uint64 stripe, +SaveStripeSkipList(Oid relid, RelFileLocator relfilelocator, uint64 stripe, StripeSkipList *chunkList, TupleDesc tupleDescriptor) { @@ -614,7 +614,7 @@ SaveStripeSkipList(RelFileLocator relfilelocator, uint64 stripe, uint32 chunkIndex = 0; uint32 columnCount = chunkList->columnCount; - uint64 storageId = LookupStorageId(relfilelocator); + uint64 storageId = LookupStorageId(relid, relfilelocator); Oid columnarChunkOid = ColumnarChunkRelationId(); Relation columnarChunk = table_open(columnarChunkOid, RowExclusiveLock); ModifyState *modifyState = StartModifyRelation(columnarChunk); @@ -684,10 +684,10 @@ SaveStripeSkipList(RelFileLocator relfilelocator, uint64 stripe, * SaveChunkGroups saves the metadata for given chunk groups in columnar.chunk_group. */ void -SaveChunkGroups(RelFileLocator relfilelocator, uint64 stripe, +SaveChunkGroups(Oid relid, RelFileLocator relfilelocator, uint64 stripe, List *chunkGroupRowCounts) { - uint64 storageId = LookupStorageId(relfilelocator); + uint64 storageId = LookupStorageId(relid, relfilelocator); Oid columnarChunkGroupOid = ColumnarChunkGroupRelationId(); Relation columnarChunkGroup = table_open(columnarChunkGroupOid, RowExclusiveLock); ModifyState *modifyState = StartModifyRelation(columnarChunkGroup); @@ -720,7 +720,7 @@ SaveChunkGroups(RelFileLocator relfilelocator, uint64 stripe, * ReadStripeSkipList fetches chunk metadata for a given stripe. */ StripeSkipList * -ReadStripeSkipList(RelFileLocator relfilelocator, uint64 stripe, +ReadStripeSkipList(Relation rel, uint64 stripe, TupleDesc tupleDescriptor, uint32 chunkCount, Snapshot snapshot) { @@ -729,7 +729,8 @@ ReadStripeSkipList(RelFileLocator relfilelocator, uint64 stripe, uint32 columnCount = tupleDescriptor->natts; ScanKeyData scanKey[2]; - uint64 storageId = LookupStorageId(relfilelocator); + uint64 storageId = LookupStorageId(RelationPrecomputeOid_compat(rel), + RelationPhysicalIdentifier_compat(rel)); Oid columnarChunkOid = ColumnarChunkRelationId(); Relation columnarChunk = table_open(columnarChunkOid, AccessShareLock); @@ -1273,9 +1274,10 @@ InsertEmptyStripeMetadataRow(uint64 storageId, uint64 stripeId, uint32 columnCou * of the given relfilenode. */ List * -StripesForRelfilelocator(RelFileLocator relfilelocator) +StripesForRelfilelocator(Relation rel) { - uint64 storageId = LookupStorageId(relfilelocator); + uint64 storageId = LookupStorageId(RelationPrecomputeOid_compat(rel), + RelationPhysicalIdentifier_compat(rel)); /* * PG18 requires snapshot to be active or registered before it's used @@ -1304,9 +1306,10 @@ StripesForRelfilelocator(RelFileLocator relfilelocator) * returns 0. */ uint64 -GetHighestUsedAddress(RelFileLocator relfilelocator) +GetHighestUsedAddress(Relation rel) { - uint64 storageId = LookupStorageId(relfilelocator); + uint64 storageId = LookupStorageId(RelationPrecomputeOid_compat(rel), + RelationPhysicalIdentifier_compat(rel)); uint64 highestUsedAddress = 0; uint64 highestUsedId = 0; @@ -1316,6 +1319,16 @@ GetHighestUsedAddress(RelFileLocator relfilelocator) } +Oid +ColumnarRelationId(Oid relid, RelFileLocator relfilelocator) +{ + return OidIsValid(relid) ? relid : RelidByRelfilenumber(RelationTablespace_compat( + relfilelocator), + RelationPhysicalIdentifierNumber_compat( + relfilelocator)); +} + + /* * GetHighestUsedAddressAndId returns the highest used address and id for * the given relfilenode across all active and inactive transactions. @@ -1591,7 +1604,7 @@ BuildStripeMetadata(Relation columnarStripes, HeapTuple heapTuple) * metadata tables. */ void -DeleteMetadataRows(RelFileLocator relfilelocator) +DeleteMetadataRows(Relation rel) { /* * During a restore for binary upgrade, metadata tables and indexes may or @@ -1602,7 +1615,8 @@ DeleteMetadataRows(RelFileLocator relfilelocator) return; } - uint64 storageId = LookupStorageId(relfilelocator); + uint64 storageId = LookupStorageId(RelationPrecomputeOid_compat(rel), + RelationPhysicalIdentifier_compat(rel)); DeleteStorageFromColumnarMetadataTable(ColumnarStripeRelationId(), Anum_columnar_stripe_storageid, @@ -2001,13 +2015,11 @@ ColumnarNamespaceId(void) * false if the relation doesn't have a meta page yet. */ static uint64 -LookupStorageId(RelFileLocator relfilelocator) +LookupStorageId(Oid relid, RelFileLocator relfilelocator) { - Oid relationId = RelidByRelfilenumber(RelationTablespace_compat(relfilelocator), - RelationPhysicalIdentifierNumber_compat( - relfilelocator)); + relid = ColumnarRelationId(relid, relfilelocator); - Relation relation = relation_open(relationId, AccessShareLock); + Relation relation = relation_open(relid, AccessShareLock); uint64 storageId = ColumnarStorageGetStorageId(relation, false); table_close(relation, AccessShareLock); diff --git a/src/backend/columnar/columnar_reader.c b/src/backend/columnar/columnar_reader.c index 65ef27617..17c4061f1 100644 --- a/src/backend/columnar/columnar_reader.c +++ b/src/backend/columnar/columnar_reader.c @@ -986,8 +986,7 @@ ColumnarTableRowCount(Relation relation) { ListCell *stripeMetadataCell = NULL; uint64 totalRowCount = 0; - List *stripeList = StripesForRelfilelocator(RelationPhysicalIdentifier_compat( - relation)); + List *stripeList = StripesForRelfilelocator(relation); foreach(stripeMetadataCell, stripeList) { @@ -1015,8 +1014,7 @@ LoadFilteredStripeBuffers(Relation relation, StripeMetadata *stripeMetadata, bool *projectedColumnMask = ProjectedColumnMask(columnCount, projectedColumnList); - StripeSkipList *stripeSkipList = ReadStripeSkipList(RelationPhysicalIdentifier_compat( - relation), + StripeSkipList *stripeSkipList = ReadStripeSkipList(relation, stripeMetadata->id, tupleDescriptor, stripeMetadata->chunkCount, diff --git a/src/backend/columnar/columnar_tableam.c b/src/backend/columnar/columnar_tableam.c index 8e3796934..8271d28b2 100644 --- a/src/backend/columnar/columnar_tableam.c +++ b/src/backend/columnar/columnar_tableam.c @@ -872,7 +872,7 @@ columnar_relation_set_new_filelocator(Relation rel, RelationPhysicalIdentifier_compat(rel)), GetCurrentSubTransactionId()); - DeleteMetadataRows(RelationPhysicalIdentifier_compat(rel)); + DeleteMetadataRows(rel); } *freezeXid = RecentXmin; @@ -897,7 +897,7 @@ columnar_relation_nontransactional_truncate(Relation rel) NonTransactionDropWriteState(RelationPhysicalIdentifierNumber_compat(relfilelocator)); /* Delete old relfilenode metadata */ - DeleteMetadataRows(relfilelocator); + DeleteMetadataRows(rel); /* * No need to set new relfilenode, since the table was created in this @@ -960,8 +960,7 @@ columnar_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap, ColumnarOptions columnarOptions = { 0 }; ReadColumnarOptions(OldHeap->rd_id, &columnarOptions); - ColumnarWriteState *writeState = ColumnarBeginWrite(RelationPhysicalIdentifier_compat( - NewHeap), + ColumnarWriteState *writeState = ColumnarBeginWrite(NewHeap, columnarOptions, targetDesc); @@ -1036,8 +1035,7 @@ NeededColumnsList(TupleDesc tupdesc, Bitmapset *attr_needed) static uint64 ColumnarTableTupleCount(Relation relation) { - List *stripeList = StripesForRelfilelocator(RelationPhysicalIdentifier_compat( - relation)); + List *stripeList = StripesForRelfilelocator(relation); uint64 tupleCount = 0; ListCell *lc = NULL; @@ -1228,7 +1226,6 @@ static void LogRelationStats(Relation rel, int elevel) { ListCell *stripeMetadataCell = NULL; - RelFileLocator relfilelocator = RelationPhysicalIdentifier_compat(rel); StringInfo infoBuf = makeStringInfo(); int compressionStats[COMPRESSION_COUNT] = { 0 }; @@ -1239,7 +1236,7 @@ LogRelationStats(Relation rel, int elevel) uint64 droppedChunksWithData = 0; uint64 totalDecompressedLength = 0; - List *stripeList = StripesForRelfilelocator(relfilelocator); + List *stripeList = StripesForRelfilelocator(rel); int stripeCount = list_length(stripeList); foreach(stripeMetadataCell, stripeList) @@ -1247,7 +1244,7 @@ LogRelationStats(Relation rel, int elevel) StripeMetadata *stripe = lfirst(stripeMetadataCell); Snapshot snapshot = RegisterSnapshot(GetTransactionSnapshot()); - StripeSkipList *skiplist = ReadStripeSkipList(relfilelocator, stripe->id, + StripeSkipList *skiplist = ReadStripeSkipList(rel, stripe->id, RelationGetDescr(rel), stripe->chunkCount, snapshot); @@ -1385,8 +1382,7 @@ TruncateColumnar(Relation rel, int elevel) * new stripes be added beyond highestPhysicalAddress while * we're truncating. */ - uint64 newDataReservation = Max(GetHighestUsedAddress( - RelationPhysicalIdentifier_compat(rel)) + 1, + uint64 newDataReservation = Max(GetHighestUsedAddress(rel) + 1, ColumnarFirstLogicalOffset); BlockNumber old_rel_pages = smgrnblocks(RelationGetSmgr(rel), MAIN_FORKNUM); @@ -2154,7 +2150,7 @@ ColumnarTableDropHook(Oid relid) Relation rel = table_open(relid, AccessExclusiveLock); RelFileLocator relfilelocator = RelationPhysicalIdentifier_compat(rel); - DeleteMetadataRows(relfilelocator); + DeleteMetadataRows(rel); DeleteColumnarTableOptions(rel->rd_id, true); MarkRelfilenumberDropped(RelationPhysicalIdentifierNumber_compat(relfilelocator), diff --git a/src/backend/columnar/columnar_writer.c b/src/backend/columnar/columnar_writer.c index 1bdc612c1..d3e16be57 100644 --- a/src/backend/columnar/columnar_writer.c +++ b/src/backend/columnar/columnar_writer.c @@ -47,6 +47,7 @@ struct ColumnarWriteState TupleDesc tupleDescriptor; FmgrInfo **comparisonFunctionArray; RelFileLocator relfilelocator; + Oid temp_relid; /* We can't rely on RelidByRelfilenumber for temp tables anymore.*/ MemoryContext stripeWriteContext; MemoryContext perTupleContext; @@ -93,10 +94,12 @@ static StringInfo CopyStringInfo(StringInfo sourceString); * data load operation. */ ColumnarWriteState * -ColumnarBeginWrite(RelFileLocator relfilelocator, +ColumnarBeginWrite(Relation rel, ColumnarOptions options, TupleDesc tupleDescriptor) { + RelFileLocator relfilelocator = RelationPhysicalIdentifier_compat(rel); + /* get comparison function pointers for each of the columns */ uint32 columnCount = tupleDescriptor->natts; FmgrInfo **comparisonFunctionArray = palloc0(columnCount * sizeof(FmgrInfo *)); @@ -134,6 +137,7 @@ ColumnarBeginWrite(RelFileLocator relfilelocator, ColumnarWriteState *writeState = palloc0(sizeof(ColumnarWriteState)); writeState->relfilelocator = relfilelocator; + writeState->temp_relid = RelationPrecomputeOid_compat(rel); writeState->options = options; writeState->tupleDescriptor = CreateTupleDescCopy(tupleDescriptor); writeState->comparisonFunctionArray = comparisonFunctionArray; @@ -183,10 +187,9 @@ ColumnarWriteRow(ColumnarWriteState *writeState, Datum *columnValues, bool *colu writeState->stripeSkipList = stripeSkipList; writeState->compressionBuffer = makeStringInfo(); - Oid relationId = RelidByRelfilenumber(RelationTablespace_compat( - writeState->relfilelocator), - RelationPhysicalIdentifierNumber_compat( - writeState->relfilelocator)); + Oid relationId = ColumnarRelationId(writeState->temp_relid, + writeState->relfilelocator); + Relation relation = relation_open(relationId, NoLock); writeState->emptyStripeReservation = ReserveEmptyStripe(relation, columnCount, chunkRowCount, @@ -404,10 +407,9 @@ FlushStripe(ColumnarWriteState *writeState) elog(DEBUG1, "Flushing Stripe of size %d", stripeBuffers->rowCount); - Oid relationId = RelidByRelfilenumber(RelationTablespace_compat( - writeState->relfilelocator), - RelationPhysicalIdentifierNumber_compat( - writeState->relfilelocator)); + Oid relationId = ColumnarRelationId(writeState->temp_relid, + writeState->relfilelocator); + Relation relation = relation_open(relationId, NoLock); /* @@ -499,10 +501,12 @@ FlushStripe(ColumnarWriteState *writeState) } } - SaveChunkGroups(writeState->relfilelocator, + SaveChunkGroups(writeState->temp_relid, + writeState->relfilelocator, stripeMetadata->id, writeState->chunkGroupRowCounts); - SaveStripeSkipList(writeState->relfilelocator, + SaveStripeSkipList(writeState->temp_relid, + writeState->relfilelocator, stripeMetadata->id, stripeSkipList, tupleDescriptor); diff --git a/src/backend/columnar/write_state_management.c b/src/backend/columnar/write_state_management.c index 7f35c5dd1..a4e0240d6 100644 --- a/src/backend/columnar/write_state_management.c +++ b/src/backend/columnar/write_state_management.c @@ -191,8 +191,7 @@ columnar_init_write_state(Relation relation, TupleDesc tupdesc, ReadColumnarOptions(tupSlotRelationId, &columnarOptions); SubXidWriteState *stackEntry = palloc0(sizeof(SubXidWriteState)); - stackEntry->writeState = ColumnarBeginWrite(RelationPhysicalIdentifier_compat( - relation), + stackEntry->writeState = ColumnarBeginWrite(relation, columnarOptions, tupdesc); stackEntry->subXid = currentSubXid; diff --git a/src/include/columnar/columnar.h b/src/include/columnar/columnar.h index 66413dddd..dc0d15c1e 100644 --- a/src/include/columnar/columnar.h +++ b/src/include/columnar/columnar.h @@ -232,7 +232,7 @@ extern void columnar_init_gucs(void); extern CompressionType ParseCompressionType(const char *compressionTypeString); /* Function declarations for writing to a columnar table */ -extern ColumnarWriteState * ColumnarBeginWrite(RelFileLocator relfilelocator, +extern ColumnarWriteState * ColumnarBeginWrite(Relation rel, ColumnarOptions options, TupleDesc tupleDescriptor); extern uint64 ColumnarWriteRow(ColumnarWriteState *state, Datum *columnValues, @@ -287,21 +287,21 @@ extern PGDLLEXPORT bool ReadColumnarOptions(Oid regclass, ColumnarOptions *optio extern PGDLLEXPORT bool IsColumnarTableAmTable(Oid relationId); /* columnar_metadata_tables.c */ -extern void DeleteMetadataRows(RelFileLocator relfilelocator); +extern void DeleteMetadataRows(Relation rel); extern uint64 ColumnarMetadataNewStorageId(void); -extern uint64 GetHighestUsedAddress(RelFileLocator relfilelocator); +extern uint64 GetHighestUsedAddress(Relation rel); extern EmptyStripeReservation * ReserveEmptyStripe(Relation rel, uint64 columnCount, uint64 chunkGroupRowCount, uint64 stripeRowCount); extern StripeMetadata * CompleteStripeReservation(Relation rel, uint64 stripeId, uint64 sizeBytes, uint64 rowCount, uint64 chunkCount); -extern void SaveStripeSkipList(RelFileLocator relfilelocator, uint64 stripe, +extern void SaveStripeSkipList(Oid relid, RelFileLocator relfilelocator, uint64 stripe, StripeSkipList *stripeSkipList, TupleDesc tupleDescriptor); -extern void SaveChunkGroups(RelFileLocator relfilelocator, uint64 stripe, +extern void SaveChunkGroups(Oid relid, RelFileLocator relfilelocator, uint64 stripe, List *chunkGroupRowCounts); -extern StripeSkipList * ReadStripeSkipList(RelFileLocator relfilelocator, uint64 stripe, +extern StripeSkipList * ReadStripeSkipList(Relation rel, uint64 stripe, TupleDesc tupleDescriptor, uint32 chunkCount, Snapshot snapshot); @@ -317,6 +317,7 @@ extern uint64 StripeGetHighestRowNumber(StripeMetadata *stripeMetadata); extern StripeMetadata * FindStripeWithHighestRowNumber(Relation relation, Snapshot snapshot); extern Datum columnar_relation_storageid(PG_FUNCTION_ARGS); +extern Oid ColumnarRelationId(Oid relid, RelFileLocator relfilelocator); /* write_state_management.c */ diff --git a/src/include/columnar/columnar_metadata.h b/src/include/columnar/columnar_metadata.h index 64867ae2f..81817f733 100644 --- a/src/include/columnar/columnar_metadata.h +++ b/src/include/columnar/columnar_metadata.h @@ -61,7 +61,7 @@ typedef struct EmptyStripeReservation uint64 stripeFirstRowNumber; } EmptyStripeReservation; -extern List * StripesForRelfilelocator(RelFileLocator relfilelocator); +extern List * StripesForRelfilelocator(Relation rel); extern void ColumnarStorageUpdateIfNeeded(Relation rel, bool isUpgrade); extern List * ExtractColumnarRelOptions(List *inOptions, List **outColumnarOptions); extern void SetColumnarRelOptions(RangeVar *rv, List *reloptions); diff --git a/src/include/pg_version_compat.h b/src/include/pg_version_compat.h index a30925e4e..83716b7cf 100644 --- a/src/include/pg_version_compat.h +++ b/src/include/pg_version_compat.h @@ -469,6 +469,8 @@ getStxstattarget_compat(HeapTuple tup) #define RelationPhysicalIdentifier_compat(a) ((a)->rd_locator) #define RelationTablespace_compat(a) (a.spcOid) +#define RelationPrecomputeOid_compat(a) (RelationUsesLocalBuffers(a) ? RelationGetRelid( \ + a) : InvalidOid) #define RelationPhysicalIdentifierNumber_compat(a) (a.relNumber) #define RelationPhysicalIdentifierNumberPtr_compat(a) (a->relNumber) #define RelationPhysicalIdentifierBackend_compat(a) (a->smgr_rlocator.locator) @@ -521,7 +523,6 @@ get_guc_variables_compat(int *gucCount) #define RelationPhysicalIdentifierBackend_compat(a) (a->smgr_rnode.node) typedef RelFileNode RelFileLocator; typedef Oid RelFileNumber; -#define RelidByRelfilenumber(a, b) RelidByRelfilenode(a, b) #define float_abs(a) Abs(a)