aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-12-06 19:40:01 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-12-06 19:40:01 +0000
commitb307d7a6c4af2de8b6b25d5614152f7cd4378f03 (patch)
tree47787a6c88bcc0a376b6643a44ffa9277ca2168f /src
parent886a02d1cb19fe25859bd3c2d1f6a64b04cdc710 (diff)
downloadpostgresql-b307d7a6c4af2de8b6b25d5614152f7cd4378f03.tar.gz
postgresql-b307d7a6c4af2de8b6b25d5614152f7cd4378f03.zip
Fix planning of SubLinks to ensure that Vars generated from transformation of
a sublink's test expression have the correct vartypmod, rather than defaulting to -1. There's at least one place where this is important because we're expecting these Vars to be exactly equal() to those appearing in the subplan itself. This is a pretty klugy solution --- it would likely be cleaner to change Param nodes to include a typmod field --- but we can't do that in the already-released 8.2 branch. Per bug report from Hubert Fongarnand.
Diffstat (limited to 'src')
-rw-r--r--src/backend/optimizer/plan/subselect.c38
1 files changed, 31 insertions, 7 deletions
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index 94c97a55aa5..72b986002dd 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.112 2006/10/04 00:29:54 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.113 2006/12/06 19:40:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -75,6 +75,7 @@ typedef struct convert_testexpr_context
{
int rtindex; /* RT index for Vars, or 0 for Params */
List *righthandIds; /* accumulated list of Vars or Param IDs */
+ List *sub_tlist; /* subselect targetlist (if given) */
} convert_testexpr_context;
typedef struct finalize_primnode_context
@@ -86,7 +87,8 @@ typedef struct finalize_primnode_context
static Node *convert_testexpr(Node *testexpr,
int rtindex,
- List **righthandIds);
+ List **righthandIds,
+ List *sub_tlist);
static Node *convert_testexpr_mutator(Node *node,
convert_testexpr_context *context);
static bool subplan_is_hashable(SubLink *slink, SubPlan *node);
@@ -379,7 +381,8 @@ make_subplan(SubLink *slink, Node *testexpr, bool isTopQual)
/* Adjust the Params */
result = convert_testexpr(testexpr,
0,
- &node->paramIds);
+ &node->paramIds,
+ NIL);
node->setParam = list_copy(node->paramIds);
PlannerInitPlan = lappend(PlannerInitPlan, node);
@@ -396,7 +399,8 @@ make_subplan(SubLink *slink, Node *testexpr, bool isTopQual)
/* Adjust the Params */
node->testexpr = convert_testexpr(testexpr,
0,
- &node->paramIds);
+ &node->paramIds,
+ NIL);
/*
* We can't convert subplans of ALL_SUBLINK or ANY_SUBLINK types to
@@ -470,6 +474,10 @@ make_subplan(SubLink *slink, Node *testexpr, bool isTopQual)
* of the Var nodes are returned in *righthandIds (this is a bit of a type
* cheat, but we can get away with it).
*
+ * The subquery targetlist need be supplied only if rtindex is not 0.
+ * We consult it to extract the correct typmods for the created Vars.
+ * (XXX this is a kluge that could go away if Params carried typmod.)
+ *
* The given testexpr has already been recursively processed by
* process_sublinks_mutator. Hence it can no longer contain any
* PARAM_SUBLINK Params for lower SubLink nodes; we can safely assume that
@@ -478,13 +486,15 @@ make_subplan(SubLink *slink, Node *testexpr, bool isTopQual)
static Node *
convert_testexpr(Node *testexpr,
int rtindex,
- List **righthandIds)
+ List **righthandIds,
+ List *sub_tlist)
{
Node *result;
convert_testexpr_context context;
context.rtindex = rtindex;
context.righthandIds = NIL;
+ context.sub_tlist = sub_tlist;
result = convert_testexpr_mutator(testexpr, &context);
*righthandIds = context.righthandIds;
return result;
@@ -516,10 +526,23 @@ convert_testexpr_mutator(Node *node,
/* Make the Var node representing the subplan's result */
Var *newvar;
+ /*
+ * XXX kluge: since Params don't carry typmod, we have to
+ * look into the subquery targetlist to find out the right
+ * typmod to assign to the Var.
+ */
+ TargetEntry *ste = get_tle_by_resno(context->sub_tlist,
+ param->paramid);
+
+ if (ste == NULL || ste->resjunk)
+ elog(ERROR, "subquery output %d not found",
+ param->paramid);
+ Assert(param->paramtype == exprType((Node *) ste->expr));
+
newvar = makeVar(context->rtindex,
param->paramid,
param->paramtype,
- -1,
+ exprTypmod((Node *) ste->expr),
0);
/*
@@ -752,7 +775,8 @@ convert_IN_to_join(PlannerInfo *root, SubLink *sublink)
*/
return convert_testexpr(sublink->testexpr,
rtindex,
- &ininfo->sub_targetlist);
+ &ininfo->sub_targetlist,
+ subselect->targetList);
}
/*