@ -44,12 +44,22 @@ ForeignNext(ForeignScanState *node)
TupleTableSlot * slot ;
TupleTableSlot * slot ;
ForeignScan * plan = ( ForeignScan * ) node - > ss . ps . plan ;
ForeignScan * plan = ( ForeignScan * ) node - > ss . ps . plan ;
ExprContext * econtext = node - > ss . ps . ps_ExprContext ;
ExprContext * econtext = node - > ss . ps . ps_ExprContext ;
EState * estate = node - > ss . ps . state ;
MemoryContext oldcontext ;
MemoryContext oldcontext ;
/* Call the Iterate function in short-lived context */
/* Call the Iterate function in short-lived context */
oldcontext = MemoryContextSwitchTo ( econtext - > ecxt_per_tuple_memory ) ;
oldcontext = MemoryContextSwitchTo ( econtext - > ecxt_per_tuple_memory ) ;
if ( plan - > operation ! = CMD_SELECT )
if ( plan - > operation ! = CMD_SELECT )
{
/*
* direct modifications cannot be re - evaluated , so shouldn ' t get here
* during EvalPlanQual processing
*/
if ( estate - > es_epq_active ! = NULL )
elog ( ERROR , " cannot re-evaluate a Foreign Update or Delete during EvalPlanQual " ) ;
slot = node - > fdwroutine - > IterateDirectModify ( node ) ;
slot = node - > fdwroutine - > IterateDirectModify ( node ) ;
}
else
else
slot = node - > fdwroutine - > IterateForeignScan ( node ) ;
slot = node - > fdwroutine - > IterateForeignScan ( node ) ;
MemoryContextSwitchTo ( oldcontext ) ;
MemoryContextSwitchTo ( oldcontext ) ;
@ -223,11 +233,25 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags)
scanstate - > fdw_state = NULL ;
scanstate - > fdw_state = NULL ;
/*
/*
* For the FDW ' s convenience , look up the modification target relation ' s .
* For the FDW ' s convenience , look up the modification target relation ' s
* ResultRelInfo .
* ResultRelInfo . The ModifyTable node should have initialized it for us ,
* see ExecInitModifyTable .
*
* Don ' t try to look up the ResultRelInfo when EvalPlanQual is active ,
* though . Direct modififications cannot be re - evaluated as part of
* EvalPlanQual . The lookup wouldn ' t work anyway because during
* EvalPlanQual processing , EvalPlanQual only initializes the subtree
* under the ModifyTable , and doesn ' t run ExecInitModifyTable .
*/
*/
if ( node - > resultRelation > 0 )
if ( node - > resultRelation > 0 & & estate - > es_epq_active = = NULL )
{
if ( estate - > es_result_relations = = NULL | |
estate - > es_result_relations [ node - > resultRelation - 1 ] = = NULL )
{
elog ( ERROR , " result relation not initialized " ) ;
}
scanstate - > resultRelInfo = estate - > es_result_relations [ node - > resultRelation - 1 ] ;
scanstate - > resultRelInfo = estate - > es_result_relations [ node - > resultRelation - 1 ] ;
}
/* Initialize any outer plan. */
/* Initialize any outer plan. */
if ( outerPlan ( node ) )
if ( outerPlan ( node ) )
@ -238,7 +262,15 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags)
* Tell the FDW to initialize the scan .
* Tell the FDW to initialize the scan .
*/
*/
if ( node - > operation ! = CMD_SELECT )
if ( node - > operation ! = CMD_SELECT )
fdwroutine - > BeginDirectModify ( scanstate , eflags ) ;
{
/*
* Direct modifications cannot be re - evaluated by EvalPlanQual , so
* don ' t bother preparing the FDW . There can ForeignScan nodes in the
* EvalPlanQual subtree , but ExecForeignScan should never be called .
*/
if ( estate - > es_epq_active = = NULL )
fdwroutine - > BeginDirectModify ( scanstate , eflags ) ;
}
else
else
fdwroutine - > BeginForeignScan ( scanstate , eflags ) ;
fdwroutine - > BeginForeignScan ( scanstate , eflags ) ;
@ -255,10 +287,14 @@ void
ExecEndForeignScan ( ForeignScanState * node )
ExecEndForeignScan ( ForeignScanState * node )
{
{
ForeignScan * plan = ( ForeignScan * ) node - > ss . ps . plan ;
ForeignScan * plan = ( ForeignScan * ) node - > ss . ps . plan ;
EState * estate = node - > ss . ps . state ;
/* Let the FDW shut down */
/* Let the FDW shut down */
if ( plan - > operation ! = CMD_SELECT )
if ( plan - > operation ! = CMD_SELECT )
node - > fdwroutine - > EndDirectModify ( node ) ;
{
if ( estate - > es_epq_active = = NULL )
node - > fdwroutine - > EndDirectModify ( node ) ;
}
else
else
node - > fdwroutine - > EndForeignScan ( node ) ;
node - > fdwroutine - > EndForeignScan ( node ) ;