Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0bb8528

Browse files
committed
Fix postgres_fdw to return the right ctid value in EvalPlanQual cases.
If a postgres_fdw foreign table is a non-locked source relation in anUPDATE, DELETE, or SELECT FOR UPDATE/SHARE, and the query selects itsctid column, the wrong value would be returned if an EvalPlanQualrecheck occurred. This happened because the foreign table's result rowwas copied via the ROW_MARK_COPY code path, and EvalPlanQualFetchRowMarksjust unconditionally set the reconstructed tuple's t_self to "invalid".To fix that, we can have EvalPlanQualFetchRowMarks copy the compositedatum's t_ctid field, and be sure to initialize that along with t_selfwhen postgres_fdw constructs a tuple to return.If we just did that much then EvalPlanQualFetchRowMarks would startreturning "(0,0)" as ctid for all other ROW_MARK_COPY cases, which perhapsdoes not matter much, but then again maybe it might. The cause of that isthat heap_form_tuple, which is the ultimate source of all composite datums,simply leaves t_ctid as zeroes in newly constructed tuples. That seemslike a bad idea on general principles: a field that's really not beeninitialized shouldn't appear to have a valid value. So let's eat thetrivial additional overhead of doing "ItemPointerSetInvalid(&(td->t_ctid))"in heap_form_tuple.This closes out our handling of Etsuro Fujita's report that tableoid andctid weren't correctly set in postgres_fdw EvalPlanQual cases. Along theway we did a great deal of work to improve FDWs' ability to control rowlocking behavior; which was not wasted effort by any means, but it didn'tend up being a fix for this problem because that feature would be tooexpensive for postgres_fdw to use all the time.Although the fix for the tableoid misbehavior was back-patched, I'mhesitant to do so here; it seems far less likely that people would careabout remote ctid than tableoid, and even such a minor behavioral changeas this in heap_form_tuple is perhaps best not back-patched. So committo HEAD only, at least for the moment.Etsuro Fujita, with some adjustments by me
1 parent3f2cec7 commit0bb8528

File tree

3 files changed

+12
-3
lines changed

3 files changed

+12
-3
lines changed

‎contrib/postgres_fdw/postgres_fdw.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2964,8 +2964,14 @@ make_tuple_from_result_row(PGresult *res,
29642964

29652965
tuple=heap_form_tuple(tupdesc,values,nulls);
29662966

2967+
/*
2968+
* If we have a CTID to return, install it in both t_self and t_ctid.
2969+
* t_self is the normal place, but if the tuple is converted to a
2970+
* composite Datum, t_self will be lost; setting t_ctid allows CTID to be
2971+
* preserved during EvalPlanQual re-evaluations (see ROW_MARK_COPY code).
2972+
*/
29672973
if (ctid)
2968-
tuple->t_self=*ctid;
2974+
tuple->t_self=tuple->t_data->t_ctid=*ctid;
29692975

29702976
/* Clean up */
29712977
MemoryContextReset(temp_context);

‎src/backend/access/common/heaptuple.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,8 @@ heap_form_tuple(TupleDesc tupleDescriptor,
727727
HeapTupleHeaderSetDatumLength(td,len);
728728
HeapTupleHeaderSetTypeId(td,tupleDescriptor->tdtypeid);
729729
HeapTupleHeaderSetTypMod(td,tupleDescriptor->tdtypmod);
730+
/* We also make sure that t_ctid is invalid unless explicitly set */
731+
ItemPointerSetInvalid(&(td->t_ctid));
730732

731733
HeapTupleHeaderSetNatts(td,numberOfAttributes);
732734
td->t_hoff=hoff;

‎src/backend/executor/execMain.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2613,10 +2613,11 @@ EvalPlanQualFetchRowMarks(EPQState *epqstate)
26132613

26142614
/* build a temporary HeapTuple control structure */
26152615
tuple.t_len=HeapTupleHeaderGetDatumLength(td);
2616-
ItemPointerSetInvalid(&(tuple.t_self));
2616+
tuple.t_data=td;
26172617
/* relation might be a foreign table, if so provide tableoid */
26182618
tuple.t_tableOid=erm->relid;
2619-
tuple.t_data=td;
2619+
/* also copy t_ctid in case there's valid data there */
2620+
tuple.t_self=td->t_ctid;
26202621

26212622
/* copy and store tuple */
26222623
EvalPlanQualSetTuple(epqstate,erm->rti,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp