@@ -49,13 +49,15 @@ planner_hook_type planner_hook = NULL;
49
49
50
50
51
51
/* Expression kind codes for preprocess_expression */
52
- #define EXPRKIND_QUAL 0
53
- #define EXPRKIND_TARGET 1
54
- #define EXPRKIND_RTFUNC 2
55
- #define EXPRKIND_VALUES 3
56
- #define EXPRKIND_LIMIT 4
57
- #define EXPRKIND_APPINFO 5
58
- #define EXPRKIND_PHV 6
52
+ #define EXPRKIND_QUAL 0
53
+ #define EXPRKIND_TARGET 1
54
+ #define EXPRKIND_RTFUNC 2
55
+ #define EXPRKIND_RTFUNC_LATERAL 3
56
+ #define EXPRKIND_VALUES 4
57
+ #define EXPRKIND_VALUES_LATERAL 5
58
+ #define EXPRKIND_LIMIT 6
59
+ #define EXPRKIND_APPINFO 7
60
+ #define EXPRKIND_PHV 8
59
61
60
62
61
63
static Node * preprocess_expression (PlannerInfo * root , Node * expr , int kind );
@@ -438,18 +440,38 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
438
440
preprocess_expression (root , (Node * ) root -> append_rel_list ,
439
441
EXPRKIND_APPINFO );
440
442
441
- /* Also need to preprocess expressions for function and values RTEs */
443
+ /* Also need to preprocess expressions within RTEs */
442
444
foreach (l , parse -> rtable )
443
445
{
444
446
RangeTblEntry * rte = (RangeTblEntry * ) lfirst (l );
447
+ int kind ;
445
448
446
- if (rte -> rtekind == RTE_FUNCTION )
447
- rte -> funcexpr = preprocess_expression (root , rte -> funcexpr ,
448
- EXPRKIND_RTFUNC );
449
+ if (rte -> rtekind == RTE_SUBQUERY )
450
+ {
451
+ /*
452
+ * We don't want to do all preprocessing yet on the subquery's
453
+ * expressions, since that will happen when we plan it. But if it
454
+ * contains any join aliases of our level, those have to get
455
+ * expanded now, because planning of the subquery won't do it.
456
+ * That's only possible if the subquery is LATERAL.
457
+ */
458
+ if (rte -> lateral && root -> hasJoinRTEs )
459
+ rte -> subquery = (Query * )
460
+ flatten_join_alias_vars (root , (Node * ) rte -> subquery );
461
+ }
462
+ else if (rte -> rtekind == RTE_FUNCTION )
463
+ {
464
+ /* Preprocess the function expression fully */
465
+ kind = rte -> lateral ? EXPRKIND_RTFUNC_LATERAL : EXPRKIND_RTFUNC ;
466
+ rte -> funcexpr = preprocess_expression (root , rte -> funcexpr , kind );
467
+ }
449
468
else if (rte -> rtekind == RTE_VALUES )
469
+ {
470
+ /* Preprocess the values lists fully */
471
+ kind = rte -> lateral ? EXPRKIND_VALUES_LATERAL : EXPRKIND_VALUES ;
450
472
rte -> values_lists = (List * )
451
- preprocess_expression (root , (Node * ) rte -> values_lists ,
452
- EXPRKIND_VALUES );
473
+ preprocess_expression (root , (Node * ) rte -> values_lists , kind );
474
+ }
453
475
}
454
476
455
477
/*
@@ -593,12 +615,13 @@ preprocess_expression(PlannerInfo *root, Node *expr, int kind)
593
615
594
616
/*
595
617
* If the query has any join RTEs, replace join alias variables with
596
- * base-relation variables. We must do this before sublink processing,
597
- * else sublinks expanded out from join aliases wouldn't get processed. We
598
- * can skip it in VALUES lists, however, since they can't contain any Vars
599
- * at all .
618
+ * base-relation variables. We must do this before sublink processing,
619
+ * else sublinks expanded out from join aliases would not get processed.
620
+ * We can skip it in non-lateral RTE functions and VALUES lists, however,
621
+ * since they can't contain any Vars of the current query level .
600
622
*/
601
- if (root -> hasJoinRTEs && kind != EXPRKIND_VALUES )
623
+ if (root -> hasJoinRTEs &&
624
+ !(kind == EXPRKIND_RTFUNC || kind == EXPRKIND_VALUES ))
602
625
expr = flatten_join_alias_vars (root , expr );
603
626
604
627
/*
0 commit comments