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

Commit178f2d5

Browse files
committed
Include result relation info in direct modify ForeignScan nodes.
FDWs that can perform an UPDATE/DELETE remotely using the "direct modify"set of APIs need to access the ResultRelInfo of the target table. That'scurrently available in EState.es_result_relation_info, but the nextcommit will remove that field.This commit adds a new resultRelation field in ForeignScan, to store thetarget relation's RT index, and the corresponding ResultRelInfo inForeignScanState. The FDW's PlanDirectModify callback is expected to set'resultRelation' along with 'operation'. The core code doesn't need themfor anything, they are for the convenience of FDW's Begin- andIterateDirectModify callbacks.Authors: Amit Langote, Etsuro FujitaDiscussion:https://www.postgresql.org/message-id/CA%2BHiwqGEmiib8FLiHMhKB%2BCH5dRgHSLc5N5wnvc4kym%2BZYpQEQ%40mail.gmail.com
1 parent39b4a95 commit178f2d5

File tree

10 files changed

+45
-13
lines changed

10 files changed

+45
-13
lines changed

‎contrib/postgres_fdw/postgres_fdw.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ static void init_returning_filter(PgFdwDirectModifyState *dmstate,
451451
List*fdw_scan_tlist,
452452
Indexrtindex);
453453
staticTupleTableSlot*apply_returning_filter(PgFdwDirectModifyState*dmstate,
454+
ResultRelInfo*resultRelInfo,
454455
TupleTableSlot*slot,
455456
EState*estate);
456457
staticvoidprepare_query_params(PlanState*node,
@@ -2287,9 +2288,10 @@ postgresPlanDirectModify(PlannerInfo *root,
22872288
}
22882289

22892290
/*
2290-
* Update the operation info.
2291+
* Update the operationand target relationinfo.
22912292
*/
22922293
fscan->operation=operation;
2294+
fscan->resultRelation=resultRelation;
22932295

22942296
/*
22952297
* Update the fdw_exprs list that will be available to the executor.
@@ -2355,7 +2357,7 @@ postgresBeginDirectModify(ForeignScanState *node, int eflags)
23552357
* Identify which user to do the remote access as. This should match what
23562358
* ExecCheckRTEPerms() does.
23572359
*/
2358-
rtindex=estate->es_result_relation_info->ri_RangeTableIndex;
2360+
rtindex=node->resultRelInfo->ri_RangeTableIndex;
23592361
rte=exec_rt_fetch(rtindex,estate);
23602362
userid=rte->checkAsUser ?rte->checkAsUser :GetUserId();
23612363

@@ -2450,7 +2452,7 @@ postgresIterateDirectModify(ForeignScanState *node)
24502452
{
24512453
PgFdwDirectModifyState*dmstate= (PgFdwDirectModifyState*)node->fdw_state;
24522454
EState*estate=node->ss.ps.state;
2453-
ResultRelInfo*resultRelInfo=estate->es_result_relation_info;
2455+
ResultRelInfo*resultRelInfo=node->resultRelInfo;
24542456

24552457
/*
24562458
* If this is the first call after Begin, execute the statement.
@@ -4086,7 +4088,7 @@ get_returning_data(ForeignScanState *node)
40864088
{
40874089
PgFdwDirectModifyState*dmstate= (PgFdwDirectModifyState*)node->fdw_state;
40884090
EState*estate=node->ss.ps.state;
4089-
ResultRelInfo*resultRelInfo=estate->es_result_relation_info;
4091+
ResultRelInfo*resultRelInfo=node->resultRelInfo;
40904092
TupleTableSlot*slot=node->ss.ss_ScanTupleSlot;
40914093
TupleTableSlot*resultSlot;
40924094

@@ -4141,7 +4143,7 @@ get_returning_data(ForeignScanState *node)
41414143
if (dmstate->rel)
41424144
resultSlot=slot;
41434145
else
4144-
resultSlot=apply_returning_filter(dmstate,slot,estate);
4146+
resultSlot=apply_returning_filter(dmstate,resultRelInfo,slot,estate);
41454147
}
41464148
dmstate->next_tuple++;
41474149

@@ -4230,10 +4232,10 @@ init_returning_filter(PgFdwDirectModifyState *dmstate,
42304232
*/
42314233
staticTupleTableSlot*
42324234
apply_returning_filter(PgFdwDirectModifyState*dmstate,
4235+
ResultRelInfo*resultRelInfo,
42334236
TupleTableSlot*slot,
42344237
EState*estate)
42354238
{
4236-
ResultRelInfo*relInfo=estate->es_result_relation_info;
42374239
TupleDescresultTupType=RelationGetDescr(dmstate->resultRel);
42384240
TupleTableSlot*resultSlot;
42394241
Datum*values;
@@ -4245,7 +4247,7 @@ apply_returning_filter(PgFdwDirectModifyState *dmstate,
42454247
/*
42464248
* Use the return tuple slot as a place to store the result tuple.
42474249
*/
4248-
resultSlot=ExecGetReturningSlot(estate,relInfo);
4250+
resultSlot=ExecGetReturningSlot(estate,resultRelInfo);
42494251

42504252
/*
42514253
* Extract all the values of the scan tuple.

‎doc/src/sgml/fdwhandler.sgml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -861,11 +861,15 @@ PlanDirectModify(PlannerInfo *root,
861861
To execute the direct modification on the remote server, this function
862862
must rewrite the target subplan with a <structname>ForeignScan</structname> plan
863863
node that executes the direct modification on the remote server. The
864-
<structfield>operation</structfield> field of the <structname>ForeignScan</structname> must
865-
be set to the <literal>CmdType</literal> enumeration appropriately; that is,
864+
<structfield>operation</structfield> and <structfield>resultRelation</structfield> fields
865+
of the <structname>ForeignScan</structname> must be set appropriately.
866+
<structfield>operation</structfield> must be set to the <literal>CmdType</literal>
867+
enumeration corresponding to the statement kind (that is,
866868
<literal>CMD_UPDATE</literal> for <command>UPDATE</command>,
867869
<literal>CMD_INSERT</literal> for <command>INSERT</command>, and
868-
<literal>CMD_DELETE</literal> for <command>DELETE</command>.
870+
<literal>CMD_DELETE</literal> for <command>DELETE</command>), and the
871+
<literal>resultRelation</literal> argument must be copied to the
872+
<structfield>resultRelation</structfield> field.
869873
</para>
870874

871875
<para>
@@ -925,9 +929,8 @@ IterateDirectModify(ForeignScanState *node);
925929
needed for the <literal>RETURNING</literal> calculation, returning it in a
926930
tuple table slot (the node's <structfield>ScanTupleSlot</structfield> should be
927931
used for this purpose). The data that was actually inserted, updated
928-
or deleted must be stored in the
929-
<literal>es_result_relation_info-&gt;ri_projectReturning-&gt;pi_exprContext-&gt;ecxt_scantuple</literal>
930-
of the node's <structname>EState</structname>.
932+
or deleted must be stored in
933+
<literal>node->resultRelInfo->ri_projectReturning-&gt;pi_exprContext-&gt;ecxt_scantuple</literal>.
931934
Return NULL if no more rows are available.
932935
Note that this is called in a short-lived memory context that will be
933936
reset between invocations. Create a memory context in

‎src/backend/executor/nodeForeignscan.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,13 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags)
215215
scanstate->fdwroutine=fdwroutine;
216216
scanstate->fdw_state=NULL;
217217

218+
/*
219+
* For the FDW's convenience, look up the modification target relation's.
220+
* ResultRelInfo.
221+
*/
222+
if (node->resultRelation>0)
223+
scanstate->resultRelInfo=estate->es_result_relations[node->resultRelation-1];
224+
218225
/* Initialize any outer plan. */
219226
if (outerPlan(node))
220227
outerPlanState(scanstate)=

‎src/backend/nodes/copyfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,7 @@ _copyForeignScan(const ForeignScan *from)
758758
COPY_NODE_FIELD(fdw_recheck_quals);
759759
COPY_BITMAPSET_FIELD(fs_relids);
760760
COPY_SCALAR_FIELD(fsSystemCol);
761+
COPY_SCALAR_FIELD(resultRelation);
761762

762763
returnnewnode;
763764
}

‎src/backend/nodes/outfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,7 @@ _outForeignScan(StringInfo str, const ForeignScan *node)
695695
WRITE_NODE_FIELD(fdw_recheck_quals);
696696
WRITE_BITMAPSET_FIELD(fs_relids);
697697
WRITE_BOOL_FIELD(fsSystemCol);
698+
WRITE_INT_FIELD(resultRelation);
698699
}
699700

700701
staticvoid

‎src/backend/nodes/readfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2014,6 +2014,7 @@ _readForeignScan(void)
20142014
READ_NODE_FIELD(fdw_recheck_quals);
20152015
READ_BITMAPSET_FIELD(fs_relids);
20162016
READ_BOOL_FIELD(fsSystemCol);
2017+
READ_INT_FIELD(resultRelation);
20172018

20182019
READ_DONE();
20192020
}

‎src/backend/optimizer/plan/createplan.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5530,7 +5530,11 @@ make_foreignscan(List *qptlist,
55305530
plan->lefttree=outer_plan;
55315531
plan->righttree=NULL;
55325532
node->scan.scanrelid=scanrelid;
5533+
5534+
/* these may be overridden by the FDW's PlanDirectModify callback. */
55335535
node->operation=CMD_SELECT;
5536+
node->resultRelation=0;
5537+
55345538
/* fs_server will be filled in by create_foreignscan_plan */
55355539
node->fs_server=InvalidOid;
55365540
node->fdw_exprs=fdw_exprs;

‎src/backend/optimizer/plan/setrefs.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,6 +1310,10 @@ set_foreignscan_references(PlannerInfo *root,
13101310
}
13111311

13121312
fscan->fs_relids=offset_relid_set(fscan->fs_relids,rtoffset);
1313+
1314+
/* Adjust resultRelation if it's valid */
1315+
if (fscan->resultRelation>0)
1316+
fscan->resultRelation+=rtoffset;
13131317
}
13141318

13151319
/*

‎src/include/nodes/execnodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1777,6 +1777,7 @@ typedef struct ForeignScanState
17771777
ScanStatess;/* its first field is NodeTag */
17781778
ExprState*fdw_recheck_quals;/* original quals not in ss.ps.qual */
17791779
Sizepscan_len;/* size of parallel coordination information */
1780+
ResultRelInfo*resultRelInfo;/* result rel info, if UPDATE or DELETE */
17801781
/* use struct pointer to avoid including fdwapi.h here */
17811782
structFdwRoutine*fdwroutine;
17821783
void*fdw_state;/* foreign-data wrapper can keep state here */

‎src/include/nodes/plannodes.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,12 +599,20 @@ typedef struct WorkTableScan
599599
* When the plan node represents a foreign join, scan.scanrelid is zero and
600600
* fs_relids must be consulted to identify the join relation. (fs_relids
601601
* is valid for simple scans as well, but will always match scan.scanrelid.)
602+
*
603+
* If the FDW's PlanDirectModify() callback decides to repurpose a ForeignScan
604+
* node to perform the UPDATE or DELETE operation directly in the remote
605+
* server, it sets 'operation' and 'resultRelation' to identify the operation
606+
* type and target relation. Note that these fields are only set if the
607+
* modification is performed *fully* remotely; otherwise, the modification is
608+
* driven by a local ModifyTable node and 'operation' is left to CMD_SELECT.
602609
* ----------------
603610
*/
604611
typedefstructForeignScan
605612
{
606613
Scanscan;
607614
CmdTypeoperation;/* SELECT/INSERT/UPDATE/DELETE */
615+
IndexresultRelation;/* direct modification target's RT index */
608616
Oidfs_server;/* OID of foreign server */
609617
List*fdw_exprs;/* expressions that FDW may evaluate */
610618
List*fdw_private;/* private data for FDW */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp