Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0997e0a

Browse files
committed
Add TupleTableSlotOps.is_current_xact_tuple() method
This allows us to abstract how/whether table AM uses transaction identifiers.A custom table AM can use a custom slot, which may not store xmin directly,but determine the tuple belonging to the current transaction in the other way.Discussion:https://postgr.es/m/CAPpHfdurb9ycV8udYqM%3Do0sPS66PJ4RCBM1g-bBpvzUfogY0EA%40mail.gmail.comReviewed-by: Matthias van de Meent, Mark Dilger, Pavel BorisovReviewed-by: Nikita Malakhov, Japin Li
1 parentc35a3fb commit0997e0a

File tree

3 files changed

+101
-7
lines changed

3 files changed

+101
-7
lines changed

‎src/backend/executor/execTuples.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
#include"access/heaptoast.h"
6161
#include"access/htup_details.h"
6262
#include"access/tupdesc_details.h"
63+
#include"access/xact.h"
6364
#include"catalog/pg_type.h"
6465
#include"funcapi.h"
6566
#include"nodes/nodeFuncs.h"
@@ -148,6 +149,22 @@ tts_virtual_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
148149
return0;/* silence compiler warnings */
149150
}
150151

152+
/*
153+
* VirtualTupleTableSlots never have storage tuples. We generally
154+
* shouldn't get here, but provide a user-friendly message if we do.
155+
*/
156+
staticbool
157+
tts_virtual_is_current_xact_tuple(TupleTableSlot*slot)
158+
{
159+
Assert(!TTS_EMPTY(slot));
160+
161+
ereport(ERROR,
162+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
163+
errmsg("don't have a storage tuple in this context")));
164+
165+
return false;/* silence compiler warnings */
166+
}
167+
151168
/*
152169
* To materialize a virtual slot all the datums that aren't passed by value
153170
* have to be copied into the slot's memory context. To do so, compute the
@@ -354,6 +371,29 @@ tts_heap_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
354371
slot->tts_tupleDescriptor,isnull);
355372
}
356373

374+
staticbool
375+
tts_heap_is_current_xact_tuple(TupleTableSlot*slot)
376+
{
377+
HeapTupleTableSlot*hslot= (HeapTupleTableSlot*)slot;
378+
TransactionIdxmin;
379+
380+
Assert(!TTS_EMPTY(slot));
381+
382+
/*
383+
* In some code paths it's possible to get here with a non-materialized
384+
* slot, in which case we can't check if tuple is created by the current
385+
* transaction.
386+
*/
387+
if (!hslot->tuple)
388+
ereport(ERROR,
389+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
390+
errmsg("don't have a storage tuple in this context")));
391+
392+
xmin=HeapTupleHeaderGetRawXmin(hslot->tuple->t_data);
393+
394+
returnTransactionIdIsCurrentTransactionId(xmin);
395+
}
396+
357397
staticvoid
358398
tts_heap_materialize(TupleTableSlot*slot)
359399
{
@@ -521,6 +561,18 @@ tts_minimal_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
521561
return0;/* silence compiler warnings */
522562
}
523563

564+
staticbool
565+
tts_minimal_is_current_xact_tuple(TupleTableSlot*slot)
566+
{
567+
Assert(!TTS_EMPTY(slot));
568+
569+
ereport(ERROR,
570+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
571+
errmsg("don't have a storage tuple in this context")));
572+
573+
return false;/* silence compiler warnings */
574+
}
575+
524576
staticvoid
525577
tts_minimal_materialize(TupleTableSlot*slot)
526578
{
@@ -714,6 +766,29 @@ tts_buffer_heap_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
714766
slot->tts_tupleDescriptor,isnull);
715767
}
716768

769+
staticbool
770+
tts_buffer_is_current_xact_tuple(TupleTableSlot*slot)
771+
{
772+
BufferHeapTupleTableSlot*bslot= (BufferHeapTupleTableSlot*)slot;
773+
TransactionIdxmin;
774+
775+
Assert(!TTS_EMPTY(slot));
776+
777+
/*
778+
* In some code paths it's possible to get here with a non-materialized
779+
* slot, in which case we can't check if tuple is created by the current
780+
* transaction.
781+
*/
782+
if (!bslot->base.tuple)
783+
ereport(ERROR,
784+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
785+
errmsg("don't have a storage tuple in this context")));
786+
787+
xmin=HeapTupleHeaderGetRawXmin(bslot->base.tuple->t_data);
788+
789+
returnTransactionIdIsCurrentTransactionId(xmin);
790+
}
791+
717792
staticvoid
718793
tts_buffer_heap_materialize(TupleTableSlot*slot)
719794
{
@@ -1029,6 +1104,7 @@ const TupleTableSlotOps TTSOpsVirtual = {
10291104
.getsomeattrs=tts_virtual_getsomeattrs,
10301105
.getsysattr=tts_virtual_getsysattr,
10311106
.materialize=tts_virtual_materialize,
1107+
.is_current_xact_tuple=tts_virtual_is_current_xact_tuple,
10321108
.copyslot=tts_virtual_copyslot,
10331109

10341110
/*
@@ -1048,6 +1124,7 @@ const TupleTableSlotOps TTSOpsHeapTuple = {
10481124
.clear=tts_heap_clear,
10491125
.getsomeattrs=tts_heap_getsomeattrs,
10501126
.getsysattr=tts_heap_getsysattr,
1127+
.is_current_xact_tuple=tts_heap_is_current_xact_tuple,
10511128
.materialize=tts_heap_materialize,
10521129
.copyslot=tts_heap_copyslot,
10531130
.get_heap_tuple=tts_heap_get_heap_tuple,
@@ -1065,6 +1142,7 @@ const TupleTableSlotOps TTSOpsMinimalTuple = {
10651142
.clear=tts_minimal_clear,
10661143
.getsomeattrs=tts_minimal_getsomeattrs,
10671144
.getsysattr=tts_minimal_getsysattr,
1145+
.is_current_xact_tuple=tts_minimal_is_current_xact_tuple,
10681146
.materialize=tts_minimal_materialize,
10691147
.copyslot=tts_minimal_copyslot,
10701148

@@ -1082,6 +1160,7 @@ const TupleTableSlotOps TTSOpsBufferHeapTuple = {
10821160
.clear=tts_buffer_heap_clear,
10831161
.getsomeattrs=tts_buffer_heap_getsomeattrs,
10841162
.getsysattr=tts_buffer_heap_getsysattr,
1163+
.is_current_xact_tuple=tts_buffer_is_current_xact_tuple,
10851164
.materialize=tts_buffer_heap_materialize,
10861165
.copyslot=tts_buffer_heap_copyslot,
10871166
.get_heap_tuple=tts_buffer_heap_get_heap_tuple,

‎src/backend/utils/adt/ri_triggers.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,9 +1260,6 @@ RI_FKey_fk_upd_check_required(Trigger *trigger, Relation fk_rel,
12601260
{
12611261
constRI_ConstraintInfo*riinfo;
12621262
intri_nullcheck;
1263-
DatumxminDatum;
1264-
TransactionIdxmin;
1265-
boolisnull;
12661263

12671264
/*
12681265
* AfterTriggerSaveEvent() handles things such that this function is never
@@ -1330,10 +1327,7 @@ RI_FKey_fk_upd_check_required(Trigger *trigger, Relation fk_rel,
13301327
* this if we knew the INSERT trigger already fired, but there is no easy
13311328
* way to know that.)
13321329
*/
1333-
xminDatum=slot_getsysattr(oldslot,MinTransactionIdAttributeNumber,&isnull);
1334-
Assert(!isnull);
1335-
xmin=DatumGetTransactionId(xminDatum);
1336-
if (TransactionIdIsCurrentTransactionId(xmin))
1330+
if (slot_is_current_xact_tuple(oldslot))
13371331
return true;
13381332

13391333
/* If all old and new key values are equal, no check is needed */

‎src/include/executor/tuptable.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,12 @@ struct TupleTableSlotOps
166166
*/
167167
Datum(*getsysattr) (TupleTableSlot*slot,intattnum,bool*isnull);
168168

169+
/*
170+
* Check if the tuple is created by the current transaction. Throws an
171+
* error if the slot doesn't contain the storage tuple.
172+
*/
173+
bool(*is_current_xact_tuple) (TupleTableSlot*slot);
174+
169175
/*
170176
* Make the contents of the slot solely depend on the slot, and not on
171177
* underlying resources (like another memory context, buffers, etc).
@@ -426,6 +432,21 @@ slot_getsysattr(TupleTableSlot *slot, int attnum, bool *isnull)
426432
returnslot->tts_ops->getsysattr(slot,attnum,isnull);
427433
}
428434

435+
/*
436+
* slot_is_current_xact_tuple - check if the slot's current tuple is created
437+
*by the current transaction.
438+
*
439+
* If the slot does not contain a storage tuple, this will throw an error.
440+
* Hence before calling this function, callers should make sure that the
441+
* slot type supports storage tuples and that there is currently one inside
442+
* the slot.
443+
*/
444+
staticinlinebool
445+
slot_is_current_xact_tuple(TupleTableSlot*slot)
446+
{
447+
returnslot->tts_ops->is_current_xact_tuple(slot);
448+
}
449+
429450
/*
430451
* ExecClearTuple - clear the slot's contents
431452
*/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp