From: | Albe Laurenz <laurenz(dot)albe(at)wien(dot)gv(dot)at> |
---|---|
To: | Tomas Vondra *EXTERN* <tv(at)fuzzy(dot)cz>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: writable FDWs / update targets confusion |
Date: | 2013-11-15 16:15:38 |
Message-ID: | A737B7A37273E048B164557ADEF4A58B17C5A4F2@ntex2010i.host.magwien.gv.at |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | 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
From | Date | Subject | |
---|---|---|---|
Next Message | Andres Freund | 2013-11-15 16:28:57 | Re: Minmax indexes (timings) |
Previous Message | Erik Rijkers | 2013-11-15 16:11:46 | Re: Minmax indexes (timings) |