summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2019-01-11 15:53:34 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2019-01-11 15:53:34 -0500
commit4f80974990dce96771ef0e44c45999d8cc029c22 (patch)
treec161547512802e0ab638a7d0b2d2888cf4497629 /src/include
parent2763cc4a0367ef21601ecdc0c3ab1c5db24e458d (diff)
downloadpostgresql-4f80974990dce96771ef0e44c45999d8cc029c22.tar.gz
Avoid sharing PARAM_EXEC slots between different levels of NestLoop.
Up to now, createplan.c attempted to share PARAM_EXEC slots for NestLoopParams across different plan levels, if the same underlying Var was being fed down to different righthand-side subplan trees by different NestLoops. This was, I think, more of an artifact of using subselect.c's PlannerParamItem infrastructure than an explicit design goal, but anyway that was the end result. This works well enough as long as the plan tree is executing synchronously, but the feature whereby Gather can execute the parallelized subplan locally breaks it. An upper NestLoop node might execute for a row retrieved from a parallel worker, and assign a value for a PARAM_EXEC slot from that row, while the leader's copy of the parallelized subplan is suspended with a different active value of the row the Var comes from. When control eventually returns to the leader's subplan, it gets the wrong answers if the same PARAM_EXEC slot is being used within the subplan, as reported in bug #15577 from Bartosz Polnik. This is pretty reminiscent of the problem fixed in commit 46c508fbc, and the proper fix seems to be the same: don't try to share PARAM_EXEC slots across different levels of controlling NestLoop nodes. This requires decoupling NestLoopParam handling from PlannerParamItem handling, although the logic remains somewhat similar. To avoid bizarre division of labor between subselect.c and createplan.c, I decided to move all the param-slot-assignment logic for both cases out of those files and put it into a new file paramassign.c. Hopefully it's a bit better documented now, too. A regression test case for this might be nice, but we don't know a test case that triggers the problem with a suitably small amount of data. Back-patch to 9.6 where we added Gather nodes. It's conceivable that related problems exist in older branches; but without some evidence for that, I'll leave the older branches alone. Discussion: https://postgr.es/m/15577-ca61ab18904af852@postgresql.org
Diffstat (limited to 'src/include')
-rw-r--r--src/include/optimizer/paramassign.h34
-rw-r--r--src/include/optimizer/subselect.h6
2 files changed, 37 insertions, 3 deletions
diff --git a/src/include/optimizer/paramassign.h b/src/include/optimizer/paramassign.h
new file mode 100644
index 0000000000..d18c85c938
--- /dev/null
+++ b/src/include/optimizer/paramassign.h
@@ -0,0 +1,34 @@
+/*-------------------------------------------------------------------------
+ *
+ * paramassign.h
+ * Functions for assigning PARAM_EXEC slots during planning.
+ *
+ * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/optimizer/paramassign.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PARAMASSIGN_H
+#define PARAMASSIGN_H
+
+#include "nodes/relation.h"
+
+extern Param *replace_outer_var(PlannerInfo *root, Var *var);
+extern Param *replace_outer_placeholdervar(PlannerInfo *root,
+ PlaceHolderVar *phv);
+extern Param *replace_outer_agg(PlannerInfo *root, Aggref *agg);
+extern Param *replace_outer_grouping(PlannerInfo *root, GroupingFunc *grp);
+extern Param *replace_nestloop_param_var(PlannerInfo *root, Var *var);
+extern Param *replace_nestloop_param_placeholdervar(PlannerInfo *root,
+ PlaceHolderVar *phv);
+extern void process_subquery_nestloop_params(PlannerInfo *root,
+ List *subplan_params);
+extern List *identify_current_nestloop_params(PlannerInfo *root,
+ Relids leftrelids);
+extern Param *generate_new_exec_param(PlannerInfo *root, Oid paramtype,
+ int32 paramtypmod, Oid paramcollation);
+extern int assign_special_exec_param(PlannerInfo *root);
+
+#endif /* PARAMASSIGN_H */
diff --git a/src/include/optimizer/subselect.h b/src/include/optimizer/subselect.h
index f100d02940..fbf605f7cf 100644
--- a/src/include/optimizer/subselect.h
+++ b/src/include/optimizer/subselect.h
@@ -1,6 +1,7 @@
/*-------------------------------------------------------------------------
*
* subselect.h
+ * Planning routines for subselects.
*
* Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
@@ -35,9 +36,8 @@ extern Param *SS_make_initplan_output_param(PlannerInfo *root,
extern void SS_make_initplan_from_plan(PlannerInfo *root,
PlannerInfo *subroot, Plan *plan,
Param *prm);
-extern Param *assign_nestloop_param_var(PlannerInfo *root, Var *var);
-extern Param *assign_nestloop_param_placeholdervar(PlannerInfo *root,
- PlaceHolderVar *phv);
+
+/* XXX deprecated: */
extern int SS_assign_special_param(PlannerInfo *root);
#endif /* SUBSELECT_H */