Re: writable FDWs / update targets confusion - Mailing list pgsql-hackers
From | Albe Laurenz |
---|---|
Subject | Re: writable FDWs / update targets confusion |
Date | |
Msg-id | A737B7A37273E048B164557ADEF4A58B17C5A4F2@ntex2010i.host.magwien.gv.at Whole thread Raw |
In response to | writable FDWs / update targets confusion ("Tomas Vondra" <tv@fuzzy.cz>) |
Responses |
Re: writable FDWs / update targets confusion
|
List | pgsql-hackers |
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
pgsql-hackers by date: