mirror of https://github.com/citusdata/citus.git
PG18 - use systable_inplace_update_* in UpdateStripeMetadataRow
PG18 has removed heap_inplace_update(), which is crucial for citus_columnar extension because we always want to update stripe entries for columnar in-place. Relevant PG18 commit: https://github.com/postgres/postgres/commit/a07e03f heap_inplace_update() has been replaced by heap_inplace_update_and_unlock, which is used inside systable_inplace_update_finish, which is used together with systable_inplace_update_begin. This change has been back-patched up to v12, which is enough for us since the oldest version Citus supports is v15. In PG<18, a deprecated heap_inplace_update() is retained, however, let's start using the new functions because they are better, and such that we don't need to wrap these changes in PG18 version conditionals. Basically, in this commit we replace the following: SysScanDesc scanDescriptor = systable_beginscan(columnarStripes, indexId, indexOk, &dirtySnapshot, 2, scanKey); heap_inplace_update(columnarStripes, modifiedTuple); with the following: systable_inplace_update_begin(columnarStripes, indexId, indexOk, NULL, 2, scanKey, &tuple, &state); systable_inplace_update_finish(state, tuple); For more understanding, it's best to refer to an example: REL_18_0/src/backend/catalog/toasting.c#L349-L371 of how systable_inplace_update_begin and systable_inplace_update_finish are used in PG18, because they mirror the need of citus columnar. Fixes #8207pull/8242/head^2
parent
abd50a0bb8
commit
76f18624e5
|
|
@ -1394,9 +1394,6 @@ static StripeMetadata *
|
|||
UpdateStripeMetadataRow(uint64 storageId, uint64 stripeId, uint64 fileOffset,
|
||||
uint64 dataLength, uint64 rowCount, uint64 chunkCount)
|
||||
{
|
||||
SnapshotData dirtySnapshot;
|
||||
InitDirtySnapshot(dirtySnapshot);
|
||||
|
||||
ScanKeyData scanKey[2];
|
||||
ScanKeyInit(&scanKey[0], Anum_columnar_stripe_storageid,
|
||||
BTEqualStrategyNumber, F_INT8EQ, Int64GetDatum(storageId));
|
||||
|
|
@ -1410,8 +1407,11 @@ UpdateStripeMetadataRow(uint64 storageId, uint64 stripeId, uint64 fileOffset,
|
|||
|
||||
Oid indexId = ColumnarStripePKeyIndexRelationId();
|
||||
bool indexOk = OidIsValid(indexId);
|
||||
SysScanDesc scanDescriptor = systable_beginscan(columnarStripes, indexId, indexOk,
|
||||
&dirtySnapshot, 2, scanKey);
|
||||
|
||||
void *state;
|
||||
HeapTuple tuple;
|
||||
systable_inplace_update_begin(columnarStripes, indexId, indexOk, NULL,
|
||||
2, scanKey, &tuple, &state);
|
||||
|
||||
static bool loggedSlowMetadataAccessWarning = false;
|
||||
if (!indexOk && !loggedSlowMetadataAccessWarning)
|
||||
|
|
@ -1420,8 +1420,7 @@ UpdateStripeMetadataRow(uint64 storageId, uint64 stripeId, uint64 fileOffset,
|
|||
loggedSlowMetadataAccessWarning = true;
|
||||
}
|
||||
|
||||
HeapTuple oldTuple = systable_getnext(scanDescriptor);
|
||||
if (!HeapTupleIsValid(oldTuple))
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
{
|
||||
ereport(ERROR, (errmsg("attempted to modify an unexpected stripe, "
|
||||
"columnar storage with id=" UINT64_FORMAT
|
||||
|
|
@ -1429,17 +1428,11 @@ UpdateStripeMetadataRow(uint64 storageId, uint64 stripeId, uint64 fileOffset,
|
|||
storageId, stripeId)));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* heap_modify_tuple + heap_inplace_update only exist on PG < 18;
|
||||
* on PG18 the in-place helper was removed upstream, so we skip the whole block.
|
||||
*/
|
||||
#if PG_VERSION_NUM < PG_VERSION_18
|
||||
|
||||
/*
|
||||
* heap_inplace_update already doesn't allow changing size of the original
|
||||
* systable_inplace_update_finish already doesn't allow changing size of the original
|
||||
* tuple, so we don't allow setting any Datum's to NULL values.
|
||||
*/
|
||||
|
||||
Datum *newValues = (Datum *) palloc(tupleDescriptor->natts * sizeof(Datum));
|
||||
bool *newNulls = (bool *) palloc0(tupleDescriptor->natts * sizeof(bool));
|
||||
bool *update = (bool *) palloc0(tupleDescriptor->natts * sizeof(bool));
|
||||
|
|
@ -1454,32 +1447,20 @@ UpdateStripeMetadataRow(uint64 storageId, uint64 stripeId, uint64 fileOffset,
|
|||
newValues[Anum_columnar_stripe_row_count - 1] = UInt64GetDatum(rowCount);
|
||||
newValues[Anum_columnar_stripe_chunk_count - 1] = Int32GetDatum(chunkCount);
|
||||
|
||||
HeapTuple modifiedTuple = heap_modify_tuple(oldTuple,
|
||||
tupleDescriptor,
|
||||
newValues,
|
||||
newNulls,
|
||||
update);
|
||||
tuple = heap_modify_tuple(tuple,
|
||||
tupleDescriptor,
|
||||
newValues,
|
||||
newNulls,
|
||||
update);
|
||||
|
||||
heap_inplace_update(columnarStripes, modifiedTuple);
|
||||
#endif
|
||||
systable_inplace_update_finish(state, tuple);
|
||||
|
||||
|
||||
/*
|
||||
* Existing tuple now contains modifications, because we used
|
||||
* heap_inplace_update().
|
||||
*/
|
||||
HeapTuple newTuple = oldTuple;
|
||||
|
||||
/*
|
||||
* Must not pass modifiedTuple, because BuildStripeMetadata expects a real
|
||||
* heap tuple with MVCC fields.
|
||||
*/
|
||||
StripeMetadata *modifiedStripeMetadata = BuildStripeMetadata(columnarStripes,
|
||||
newTuple);
|
||||
tuple);
|
||||
|
||||
CommandCounterIncrement();
|
||||
|
||||
systable_endscan(scanDescriptor);
|
||||
heap_freetuple(tuple);
|
||||
table_close(columnarStripes, AccessShareLock);
|
||||
|
||||
pfree(newValues);
|
||||
|
|
|
|||
Loading…
Reference in New Issue