Tomas Vondra wrote:
> I'm working on adding write support to one of my FDWs. Adding INSERT went
> pretty fine, but when adding DELETE/UPDATE I got really confused about how
> the update targets are supposed to work.
>
> My understanding of how it's supposed to work is this:
>
> (1) AddForeignUpdateTargets adds columns that serve as ID of the record
> (e.g. postgres_fdw adds 'ctid')
>
> (2) planning the inner foreign scan handles the new column appropriately
> (e.g. scans system columns, as in case of 'ctid' etc.)
>
> (3) IterateForeignScan will see the column in the tuple descriptor, will
> set it just like any other column, etc.
>
> (4) ExecForeignDelete will fetch the new column and do something with it
>
> However no matter what I do, I can't get the steps (3) and (4) working this
> way.
I have no idea either.
> And looking at postgres_fdw it seems to me it does not really set the ctid
> into the tuple as a column, but just does this:
>
> if (ctid)
> tuple->t_self = *ctid;
>
> which I can't really do because I need to use INT8 and not TID. But even
> if I do this,
What exactly did you do?
Did you try
tuple->t_self = myInt8;
That would write 8 bytes into a 6-byte variable, thus scribbling
past the end, right?
> Interestingly, if I do this in ExecForeignDelete
>
> static TupleTableSlot *
> myExecForeignDelete(EState *estate,
> ResultRelInfo *resultRelInfo,
> TupleTableSlot *slot,
> TupleTableSlot *planSlot)
> {
>
> bool isNull;
> MyModifyState state = (MyModifyState)resultRelInfo->ri_FdwState;
> int64 ctid;
>
> Datum datum = ExecGetJunkAttribute(planSlot,
> state->ctidAttno, &isNull);
>
> ctid = DatumGetInt64(datum);
>
> elog(WARNING, "ID = %ld", ctid);
>
> if (isNull)
> elog(ERROR, "ctid is NULL");
>
> /* FIXME not yet implemented */
> return NULL;
> }
>
> I do get (isNull=FALSE) but the ctid evaluates to some random number, e.g.
>
> WARNING: ID = 44384788 (44384788)
> WARNING: ID = 44392980 (44392980)
>
> and so on.
Maybe that's the effect of writing past the end of the variable.
> So what did I get wrong? Is it possible to use arbitrary hidden column as
> "junk" columns (documentation seems to suggest that)? What is the right
> way to do that / whad did I get wrong?
I would like to know an answer to this as well.
I don't think that assigning to tuple->t_self will work, and I
know too little about the executor to know if there's any way
to fit a ctid that is *not* an ItemPointerData into a TupleTableSlot
so that it will show up as resjunk TargerEntry in ExecForeignUpdate.
Tom, could you show us a rope if there is one?
Yours,
Laurenz Albe
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers