8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/optimizer/util/var.c,v 1.63 2004/12/31 22: 00:23 pgsql Exp $
11
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/var.c,v 1.63.4.1 2010/07/08 00:14:33 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 ,
@@ -478,6 +480,14 @@ pull_var_clause_walker(Node *node, pull_var_clause_context *context)
478
480
* is necessary since we will not scan the JOIN as a base relation, which
479
481
* is the only way that the executor can directly handle whole-row Vars.
480
482
*
483
+ * If a JOIN contains sub-selects that have been flattened, its join alias
484
+ * entries might now be arbitrary expressions, not just Vars. This affects
485
+ * this function in one important way: we might find ourselves inserting
486
+ * SubLink expressions into subqueries, and we must make sure that their
487
+ * Query.hasSubLinks fields get set to TRUE if so. If there are any
488
+ * SubLinks in the join alias lists, the outer Query should already have
489
+ * hasSubLinks = TRUE, so this is only relevant to un-flattened subqueries.
490
+ *
481
491
* NOTE: this is used on not-yet-planned expressions. We do not expect it
482
492
* to be applied directly to a Query node.
483
493
*/
@@ -488,6 +498,10 @@ flatten_join_alias_vars(Query *root, Node *node)
488
498
489
499
context .root = root ;
490
500
context .sublevels_up = 0 ;
501
+ /* flag whether join aliases could possibly contain SubLinks */
502
+ context .possible_sublink = root -> hasSubLinks ;
503
+ /* if hasSubLinks is already true, no need to work hard */
504
+ context .inserted_sublink = root -> hasSubLinks ;
491
505
492
506
return flatten_join_alias_vars_mutator (node , & context );
493
507
}
@@ -539,6 +553,7 @@ flatten_join_alias_vars_mutator(Node *node,
539
553
IncrementVarSublevelsUp (newvar , context -> sublevels_up , 0 );
540
554
}
541
555
/* Recurse in case join input is itself a join */
556
+ /* (also takes care of setting inserted_sublink if needed) */
542
557
newvar = flatten_join_alias_vars_mutator (newvar , context );
543
558
fields = lappend (fields , newvar );
544
559
}
@@ -563,8 +578,15 @@ flatten_join_alias_vars_mutator(Node *node,
563
578
newvar = copyObject (newvar );
564
579
IncrementVarSublevelsUp (newvar , context -> sublevels_up , 0 );
565
580
}
581
+
566
582
/* Recurse in case join input is itself a join */
567
- return flatten_join_alias_vars_mutator (newvar , context );
583
+ newvar = flatten_join_alias_vars_mutator (newvar , context );
584
+
585
+ /* Detect if we are adding a sublink to query */
586
+ if (context -> possible_sublink && !context -> inserted_sublink )
587
+ context -> inserted_sublink = checkExprHasSubLink (newvar );
588
+
589
+ return newvar ;
568
590
}
569
591
if (IsA (node , InClauseInfo ))
570
592
{
@@ -589,12 +611,17 @@ flatten_join_alias_vars_mutator(Node *node,
589
611
{
590
612
/* Recurse into RTE subquery or not-yet-planned sublink subquery */
591
613
Query * newnode ;
614
+ bool save_inserted_sublink ;
592
615
593
616
context -> sublevels_up ++ ;
617
+ save_inserted_sublink = context -> inserted_sublink ;
618
+ context -> inserted_sublink = ((Query * ) node )-> hasSubLinks ;
594
619
newnode = query_tree_mutator ((Query * ) node ,
595
620
flatten_join_alias_vars_mutator ,
596
621
(void * ) context ,
597
622
QTW_IGNORE_JOINALIASES );
623
+ newnode -> hasSubLinks |= context -> inserted_sublink ;
624
+ context -> inserted_sublink = save_inserted_sublink ;
598
625
context -> sublevels_up -- ;
599
626
return (Node * ) newnode ;
600
627
}
0 commit comments