@@ -11,7 +11,7 @@ index bbf220407b..8225105893 100644
1111 auth_delay\
1212 auto_explain\
1313diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
14- indexa0311ce9dc..a4fa160d5a 100644
14+ index35c23bd27d..9dee2cee50 100644
1515--- a/src/backend/commands/explain.c
1616+++ b/src/backend/commands/explain.c
1717@@ -24,6 +24,7 @@
@@ -57,7 +57,7 @@ index a0311ce9dc..a4fa160d5a 100644
5757 if (es->format == EXPLAIN_FORMAT_TEXT)
5858 appendStringInfoChar(es->str, '\n');
5959diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
60- index29ae32d960..d009b161da 100644
60+ index7918bb6f0d..36099866bb 100644
6161--- a/src/backend/optimizer/path/costsize.c
6262+++ b/src/backend/optimizer/path/costsize.c
6363@@ -99,6 +99,11 @@
@@ -80,7 +80,7 @@ index 29ae32d960..d009b161da 100644
8080
8181
8282 /*
83- @@ -4970 ,6 +4974 ,58 @@ approx_tuple_count(PlannerInfo *root, JoinPath *path, List *quals)
83+ @@ -4976 ,6 +4980 ,58 @@ approx_tuple_count(PlannerInfo *root, JoinPath *path, List *quals)
8484 }
8585
8686
@@ -139,7 +139,7 @@ index 29ae32d960..d009b161da 100644
139139 /*
140140 * set_baserel_size_estimates
141141 *Set the size estimates for the given base relation.
142- @@ -4986 ,19 +5042 ,10 @@ approx_tuple_count(PlannerInfo *root, JoinPath *path, List *quals)
142+ @@ -4992 ,19 +5048 ,10 @@ approx_tuple_count(PlannerInfo *root, JoinPath *path, List *quals)
143143 void
144144 set_baserel_size_estimates(PlannerInfo *root, RelOptInfo *rel)
145145 {
@@ -160,7 +160,7 @@ index 29ae32d960..d009b161da 100644
160160
161161 cost_qual_eval(&rel->baserestrictcost, rel->baserestrictinfo, root);
162162
163- @@ -5009 ,13 +5056 ,33 @@ set_baserel_size_estimates(PlannerInfo *root, RelOptInfo *rel)
163+ @@ -5015 ,13 +5062 ,33 @@ set_baserel_size_estimates(PlannerInfo *root, RelOptInfo *rel)
164164 * get_parameterized_baserel_size
165165 *Make a size estimate for a parameterized scan of a base relation.
166166 *
@@ -196,7 +196,7 @@ index 29ae32d960..d009b161da 100644
196196 {
197197 List *allclauses;
198198 doublenrows;
199- @@ -5044 ,6 +5111 ,36 @@ get_parameterized_baserel_size(PlannerInfo *root, RelOptInfo *rel,
199+ @@ -5050 ,6 +5117 ,36 @@ get_parameterized_baserel_size(PlannerInfo *root, RelOptInfo *rel,
200200 * set_joinrel_size_estimates
201201 *Set the size estimates for the given join relation.
202202 *
@@ -233,7 +233,7 @@ index 29ae32d960..d009b161da 100644
233233 * The rel's targetlist must have been constructed already, and a
234234 * restriction clause list that matches the given component rels must
235235 * be provided.
236- @@ -5063 ,11 +5160 ,11 @@ get_parameterized_baserel_size(PlannerInfo *root, RelOptInfo *rel,
236+ @@ -5069 ,11 +5166 ,11 @@ get_parameterized_baserel_size(PlannerInfo *root, RelOptInfo *rel,
237237 * build_joinrel_tlist, and baserestrictcost is not used for join rels.
238238 */
239239 void
@@ -250,7 +250,7 @@ index 29ae32d960..d009b161da 100644
250250 {
251251 rel->rows = calc_joinrel_size_estimate(root,
252252 rel,
253- @@ -5083 ,6 +5180 ,35 @@ set_joinrel_size_estimates(PlannerInfo *root, RelOptInfo *rel,
253+ @@ -5089 ,6 +5186 ,35 @@ set_joinrel_size_estimates(PlannerInfo *root, RelOptInfo *rel,
254254 * get_parameterized_joinrel_size
255255 *Make a size estimate for a parameterized scan of a join relation.
256256 *
@@ -286,7 +286,7 @@ index 29ae32d960..d009b161da 100644
286286 * 'rel' is the joinrel under consideration.
287287 * 'outer_path', 'inner_path' are (probably also parameterized) Paths that
288288 *produce the relations being joined.
289- @@ -5095 ,11 +5221 ,11 @@ set_joinrel_size_estimates(PlannerInfo *root, RelOptInfo *rel,
289+ @@ -5101 ,11 +5227 ,11 @@ set_joinrel_size_estimates(PlannerInfo *root, RelOptInfo *rel,
290290 * set_joinrel_size_estimates must have been applied already.
291291 */
292292 double
@@ -303,7 +303,7 @@ index 29ae32d960..d009b161da 100644
303303 {
304304 doublenrows;
305305
306- @@ -5814 ,7 +5940 ,7 @@ set_foreign_size_estimates(PlannerInfo *root, RelOptInfo *rel)
306+ @@ -5820 ,7 +5946 ,7 @@ set_foreign_size_estimates(PlannerInfo *root, RelOptInfo *rel)
307307 /* Should only be applied to base relations */
308308 Assert(rel->relid > 0);
309309
@@ -312,7 +312,7 @@ index 29ae32d960..d009b161da 100644
312312
313313 cost_qual_eval(&rel->baserestrictcost, rel->baserestrictinfo, root);
314314
315- @@ -6101 ,7 +6227 ,7 @@ page_size(double tuples, int width)
315+ @@ -6107 ,7 +6233 ,7 @@ page_size(double tuples, int width)
316316 * Estimate the fraction of the work that each worker will do given the
317317 * number of workers budgeted for the path.
318318 */
@@ -322,7 +322,7 @@ index 29ae32d960..d009b161da 100644
322322 {
323323 doubleparallel_divisor = path->parallel_workers;
324324diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
325- indexcd68942af0..ab782b47ab 100644
325+ index1b11852814..9629876f9f 100644
326326--- a/src/backend/optimizer/plan/createplan.c
327327+++ b/src/backend/optimizer/plan/createplan.c
328328@@ -70,6 +70,7 @@
@@ -344,7 +344,7 @@ index cd68942af0..ab782b47ab 100644
344344 return plan;
345345 }
346346
347- @@ -5371 ,6 +5376 ,7 @@ copy_generic_path_info(Plan *dest, Path *src)
347+ @@ -5379 ,6 +5384 ,7 @@ copy_generic_path_info(Plan *dest, Path *src)
348348 dest->plan_width = src->pathtarget->width;
349349 dest->parallel_aware = src->parallel_aware;
350350 dest->parallel_safe = src->parallel_safe;
@@ -353,7 +353,7 @@ index cd68942af0..ab782b47ab 100644
353353
354354 /*
355355diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
356- index05f44faf6e..082e47332d 100644
356+ indexdb5ff6fdca..f2ace8d1be 100644
357357--- a/src/backend/optimizer/plan/planner.c
358358+++ b/src/backend/optimizer/plan/planner.c
359359@@ -145,7 +145,8 @@ static List *extract_rollup_sets(List *groupingSets);
@@ -366,7 +366,7 @@ index 05f44faf6e..082e47332d 100644
366366 grouping_sets_data *gd,
367367 List *target_list);
368368 static RelOptInfo *create_grouping_paths(PlannerInfo *root,
369- @@ -3544 ,7 +3545 ,8 @@ standard_qp_callback(PlannerInfo *root, void *extra)
369+ @@ -3554 ,7 +3555 ,8 @@ standard_qp_callback(PlannerInfo *root, void *extra)
370370 */
371371 static double
372372 get_number_of_groups(PlannerInfo *root,
@@ -376,7 +376,7 @@ index 05f44faf6e..082e47332d 100644
376376 grouping_sets_data *gd,
377377 List *target_list)
378378 {
379- @@ -3581 ,7 +3583 ,7 @@ get_number_of_groups(PlannerInfo *root,
379+ @@ -3591 ,7 +3593 ,7 @@ get_number_of_groups(PlannerInfo *root,
380380 GroupingSetData *gs = lfirst_node(GroupingSetData, lc3);
381381 doublenumGroups = estimate_num_groups(root,
382382 groupExprs,
@@ -385,7 +385,7 @@ index 05f44faf6e..082e47332d 100644
385385 &gset,
386386 NULL);
387387
388- @@ -3607 ,7 +3609 ,7 @@ get_number_of_groups(PlannerInfo *root,
388+ @@ -3617 ,7 +3619 ,7 @@ get_number_of_groups(PlannerInfo *root,
389389 GroupingSetData *gs = lfirst_node(GroupingSetData, lc2);
390390 doublenumGroups = estimate_num_groups(root,
391391 groupExprs,
@@ -394,7 +394,7 @@ index 05f44faf6e..082e47332d 100644
394394 &gset,
395395 NULL);
396396
397- @@ -3624 ,8 +3626 ,8 @@ get_number_of_groups(PlannerInfo *root,
397+ @@ -3634 ,8 +3636 ,8 @@ get_number_of_groups(PlannerInfo *root,
398398 groupExprs = get_sortgrouplist_exprs(root->processed_groupClause,
399399 target_list);
400400
@@ -405,7 +405,7 @@ index 05f44faf6e..082e47332d 100644
405405 }
406406 }
407407 else if (parse->groupingSets)
408- @@ -4015 ,7 +4017 ,8 @@ create_ordinary_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel,
408+ @@ -4025 ,7 +4027 ,8 @@ create_ordinary_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel,
409409 * Estimate number of groups.
410410 */
411411 dNumGroups = get_number_of_groups(root,
@@ -415,7 +415,7 @@ index 05f44faf6e..082e47332d 100644
415415 gd,
416416 extra->targetList);
417417
418- @@ -7115 ,13 +7118 ,15 @@ create_partial_grouping_paths(PlannerInfo *root,
418+ @@ -7127 ,13 +7130 ,15 @@ create_partial_grouping_paths(PlannerInfo *root,
419419 if (cheapest_total_path != NULL)
420420 dNumPartialGroups =
421421 get_number_of_groups(root,
@@ -434,73 +434,73 @@ index 05f44faf6e..082e47332d 100644
434434 extra->targetList);
435435
436436diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
437- index18b92336be..d56fd933d8 100644
437+ indexad84cc43e1..8e1e436caf 100644
438438--- a/src/backend/optimizer/util/relnode.c
439439+++ b/src/backend/optimizer/util/relnode.c
440- @@ -265 ,6 +265 ,7 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)
440+ @@ -272 ,6 +272 ,7 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)
441441 rel->all_partrels = NULL;
442442 rel->partexprs = NULL;
443443 rel->nullable_partexprs = NULL;
444444+ rel->ext_nodes = NULL;
445445
446446 /*
447447 * Pass assorted information down the inheritance hierarchy.
448- @@ -388 ,7 +389 ,6 @@ find_base_rel(PlannerInfo *root, int relid)
448+ @@ -402 ,7 +403 ,6 @@ find_base_rel(PlannerInfo *root, int relid)
449449 if (rel)
450450 return rel;
451451 }
452452-
453453 elog(ERROR, "no relation entry for relid %d", relid);
454454
455455 return NULL;/* keep compiler quiet */
456- @@ -679 ,6 +679 ,7 @@ build_join_rel(PlannerInfo *root,
456+ @@ -732 ,6 +732 ,7 @@ build_join_rel(PlannerInfo *root,
457457 joinrel->all_partrels = NULL;
458458 joinrel->partexprs = NULL;
459459 joinrel->nullable_partexprs = NULL;
460460+ joinrel->ext_nodes = NULL;
461461
462462 /* Compute information relevant to the foreign relations. */
463463 set_foreign_rel_properties(joinrel, outer_rel, inner_rel);
464- @@ -858 ,6 +859 ,7 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel,
464+ @@ -917 ,6 +918 ,7 @@ build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel,
465465 joinrel->all_partrels = NULL;
466466 joinrel->partexprs = NULL;
467467 joinrel->nullable_partexprs = NULL;
468468+ joinrel->ext_nodes = NULL;
469469
470470 /* Compute information relevant to foreign relations. */
471471 set_foreign_rel_properties(joinrel, outer_rel, inner_rel);
472- @@ -1298 ,6 +1300 ,7 @@ find_childrel_parents(PlannerInfo *root, RelOptInfo *rel)
472+ @@ -1467 ,6 +1469 ,7 @@ find_childrel_parents(PlannerInfo *root, RelOptInfo *rel)
473473 }
474474
475475
476476+ set_parampathinfo_postinit_hook_type parampathinfo_postinit_hook = NULL;
477477 /*
478478 * get_baserel_parampathinfo
479479 *Get the ParamPathInfo for a parameterized path for a base relation,
480- @@ -1366,6 +1369,10 @@ get_baserel_parampathinfo(PlannerInfo *root, RelOptInfo *baserel,
481- ppi->ppi_req_outer = required_outer;
480+ @@ -1546,6 +1549,10 @@ get_baserel_parampathinfo(PlannerInfo *root, RelOptInfo *baserel,
482481 ppi->ppi_rows = rows;
483482 ppi->ppi_clauses = pclauses;
483+ ppi->ppi_serials = pserials;
484484+
485485+ if (parampathinfo_postinit_hook)
486486+ (*parampathinfo_postinit_hook)(ppi);
487487+
488488 baserel->ppilist = lappend(baserel->ppilist, ppi);
489489
490490 return ppi;
491- @@ -1591,6 +1598,10 @@ get_joinrel_parampathinfo(PlannerInfo *root, RelOptInfo *joinrel,
492- ppi->ppi_req_outer = required_outer;
493- ppi->ppi_rows = rows;
491+ @@ -1799,6 +1806,10 @@ get_appendrel_parampathinfo(RelOptInfo *appendrel, Relids required_outer)
492+ ppi->ppi_rows = 0;
494493 ppi->ppi_clauses = NIL;
494+ ppi->ppi_serials = NULL;
495495+
496496+ if (parampathinfo_postinit_hook)
497- + (*parampathinfo_postinit_hook)(ppi);
497+ + (*parampathinfo_postinit_hook)(ppi);
498498+
499- joinrel ->ppilist = lappend(joinrel ->ppilist, ppi);
499+ appendrel ->ppilist = lappend(appendrel ->ppilist, ppi);
500500
501501 return ppi;
502502diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
503- index4e4888dde4..5b22f65012 100644
503+ indexfe37e65af0..0e5299078b 100644
504504--- a/src/backend/utils/adt/selfuncs.c
505505+++ b/src/backend/utils/adt/selfuncs.c
506506@@ -145,6 +145,7 @@
@@ -556,10 +556,10 @@ index 7c1071ddd1..72e954dd3e 100644
556556 extern void ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
557557 ParamListInfo params, DestReceiver *dest);
558558diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
559- index2d1d8f4bcd..48d60559f5 100644
559+ index62d9460258..a946d05e60 100644
560560--- a/src/include/nodes/pathnodes.h
561561+++ b/src/include/nodes/pathnodes.h
562- @@ -1025 ,6 +1025 ,16 @@ typedef struct RelOptInfo
562+ @@ -1038 ,6 +1038 ,16 @@ typedef struct RelOptInfo
563563 List **partexprs pg_node_attr(read_write_ignore);
564564 /* Nullable partition key expressions */
565565 List **nullable_partexprs pg_node_attr(read_write_ignore);
@@ -576,19 +576,19 @@ index 2d1d8f4bcd..48d60559f5 100644
576576 } RelOptInfo;
577577
578578 /*
579- @@ -1495,6 +1505,10 @@ typedef struct ParamPathInfo
580- Relidsppi_req_outer;/* rels supplying parameters used by path */
579+ @@ -1558,6 +1568,10 @@ typedef struct ParamPathInfo
581580 Cardinality ppi_rows;/* estimated number of result tuples */
582581 List *ppi_clauses;/* join clauses available from outer rels */
582+ Bitmapset *ppi_serials;/* set of rinfo_serial for enforced quals */
583583+
584584+ /* AQO DEBUG purposes */
585- + double predicted_ppi_rows;
586- + double fss_ppi_hash;
585+ + double predicted_ppi_rows;
586+ + double fss_ppi_hash;
587587 } ParamPathInfo;
588588
589589
590590diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
591- indexc1234fcf36..8c77da84aa 100644
591+ index4781a9c632..03f8216664 100644
592592--- a/src/include/nodes/plannodes.h
593593+++ b/src/include/nodes/plannodes.h
594594@@ -173,6 +173,9 @@ typedef struct Plan
@@ -686,7 +686,7 @@ index 6cf49705d3..6a96baf130 100644
686686
687687 #endif/* COST_H */
688688diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h
689- index02305ef902..5226ddc8e8 100644
689+ index69be701b16..497abb69c7 100644
690690--- a/src/include/optimizer/pathnode.h
691691+++ b/src/include/optimizer/pathnode.h
692692@@ -18,6 +18,10 @@
@@ -701,7 +701,7 @@ index 02305ef902..5226ddc8e8 100644
701701 * prototypes for pathnode.c
702702 */
703703diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h
704- index95ecefdade..a732d24fb6 100644
704+ index5fc900737d..5e5ce876c4 100644
705705--- a/src/include/optimizer/planmain.h
706706+++ b/src/include/optimizer/planmain.h
707707@@ -24,6 +24,12 @@ extern PGDLLIMPORT double cursor_tuple_fraction;