Here is another set of preparatory patches that clean up various special cases and similar in the node support.

0001-Remove-T_Expr.patch

Removes unneeded T_Expr.

0002-Add-COPY_ARRAY_FIELD-and-COMPARE_ARRAY_FIELD.patch
0003-Add-WRITE_INDEX_ARRAY.patch

These add macros to handle a few cases that were previously hand-coded.

0004-Make-node-output-prefix-match-node-structure-name.patch

Some nodes' output/read functions use a label that is slightly different from their node name, e.g., "NOTIFY" instead of "NOTIFYSTMT". This cleans that up so that an automated approach doesn't have to deal with these special cases.

0005-Add-Cardinality-typedef.patch

Adds a typedef Cardinality for double fields that store an estimated row or other count. Works alongside Cost and Selectivity.

This is useful because it appears that the serialization format for these float fields depends on their intent: Cardinality => %.0f, Cost => %.2f, Selectivity => %.4f. The only remaining exception is allvisfrac, which uses %.6f. Maybe that could also be a Selectivity, but I left it as is. I think this improves the clarity in this area.
From 4a9cc84d667f64bdcdffb1df8c89c4e73b02c1fb Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 17 Aug 2021 15:51:45 +0200
Subject: [PATCH 1/5] Remove T_Expr

This is an abstract node that shouldn't have a node tag defined.
---
 src/include/nodes/nodes.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 6a4d82f0a8..5ac1996738 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -153,7 +153,6 @@ typedef enum NodeTag
        T_Alias,
        T_RangeVar,
        T_TableFunc,
-       T_Expr,
        T_Var,
        T_Const,
        T_Param,
-- 
2.32.0

From a6f0e9031071ce695153fea600b5cb07a6507e11 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 17 Aug 2021 15:51:45 +0200
Subject: [PATCH 2/5] Add COPY_ARRAY_FIELD and COMPARE_ARRAY_FIELD

These handle node fields that are inline arrays (as opposed to
dynamically allocated arrays handled by COPY_POINTER_FIELD and
COMPARE_POINTER_FIELD).  These cases were hand-coded until now.
---
 src/backend/nodes/copyfuncs.c  | 11 +++++++----
 src/backend/nodes/equalfuncs.c |  7 +++++++
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 38251c2b8e..05c8ca080c 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -53,6 +53,10 @@
 #define COPY_STRING_FIELD(fldname) \
        (newnode->fldname = from->fldname ? pstrdup(from->fldname) : (char *) 
NULL)
 
+/* Copy a field that is an inline array */
+#define COPY_ARRAY_FIELD(fldname) \
+       memcpy(newnode->fldname, from->fldname, sizeof(newnode->fldname))
+
 /* Copy a field that is a pointer to a simple palloc'd object of size sz */
 #define COPY_POINTER_FIELD(fldname, sz) \
        do { \
@@ -4931,10 +4935,9 @@ _copyForeignKeyCacheInfo(const ForeignKeyCacheInfo *from)
        COPY_SCALAR_FIELD(conrelid);
        COPY_SCALAR_FIELD(confrelid);
        COPY_SCALAR_FIELD(nkeys);
-       /* COPY_SCALAR_FIELD might work for these, but let's not assume that */
-       memcpy(newnode->conkey, from->conkey, sizeof(newnode->conkey));
-       memcpy(newnode->confkey, from->confkey, sizeof(newnode->confkey));
-       memcpy(newnode->conpfeqop, from->conpfeqop, sizeof(newnode->conpfeqop));
+       COPY_ARRAY_FIELD(conkey);
+       COPY_ARRAY_FIELD(confkey);
+       COPY_ARRAY_FIELD(conpfeqop);
 
        return newnode;
 }
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 8a1762000c..6f656fab97 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -74,6 +74,13 @@
 #define equalstr(a, b) \
        (((a) != NULL && (b) != NULL) ? (strcmp(a, b) == 0) : (a) == (b))
 
+/* Compare a field that is an inline array */
+#define COMPARE_ARRAY_FIELD(fldname) \
+       do { \
+               if (memcmp(a->fldname, b->fldname, sizeof(a->fldname)) != 0) \
+                       return false; \
+       } while (0)
+
 /* Compare a field that is a pointer to a simple palloc'd object of size sz */
 #define COMPARE_POINTER_FIELD(fldname, sz) \
        do { \
-- 
2.32.0

From 7d1d7d6697d03b0a4ad3baaf37f315252f2b70c4 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 17 Aug 2021 15:51:45 +0200
Subject: [PATCH 3/5] Add WRITE_INDEX_ARRAY

We have a few WRITE_{name of type}_ARRAY macros, but the one case
using the Index type was hand-coded.  Wrap it into a macro as well.

This also changes the behavior slightly: Before, the field name was
skipped if the length was zero.  Now it prints the field name even in
that case.  This is more consistent with how other array fields are
handled.
---
 src/backend/nodes/outfuncs.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 87561cbb6f..50ed59bb4a 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -124,6 +124,13 @@ static void outChar(StringInfo str, char c);
                        appendStringInfo(str, " %u", node->fldname[i]); \
        } while(0)
 
+#define WRITE_INDEX_ARRAY(fldname, len) \
+       do { \
+               appendStringInfoString(str, " :" CppAsString(fldname) " "); \
+               for (int i = 0; i < len; i++) \
+                       appendStringInfo(str, " %u", node->fldname[i]); \
+       } while(0)
+
 #define WRITE_INT_ARRAY(fldname, len) \
        do { \
                appendStringInfoString(str, " :" CppAsString(fldname) " "); \
@@ -2510,14 +2517,7 @@ _outPathTarget(StringInfo str, const PathTarget *node)
        WRITE_NODE_TYPE("PATHTARGET");
 
        WRITE_NODE_FIELD(exprs);
-       if (node->sortgrouprefs)
-       {
-               int                     i;
-
-               appendStringInfoString(str, " :sortgrouprefs");
-               for (i = 0; i < list_length(node->exprs); i++)
-                       appendStringInfo(str, " %u", node->sortgrouprefs[i]);
-       }
+       WRITE_INDEX_ARRAY(sortgrouprefs, list_length(node->exprs));
        WRITE_FLOAT_FIELD(cost.startup, "%.2f");
        WRITE_FLOAT_FIELD(cost.per_tuple, "%.2f");
        WRITE_INT_FIELD(width);
-- 
2.32.0

From a65730f24753c759cd14f828aed9d5a3137cd531 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 17 Aug 2021 15:51:45 +0200
Subject: [PATCH 4/5] Make node output prefix match node structure name

In most cases, the prefix string in a node output is the upper case of
the node structure name, e.g., MergeAppend -> MERGEAPPEND.  There were
a few exceptions that for either no apparent reason or perhaps minor
aesthetic reasons deviated from this.  In order to simplify this and
perhaps allow automatic generation without having to deal with
exception cases, make them all match.

Regularize node type serialization in some cases
---
 src/backend/nodes/outfuncs.c  | 22 +++++++++++-----------
 src/backend/nodes/readfuncs.c | 22 +++++++++++-----------
 2 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 50ed59bb4a..09cfce05b1 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -1472,7 +1472,7 @@ _outConvertRowtypeExpr(StringInfo str, const 
ConvertRowtypeExpr *node)
 static void
 _outCollateExpr(StringInfo str, const CollateExpr *node)
 {
-       WRITE_NODE_TYPE("COLLATE");
+       WRITE_NODE_TYPE("COLLATEEXPR");
 
        WRITE_NODE_FIELD(arg);
        WRITE_OID_FIELD(collOid);
@@ -1482,7 +1482,7 @@ _outCollateExpr(StringInfo str, const CollateExpr *node)
 static void
 _outCaseExpr(StringInfo str, const CaseExpr *node)
 {
-       WRITE_NODE_TYPE("CASE");
+       WRITE_NODE_TYPE("CASEEXPR");
 
        WRITE_OID_FIELD(casetype);
        WRITE_OID_FIELD(casecollid);
@@ -1495,7 +1495,7 @@ _outCaseExpr(StringInfo str, const CaseExpr *node)
 static void
 _outCaseWhen(StringInfo str, const CaseWhen *node)
 {
-       WRITE_NODE_TYPE("WHEN");
+       WRITE_NODE_TYPE("CASEWHEN");
 
        WRITE_NODE_FIELD(expr);
        WRITE_NODE_FIELD(result);
@@ -1515,7 +1515,7 @@ _outCaseTestExpr(StringInfo str, const CaseTestExpr *node)
 static void
 _outArrayExpr(StringInfo str, const ArrayExpr *node)
 {
-       WRITE_NODE_TYPE("ARRAY");
+       WRITE_NODE_TYPE("ARRAYEXPR");
 
        WRITE_OID_FIELD(array_typeid);
        WRITE_OID_FIELD(array_collid);
@@ -1528,7 +1528,7 @@ _outArrayExpr(StringInfo str, const ArrayExpr *node)
 static void
 _outRowExpr(StringInfo str, const RowExpr *node)
 {
-       WRITE_NODE_TYPE("ROW");
+       WRITE_NODE_TYPE("ROWEXPR");
 
        WRITE_NODE_FIELD(args);
        WRITE_OID_FIELD(row_typeid);
@@ -1540,7 +1540,7 @@ _outRowExpr(StringInfo str, const RowExpr *node)
 static void
 _outRowCompareExpr(StringInfo str, const RowCompareExpr *node)
 {
-       WRITE_NODE_TYPE("ROWCOMPARE");
+       WRITE_NODE_TYPE("ROWCOMPAREEXPR");
 
        WRITE_ENUM_FIELD(rctype, RowCompareType);
        WRITE_NODE_FIELD(opnos);
@@ -1553,7 +1553,7 @@ _outRowCompareExpr(StringInfo str, const RowCompareExpr 
*node)
 static void
 _outCoalesceExpr(StringInfo str, const CoalesceExpr *node)
 {
-       WRITE_NODE_TYPE("COALESCE");
+       WRITE_NODE_TYPE("COALESCEEXPR");
 
        WRITE_OID_FIELD(coalescetype);
        WRITE_OID_FIELD(coalescecollid);
@@ -1564,7 +1564,7 @@ _outCoalesceExpr(StringInfo str, const CoalesceExpr *node)
 static void
 _outMinMaxExpr(StringInfo str, const MinMaxExpr *node)
 {
-       WRITE_NODE_TYPE("MINMAX");
+       WRITE_NODE_TYPE("MINMAXEXPR");
 
        WRITE_OID_FIELD(minmaxtype);
        WRITE_OID_FIELD(minmaxcollid);
@@ -2807,7 +2807,7 @@ _outAlterStatsStmt(StringInfo str, const AlterStatsStmt 
*node)
 static void
 _outNotifyStmt(StringInfo str, const NotifyStmt *node)
 {
-       WRITE_NODE_TYPE("NOTIFY");
+       WRITE_NODE_TYPE("NOTIFYSTMT");
 
        WRITE_STRING_FIELD(conditionname);
        WRITE_STRING_FIELD(payload);
@@ -2816,7 +2816,7 @@ _outNotifyStmt(StringInfo str, const NotifyStmt *node)
 static void
 _outDeclareCursorStmt(StringInfo str, const DeclareCursorStmt *node)
 {
-       WRITE_NODE_TYPE("DECLARECURSOR");
+       WRITE_NODE_TYPE("DECLARECURSORSTMT");
 
        WRITE_STRING_FIELD(portalname);
        WRITE_INT_FIELD(options);
@@ -3238,7 +3238,7 @@ _outSetOperationStmt(StringInfo str, const 
SetOperationStmt *node)
 static void
 _outRangeTblEntry(StringInfo str, const RangeTblEntry *node)
 {
-       WRITE_NODE_TYPE("RTE");
+       WRITE_NODE_TYPE("RANGETBLENTRY");
 
        /* put alias + eref first to make dump more legible */
        WRITE_NODE_FIELD(alias);
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 0dd1ad7dfc..01aee85bd4 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -2795,23 +2795,23 @@ parseNodeString(void)
                return_value = _readArrayCoerceExpr();
        else if (MATCH("CONVERTROWTYPEEXPR", 18))
                return_value = _readConvertRowtypeExpr();
-       else if (MATCH("COLLATE", 7))
+       else if (MATCH("COLLATEEXPR", 11))
                return_value = _readCollateExpr();
-       else if (MATCH("CASE", 4))
+       else if (MATCH("CASEEXPR", 8))
                return_value = _readCaseExpr();
-       else if (MATCH("WHEN", 4))
+       else if (MATCH("CASEWHEN", 8))
                return_value = _readCaseWhen();
        else if (MATCH("CASETESTEXPR", 12))
                return_value = _readCaseTestExpr();
-       else if (MATCH("ARRAY", 5))
+       else if (MATCH("ARRAYEXPR", 9))
                return_value = _readArrayExpr();
-       else if (MATCH("ROW", 3))
+       else if (MATCH("ROWEXPR", 7))
                return_value = _readRowExpr();
-       else if (MATCH("ROWCOMPARE", 10))
+       else if (MATCH("ROWCOMPAREEXPR", 14))
                return_value = _readRowCompareExpr();
-       else if (MATCH("COALESCE", 8))
+       else if (MATCH("COALESCEEXPR", 12))
                return_value = _readCoalesceExpr();
-       else if (MATCH("MINMAX", 6))
+       else if (MATCH("MINMAXEXPR", 10))
                return_value = _readMinMaxExpr();
        else if (MATCH("SQLVALUEFUNCTION", 16))
                return_value = _readSQLValueFunction();
@@ -2845,17 +2845,17 @@ parseNodeString(void)
                return_value = _readOnConflictExpr();
        else if (MATCH("APPENDRELINFO", 13))
                return_value = _readAppendRelInfo();
-       else if (MATCH("RTE", 3))
+       else if (MATCH("RANGETBLENTRY", 13))
                return_value = _readRangeTblEntry();
        else if (MATCH("RANGETBLFUNCTION", 16))
                return_value = _readRangeTblFunction();
        else if (MATCH("TABLESAMPLECLAUSE", 17))
                return_value = _readTableSampleClause();
-       else if (MATCH("NOTIFY", 6))
+       else if (MATCH("NOTIFYSTMT", 10))
                return_value = _readNotifyStmt();
        else if (MATCH("DEFELEM", 7))
                return_value = _readDefElem();
-       else if (MATCH("DECLARECURSOR", 13))
+       else if (MATCH("DECLARECURSORSTMT", 17))
                return_value = _readDeclareCursorStmt();
        else if (MATCH("PLANNEDSTMT", 11))
                return_value = _readPlannedStmt();
-- 
2.32.0

From 1e941046d1bcb0622e3e7daad3be9234181eeed9 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <pe...@eisentraut.org>
Date: Tue, 17 Aug 2021 15:51:45 +0200
Subject: [PATCH 5/5] Add Cardinality typedef

Similar to Cost and Selectivity, this is just a double, which can be
used in path and plan nodes to give some hint about the meaning of a
field.
---
 src/include/nodes/nodes.h     |  1 +
 src/include/nodes/pathnodes.h | 46 +++++++++++++++++------------------
 src/include/nodes/plannodes.h |  4 +--
 3 files changed, 26 insertions(+), 25 deletions(-)

diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 5ac1996738..b5157ec4c7 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -669,6 +669,7 @@ extern bool equal(const void *a, const void *b);
  */
 typedef double Selectivity;            /* fraction of tuples a qualifier will 
pass */
 typedef double Cost;                   /* execution cost (in page-access 
units) */
+typedef double Cardinality;            /* (estimated) number of rows or other 
integer count */
 
 
 /*
diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index 6e068f2c8b..d980c7ba04 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -333,11 +333,11 @@ struct PlannerInfo
 
        MemoryContext planner_cxt;      /* context holding PlannerInfo */
 
-       double          total_table_pages;      /* # of pages in all non-dummy 
tables of
+       Cardinality     total_table_pages;      /* # of pages in all non-dummy 
tables of
                                                                         * 
query */
 
-       double          tuple_fraction; /* tuple_fraction passed to 
query_planner */
-       double          limit_tuples;   /* limit_tuples passed to query_planner 
*/
+       Selectivity     tuple_fraction; /* tuple_fraction passed to 
query_planner */
+       Cardinality     limit_tuples;   /* limit_tuples passed to query_planner 
*/
 
        Index           qual_security_level;    /* minimum security_level for 
quals */
        /* Note: qual_security_level is zero if there are no securityQuals */
@@ -676,7 +676,7 @@ typedef struct RelOptInfo
        Relids          relids;                 /* set of base relids 
(rangetable indexes) */
 
        /* size estimates generated by planner */
-       double          rows;                   /* estimated number of result 
tuples */
+       Cardinality     rows;                   /* estimated number of result 
tuples */
 
        /* per-relation planner control flags */
        bool            consider_startup;       /* keep cheap-startup-cost 
paths? */
@@ -713,7 +713,7 @@ typedef struct RelOptInfo
        List       *indexlist;          /* list of IndexOptInfo */
        List       *statlist;           /* list of StatisticExtInfo */
        BlockNumber pages;                      /* size estimates derived from 
pg_class */
-       double          tuples;
+       Cardinality     tuples;
        double          allvisfrac;
        Bitmapset  *eclass_indexes; /* Indexes in PlannerInfo's eq_classes list 
of
                                                                 * ECs that 
mention this rel */
@@ -836,7 +836,7 @@ struct IndexOptInfo
 
        /* index-size statistics (from pg_class and elsewhere) */
        BlockNumber pages;                      /* number of disk pages in 
index */
-       double          tuples;                 /* number of index tuples in 
index */
+       Cardinality     tuples;                 /* number of index tuples in 
index */
        int                     tree_height;    /* index tree height, or -1 if 
unknown */
 
        /* index descriptor information */
@@ -1134,7 +1134,7 @@ typedef struct ParamPathInfo
        NodeTag         type;
 
        Relids          ppi_req_outer;  /* rels supplying parameters used by 
path */
-       double          ppi_rows;               /* estimated number of result 
tuples */
+       Cardinality     ppi_rows;               /* estimated number of result 
tuples */
        List       *ppi_clauses;        /* join clauses available from outer 
rels */
 } ParamPathInfo;
 
@@ -1184,7 +1184,7 @@ typedef struct Path
        int                     parallel_workers;       /* desired # of 
workers; 0 = not parallel */
 
        /* estimated size/costs for path (see costsize.c for more info) */
-       double          rows;                   /* estimated number of result 
tuples */
+       Cardinality     rows;                   /* estimated number of result 
tuples */
        Cost            startup_cost;   /* cost expended before fetching any 
tuples */
        Cost            total_cost;             /* total cost (assuming all 
tuples fetched) */
 
@@ -1447,7 +1447,7 @@ typedef struct AppendPath
        List       *subpaths;           /* list of component Paths */
        /* Index of first partial path in subpaths; list_length(subpaths) if 
none */
        int                     first_partial_path;
-       double          limit_tuples;   /* hard limit on output tuples, or -1 */
+       Cardinality     limit_tuples;   /* hard limit on output tuples, or -1 */
 } AppendPath;
 
 #define IS_DUMMY_APPEND(p) \
@@ -1469,7 +1469,7 @@ typedef struct MergeAppendPath
 {
        Path            path;
        List       *subpaths;           /* list of component Paths */
-       double          limit_tuples;   /* hard limit on output tuples, or -1 */
+       Cardinality     limit_tuples;   /* hard limit on output tuples, or -1 */
 } MergeAppendPath;
 
 /*
@@ -1510,7 +1510,7 @@ typedef struct MemoizePath
        List       *param_exprs;        /* cache keys */
        bool            singlerow;              /* true if the cache entry is 
to be marked as
                                                                 * complete 
after caching the first record. */
-       double          calls;                  /* expected number of rescans */
+       Cardinality     calls;                  /* expected number of rescans */
        uint32          est_entries;    /* The maximum number of entries that 
the
                                                                 * planner 
expects will fit in the cache, or 0
                                                                 * if unknown */
@@ -1662,7 +1662,7 @@ typedef struct HashPath
        JoinPath        jpath;
        List       *path_hashclauses;   /* join clauses used for hashing */
        int                     num_batches;    /* number of batches expected */
-       double          inner_rows_total;       /* total inner rows expected */
+       Cardinality     inner_rows_total;       /* total inner rows expected */
 } HashPath;
 
 /*
@@ -1765,7 +1765,7 @@ typedef struct AggPath
        Path       *subpath;            /* path representing input source */
        AggStrategy aggstrategy;        /* basic strategy, see nodes.h */
        AggSplit        aggsplit;               /* agg-splitting mode, see 
nodes.h */
-       double          numGroups;              /* estimated number of groups 
in input */
+       Cardinality     numGroups;              /* estimated number of groups 
in input */
        uint64          transitionSpace;        /* for pass-by-ref transition 
data */
        List       *groupClause;        /* a list of SortGroupClause's */
        List       *qual;                       /* quals (HAVING quals), if any 
*/
@@ -1779,7 +1779,7 @@ typedef struct GroupingSetData
 {
        NodeTag         type;
        List       *set;                        /* grouping set as list of 
sortgrouprefs */
-       double          numGroups;              /* est. number of result groups 
*/
+       Cardinality     numGroups;              /* est. number of result groups 
*/
 } GroupingSetData;
 
 typedef struct RollupData
@@ -1788,7 +1788,7 @@ typedef struct RollupData
        List       *groupClause;        /* applicable subset of 
parse->groupClause */
        List       *gsets;                      /* lists of integer indexes 
into groupClause */
        List       *gsets_data;         /* list of GroupingSetData */
-       double          numGroups;              /* est. number of result groups 
*/
+       Cardinality     numGroups;              /* est. number of result groups 
*/
        bool            hashable;               /* can be hashed */
        bool            is_hashed;              /* to be implemented as a 
hashagg */
 } RollupData;
@@ -1839,7 +1839,7 @@ typedef struct SetOpPath
        List       *distinctList;       /* SortGroupClauses identifying target 
cols */
        AttrNumber      flagColIdx;             /* where is the flag column, if 
any */
        int                     firstFlag;              /* flag value for first 
input relation */
-       double          numGroups;              /* estimated number of groups 
in input */
+       Cardinality     numGroups;              /* estimated number of groups 
in input */
 } SetOpPath;
 
 /*
@@ -1852,7 +1852,7 @@ typedef struct RecursiveUnionPath
        Path       *rightpath;
        List       *distinctList;       /* SortGroupClauses identifying target 
cols */
        int                     wtParam;                /* ID of Param 
representing work table */
-       double          numGroups;              /* estimated number of groups 
in input */
+       Cardinality     numGroups;              /* estimated number of groups 
in input */
 } RecursiveUnionPath;
 
 /*
@@ -2607,7 +2607,7 @@ typedef struct
 typedef struct
 {
        bool            limit_needed;
-       double          limit_tuples;
+       Cardinality     limit_tuples;
        int64           count_est;
        int64           offset_est;
 } FinalPathExtraData;
@@ -2638,15 +2638,15 @@ typedef struct JoinCostWorkspace
        Cost            inner_rescan_run_cost;
 
        /* private for cost_mergejoin code */
-       double          outer_rows;
-       double          inner_rows;
-       double          outer_skip_rows;
-       double          inner_skip_rows;
+       Cardinality     outer_rows;
+       Cardinality     inner_rows;
+       Cardinality     outer_skip_rows;
+       Cardinality     inner_skip_rows;
 
        /* private for cost_hashjoin code */
        int                     numbuckets;
        int                     numbatches;
-       double          inner_rows_total;
+       Cardinality     inner_rows_total;
 } JoinCostWorkspace;
 
 /*
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index ec9a8b0c81..01a246d50e 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -120,7 +120,7 @@ typedef struct Plan
        /*
         * planner's estimate of result size of this plan step
         */
-       double          plan_rows;              /* number of rows plan is 
expected to emit */
+       Cardinality     plan_rows;              /* number of rows plan is 
expected to emit */
        int                     plan_width;             /* average row width in 
bytes */
 
        /*
@@ -976,7 +976,7 @@ typedef struct Hash
        AttrNumber      skewColumn;             /* outer join key's column #, 
or zero */
        bool            skewInherit;    /* is outer join rel an inheritance 
tree? */
        /* all other info is in the parent HashJoin node */
-       double          rows_total;             /* estimate total rows if 
parallel_aware */
+       Cardinality     rows_total;             /* estimate total rows if 
parallel_aware */
 } Hash;
 
 /* ----------------
-- 
2.32.0

Reply via email to