14
14
*
15
15
*
16
16
* IDENTIFICATION
17
- * $PostgreSQL: pgsql/src/backend/optimizer/util/var.c,v 1.87 2010/01/02 16:57:48 momjian Exp $
17
+ * $PostgreSQL: pgsql/src/backend/optimizer/util/var.c,v 1.88 2010/07/08 00:14:03 tgl Exp $
18
18
*
19
19
*-------------------------------------------------------------------------
20
20
*/
@@ -63,6 +63,8 @@ typedef struct
63
63
{
64
64
PlannerInfo * root ;
65
65
int sublevels_up ;
66
+ bool possible_sublink ; /* could aliases include a SubLink? */
67
+ bool inserted_sublink ; /* have we inserted a SubLink? */
66
68
} flatten_join_alias_vars_context ;
67
69
68
70
static bool pull_varnos_walker (Node * node ,
@@ -688,6 +690,14 @@ pull_var_clause_walker(Node *node, pull_var_clause_context *context)
688
690
* This also adjusts relid sets found in some expression node types to
689
691
* substitute the contained base rels for any join relid.
690
692
*
693
+ * If a JOIN contains sub-selects that have been flattened, its join alias
694
+ * entries might now be arbitrary expressions, not just Vars. This affects
695
+ * this function in one important way: we might find ourselves inserting
696
+ * SubLink expressions into subqueries, and we must make sure that their
697
+ * Query.hasSubLinks fields get set to TRUE if so. If there are any
698
+ * SubLinks in the join alias lists, the outer Query should already have
699
+ * hasSubLinks = TRUE, so this is only relevant to un-flattened subqueries.
700
+ *
691
701
* NOTE: this is used on not-yet-planned expressions. We do not expect it
692
702
* to be applied directly to a Query node.
693
703
*/
@@ -698,6 +708,10 @@ flatten_join_alias_vars(PlannerInfo *root, Node *node)
698
708
699
709
context .root = root ;
700
710
context .sublevels_up = 0 ;
711
+ /* flag whether join aliases could possibly contain SubLinks */
712
+ context .possible_sublink = root -> parse -> hasSubLinks ;
713
+ /* if hasSubLinks is already true, no need to work hard */
714
+ context .inserted_sublink = root -> parse -> hasSubLinks ;
701
715
702
716
return flatten_join_alias_vars_mutator (node , & context );
703
717
}
@@ -747,6 +761,7 @@ flatten_join_alias_vars_mutator(Node *node,
747
761
IncrementVarSublevelsUp (newvar , context -> sublevels_up , 0 );
748
762
}
749
763
/* Recurse in case join input is itself a join */
764
+ /* (also takes care of setting inserted_sublink if needed) */
750
765
newvar = flatten_join_alias_vars_mutator (newvar , context );
751
766
fields = lappend (fields , newvar );
752
767
}
@@ -773,8 +788,15 @@ flatten_join_alias_vars_mutator(Node *node,
773
788
newvar = copyObject (newvar );
774
789
IncrementVarSublevelsUp (newvar , context -> sublevels_up , 0 );
775
790
}
791
+
776
792
/* Recurse in case join input is itself a join */
777
- return flatten_join_alias_vars_mutator (newvar , context );
793
+ newvar = flatten_join_alias_vars_mutator (newvar , context );
794
+
795
+ /* Detect if we are adding a sublink to query */
796
+ if (context -> possible_sublink && !context -> inserted_sublink )
797
+ context -> inserted_sublink = checkExprHasSubLink (newvar );
798
+
799
+ return newvar ;
778
800
}
779
801
if (IsA (node , PlaceHolderVar ))
780
802
{
@@ -797,12 +819,17 @@ flatten_join_alias_vars_mutator(Node *node,
797
819
{
798
820
/* Recurse into RTE subquery or not-yet-planned sublink subquery */
799
821
Query * newnode ;
822
+ bool save_inserted_sublink ;
800
823
801
824
context -> sublevels_up ++ ;
825
+ save_inserted_sublink = context -> inserted_sublink ;
826
+ context -> inserted_sublink = ((Query * ) node )-> hasSubLinks ;
802
827
newnode = query_tree_mutator ((Query * ) node ,
803
828
flatten_join_alias_vars_mutator ,
804
829
(void * ) context ,
805
830
QTW_IGNORE_JOINALIASES );
831
+ newnode -> hasSubLinks |= context -> inserted_sublink ;
832
+ context -> inserted_sublink = save_inserted_sublink ;
806
833
context -> sublevels_up -- ;
807
834
return (Node * ) newnode ;
808
835
}
0 commit comments