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

Back-patch fix for subselect in targetlist of Append node.

This commit is contained in:
Tom Lane
2000-09-23 23:41:05 +00:00
parent 0e0832b0dd
commit 783af51cb1

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.62 2000/04/12 17:15:22 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.62.2.1 2000/09/23 23:41:05 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -17,12 +17,10 @@
#include "postgres.h" #include "postgres.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h" #include "nodes/nodeFuncs.h"
#include "optimizer/clauses.h" #include "optimizer/clauses.h"
#include "optimizer/planmain.h" #include "optimizer/planmain.h"
#include "optimizer/tlist.h" #include "optimizer/tlist.h"
#include "optimizer/var.h"
typedef struct typedef struct
{ {
@ -37,6 +35,7 @@ typedef struct
List *subplanTargetList; List *subplanTargetList;
} replace_vars_with_subplan_refs_context; } replace_vars_with_subplan_refs_context;
static void fix_expr_references(Plan *plan, Node *node);
static void set_join_references(Join *join); static void set_join_references(Join *join);
static void set_uppernode_references(Plan *plan, Index subvarno); static void set_uppernode_references(Plan *plan, Index subvarno);
static Node *join_references_mutator(Node *node, static Node *join_references_mutator(Node *node,
@ -88,34 +87,39 @@ set_plan_references(Plan *plan)
switch (nodeTag(plan)) switch (nodeTag(plan))
{ {
case T_SeqScan: case T_SeqScan:
/* nothing special */ fix_expr_references(plan, (Node *) plan->targetlist);
fix_expr_references(plan, (Node *) plan->qual);
break; break;
case T_IndexScan: case T_IndexScan:
fix_opids((Node *) ((IndexScan *) plan)->indxqual); fix_expr_references(plan, (Node *) plan->targetlist);
fix_opids((Node *) ((IndexScan *) plan)->indxqualorig); fix_expr_references(plan, (Node *) plan->qual);
plan->subPlan = fix_expr_references(plan,
nconc(plan->subPlan, (Node *) ((IndexScan *) plan)->indxqual);
pull_subplans((Node *) ((IndexScan *) plan)->indxqual)); fix_expr_references(plan,
plan->subPlan = (Node *) ((IndexScan *) plan)->indxqualorig);
nconc(plan->subPlan, break;
pull_subplans((Node *) ((IndexScan *) plan)->indxqualorig)); case T_TidScan:
fix_expr_references(plan, (Node *) plan->targetlist);
fix_expr_references(plan, (Node *) plan->qual);
break; break;
case T_NestLoop: case T_NestLoop:
set_join_references((Join *) plan); set_join_references((Join *) plan);
fix_expr_references(plan, (Node *) plan->targetlist);
fix_expr_references(plan, (Node *) plan->qual);
break; break;
case T_MergeJoin: case T_MergeJoin:
set_join_references((Join *) plan); set_join_references((Join *) plan);
fix_opids((Node *) ((MergeJoin *) plan)->mergeclauses); fix_expr_references(plan, (Node *) plan->targetlist);
plan->subPlan = fix_expr_references(plan, (Node *) plan->qual);
nconc(plan->subPlan, fix_expr_references(plan,
pull_subplans((Node *) ((MergeJoin *) plan)->mergeclauses)); (Node *) ((MergeJoin *) plan)->mergeclauses);
break; break;
case T_HashJoin: case T_HashJoin:
set_join_references((Join *) plan); set_join_references((Join *) plan);
fix_opids((Node *) ((HashJoin *) plan)->hashclauses); fix_expr_references(plan, (Node *) plan->targetlist);
plan->subPlan = fix_expr_references(plan, (Node *) plan->qual);
nconc(plan->subPlan, fix_expr_references(plan,
pull_subplans((Node *) ((HashJoin *) plan)->hashclauses)); (Node *) ((HashJoin *) plan)->hashclauses);
break; break;
case T_Material: case T_Material:
case T_Sort: case T_Sort:
@ -127,12 +131,17 @@ set_plan_references(Plan *plan)
* targetlists or quals (because they just return their * targetlists or quals (because they just return their
* unmodified input tuples). The optimizer is lazy about * unmodified input tuples). The optimizer is lazy about
* creating really valid targetlists for them. Best to just * creating really valid targetlists for them. Best to just
* leave the targetlist alone. * leave the targetlist alone. In particular, we do not want
* to pull a subplan list for them, since we will likely end
* up with duplicate list entries for subplans that also appear
* in lower levels of the plan tree!
*/ */
break; break;
case T_Agg: case T_Agg:
case T_Group: case T_Group:
set_uppernode_references(plan, (Index) 0); set_uppernode_references(plan, (Index) 0);
fix_expr_references(plan, (Node *) plan->targetlist);
fix_expr_references(plan, (Node *) plan->qual);
break; break;
case T_Result: case T_Result:
@ -144,37 +153,25 @@ set_plan_references(Plan *plan)
*/ */
if (plan->lefttree != NULL) if (plan->lefttree != NULL)
set_uppernode_references(plan, (Index) OUTER); set_uppernode_references(plan, (Index) OUTER);
fix_opids(((Result *) plan)->resconstantqual); fix_expr_references(plan, (Node *) plan->targetlist);
plan->subPlan = fix_expr_references(plan, (Node *) plan->qual);
nconc(plan->subPlan, fix_expr_references(plan, ((Result *) plan)->resconstantqual);
pull_subplans(((Result *) plan)->resconstantqual));
break; break;
case T_Append: case T_Append:
/*
* Append, like Sort et al, doesn't actually evaluate its
* targetlist or quals, and we haven't bothered to give it
* its own tlist copy. So, don't fix targetlist/qual.
*/
foreach(pl, ((Append *) plan)->appendplans) foreach(pl, ((Append *) plan)->appendplans)
set_plan_references((Plan *) lfirst(pl)); set_plan_references((Plan *) lfirst(pl));
break; break;
case T_TidScan:
/* nothing special */
break;
default: default:
elog(ERROR, "set_plan_references: unknown plan type %d", elog(ERROR, "set_plan_references: unknown plan type %d",
nodeTag(plan)); nodeTag(plan));
break; break;
} }
/*
* For all plan types, fix operators in targetlist and qual
* expressions, and find subplans therein.
*/
fix_opids((Node *) plan->targetlist);
fix_opids((Node *) plan->qual);
plan->subPlan =
nconc(plan->subPlan,
pull_subplans((Node *) plan->targetlist));
plan->subPlan =
nconc(plan->subPlan,
pull_subplans((Node *) plan->qual));
/* /*
* Now recurse into subplans, if any * Now recurse into subplans, if any
* *
@ -202,6 +199,20 @@ set_plan_references(Plan *plan)
} }
} }
/*
* fix_expr_references
* Do final cleanup on expressions (targetlists or quals).
*
* This consists of looking up operator opcode info for Oper nodes
* and adding subplans to the Plan node's list of contained subplans.
*/
static void
fix_expr_references(Plan *plan, Node *node)
{
fix_opids(node);
plan->subPlan = nconc(plan->subPlan, pull_subplans(node));
}
/* /*
* set_join_references * set_join_references
* Modifies the target list of a join node to reference its subplans, * Modifies the target list of a join node to reference its subplans,