Hello, Sorry, this was no relation with this patch.
ForeignNext materializes the slot, which would be any of physical and virtual tuple, when system column was requested. If it was a virtual one, file_fdw makes this, heap_form_tuple generates the tuple as DatumTuple. The result is a jumble of virtual and physical. But the returning slot has tts_tuple so the caller interprets it as a physical one. Anyway the requests for xmin/xmax could not be prevented beforehand in current framework, I did rewrite the physical tuple header so as to really be a physical one. This would be another patch, so I will put this into next CF if this don't get any immediate objection. > By the way, I tried xmin and xmax for the file_fdw tables. > > postgres=# select tableoid, xmin, xmax, * from passwd1; > tableoid | xmin | xmax | uname | pass | uid | gid | .. > 16396 | 244 | 4294967295 | root | x | 0 | 0 | root... > 16396 | 252 | 4294967295 | bin | x | 1 | 1 | bin... > 16396 | 284 | 4294967295 | daemon | x | 2 | 2 | > daemon... > > The xmin and xmax apparently doesn't look sane. After some > investigation, I found that they came from the following place in > heap_form_tuple(), (call stach is show below) regards, -- Kyotaro Horiguchi NTT Open Source Software Center
diff --git a/src/backend/executor/nodeForeignscan.c b/src/backend/executor/nodeForeignscan.c index 9cc5345..728db14 100644 --- a/src/backend/executor/nodeForeignscan.c +++ b/src/backend/executor/nodeForeignscan.c @@ -22,6 +22,8 @@ */ #include "postgres.h" +#include "access/transam.h" +#include "access/htup_details.h" #include "executor/executor.h" #include "executor/nodeForeignscan.h" #include "foreign/fdwapi.h" @@ -58,8 +60,21 @@ ForeignNext(ForeignScanState *node) */ if (plan->fsSystemCol && !TupIsNull(slot)) { + bool was_virtual_tuple = (slot->tts_tuple == NULL); HeapTuple tup = ExecMaterializeSlot(slot); + if (was_virtual_tuple) + { + /* + * ExecMaterializeSlot fills the tuple header as a + * DatumTupleFields if the slot was a virtual tuple, but a + * physical one is needed here. So rewrite the tuple header as + * HeapTupleFirelds. + */ + HeapTupleHeaderSetXmin(tup->t_data, FrozenTransactionId); + HeapTupleHeaderSetXmax(tup->t_data, InvalidTransactionId); + HeapTupleHeaderSetCmin(tup->t_data, FirstCommandId); + } tup->t_tableOid = RelationGetRelid(node->ss.ss_currentRelation); }
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers