aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid Rowley <drowley@postgresql.org>2023-12-07 21:28:24 +1300
committerDavid Rowley <drowley@postgresql.org>2023-12-07 21:28:24 +1300
commitd16a0c1e2e3874cd5adfa9ee968008b6c4b1ae01 (patch)
treef4944907f0efee646c07a9af36bff630022efba1 /src
parentd43bd090a8fee81fe88eb1e9e15e30d30ee130ed (diff)
downloadpostgresql-d16a0c1e2e3874cd5adfa9ee968008b6c4b1ae01.tar.gz
postgresql-d16a0c1e2e3874cd5adfa9ee968008b6c4b1ae01.zip
Verify that attribute counts match in ExecCopySlot
tts_virtual_copyslot() contained an Assert that checked that the srcslot contained <= attributes than the dstslot. This seems to be backwards as if the srcslot contained fewer attributes then the dstslot could be left with stale Datum values from the previously stored tuple. It might make more sense to allow the source to contain additional attributes and only copy the leading ones that also exist in the destination, however, that's not what we're doing here. Here we just remove the Assert from tts_virtual_copyslot() and add an Assert to ExecCopySlot() to verify the attribute counts match. There does not seem to be any places where the destination contains fewer attributes, so instead of going to the trouble of making the code properly handle this, let's just ensure the attribute counts match. If this Assert fails then that will indicate that we do have cases that require us to handle the srcslot with more attributes than the dstslot. It seems better to only write this code if there's a genuine requirement for it rather than write it now only to leave it untested. Thanks to Andres Freund for helping with the analysis of this. Discussion: https://postgr.es/m/CAApHDvpMAvBL0T+TRORquyx1iqFQKMVTXtqNocOw0Pa2uh1heg@mail.gmail.com
Diffstat (limited to 'src')
-rw-r--r--src/backend/executor/execTuples.c2
-rw-r--r--src/include/executor/tuptable.h10
2 files changed, 9 insertions, 3 deletions
diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c
index 2c2712ceac3..5a2db83987e 100644
--- a/src/backend/executor/execTuples.c
+++ b/src/backend/executor/execTuples.c
@@ -253,8 +253,6 @@ tts_virtual_copyslot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
{
TupleDesc srcdesc = srcslot->tts_tupleDescriptor;
- Assert(srcdesc->natts <= dstslot->tts_tupleDescriptor->natts);
-
tts_virtual_clear(dstslot);
slot_getallattrs(srcslot);
diff --git a/src/include/executor/tuptable.h b/src/include/executor/tuptable.h
index 4210d6d838f..5250be52d33 100644
--- a/src/include/executor/tuptable.h
+++ b/src/include/executor/tuptable.h
@@ -174,7 +174,8 @@ struct TupleTableSlotOps
/*
* Copy the contents of the source slot into the destination slot's own
- * context. Invoked using callback of the destination slot.
+ * context. Invoked using callback of the destination slot. 'dstslot' and
+ * 'srcslot' can be assumed to have the same number of attributes.
*/
void (*copyslot) (TupleTableSlot *dstslot, TupleTableSlot *srcslot);
@@ -477,12 +478,19 @@ ExecCopySlotMinimalTuple(TupleTableSlot *slot)
*
* If a source's system attributes are supposed to be accessed in the target
* slot, the target slot and source slot types need to match.
+ *
+ * Currently, 'dstslot' and 'srcslot' must have the same number of attributes.
+ * Future work could see this relaxed to allow the source to contain
+ * additional attributes and have the code here only copy over the leading
+ * attributes.
*/
static inline TupleTableSlot *
ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
{
Assert(!TTS_EMPTY(srcslot));
Assert(srcslot != dstslot);
+ Assert(dstslot->tts_tupleDescriptor->natts ==
+ srcslot->tts_tupleDescriptor->natts);
dstslot->tts_ops->copyslot(dstslot, srcslot);