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