[BUG?] tuples from file_fdw has strange xids. - Mailing list pgsql-hackers

From Kyotaro HORIGUCHI
Subject [BUG?] tuples from file_fdw has strange xids.
Date
Msg-id 20140716.170459.194134171.horiguchi.kyotaro@lab.ntt.co.jp
Whole thread Raw
In response to Re: inherit support for foreign tables  (Kyotaro HORIGUCHI <horiguchi.kyotaro@lab.ntt.co.jp>)
Responses Re: [BUG?] tuples from file_fdw has strange xids.  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-hackers
Hello, I found that tuples come from file_fdw has strange xmin and xmax.

> 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...

Back to 9.1 gives the same result.

These xmin and xmax are the simple interpretations of a
DatumTupleFields filled by ExecMaterializedSlot() beeing fed the
source virtual tuple slot from file_fdw. On the other hand,
postgres_fdw gives sane xids (xmin = 2, xmax = 0).

This is because ForeignNext returns physical tuples in which
their headers are DatumTupleFields regardless whether the system
columns are requested or not. The fdw machinary desn't seem to
provide fdw handlers with a means to reject requests for
unavailable system columns, so the tuple header should be fixed
with the sane values as HeapTupleFields.

The patch attached fixes the header of materialized tuple to be
sane (2, 0) if the source slot was a virtual tuple in mechanism().


regards,

-- 
Kyotaro Horiguchi
NTT Open Source Software Center
diff --git a/src/backend/executor/nodeForeignscan.c b/src/backend/executor/nodeForeignscan.c
index 9cc5345..59dc5f4 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, although a
+             * physical one is needed by the callers. So rewrite the tuple
+             * header as a sane HeapTupleFields.
+             */
+            HeapTupleHeaderSetXmin(tup->t_data, FrozenTransactionId);
+            HeapTupleHeaderSetXmax(tup->t_data, InvalidTransactionId);
+            HeapTupleHeaderSetCmin(tup->t_data, FirstCommandId);
+        }        tup->t_tableOid = RelationGetRelid(node->ss.ss_currentRelation);    }

pgsql-hackers by date:

Previous
From: Petr Jelinek
Date:
Subject: Re: Built-in binning functions
Next
From: Kyotaro HORIGUCHI
Date:
Subject: BUFFER_LOCK_EXCLUSIVE is used in ginbuildempty().