1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-13 07:41:39 +03:00

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's
currently available in EState.es_result_relation_info, but the next
commit will remove that field.

This commit adds a new resultRelation field in ForeignScan, to store the
target relation's RT index, and the corresponding ResultRelInfo in
ForeignScanState. The FDW's PlanDirectModify callback is expected to set
'resultRelation' along with 'operation'. The core code doesn't need them
for anything, they are for the convenience of FDW's Begin- and
IterateDirectModify callbacks.

Authors: Amit Langote, Etsuro Fujita
Discussion: https://www.postgresql.org/message-id/CA%2BHiwqGEmiib8FLiHMhKB%2BCH5dRgHSLc5N5wnvc4kym%2BZYpQEQ%40mail.gmail.com
This commit is contained in:
Heikki Linnakangas
2020-10-14 10:58:38 +03:00
parent 39b4a95100
commit 178f2d560d
10 changed files with 45 additions and 13 deletions

View File

@ -451,6 +451,7 @@ static void init_returning_filter(PgFdwDirectModifyState *dmstate,
List *fdw_scan_tlist,
Index rtindex);
static TupleTableSlot *apply_returning_filter(PgFdwDirectModifyState *dmstate,
ResultRelInfo *resultRelInfo,
TupleTableSlot *slot,
EState *estate);
static void prepare_query_params(PlanState *node,
@ -2287,9 +2288,10 @@ postgresPlanDirectModify(PlannerInfo *root,
}
/*
* Update the operation info.
* Update the operation and target relation info.
*/
fscan->operation = operation;
fscan->resultRelation = resultRelation;
/*
* Update the fdw_exprs list that will be available to the executor.
@ -2355,7 +2357,7 @@ postgresBeginDirectModify(ForeignScanState *node, int eflags)
* Identify which user to do the remote access as. This should match what
* ExecCheckRTEPerms() does.
*/
rtindex = estate->es_result_relation_info->ri_RangeTableIndex;
rtindex = node->resultRelInfo->ri_RangeTableIndex;
rte = exec_rt_fetch(rtindex, estate);
userid = rte->checkAsUser ? rte->checkAsUser : GetUserId();
@ -2450,7 +2452,7 @@ postgresIterateDirectModify(ForeignScanState *node)
{
PgFdwDirectModifyState *dmstate = (PgFdwDirectModifyState *) node->fdw_state;
EState *estate = node->ss.ps.state;
ResultRelInfo *resultRelInfo = estate->es_result_relation_info;
ResultRelInfo *resultRelInfo = node->resultRelInfo;
/*
* If this is the first call after Begin, execute the statement.
@ -4086,7 +4088,7 @@ get_returning_data(ForeignScanState *node)
{
PgFdwDirectModifyState *dmstate = (PgFdwDirectModifyState *) node->fdw_state;
EState *estate = node->ss.ps.state;
ResultRelInfo *resultRelInfo = estate->es_result_relation_info;
ResultRelInfo *resultRelInfo = node->resultRelInfo;
TupleTableSlot *slot = node->ss.ss_ScanTupleSlot;
TupleTableSlot *resultSlot;
@ -4141,7 +4143,7 @@ get_returning_data(ForeignScanState *node)
if (dmstate->rel)
resultSlot = slot;
else
resultSlot = apply_returning_filter(dmstate, slot, estate);
resultSlot = apply_returning_filter(dmstate, resultRelInfo, slot, estate);
}
dmstate->next_tuple++;
@ -4230,10 +4232,10 @@ init_returning_filter(PgFdwDirectModifyState *dmstate,
*/
static TupleTableSlot *
apply_returning_filter(PgFdwDirectModifyState *dmstate,
ResultRelInfo *resultRelInfo,
TupleTableSlot *slot,
EState *estate)
{
ResultRelInfo *relInfo = estate->es_result_relation_info;
TupleDesc resultTupType = RelationGetDescr(dmstate->resultRel);
TupleTableSlot *resultSlot;
Datum *values;
@ -4245,7 +4247,7 @@ apply_returning_filter(PgFdwDirectModifyState *dmstate,
/*
* Use the return tuple slot as a place to store the result tuple.
*/
resultSlot = ExecGetReturningSlot(estate, relInfo);
resultSlot = ExecGetReturningSlot(estate, resultRelInfo);
/*
* Extract all the values of the scan tuple.