11diff --git a/contrib/Makefile b/contrib/Makefile
2- indexf27e458482e..0c621919045 100644
2+ indexf27e458482..0c62191904 100644
33--- a/contrib/Makefile
44+++ b/contrib/Makefile
55@@ -7,6 +7,7 @@ include $(top_builddir)/src/Makefile.global
@@ -11,17 +11,17 @@ index f27e458482e..0c621919045 100644
1111 auto_explain\
1212 bloom\
1313diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
14- index70551522dac..d9cca82fe84 100644
14+ index70551522da..958529fbab 100644
1515--- a/src/backend/commands/explain.c
1616+++ b/src/backend/commands/explain.c
17- @@ -25,6 +25,7 @@
17+ @@ -24,6 +24,7 @@
18+ #include "nodes/extensible.h"
1819 #include "nodes/makefuncs.h"
1920 #include "nodes/nodeFuncs.h"
20- #include "parser/analyze.h"
2121+ #include "optimizer/cost.h"
22+ #include "parser/analyze.h"
2223 #include "parser/parsetree.h"
2324 #include "rewrite/rewriteHandler.h"
24- #include "storage/bufmgr.h"
2525@@ -47,6 +48,12 @@ ExplainOneQuery_hook_type ExplainOneQuery_hook = NULL;
2626 /* Hook for plugins to get control in explain_get_index_name() */
2727 explain_get_index_name_hook_type explain_get_index_name_hook = NULL;
@@ -57,7 +57,7 @@ index 70551522dac..d9cca82fe84 100644
5757 if (es->format == EXPLAIN_FORMAT_TEXT)
5858 appendStringInfoChar(es->str, '\n');
5959diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
60- index4d9746d54a0..6fa85d1c71f 100644
60+ index4d9746d54a..6fa85d1c71 100644
6161--- a/src/backend/nodes/copyfuncs.c
6262+++ b/src/backend/nodes/copyfuncs.c
6363@@ -132,6 +132,7 @@ CopyPlanFields(const Plan *from, Plan *newnode)
@@ -69,7 +69,7 @@ index 4d9746d54a0..6fa85d1c71f 100644
6969
7070 /*
7171diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
72- index58c2590698c..1e06738a137 100644
72+ index58c2590698..1e06738a13 100644
7373--- a/src/backend/nodes/outfuncs.c
7474+++ b/src/backend/nodes/outfuncs.c
7575@@ -342,6 +342,7 @@ _outPlanInfo(StringInfo str, const Plan *node)
@@ -81,7 +81,7 @@ index 58c2590698c..1e06738a137 100644
8181
8282 /*
8383diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
84- indexeaa51c5c062..6ad8b78c7d5 100644
84+ indexeaa51c5c06..6ad8b78c7d 100644
8585--- a/src/backend/nodes/readfuncs.c
8686+++ b/src/backend/nodes/readfuncs.c
8787@@ -1628,6 +1628,11 @@ ReadCommonPlan(Plan *local_node)
@@ -97,7 +97,7 @@ index eaa51c5c062..6ad8b78c7d5 100644
9797
9898 /*
9999diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
100- index006f91f0a87..ef9c8ec5817 100644
100+ index006f91f0a8..ef9c8ec581 100644
101101--- a/src/backend/optimizer/path/costsize.c
102102+++ b/src/backend/optimizer/path/costsize.c
103103@@ -98,6 +98,11 @@
@@ -362,7 +362,7 @@ index 006f91f0a87..ef9c8ec5817 100644
362362 {
363363 doubleparallel_divisor = path->parallel_workers;
364364diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
365- index0ed858f305a..9d4a6c59030 100644
365+ index0ed858f305..9d4a6c5903 100644
366366--- a/src/backend/optimizer/plan/createplan.c
367367+++ b/src/backend/optimizer/plan/createplan.c
368368@@ -71,6 +71,7 @@
@@ -393,7 +393,7 @@ index 0ed858f305a..9d4a6c59030 100644
393393
394394 /*
395395diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
396- index70899e5430e..dac6132af54 100644
396+ index70899e5430..34075cc87b 100644
397397--- a/src/backend/optimizer/plan/planner.c
398398+++ b/src/backend/optimizer/plan/planner.c
399399@@ -143,7 +143,8 @@ static List *extract_rollup_sets(List *groupingSets);
@@ -441,7 +441,7 @@ index 70899e5430e..dac6132af54 100644
441441- dNumGroups = estimate_num_groups(root, groupExprs, path_rows,
442442- NULL, NULL);
443443+ dNumGroups = estimate_num_groups_ext(root, groupExprs, subpath,
444- + grouped_rel, NULL);
444+ + grouped_rel, NULL, NULL );
445445 }
446446 }
447447 else if (parse->groupingSets)
@@ -474,7 +474,7 @@ index 70899e5430e..dac6132af54 100644
474474 extra->targetList);
475475
476476diff --git a/src/backend/optimizer/util/relnode.c b/src/backend/optimizer/util/relnode.c
477- indexe105a4d5f1d..c5bcc9d1d15 100644
477+ indexe105a4d5f1..c5bcc9d1d1 100644
478478--- a/src/backend/optimizer/util/relnode.c
479479+++ b/src/backend/optimizer/util/relnode.c
480480@@ -258,6 +258,7 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)
@@ -540,15 +540,9 @@ index e105a4d5f1d..c5bcc9d1d15 100644
540540
541541 return ppi;
542542diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
543- index962dec6d504..899ee2bf4c5 100644
543+ index87879c9ddc..1aad8c43d9 100644
544544--- a/src/backend/utils/adt/selfuncs.c
545545+++ b/src/backend/utils/adt/selfuncs.c
546- @@ -1,4 +1,4 @@
547- - /*-------------------------------------------------------------------------
548- + /*-------------------------------------------------------------------------
549- *
550- * selfuncs.c
551- * Selectivity functions and index cost estimation functions for
552546@@ -143,6 +143,7 @@
553547 /* Hooks for plugins to get control when we ask for stats */
554548 get_relation_stats_hook_type get_relation_stats_hook = NULL;
@@ -557,28 +551,29 @@ index 962dec6d504..899ee2bf4c5 100644
557551
558552 static double eqsel_internal(PG_FUNCTION_ARGS, bool negate);
559553 static double eqjoinsel_inner(Oid opfuncoid, Oid collation,
560- @@ -3293,6 +3294,19 @@ add_unique_group_var(PlannerInfo *root, List *varinfos,
554+ @@ -3293,6 +3294,20 @@ add_unique_group_var(PlannerInfo *root, List *varinfos,
561555 return varinfos;
562556 }
563557
564558+ double
565559+ estimate_num_groups_ext(PlannerInfo *root, List *groupExprs, Path *subpath,
566- + RelOptInfo *grouped_rel, List **pgset)
560+ + RelOptInfo *grouped_rel, List **pgset,
561+ + EstimationInfo *estinfo)
567562+ {
568563+ double input_rows = subpath->rows;
569564+
570565+ if (estimate_num_groups_hook != NULL)
571- + return (*estimate_num_groups_hook)(root, groupExprs, subpath,
572- + grouped_rel, pgset );
566+ + return (*estimate_num_groups_hook)(root, groupExprs, subpath, grouped_rel,
567+ + pgset, estinfo );
573568+
574- + return estimate_num_groups(root, groupExprs, input_rows, pgset,NULL );
569+ + return estimate_num_groups(root, groupExprs, input_rows, pgset,estinfo );
575570+ }
576571+
577572 /*
578573 * estimate_num_groups- Estimate number of groups in a grouped query
579574 *
580575diff --git a/src/include/commands/explain.h b/src/include/commands/explain.h
581- indexe94d9e49cf6..49236ced77c 100644
576+ indexe94d9e49cf..49236ced77 100644
582577--- a/src/include/commands/explain.h
583578+++ b/src/include/commands/explain.h
584579@@ -75,6 +75,18 @@ extern PGDLLIMPORT ExplainOneQuery_hook_type ExplainOneQuery_hook;
@@ -601,7 +596,7 @@ index e94d9e49cf6..49236ced77c 100644
601596 extern void ExplainQuery(ParseState *pstate, ExplainStmt *stmt,
602597 ParamListInfo params, DestReceiver *dest);
603598diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
604- indexf16466a0df1..8f0ed706817 100644
599+ indexe370a01141..9f2f1628f5 100644
605600--- a/src/include/nodes/pathnodes.h
606601+++ b/src/include/nodes/pathnodes.h
607602@@ -756,6 +756,10 @@ typedef struct RelOptInfo
@@ -640,24 +635,21 @@ index f16466a0df1..8f0ed706817 100644
640635
641636
642637diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
643- index2308c80ddee..dc74cf85bd2 100644
638+ index2308c80dde..a933afa483 100644
644639--- a/src/include/nodes/plannodes.h
645640+++ b/src/include/nodes/plannodes.h
646- @@ -158,6 +158,12 @@ typedef struct Plan
641+ @@ -158,6 +158,9 @@ typedef struct Plan
647642 */
648643 Bitmapset *extParam;
649644 Bitmapset *allParam;
650645+
651- + /*
652- + * Additional fields for an extension purposes.
653- + * TODO: allow to serialize/deserialize this list.
654- + */
646+ + /* Additional field for an extension purposes. */
655647+ List*ext_nodes;
656648 } Plan;
657649
658650 /* ----------------
659651diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h
660- index2113bc82de0..bcc2520cec5 100644
652+ index2113bc82de..bcc2520cec 100644
661653--- a/src/include/optimizer/cost.h
662654+++ b/src/include/optimizer/cost.h
663655@@ -39,6 +39,37 @@ typedef enum
@@ -741,7 +733,7 @@ index 2113bc82de0..bcc2520cec5 100644
741733
742734 #endif/* COST_H */
743735diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h
744- index2922c0cdc14..c59dce6989e 100644
736+ index2922c0cdc1..c59dce6989 100644
745737--- a/src/include/optimizer/pathnode.h
746738+++ b/src/include/optimizer/pathnode.h
747739@@ -18,6 +18,10 @@
@@ -756,7 +748,7 @@ index 2922c0cdc14..c59dce6989e 100644
756748 * prototypes for pathnode.c
757749 */
758750diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h
759- indexbf1adfc52ac..9c78e0f4e02 100644
751+ indexbf1adfc52a..9c78e0f4e0 100644
760752--- a/src/include/optimizer/planmain.h
761753+++ b/src/include/optimizer/planmain.h
762754@@ -24,6 +24,12 @@ extern double cursor_tuple_fraction;
@@ -773,29 +765,30 @@ index bf1adfc52ac..9c78e0f4e02 100644
773765 * prototypes for plan/planmain.c
774766 */
775767diff --git a/src/include/utils/selfuncs.h b/src/include/utils/selfuncs.h
776- index9dd444e1ff5..37133340d84 100644
768+ index9dd444e1ff..cfaae98aa2 100644
777769--- a/src/include/utils/selfuncs.h
778770+++ b/src/include/utils/selfuncs.h
779- @@ -144,6 +144,12 @@ typedef bool (*get_index_stats_hook_type) (PlannerInfo *root,
771+ @@ -144,6 +144,13 @@ typedef bool (*get_index_stats_hook_type) (PlannerInfo *root,
780772 AttrNumber indexattnum,
781773 VariableStatData *vardata);
782774 extern PGDLLIMPORT get_index_stats_hook_type get_index_stats_hook;
783775+ typedef double (*estimate_num_groups_hook_type) (PlannerInfo *root,
784776+ List *groupExprs,
785777+ Path *subpath,
786778+ RelOptInfo *grouped_rel,
787- + List **pgset);
779+ + List **pgset,
780+ + EstimationInfo *estinfo);
788781+ extern PGDLLIMPORT estimate_num_groups_hook_type estimate_num_groups_hook;
789782
790783 /* Functions in selfuncs.c */
791784
792- @@ -213,6 +219 ,9 @@ extern void mergejoinscansel(PlannerInfo *root, Node *clause,
785+ @@ -213,6 +220 ,9 @@ extern void mergejoinscansel(PlannerInfo *root, Node *clause,
793786 extern double estimate_num_groups(PlannerInfo *root, List *groupExprs,
794787 double input_rows, List **pgset,
795788 EstimationInfo *estinfo);
796789+ extern double estimate_num_groups_ext(PlannerInfo *root, List *groupExprs,
797790+ Path *subpath, RelOptInfo *grouped_rel,
798- + List **pgset);
791+ + List **pgset, EstimationInfo *estinfo );
799792
800793 extern void estimate_hash_bucket_stats(PlannerInfo *root,
801794 Node *hashkey, double nbuckets,