88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.54 2003/08 /08 21:41:55 momjian Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/var.c,v 1.54.4.1 2010/07 /08 00:14:41 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -51,6 +51,8 @@ typedef struct
5151{
5252 Query * root ;
5353 int sublevels_up ;
54+ bool possible_sublink ; /* could aliases include a SubLink? */
55+ bool inserted_sublink ; /* have we inserted a SubLink? */
5456} flatten_join_alias_vars_context ;
5557
5658static bool pull_varnos_walker (Node * node ,
@@ -488,6 +490,14 @@ pull_var_clause_walker(Node *node, pull_var_clause_context *context)
488490 * relation variables instead. This allows quals involving such vars to be
489491 * pushed down.
490492 *
493+ * If a JOIN contains sub-selects that have been flattened, its join alias
494+ * entries might now be arbitrary expressions, not just Vars. This affects
495+ * this function in one important way: we might find ourselves inserting
496+ * SubLink expressions into subqueries, and we must make sure that their
497+ * Query.hasSubLinks fields get set to TRUE if so. If there are any
498+ * SubLinks in the join alias lists, the outer Query should already have
499+ * hasSubLinks = TRUE, so this is only relevant to un-flattened subqueries.
500+ *
491501 * NOTE: this is used on not-yet-planned expressions. We do not expect it
492502 * to be applied directly to a Query node.
493503 */
@@ -498,6 +508,10 @@ flatten_join_alias_vars(Query *root, Node *node)
498508
499509 context .root = root ;
500510 context .sublevels_up = 0 ;
511+ /* flag whether join aliases could possibly contain SubLinks */
512+ context .possible_sublink = root -> hasSubLinks ;
513+ /* if hasSubLinks is already true, no need to work hard */
514+ context .inserted_sublink = root -> hasSubLinks ;
501515
502516 return flatten_join_alias_vars_mutator (node , & context );
503517}
@@ -533,8 +547,15 @@ flatten_join_alias_vars_mutator(Node *node,
533547 newvar = copyObject (newvar );
534548 IncrementVarSublevelsUp (newvar , context -> sublevels_up , 0 );
535549 }
550+
536551 /* Recurse in case join input is itself a join */
537- return flatten_join_alias_vars_mutator (newvar , context );
552+ newvar = flatten_join_alias_vars_mutator (newvar , context );
553+
554+ /* Detect if we are adding a sublink to query */
555+ if (context -> possible_sublink && !context -> inserted_sublink )
556+ context -> inserted_sublink = checkExprHasSubLink (newvar );
557+
558+ return newvar ;
538559 }
539560 if (IsA (node , InClauseInfo ))
540561 {
@@ -559,12 +580,17 @@ flatten_join_alias_vars_mutator(Node *node,
559580 {
560581 /* Recurse into RTE subquery or not-yet-planned sublink subquery */
561582 Query * newnode ;
583+ bool save_inserted_sublink ;
562584
563585 context -> sublevels_up ++ ;
586+ save_inserted_sublink = context -> inserted_sublink ;
587+ context -> inserted_sublink = ((Query * ) node )-> hasSubLinks ;
564588 newnode = query_tree_mutator ((Query * ) node ,
565589 flatten_join_alias_vars_mutator ,
566590 (void * ) context ,
567591 QTW_IGNORE_JOINALIASES );
592+ newnode -> hasSubLinks |= context -> inserted_sublink ;
593+ context -> inserted_sublink = save_inserted_sublink ;
568594 context -> sublevels_up -- ;
569595 return (Node * ) newnode ;
570596 }
0 commit comments