27
27
#include "optimizer/clauses.h"
28
28
#include "optimizer/cost.h"
29
29
#include "optimizer/paths.h"
30
+ #include "optimizer/placeholder.h"
30
31
#include "optimizer/plancat.h"
31
32
#include "optimizer/planmain.h"
32
33
#include "optimizer/predtest.h"
@@ -1926,7 +1927,20 @@ create_nestloop_plan(PlannerInfo *root,
1926
1927
NestLoopParam * nlp = (NestLoopParam * ) lfirst (cell );
1927
1928
1928
1929
next = lnext (cell );
1929
- if (bms_is_member (nlp -> paramval -> varno , outerrelids ))
1930
+ if (IsA (nlp -> paramval , Var ) &&
1931
+ bms_is_member (nlp -> paramval -> varno , outerrelids ))
1932
+ {
1933
+ root -> curOuterParams = list_delete_cell (root -> curOuterParams ,
1934
+ cell , prev );
1935
+ nestParams = lappend (nestParams , nlp );
1936
+ }
1937
+ else if (IsA (nlp -> paramval , PlaceHolderVar ) &&
1938
+ bms_overlap (((PlaceHolderVar * ) nlp -> paramval )-> phrels ,
1939
+ outerrelids ) &&
1940
+ bms_is_subset (find_placeholder_info (root ,
1941
+ (PlaceHolderVar * ) nlp -> paramval ,
1942
+ false)-> ph_eval_at ,
1943
+ outerrelids ))
1930
1944
{
1931
1945
root -> curOuterParams = list_delete_cell (root -> curOuterParams ,
1932
1946
cell , prev );
@@ -2354,11 +2368,12 @@ create_hashjoin_plan(PlannerInfo *root,
2354
2368
2355
2369
/*
2356
2370
* replace_nestloop_params
2357
- * Replace outer-relation Vars in the given expression with nestloop Params
2371
+ * Replace outer-relation Vars and PlaceHolderVars in the given expression
2372
+ * with nestloop Params
2358
2373
*
2359
- * All Vars belonging to the relation(s) identified by root->curOuterRels
2360
- * are replaced by Params, and entries are added to root->curOuterParams if
2361
- * not already present.
2374
+ * All Vars and PlaceHolderVars belonging to the relation(s) identified by
2375
+ * root->curOuterRels are replaced by Params, and entries are added to
2376
+ * root->curOuterParams if not already present.
2362
2377
*/
2363
2378
static Node *
2364
2379
replace_nestloop_params (PlannerInfo * root , Node * expr )
@@ -2385,7 +2400,7 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root)
2385
2400
if (!bms_is_member (var -> varno , root -> curOuterRels ))
2386
2401
return node ;
2387
2402
/* Create a Param representing the Var */
2388
- param = assign_nestloop_param (root , var );
2403
+ param = assign_nestloop_param_var (root , var );
2389
2404
/* Is this param already listed in root->curOuterParams? */
2390
2405
foreach (lc , root -> curOuterParams )
2391
2406
{
@@ -2405,6 +2420,48 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root)
2405
2420
/* And return the replacement Param */
2406
2421
return (Node * ) param ;
2407
2422
}
2423
+ if (IsA (node , PlaceHolderVar ))
2424
+ {
2425
+ PlaceHolderVar * phv = (PlaceHolderVar * ) node ;
2426
+ Param * param ;
2427
+ NestLoopParam * nlp ;
2428
+ ListCell * lc ;
2429
+
2430
+ /* Upper-level PlaceHolderVars should be long gone at this point */
2431
+ Assert (phv -> phlevelsup == 0 );
2432
+
2433
+ /*
2434
+ * If not to be replaced, just return the PlaceHolderVar unmodified.
2435
+ * We use bms_overlap as a cheap/quick test to see if the PHV might
2436
+ * be evaluated in the outer rels, and then grab its PlaceHolderInfo
2437
+ * to tell for sure.
2438
+ */
2439
+ if (!bms_overlap (phv -> phrels , root -> curOuterRels ))
2440
+ return node ;
2441
+ if (!bms_is_subset (find_placeholder_info (root , phv , false)-> ph_eval_at ,
2442
+ root -> curOuterRels ))
2443
+ return node ;
2444
+ /* Create a Param representing the PlaceHolderVar */
2445
+ param = assign_nestloop_param_placeholdervar (root , phv );
2446
+ /* Is this param already listed in root->curOuterParams? */
2447
+ foreach (lc , root -> curOuterParams )
2448
+ {
2449
+ nlp = (NestLoopParam * ) lfirst (lc );
2450
+ if (nlp -> paramno == param -> paramid )
2451
+ {
2452
+ Assert (equal (phv , nlp -> paramval ));
2453
+ /* Present, so we can just return the Param */
2454
+ return (Node * ) param ;
2455
+ }
2456
+ }
2457
+ /* No, so add it */
2458
+ nlp = makeNode (NestLoopParam );
2459
+ nlp -> paramno = param -> paramid ;
2460
+ nlp -> paramval = (Var * ) phv ;
2461
+ root -> curOuterParams = lappend (root -> curOuterParams , nlp );
2462
+ /* And return the replacement Param */
2463
+ return (Node * ) param ;
2464
+ }
2408
2465
return expression_tree_mutator (node ,
2409
2466
replace_nestloop_params_mutator ,
2410
2467
(void * ) root );
@@ -2417,7 +2474,7 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root)
2417
2474
*
2418
2475
* We have four tasks here:
2419
2476
* * Remove RestrictInfo nodes from the input clauses.
2420
- * * Replace any outer-relation Var nodes with nestloop Params.
2477
+ * * Replace any outer-relation Var or PHV nodes with nestloop Params.
2421
2478
* (XXX eventually, that responsibility should go elsewhere?)
2422
2479
* * Index keys must be represented by Var nodes with varattno set to the
2423
2480
* index's attribute number, not the attribute number in the original rel.
0 commit comments