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 e3264311c..e0e97247d 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); @@ -674,10 +674,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); @@ -710,7 +710,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) { @@ -719,7 +719,8 @@ ReadStripeSkipList(RelFileLocator relfilelocator, uint64 stripe, uint32 columnCount = tupleDescriptor->natts; ScanKeyData scanKey[2]; - uint64 storageId = LookupStorageId(relfilelocator); + uint64 storageId = LookupStorageId(RelationPrecomputeOid(rel), + RelationPhysicalIdentifier_compat(rel)); Oid columnarChunkOid = ColumnarChunkRelationId(); Relation columnarChunk = table_open(columnarChunkOid, AccessShareLock); @@ -1263,9 +1264,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(rel), + RelationPhysicalIdentifier_compat(rel)); return ReadDataFileStripeList(storageId, GetTransactionSnapshot()); } @@ -1280,9 +1282,10 @@ StripesForRelfilelocator(RelFileLocator relfilelocator) * returns 0. */ uint64 -GetHighestUsedAddress(RelFileLocator relfilelocator) +GetHighestUsedAddress(Relation rel) { - uint64 storageId = LookupStorageId(relfilelocator); + uint64 storageId = LookupStorageId(RelationPrecomputeOid(rel), + RelationPhysicalIdentifier_compat(rel)); uint64 highestUsedAddress = 0; uint64 highestUsedId = 0; @@ -1292,6 +1295,24 @@ GetHighestUsedAddress(RelFileLocator relfilelocator) } +/* + * In case if relid hasn't been defined yet, we should use RelidByRelfilenumber + * to get correct relid value. + * + * Now it is basically used for temp rels, because since PG18(it was backpatched + * through PG13) RelidByRelfilenumber skip temp relations and we should use + * alternative ways to get relid value in case of temp objects. + */ +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. @@ -1595,7 +1616,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 @@ -1606,7 +1627,8 @@ DeleteMetadataRows(RelFileLocator relfilelocator) return; } - uint64 storageId = LookupStorageId(relfilelocator); + uint64 storageId = LookupStorageId(RelationPrecomputeOid(rel), + RelationPhysicalIdentifier_compat(rel)); DeleteStorageFromColumnarMetadataTable(ColumnarStripeRelationId(), Anum_columnar_stripe_storageid, @@ -2005,13 +2027,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 2b11dd27a..ffe52442d 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,13 +1236,13 @@ 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) { StripeMetadata *stripe = lfirst(stripeMetadataCell); - StripeSkipList *skiplist = ReadStripeSkipList(relfilelocator, stripe->id, + StripeSkipList *skiplist = ReadStripeSkipList(rel, stripe->id, RelationGetDescr(rel), stripe->chunkCount, GetTransactionSnapshot()); @@ -1381,8 +1378,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); @@ -2150,7 +2146,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..e698d1a41 100644 --- a/src/backend/columnar/columnar_writer.c +++ b/src/backend/columnar/columnar_writer.c @@ -48,6 +48,12 @@ struct ColumnarWriteState FmgrInfo **comparisonFunctionArray; RelFileLocator relfilelocator; + /* + * We can't rely on RelidByRelfilenumber for temp tables since + * PG18(it was backpatched through PG13). + */ + Oid temp_relid; + MemoryContext stripeWriteContext; MemoryContext perTupleContext; StripeBuffers *stripeBuffers; @@ -93,10 +99,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 +142,7 @@ ColumnarBeginWrite(RelFileLocator relfilelocator, ColumnarWriteState *writeState = palloc0(sizeof(ColumnarWriteState)); writeState->relfilelocator = relfilelocator; + writeState->temp_relid = RelationPrecomputeOid(rel); writeState->options = options; writeState->tupleDescriptor = CreateTupleDescCopy(tupleDescriptor); writeState->comparisonFunctionArray = comparisonFunctionArray; @@ -183,10 +192,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 +412,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 +506,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..1883be38b 100644 --- a/src/include/columnar/columnar.h +++ b/src/include/columnar/columnar.h @@ -64,6 +64,14 @@ /*global variables for citus_columnar fake version Y */ #define CITUS_COLUMNAR_INTERNAL_VERSION "11.1-0" +/* + * We can't rely on RelidByRelfilenumber for temp tables since PG18(it was backpatched + * through PG13), so we can use this macro to define relid within relation in case of + * temp relations. Otherwise RelidByRelfilenumber should be used. + */ +#define RelationPrecomputeOid(a) (RelationUsesLocalBuffers(a) ? RelationGetRelid(a) : \ + InvalidOid) + /* * ColumnarOptions holds the option values to be used when reading or writing * a columnar table. To resolve these values, we first check foreign table's options, @@ -232,7 +240,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 +295,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 +325,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);