77 * Portions Copyright (c) 1994, Regents of the University of California
88 *
99 * IDENTIFICATION
10- * $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.113 2006/12/06 19:40:01 tgl Exp $
10+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.114 2006/12/10 22:13:26 tgl Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
@@ -75,7 +75,6 @@ typedef struct convert_testexpr_context
7575{
7676int rtindex ;/* RT index for Vars, or 0 for Params */
7777List * righthandIds ;/* accumulated list of Vars or Param IDs */
78- List * sub_tlist ;/* subselect targetlist (if given) */
7978}convert_testexpr_context ;
8079
8180typedef struct finalize_primnode_context
@@ -87,8 +86,7 @@ typedef struct finalize_primnode_context
8786
8887static Node * convert_testexpr (Node * testexpr ,
8988int rtindex ,
90- List * * righthandIds ,
91- List * sub_tlist );
89+ List * * righthandIds );
9290static Node * convert_testexpr_mutator (Node * node ,
9391convert_testexpr_context * context );
9492static bool subplan_is_hashable (SubLink * slink ,SubPlan * node );
@@ -166,6 +164,7 @@ replace_outer_var(Var *var)
166164retval -> paramkind = PARAM_EXEC ;
167165retval -> paramid = i ;
168166retval -> paramtype = var -> vartype ;
167+ retval -> paramtypmod = var -> vartypmod ;
169168
170169return retval ;
171170}
@@ -204,6 +203,7 @@ replace_outer_agg(Aggref *agg)
204203retval -> paramkind = PARAM_EXEC ;
205204retval -> paramid = i ;
206205retval -> paramtype = agg -> aggtype ;
206+ retval -> paramtypmod = -1 ;
207207
208208return retval ;
209209}
@@ -212,8 +212,6 @@ replace_outer_agg(Aggref *agg)
212212 * Generate a new Param node that will not conflict with any other.
213213 *
214214 * This is used to allocate PARAM_EXEC slots for subplan outputs.
215- *
216- * paramtypmod is currently unused but might be wanted someday.
217215 */
218216static Param *
219217generate_new_param (Oid paramtype ,int32 paramtypmod )
@@ -225,6 +223,7 @@ generate_new_param(Oid paramtype, int32 paramtypmod)
225223retval -> paramkind = PARAM_EXEC ;
226224retval -> paramid = list_length (PlannerParamList );
227225retval -> paramtype = paramtype ;
226+ retval -> paramtypmod = paramtypmod ;
228227
229228pitem = (PlannerParamItem * )palloc (sizeof (PlannerParamItem ));
230229pitem -> item = (Node * )retval ;
@@ -371,7 +370,7 @@ make_subplan(SubLink *slink, Node *testexpr, bool isTopQual)
371370if (!OidIsValid (arraytype ))
372371elog (ERROR ,"could not find array type for datatype %s" ,
373372format_type_be (exprType ((Node * )te -> expr )));
374- prm = generate_new_param (arraytype ,-1 );
373+ prm = generate_new_param (arraytype ,exprTypmod (( Node * ) te -> expr ) );
375374node -> setParam = list_make1_int (prm -> paramid );
376375PlannerInitPlan = lappend (PlannerInitPlan ,node );
377376result = (Node * )prm ;
@@ -381,8 +380,7 @@ make_subplan(SubLink *slink, Node *testexpr, bool isTopQual)
381380/* Adjust the Params */
382381result = convert_testexpr (testexpr ,
3833820 ,
384- & node -> paramIds ,
385- NIL );
383+ & node -> paramIds );
386384node -> setParam = list_copy (node -> paramIds );
387385PlannerInitPlan = lappend (PlannerInitPlan ,node );
388386
@@ -399,8 +397,7 @@ make_subplan(SubLink *slink, Node *testexpr, bool isTopQual)
399397/* Adjust the Params */
400398node -> testexpr = convert_testexpr (testexpr ,
4013990 ,
402- & node -> paramIds ,
403- NIL );
400+ & node -> paramIds );
404401
405402/*
406403 * We can't convert subplans of ALL_SUBLINK or ANY_SUBLINK types to
@@ -474,10 +471,6 @@ make_subplan(SubLink *slink, Node *testexpr, bool isTopQual)
474471 * of the Var nodes are returned in *righthandIds (this is a bit of a type
475472 * cheat, but we can get away with it).
476473 *
477- * The subquery targetlist need be supplied only if rtindex is not 0.
478- * We consult it to extract the correct typmods for the created Vars.
479- * (XXX this is a kluge that could go away if Params carried typmod.)
480- *
481474 * The given testexpr has already been recursively processed by
482475 * process_sublinks_mutator. Hence it can no longer contain any
483476 * PARAM_SUBLINK Params for lower SubLink nodes; we can safely assume that
@@ -486,15 +479,13 @@ make_subplan(SubLink *slink, Node *testexpr, bool isTopQual)
486479static Node *
487480convert_testexpr (Node * testexpr ,
488481int rtindex ,
489- List * * righthandIds ,
490- List * sub_tlist )
482+ List * * righthandIds )
491483{
492484Node * result ;
493485convert_testexpr_context context ;
494486
495487context .rtindex = rtindex ;
496488context .righthandIds = NIL ;
497- context .sub_tlist = sub_tlist ;
498489result = convert_testexpr_mutator (testexpr ,& context );
499490* righthandIds = context .righthandIds ;
500491return result ;
@@ -526,23 +517,10 @@ convert_testexpr_mutator(Node *node,
526517/* Make the Var node representing the subplan's result */
527518Var * newvar ;
528519
529- /*
530- * XXX kluge: since Params don't carry typmod, we have to
531- * look into the subquery targetlist to find out the right
532- * typmod to assign to the Var.
533- */
534- TargetEntry * ste = get_tle_by_resno (context -> sub_tlist ,
535- param -> paramid );
536-
537- if (ste == NULL || ste -> resjunk )
538- elog (ERROR ,"subquery output %d not found" ,
539- param -> paramid );
540- Assert (param -> paramtype == exprType ((Node * )ste -> expr ));
541-
542520newvar = makeVar (context -> rtindex ,
543521param -> paramid ,
544522param -> paramtype ,
545- exprTypmod (( Node * ) ste -> expr ) ,
523+ param -> paramtypmod ,
5465240 );
547525
548526/*
@@ -558,7 +536,8 @@ convert_testexpr_mutator(Node *node,
558536/* Make the Param node representing the subplan's result */
559537Param * newparam ;
560538
561- newparam = generate_new_param (param -> paramtype ,-1 );
539+ newparam = generate_new_param (param -> paramtype ,
540+ param -> paramtypmod );
562541/* Record its ID */
563542context -> righthandIds = lappend_int (context -> righthandIds ,
564543newparam -> paramid );
@@ -775,8 +754,7 @@ convert_IN_to_join(PlannerInfo *root, SubLink *sublink)
775754 */
776755return convert_testexpr (sublink -> testexpr ,
777756rtindex ,
778- & ininfo -> sub_targetlist ,
779- subselect -> targetList );
757+ & ininfo -> sub_targetlist );
780758}
781759
782760/*