8
8
*
9
9
*
10
10
* 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 $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -51,6 +51,8 @@ typedef struct
51
51
{
52
52
Query * root ;
53
53
int sublevels_up ;
54
+ bool possible_sublink ; /* could aliases include a SubLink? */
55
+ bool inserted_sublink ; /* have we inserted a SubLink? */
54
56
} flatten_join_alias_vars_context ;
55
57
56
58
static bool pull_varnos_walker (Node * node ,
@@ -488,6 +490,14 @@ pull_var_clause_walker(Node *node, pull_var_clause_context *context)
488
490
* relation variables instead. This allows quals involving such vars to be
489
491
* pushed down.
490
492
*
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
+ *
491
501
* NOTE: this is used on not-yet-planned expressions. We do not expect it
492
502
* to be applied directly to a Query node.
493
503
*/
@@ -498,6 +508,10 @@ flatten_join_alias_vars(Query *root, Node *node)
498
508
499
509
context .root = root ;
500
510
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 ;
501
515
502
516
return flatten_join_alias_vars_mutator (node , & context );
503
517
}
@@ -533,8 +547,15 @@ flatten_join_alias_vars_mutator(Node *node,
533
547
newvar = copyObject (newvar );
534
548
IncrementVarSublevelsUp (newvar , context -> sublevels_up , 0 );
535
549
}
550
+
536
551
/* 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 ;
538
559
}
539
560
if (IsA (node , InClauseInfo ))
540
561
{
@@ -559,12 +580,17 @@ flatten_join_alias_vars_mutator(Node *node,
559
580
{
560
581
/* Recurse into RTE subquery or not-yet-planned sublink subquery */
561
582
Query * newnode ;
583
+ bool save_inserted_sublink ;
562
584
563
585
context -> sublevels_up ++ ;
586
+ save_inserted_sublink = context -> inserted_sublink ;
587
+ context -> inserted_sublink = ((Query * ) node )-> hasSubLinks ;
564
588
newnode = query_tree_mutator ((Query * ) node ,
565
589
flatten_join_alias_vars_mutator ,
566
590
(void * ) context ,
567
591
QTW_IGNORE_JOINALIASES );
592
+ newnode -> hasSubLinks |= context -> inserted_sublink ;
593
+ context -> inserted_sublink = save_inserted_sublink ;
568
594
context -> sublevels_up -- ;
569
595
return (Node * ) newnode ;
570
596
}
0 commit comments