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

Commit4477704

Browse files
committed
Rearrange CustomScan API.
Make it work more like FDW plans do: instead of assuming that there areexpressions in a CustomScan plan node that the core code doesn't knowabout, insist that all subexpressions that need planner attention be ina "custom_exprs" list in the Plan representation. (Of course, thecustom plugin can break the list apart again at executor initialization.)This lets us revert the parts of the patch that exposed setrefs.c andsubselect.c processing to the outside world.Also revert the GetSpecialCustomVar stuff in ruleutils.c; that conceptmay work in future, but it's far from fully baked right now.
1 parentc2ea228 commit4477704

File tree

11 files changed

+108
-163
lines changed

11 files changed

+108
-163
lines changed

‎src/backend/nodes/copyfuncs.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -603,17 +603,24 @@ _copyForeignScan(const ForeignScan *from)
603603
staticCustomScan*
604604
_copyCustomScan(constCustomScan*from)
605605
{
606-
CustomScan*newnode;
607-
608-
newnode=from->methods->CopyCustomScan(from);
609-
Assert(nodeTag(newnode)==nodeTag(from));
606+
CustomScan*newnode=makeNode(CustomScan);
610607

608+
/*
609+
* copy node superclass fields
610+
*/
611611
CopyScanFields((constScan*)from, (Scan*)newnode);
612+
613+
/*
614+
* copy remainder of node
615+
*/
612616
COPY_SCALAR_FIELD(flags);
617+
COPY_NODE_FIELD(custom_exprs);
618+
COPY_NODE_FIELD(custom_private);
619+
613620
/*
614-
* NOTE: The method field of CustomScan is required to be a pointer
615-
*to astatic table of callback functions.So, we don't copy the
616-
*table itself,just reference the original one.
621+
* NOTE: The method field of CustomScan is required to be a pointer to a
622+
* static table of callback functions. So we don't copy the table itself,
623+
* just reference the original one.
617624
*/
618625
COPY_SCALAR_FIELD(methods);
619626

‎src/backend/nodes/outfuncs.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -569,10 +569,14 @@ _outCustomScan(StringInfo str, const CustomScan *node)
569569
WRITE_NODE_TYPE("CUSTOMSCAN");
570570

571571
_outScanInfo(str, (constScan*)node);
572+
572573
WRITE_UINT_FIELD(flags);
573-
appendStringInfo(str," :methods");
574+
WRITE_NODE_FIELD(custom_exprs);
575+
WRITE_NODE_FIELD(custom_private);
576+
appendStringInfoString(str," :methods ");
574577
_outToken(str,node->methods->CustomName);
575-
node->methods->TextOutCustomScan(str,node);
578+
if (node->methods->TextOutCustomScan)
579+
node->methods->TextOutCustomScan(str,node);
576580
}
577581

578582
staticvoid
@@ -1600,11 +1604,15 @@ static void
16001604
_outCustomPath(StringInfostr,constCustomPath*node)
16011605
{
16021606
WRITE_NODE_TYPE("CUSTOMPATH");
1607+
16031608
_outPathInfo(str, (constPath*)node);
1609+
16041610
WRITE_UINT_FIELD(flags);
1605-
appendStringInfo(str," :methods");
1611+
WRITE_NODE_FIELD(custom_private);
1612+
appendStringInfoString(str," :methods ");
16061613
_outToken(str,node->methods->CustomName);
1607-
node->methods->TextOutCustomPath(str,node);
1614+
if (node->methods->TextOutCustomPath)
1615+
node->methods->TextOutCustomPath(str,node);
16081616
}
16091617

16101618
staticvoid

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

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ static WorkTableScan *create_worktablescan_plan(PlannerInfo *root, Path *best_pa
7777
List*tlist,List*scan_clauses);
7878
staticForeignScan*create_foreignscan_plan(PlannerInfo*root,ForeignPath*best_path,
7979
List*tlist,List*scan_clauses);
80-
staticPlan*create_customscan_plan(PlannerInfo*root,
80+
staticCustomScan*create_customscan_plan(PlannerInfo*root,
8181
CustomPath*best_path,
8282
List*tlist,List*scan_clauses);
8383
staticNestLoop*create_nestloop_plan(PlannerInfo*root,NestPath*best_path,
@@ -86,6 +86,7 @@ static MergeJoin *create_mergejoin_plan(PlannerInfo *root, MergePath *best_path,
8686
Plan*outer_plan,Plan*inner_plan);
8787
staticHashJoin*create_hashjoin_plan(PlannerInfo*root,HashPath*best_path,
8888
Plan*outer_plan,Plan*inner_plan);
89+
staticNode*replace_nestloop_params(PlannerInfo*root,Node*expr);
8990
staticNode*replace_nestloop_params_mutator(Node*node,PlannerInfo*root);
9091
staticvoidprocess_subquery_nestloop_params(PlannerInfo*root,
9192
List*subplan_params);
@@ -413,10 +414,10 @@ create_scan_plan(PlannerInfo *root, Path *best_path)
413414
break;
414415

415416
caseT_CustomScan:
416-
plan=create_customscan_plan(root,
417-
(CustomPath*)best_path,
418-
tlist,
419-
scan_clauses);
417+
plan=(Plan*)create_customscan_plan(root,
418+
(CustomPath*)best_path,
419+
tlist,
420+
scan_clauses);
420421
break;
421422

422423
default:
@@ -2022,11 +2023,11 @@ create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path,
20222023
*
20232024
* Transform a CustomPath into a Plan.
20242025
*/
2025-
staticPlan*
2026+
staticCustomScan*
20262027
create_customscan_plan(PlannerInfo*root,CustomPath*best_path,
20272028
List*tlist,List*scan_clauses)
20282029
{
2029-
Plan*plan;
2030+
CustomScan*cplan;
20302031
RelOptInfo*rel=best_path->path.parent;
20312032

20322033
/*
@@ -2045,23 +2046,35 @@ create_customscan_plan(PlannerInfo *root, CustomPath *best_path,
20452046
* Invoke custom plan provider to create the Plan node represented by the
20462047
* CustomPath.
20472048
*/
2048-
plan=best_path->methods->PlanCustomPath(root,rel,best_path,tlist,
2049-
scan_clauses);
2049+
cplan= (CustomScan*)best_path->methods->PlanCustomPath(root,
2050+
rel,
2051+
best_path,
2052+
tlist,
2053+
scan_clauses);
2054+
Assert(IsA(cplan,CustomScan));
20502055

20512056
/*
2052-
* NOTE: unlike create_foreignscan_plan(), it is the responsibility of the
2053-
* custom plan provider to replace outer-relation variables with nestloop
2054-
* params, because we cannot know what expression trees may be held in
2055-
* private fields.
2057+
* Copy cost data from Path to Plan; no need to make custom-plan providers
2058+
* do this
20562059
*/
2060+
copy_path_costsize(&cplan->scan.plan,&best_path->path);
20572061

20582062
/*
2059-
* Copy cost data from Path to Plan; no need to make custom-plan providers
2060-
* do this
2063+
* Replace any outer-relation variables with nestloop params in the qual
2064+
* and custom_exprs expressions. We do this last so that the custom-plan
2065+
* provider doesn't have to be involved. (Note that parts of custom_exprs
2066+
* could have come from join clauses, so doing this beforehand on the
2067+
* scan_clauses wouldn't work.)
20612068
*/
2062-
copy_path_costsize(plan,&best_path->path);
2069+
if (best_path->path.param_info)
2070+
{
2071+
cplan->scan.plan.qual= (List*)
2072+
replace_nestloop_params(root, (Node*)cplan->scan.plan.qual);
2073+
cplan->custom_exprs= (List*)
2074+
replace_nestloop_params(root, (Node*)cplan->custom_exprs);
2075+
}
20632076

2064-
returnplan;
2077+
returncplan;
20652078
}
20662079

20672080

@@ -2598,7 +2611,7 @@ create_hashjoin_plan(PlannerInfo *root,
25982611
* root->curOuterRels are replaced by Params, and entries are added to
25992612
* root->curOuterParams if not already present.
26002613
*/
2601-
Node*
2614+
staticNode*
26022615
replace_nestloop_params(PlannerInfo*root,Node*expr)
26032616
{
26042617
/* No setup needed for tree walk, so away we go */

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

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ static Plan *set_subqueryscan_references(PlannerInfo *root,
9494
SubqueryScan*plan,
9595
intrtoffset);
9696
staticbooltrivial_subqueryscan(SubqueryScan*plan);
97+
staticNode*fix_scan_expr(PlannerInfo*root,Node*node,intrtoffset);
9798
staticNode*fix_scan_expr_mutator(Node*node,fix_scan_expr_context*context);
9899
staticboolfix_scan_expr_walker(Node*node,fix_scan_expr_context*context);
99100
staticvoidset_join_references(PlannerInfo*root,Join*join,intrtoffset);
@@ -580,23 +581,15 @@ set_plan_refs(PlannerInfo *root, Plan *plan, int rtoffset)
580581

581582
caseT_CustomScan:
582583
{
583-
CustomScan*cscan= (CustomScan*)plan;
584+
CustomScan*splan= (CustomScan*)plan;
584585

585-
cscan->scan.scanrelid+=rtoffset;
586-
cscan->scan.plan.targetlist=
587-
fix_scan_list(root,cscan->scan.plan.targetlist,rtoffset);
588-
cscan->scan.plan.qual=
589-
fix_scan_list(root,cscan->scan.plan.qual,rtoffset);
590-
591-
/*
592-
* The core implementation applies the routine to fixup varno
593-
* on the target-list and scan qualifier. If custom-scan has
594-
* additional expression nodes on its private fields, it has
595-
* to apply same fixup on them. Otherwise, the custom-plan
596-
* provider can skip this callback.
597-
*/
598-
if (cscan->methods->SetCustomScanRef)
599-
cscan->methods->SetCustomScanRef(root,cscan,rtoffset);
586+
splan->scan.scanrelid+=rtoffset;
587+
splan->scan.plan.targetlist=
588+
fix_scan_list(root,splan->scan.plan.targetlist,rtoffset);
589+
splan->scan.plan.qual=
590+
fix_scan_list(root,splan->scan.plan.qual,rtoffset);
591+
splan->custom_exprs=
592+
fix_scan_list(root,splan->custom_exprs,rtoffset);
600593
}
601594
break;
602595

@@ -1182,7 +1175,7 @@ fix_param_node(PlannerInfo *root, Param *p)
11821175
* looking up operator opcode info for OpExpr and related nodes,
11831176
* and adding OIDs from regclass Const nodes into root->glob->relationOids.
11841177
*/
1185-
Node*
1178+
staticNode*
11861179
fix_scan_expr(PlannerInfo*root,Node*node,intrtoffset)
11871180
{
11881181
fix_scan_expr_contextcontext;

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

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2284,24 +2284,9 @@ finalize_plan(PlannerInfo *root, Plan *plan, Bitmapset *valid_params,
22842284
break;
22852285

22862286
caseT_CustomScan:
2287-
{
2288-
CustomScan*custom_scan= (CustomScan*)plan;
2289-
2290-
context.paramids=bms_add_members(context.paramids,
2291-
scan_params);
2292-
/*
2293-
* custom-scan provider is responsible to apply
2294-
* finalize_primnode() on the expression node of
2295-
* its private fields, but no need to apply it
2296-
* on the tlist and qual of Plan node because it
2297-
* is already done above.
2298-
*/
2299-
if (custom_scan->methods->FinalizeCustomScan)
2300-
custom_scan->methods->FinalizeCustomScan(root,
2301-
custom_scan,
2302-
finalize_primnode,
2303-
(void*)&context);
2304-
}
2287+
finalize_primnode((Node*) ((CustomScan*)plan)->custom_exprs,
2288+
&context);
2289+
context.paramids=bms_add_members(context.paramids,scan_params);
23052290
break;
23062291

23072292
caseT_ModifyTable:

‎src/backend/utils/adt/ruleutils.c

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -5493,26 +5493,6 @@ get_utility_query_def(Query *query, deparse_context *context)
54935493
}
54945494
}
54955495

5496-
/*
5497-
* GetSpecialCustomVar
5498-
*
5499-
* If a custom-scan provider uses a special varnode, this function will be
5500-
* called when deparsing; it should return an Expr node to be reversed-listed
5501-
* in lieu of the special Var.
5502-
*/
5503-
staticNode*
5504-
GetSpecialCustomVar(CustomScanState*css,Var*varnode,PlanState**child_ps)
5505-
{
5506-
Assert(IsA(css,CustomScanState));
5507-
Assert(IS_SPECIAL_VARNO(varnode->varno));
5508-
5509-
if (!css->methods->GetSpecialCustomVar)
5510-
ereport(ERROR,
5511-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
5512-
errmsg("%s does not support special varno reference",
5513-
css->methods->CustomName)));
5514-
return (Node*)css->methods->GetSpecialCustomVar(css,varnode,child_ps);
5515-
}
55165496

55175497
/*
55185498
* Display a Var appropriately.
@@ -5542,8 +5522,6 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
55425522
intnetlevelsup;
55435523
deparse_namespace*dpns;
55445524
deparse_columns*colinfo;
5545-
PlanState*child_ps=NULL;
5546-
Node*expr;
55475525
char*refname;
55485526
char*attname;
55495527

@@ -5568,29 +5546,6 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
55685546
colinfo=deparse_columns_fetch(var->varno,dpns);
55695547
attnum=var->varattno;
55705548
}
5571-
elseif (IS_SPECIAL_VARNO(var->varno)&&
5572-
IsA(dpns->planstate,CustomScanState)&&
5573-
(expr=GetSpecialCustomVar((CustomScanState*)dpns->planstate,
5574-
var,&child_ps))!=NULL)
5575-
{
5576-
deparse_namespacesave_dpns;
5577-
5578-
if (child_ps)
5579-
push_child_plan(dpns,child_ps,&save_dpns);
5580-
/*
5581-
* Force parentheses because our caller probably assumed a Var is a
5582-
* simple expression.
5583-
*/
5584-
if (!IsA(expr,Var))
5585-
appendStringInfoChar(buf,'(');
5586-
get_rule_expr((Node*)expr,context, true);
5587-
if (!IsA(expr,Var))
5588-
appendStringInfoChar(buf,')');
5589-
5590-
if (child_ps)
5591-
pop_child_plan(dpns,&save_dpns);
5592-
returnNULL;
5593-
}
55945549
elseif (var->varno==OUTER_VAR&&dpns->outer_tlist)
55955550
{
55965551
TargetEntry*tle;
@@ -5805,7 +5760,6 @@ get_name_for_var_field(Var *var, int fieldno,
58055760
AttrNumberattnum;
58065761
intnetlevelsup;
58075762
deparse_namespace*dpns;
5808-
PlanState*child_ps=NULL;
58095763
TupleDesctupleDesc;
58105764
Node*expr;
58115765

@@ -5880,30 +5834,6 @@ get_name_for_var_field(Var *var, int fieldno,
58805834
rte=rt_fetch(var->varno,dpns->rtable);
58815835
attnum=var->varattno;
58825836
}
5883-
elseif (IS_SPECIAL_VARNO(var->varno)&&
5884-
IsA(dpns->planstate,CustomScanState)&&
5885-
(expr=GetSpecialCustomVar((CustomScanState*)dpns->planstate,
5886-
var,&child_ps))!=NULL)
5887-
{
5888-
StringInfosaved=context->buf;
5889-
StringInfoDatatemp;
5890-
deparse_namespacesave_dpns;
5891-
5892-
initStringInfo(&temp);
5893-
context->buf=&temp;
5894-
5895-
if (child_ps)
5896-
push_child_plan(dpns,child_ps,&save_dpns);
5897-
if (!IsA(expr,Var))
5898-
appendStringInfoChar(context->buf,'(');
5899-
get_rule_expr((Node*)expr,context, true);
5900-
if (!IsA(expr,Var))
5901-
appendStringInfoChar(context->buf,')');
5902-
if (child_ps)
5903-
pop_child_plan(dpns,&save_dpns);
5904-
context->buf=saved;
5905-
returntemp.data;
5906-
}
59075837
elseif (var->varno==OUTER_VAR&&dpns->outer_tlist)
59085838
{
59095839
TargetEntry*tle;

‎src/include/executor/nodeCustom.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
externCustomScanState*ExecInitCustomScan(CustomScan*custom_scan,
2121
EState*estate,inteflags);
2222
externTupleTableSlot*ExecCustomScan(CustomScanState*node);
23-
externNode*MultiExecCustomScan(CustomScanState*node);
2423
externvoidExecEndCustomScan(CustomScanState*node);
2524

2625
externvoidExecReScanCustomScan(CustomScanState*node);

‎src/include/nodes/execnodes.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,9 +1503,16 @@ typedef struct ForeignScanState
15031503
}ForeignScanState;
15041504

15051505
/* ----------------
1506-
* CustomScanState information
1506+
* CustomScanState information
15071507
*
15081508
*CustomScan nodes are used to execute custom code within executor.
1509+
*
1510+
* Core code must avoid assuming that the CustomScanState is only as large as
1511+
* the structure declared here; providers are allowed to make it the first
1512+
* element in a larger structure, and typically would need to do so. The
1513+
* struct is actually allocated by the CreateCustomScanState method associated
1514+
* with the plan node. Any additional fields can be initialized there, or in
1515+
* the BeginCustomScan method.
15091516
* ----------------
15101517
*/
15111518
structExplainState;/* avoid including explain.h here */
@@ -1515,7 +1522,7 @@ typedef struct CustomExecMethods
15151522
{
15161523
constchar*CustomName;
15171524

1518-
/*EXECUTOR methods */
1525+
/*Executor methods: mark/restore are optional, the rest are required */
15191526
void(*BeginCustomScan) (structCustomScanState*node,
15201527
EState*estate,
15211528
inteflags);
@@ -1525,13 +1532,10 @@ typedef struct CustomExecMethods
15251532
void(*MarkPosCustomScan) (structCustomScanState*node);
15261533
void(*RestrPosCustomScan) (structCustomScanState*node);
15271534

1528-
/*EXPLAIN support */
1535+
/*Optional: print additional information in EXPLAIN */
15291536
void(*ExplainCustomScan) (structCustomScanState*node,
15301537
List*ancestors,
15311538
structExplainState*es);
1532-
Node*(*GetSpecialCustomVar) (structCustomScanState*node,
1533-
Var*varnode,
1534-
PlanState**child_ps);
15351539
}CustomExecMethods;
15361540

15371541
typedefstructCustomScanState

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp