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

Commitc3928b4

Browse files
committed
Fix segfault during EvalPlanQual with mix of local and foreign partitions.
It's not sensible to re-evaluate a direct-modify Foreign Update or Deleteduring EvalPlanQual. However, ExecInitForeignScan() can still get calledif a table mixes local and foreign partitions. EvalPlanQualStart() leftthe es_result_relations array uninitialized in the child EPQ EState, butExecInitForeignScan() still expected to find it. That caused a segfault.Fix by skipping the es_result_relations lookup during EvalPlanQualprocessing. To make things a bit more robust, also skip theBeginDirectModify calls, and add a runtime check that ExecForeignScan()is not called on direct-modify foreign scans during EvalPlanQualprocessing.This is new in v14, commit1375422. Before that, EvalPlanQualStart()copied the whole ResultRelInfo array to the EPQ EState. Backpatch to v14.Report and diagnosis by Andrey Lepikhov.Discussion:https://www.postgresql.org/message-id/cb2b808d-cbaa-4772-76ee-c8809bafcf3d%40postgrespro.ru
1 parenta6bd28b commitc3928b4

File tree

1 file changed

+41
-5
lines changed

1 file changed

+41
-5
lines changed

‎src/backend/executor/nodeForeignscan.c

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,22 @@ ForeignNext(ForeignScanState *node)
4444
TupleTableSlot*slot;
4545
ForeignScan*plan= (ForeignScan*)node->ss.ps.plan;
4646
ExprContext*econtext=node->ss.ps.ps_ExprContext;
47+
EState*estate=node->ss.ps.state;
4748
MemoryContextoldcontext;
4849

4950
/* Call the Iterate function in short-lived context */
5051
oldcontext=MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);
5152
if (plan->operation!=CMD_SELECT)
53+
{
54+
/*
55+
* direct modifications cannot be re-evaluated, so shouldn't get here
56+
* during EvalPlanQual processing
57+
*/
58+
if (estate->es_epq_active!=NULL)
59+
elog(ERROR,"cannot re-evaluate a Foreign Update or Delete during EvalPlanQual");
60+
5261
slot=node->fdwroutine->IterateDirectModify(node);
62+
}
5363
else
5464
slot=node->fdwroutine->IterateForeignScan(node);
5565
MemoryContextSwitchTo(oldcontext);
@@ -223,11 +233,25 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags)
223233
scanstate->fdw_state=NULL;
224234

225235
/*
226-
* For the FDW's convenience, look up the modification target relation's.
227-
* ResultRelInfo.
236+
* For the FDW's convenience, look up the modification target relation's
237+
* ResultRelInfo. The ModifyTable node should have initialized it for us,
238+
* see ExecInitModifyTable.
239+
*
240+
* Don't try to look up the ResultRelInfo when EvalPlanQual is active,
241+
* though. Direct modififications cannot be re-evaluated as part of
242+
* EvalPlanQual. The lookup wouldn't work anyway because during
243+
* EvalPlanQual processing, EvalPlanQual only initializes the subtree
244+
* under the ModifyTable, and doesn't run ExecInitModifyTable.
228245
*/
229-
if (node->resultRelation>0)
246+
if (node->resultRelation>0&&estate->es_epq_active==NULL)
247+
{
248+
if (estate->es_result_relations==NULL||
249+
estate->es_result_relations[node->resultRelation-1]==NULL)
250+
{
251+
elog(ERROR,"result relation not initialized");
252+
}
230253
scanstate->resultRelInfo=estate->es_result_relations[node->resultRelation-1];
254+
}
231255

232256
/* Initialize any outer plan. */
233257
if (outerPlan(node))
@@ -238,7 +262,15 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags)
238262
* Tell the FDW to initialize the scan.
239263
*/
240264
if (node->operation!=CMD_SELECT)
241-
fdwroutine->BeginDirectModify(scanstate,eflags);
265+
{
266+
/*
267+
* Direct modifications cannot be re-evaluated by EvalPlanQual, so
268+
* don't bother preparing the FDW. There can ForeignScan nodes in the
269+
* EvalPlanQual subtree, but ExecForeignScan should never be called.
270+
*/
271+
if (estate->es_epq_active==NULL)
272+
fdwroutine->BeginDirectModify(scanstate,eflags);
273+
}
242274
else
243275
fdwroutine->BeginForeignScan(scanstate,eflags);
244276

@@ -255,10 +287,14 @@ void
255287
ExecEndForeignScan(ForeignScanState*node)
256288
{
257289
ForeignScan*plan= (ForeignScan*)node->ss.ps.plan;
290+
EState*estate=node->ss.ps.state;
258291

259292
/* Let the FDW shut down */
260293
if (plan->operation!=CMD_SELECT)
261-
node->fdwroutine->EndDirectModify(node);
294+
{
295+
if (estate->es_epq_active==NULL)
296+
node->fdwroutine->EndDirectModify(node);
297+
}
262298
else
263299
node->fdwroutine->EndForeignScan(node);
264300

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp