9.1-planner-speedup-v5-extra-ifs.patch
text/x-patch
Filename: 9.1-planner-speedup-v5-extra-ifs.patch
Type: text/x-patch
Part: 1
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
Series: patch v5
| File | + | − |
|---|---|---|
| src/backend/nodes/bitmapset.c | 54 | 0 |
| src/backend/nodes/comparefuncs.c | 2952 | 0 |
| src/backend/nodes/Makefile | 1 | 1 |
| src/backend/optimizer/geqo/geqo_pool.c | 4 | 4 |
| src/backend/utils/adt/datum.c | 50 | 0 |
| src/include/nodes/bitmapset.h | 1 | 0 |
| src/include/nodes/nodes.h | 5 | 0 |
| src/include/utils/datum.h | 9 | 0 |
diff -dcrpN postgresql.1/src/backend/nodes/bitmapset.c postgresql.2/src/backend/nodes/bitmapset.c
*** postgresql.1/src/backend/nodes/bitmapset.c 2010-10-26 16:38:10.000000000 +0200
--- postgresql.2/src/backend/nodes/bitmapset.c 2010-10-19 10:56:19.000000000 +0200
*************** bms_equal(const Bitmapset *a, const Bitm
*** 173,178 ****
--- 173,232 ----
}
/*
+ * bms_compare - are one of the two bitmapsets equal, less or greater than the other?
+ *
+ * This is logical not physical equality; in particular, a NULL pointer will
+ * be reported as equal to a palloc'd value containing no members.
+ */
+ int
+ bms_compare(const Bitmapset *a, const Bitmapset *b)
+ {
+ const Bitmapset *shorter;
+ const Bitmapset *longer;
+ int shortlen;
+ int longlen;
+ int i;
+
+ /* Handle cases where either input is NULL */
+ if (a == NULL)
+ {
+ if (b == NULL)
+ return 0;
+ if (bms_is_empty(b))
+ return 0;
+ }
+ else if (b == NULL && bms_is_empty(a))
+ return 0;
+ /* Identify shorter and longer input */
+ if (a->nwords <= b->nwords)
+ {
+ shorter = a;
+ longer = b;
+ }
+ else
+ {
+ shorter = b;
+ longer = a;
+ }
+ /* And process */
+ shortlen = shorter->nwords;
+ for (i = 0; i < shortlen; i++)
+ {
+ if (shorter->words[i] < longer->words[i])
+ return -1;
+ else if (shorter->words[i] > longer->words[i])
+ return 1;
+ }
+ longlen = longer->nwords;
+ for (; i < longlen; i++)
+ {
+ if (longer->words[i] != 0)
+ return (longer == a ? 1 : -1);
+ }
+ return 0;
+ }
+
+ /*
* bms_make_singleton - build a bitmapset containing a single member
*/
Bitmapset *
diff -dcrpN postgresql.1/src/backend/nodes/comparefuncs.c postgresql.2/src/backend/nodes/comparefuncs.c
*** postgresql.1/src/backend/nodes/comparefuncs.c 1970-01-01 01:00:00.000000000 +0100
--- postgresql.2/src/backend/nodes/comparefuncs.c 2010-10-19 11:26:16.000000000 +0200
***************
*** 0 ****
--- 1,2952 ----
+ /*-------------------------------------------------------------------------
+ *
+ * comparefuncs.c
+ * Tree comparator functions to compare node trees.
+ *
+ * This file is a straight conversion of equalfuncs.c, see the NOTE there.
+ *
+ * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ * src/backend/nodes/comparefuncs.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+ #include "postgres.h"
+
+ #include "nodes/relation.h"
+ #include "utils/datum.h"
+
+
+ /*
+ * Macros to simplify comparison of different kinds of fields. Use these
+ * wherever possible to reduce the chance for silly typos. Note that these
+ * hard-wire the convention that the local variables in a Compare routine are
+ * named 'a' and 'b'.
+ */
+
+ /* Compare a simple scalar field (int, float, bool, enum, etc) */
+ #define COMPARE_SCALAR_FIELD(fldname) \
+ do { \
+ if (a->fldname < b->fldname) \
+ return -1; \
+ else if (a->fldname > b->fldname) \
+ return 1; \
+ } while (0)
+
+ /* Compare a field that is a pointer to some kind of Node or Node tree */
+ #define COMPARE_NODE_FIELD(fldname) \
+ do { \
+ int ret; \
+ ret = compare(a->fldname, b->fldname); \
+ if (ret != 0) \
+ return ret; \
+ } while (0)
+
+ /* Compare a field that is a pointer to a Bitmapset */
+ #define COMPARE_BITMAPSET_FIELD(fldname) \
+ do { \
+ int ret; \
+ ret = bms_compare(a->fldname, b->fldname); \
+ if (ret != 0) \
+ return ret; \
+ } while (0)
+
+ /* Compare a field that is a pointer to a C string, or perhaps NULL */
+ #define COMPARE_STRING_FIELD(fldname) \
+ do { \
+ int ret; \
+ ret = comparestr(a->fldname, b->fldname); \
+ if (ret != 0) \
+ return ret; \
+ } while (0)
+
+ /* Macro for comparing string fields that might be NULL */
+ #define comparestr(a, b) \
+ (((a) != NULL && (b) != NULL) ? strcmp(a, b) : ((a) < (b) ? -1 : ((a) > (b) ? -1 : 0 )))
+
+ /* Compare a field that is a pointer to a simple palloc'd object of size sz */
+ #define COMPARE_POINTER_FIELD(fldname, sz) \
+ do { \
+ int ret; \
+ ret = memcmp(a->fldname, b->fldname, (sz)); \
+ if (ret != 0) \
+ return ret; \
+ } while (0)
+
+ /* Compare a parse location field (this is a no-op, per note above) */
+ #define COMPARE_LOCATION_FIELD(fldname) \
+ ((void) 0)
+
+
+ /*
+ * Stuff from primnodes.h
+ */
+
+ static int
+ _compareAlias(Alias *a, Alias *b)
+ {
+ COMPARE_STRING_FIELD(aliasname);
+ COMPARE_NODE_FIELD(colnames);
+
+ return 0;
+ }
+
+ static int
+ _compareRangeVar(RangeVar *a, RangeVar *b)
+ {
+ COMPARE_STRING_FIELD(catalogname);
+ COMPARE_STRING_FIELD(schemaname);
+ COMPARE_STRING_FIELD(relname);
+ COMPARE_SCALAR_FIELD(inhOpt);
+ COMPARE_SCALAR_FIELD(istemp);
+ COMPARE_NODE_FIELD(alias);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareIntoClause(IntoClause *a, IntoClause *b)
+ {
+ COMPARE_NODE_FIELD(rel);
+ COMPARE_NODE_FIELD(colNames);
+ COMPARE_NODE_FIELD(options);
+ COMPARE_SCALAR_FIELD(onCommit);
+ COMPARE_STRING_FIELD(tableSpaceName);
+
+ return 0;
+ }
+
+ /*
+ * We don't need an _compareExpr because Expr is an abstract supertype which
+ * should never actually get instantiated. Also, since it has no common
+ * fields except NodeTag, there's no need for a helper routine to factor
+ * out comparing the common fields...
+ */
+
+ static int
+ _compareVar(Var *a, Var *b)
+ {
+ COMPARE_SCALAR_FIELD(varno);
+ COMPARE_SCALAR_FIELD(varattno);
+ COMPARE_SCALAR_FIELD(vartype);
+ COMPARE_SCALAR_FIELD(vartypmod);
+ COMPARE_SCALAR_FIELD(varlevelsup);
+ COMPARE_SCALAR_FIELD(varnoold);
+ COMPARE_SCALAR_FIELD(varoattno);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareConst(Const *a, Const *b)
+ {
+ COMPARE_SCALAR_FIELD(consttype);
+ COMPARE_SCALAR_FIELD(consttypmod);
+ COMPARE_SCALAR_FIELD(constlen);
+ COMPARE_SCALAR_FIELD(constisnull);
+ COMPARE_SCALAR_FIELD(constbyval);
+ COMPARE_LOCATION_FIELD(location);
+
+ /*
+ * We treat all NULL constants of the same type as equal. Someday this
+ * might need to change? But datumCompare doesn't work on nulls, so...
+ */
+ if (a->constisnull)
+ return 0;
+ return datumCompare(a->constvalue, b->constvalue,
+ a->constbyval, a->constlen);
+ }
+
+ static int
+ _compareParam(Param *a, Param *b)
+ {
+ COMPARE_SCALAR_FIELD(paramkind);
+ COMPARE_SCALAR_FIELD(paramid);
+ COMPARE_SCALAR_FIELD(paramtype);
+ COMPARE_SCALAR_FIELD(paramtypmod);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareAggref(Aggref *a, Aggref *b)
+ {
+ COMPARE_SCALAR_FIELD(aggfnoid);
+ COMPARE_SCALAR_FIELD(aggtype);
+ COMPARE_NODE_FIELD(args);
+ COMPARE_NODE_FIELD(aggorder);
+ COMPARE_NODE_FIELD(aggdistinct);
+ COMPARE_SCALAR_FIELD(aggstar);
+ COMPARE_SCALAR_FIELD(agglevelsup);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareWindowFunc(WindowFunc *a, WindowFunc *b)
+ {
+ COMPARE_SCALAR_FIELD(winfnoid);
+ COMPARE_SCALAR_FIELD(wintype);
+ COMPARE_NODE_FIELD(args);
+ COMPARE_SCALAR_FIELD(winref);
+ COMPARE_SCALAR_FIELD(winstar);
+ COMPARE_SCALAR_FIELD(winagg);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareArrayRef(ArrayRef *a, ArrayRef *b)
+ {
+ COMPARE_SCALAR_FIELD(refarraytype);
+ COMPARE_SCALAR_FIELD(refelemtype);
+ COMPARE_SCALAR_FIELD(reftypmod);
+ COMPARE_NODE_FIELD(refupperindexpr);
+ COMPARE_NODE_FIELD(reflowerindexpr);
+ COMPARE_NODE_FIELD(refexpr);
+ COMPARE_NODE_FIELD(refassgnexpr);
+
+ return 0;
+ }
+
+ static int
+ _compareFuncExpr(FuncExpr *a, FuncExpr *b)
+ {
+ COMPARE_SCALAR_FIELD(funcid);
+ COMPARE_SCALAR_FIELD(funcresulttype);
+ COMPARE_SCALAR_FIELD(funcretset);
+
+ /*
+ * Special-case COERCE_DONTCARE, so that planner can build coercion nodes
+ * that are equal() to both explicit and implicit coercions.
+ */
+ if (a->funcformat != COERCE_DONTCARE && b->funcformat != COERCE_DONTCARE)
+ COMPARE_SCALAR_FIELD(funcformat);
+
+ COMPARE_NODE_FIELD(args);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareNamedArgExpr(NamedArgExpr *a, NamedArgExpr *b)
+ {
+ COMPARE_NODE_FIELD(arg);
+ COMPARE_STRING_FIELD(name);
+ COMPARE_SCALAR_FIELD(argnumber);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareOpExpr(OpExpr *a, OpExpr *b)
+ {
+ COMPARE_SCALAR_FIELD(opno);
+
+ /*
+ * Special-case opfuncid: it is allowable for it to differ if one node
+ * contains zero and the other doesn't. This just means that the one node
+ * isn't as far along in the parse/plan pipeline and hasn't had the
+ * opfuncid cache filled yet.
+ */
+ if (a->opfuncid != 0 &&
+ b->opfuncid != 0)
+ COMPARE_SCALAR_FIELD(opfuncid);
+
+ COMPARE_SCALAR_FIELD(opresulttype);
+ COMPARE_SCALAR_FIELD(opretset);
+ COMPARE_NODE_FIELD(args);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareDistinctExpr(DistinctExpr *a, DistinctExpr *b)
+ {
+ COMPARE_SCALAR_FIELD(opno);
+
+ /*
+ * Special-case opfuncid: it is allowable for it to differ if one node
+ * contains zero and the other doesn't. This just means that the one node
+ * isn't as far along in the parse/plan pipeline and hasn't had the
+ * opfuncid cache filled yet.
+ */
+ if (a->opfuncid != 0 &&
+ b->opfuncid != 0)
+ COMPARE_SCALAR_FIELD(opfuncid);
+
+ COMPARE_SCALAR_FIELD(opresulttype);
+ COMPARE_SCALAR_FIELD(opretset);
+ COMPARE_NODE_FIELD(args);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareScalarArrayOpExpr(ScalarArrayOpExpr *a, ScalarArrayOpExpr *b)
+ {
+ COMPARE_SCALAR_FIELD(opno);
+
+ /*
+ * Special-case opfuncid: it is allowable for it to differ if one node
+ * contains zero and the other doesn't. This just means that the one node
+ * isn't as far along in the parse/plan pipeline and hasn't had the
+ * opfuncid cache filled yet.
+ */
+ if (a->opfuncid != 0 &&
+ b->opfuncid != 0)
+ COMPARE_SCALAR_FIELD(opfuncid);
+
+ COMPARE_SCALAR_FIELD(useOr);
+ COMPARE_NODE_FIELD(args);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareBoolExpr(BoolExpr *a, BoolExpr *b)
+ {
+ COMPARE_SCALAR_FIELD(boolop);
+ COMPARE_NODE_FIELD(args);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareSubLink(SubLink *a, SubLink *b)
+ {
+ COMPARE_SCALAR_FIELD(subLinkType);
+ COMPARE_NODE_FIELD(testexpr);
+ COMPARE_NODE_FIELD(operName);
+ COMPARE_NODE_FIELD(subselect);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareSubPlan(SubPlan *a, SubPlan *b)
+ {
+ COMPARE_SCALAR_FIELD(subLinkType);
+ COMPARE_NODE_FIELD(testexpr);
+ COMPARE_NODE_FIELD(paramIds);
+ COMPARE_SCALAR_FIELD(plan_id);
+ COMPARE_STRING_FIELD(plan_name);
+ COMPARE_SCALAR_FIELD(firstColType);
+ COMPARE_SCALAR_FIELD(firstColTypmod);
+ COMPARE_SCALAR_FIELD(useHashTable);
+ COMPARE_SCALAR_FIELD(unknownEqFalse);
+ COMPARE_NODE_FIELD(setParam);
+ COMPARE_NODE_FIELD(parParam);
+ COMPARE_NODE_FIELD(args);
+ COMPARE_SCALAR_FIELD(startup_cost);
+ COMPARE_SCALAR_FIELD(per_call_cost);
+
+ return 0;
+ }
+
+ static int
+ _compareAlternativeSubPlan(AlternativeSubPlan *a, AlternativeSubPlan *b)
+ {
+ COMPARE_NODE_FIELD(subplans);
+
+ return 0;
+ }
+
+ static int
+ _compareFieldSelect(FieldSelect *a, FieldSelect *b)
+ {
+ COMPARE_NODE_FIELD(arg);
+ COMPARE_SCALAR_FIELD(fieldnum);
+ COMPARE_SCALAR_FIELD(resulttype);
+ COMPARE_SCALAR_FIELD(resulttypmod);
+
+ return 0;
+ }
+
+ static int
+ _compareFieldStore(FieldStore *a, FieldStore *b)
+ {
+ COMPARE_NODE_FIELD(arg);
+ COMPARE_NODE_FIELD(newvals);
+ COMPARE_NODE_FIELD(fieldnums);
+ COMPARE_SCALAR_FIELD(resulttype);
+
+ return 0;
+ }
+
+ static int
+ _compareRelabelType(RelabelType *a, RelabelType *b)
+ {
+ COMPARE_NODE_FIELD(arg);
+ COMPARE_SCALAR_FIELD(resulttype);
+ COMPARE_SCALAR_FIELD(resulttypmod);
+
+ /*
+ * Special-case COERCE_DONTCARE, so that planner can build coercion nodes
+ * that are equal() to both explicit and implicit coercions.
+ */
+ if (a->relabelformat != COERCE_DONTCARE &&
+ b->relabelformat != COERCE_DONTCARE)
+ COMPARE_SCALAR_FIELD(relabelformat);
+
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareCoerceViaIO(CoerceViaIO *a, CoerceViaIO *b)
+ {
+ COMPARE_NODE_FIELD(arg);
+ COMPARE_SCALAR_FIELD(resulttype);
+
+ /*
+ * Special-case COERCE_DONTCARE, so that planner can build coercion nodes
+ * that are equal() to both explicit and implicit coercions.
+ */
+ if (a->coerceformat != COERCE_DONTCARE &&
+ b->coerceformat != COERCE_DONTCARE)
+ COMPARE_SCALAR_FIELD(coerceformat);
+
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareArrayCoerceExpr(ArrayCoerceExpr *a, ArrayCoerceExpr *b)
+ {
+ COMPARE_NODE_FIELD(arg);
+ COMPARE_SCALAR_FIELD(elemfuncid);
+ COMPARE_SCALAR_FIELD(resulttype);
+ COMPARE_SCALAR_FIELD(resulttypmod);
+ COMPARE_SCALAR_FIELD(isExplicit);
+
+ /*
+ * Special-case COERCE_DONTCARE, so that planner can build coercion nodes
+ * that are equal() to both explicit and implicit coercions.
+ */
+ if (a->coerceformat != COERCE_DONTCARE &&
+ b->coerceformat != COERCE_DONTCARE)
+ COMPARE_SCALAR_FIELD(coerceformat);
+
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareConvertRowtypeExpr(ConvertRowtypeExpr *a, ConvertRowtypeExpr *b)
+ {
+ COMPARE_NODE_FIELD(arg);
+ COMPARE_SCALAR_FIELD(resulttype);
+
+ /*
+ * Special-case COERCE_DONTCARE, so that planner can build coercion nodes
+ * that are equal() to both explicit and implicit coercions.
+ */
+ if (a->convertformat != COERCE_DONTCARE &&
+ b->convertformat != COERCE_DONTCARE)
+ COMPARE_SCALAR_FIELD(convertformat);
+
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareCaseExpr(CaseExpr *a, CaseExpr *b)
+ {
+ COMPARE_SCALAR_FIELD(casetype);
+ COMPARE_NODE_FIELD(arg);
+ COMPARE_NODE_FIELD(args);
+ COMPARE_NODE_FIELD(defresult);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareCaseWhen(CaseWhen *a, CaseWhen *b)
+ {
+ COMPARE_NODE_FIELD(expr);
+ COMPARE_NODE_FIELD(result);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareCaseTestExpr(CaseTestExpr *a, CaseTestExpr *b)
+ {
+ COMPARE_SCALAR_FIELD(typeId);
+ COMPARE_SCALAR_FIELD(typeMod);
+
+ return 0;
+ }
+
+ static int
+ _compareArrayExpr(ArrayExpr *a, ArrayExpr *b)
+ {
+ COMPARE_SCALAR_FIELD(array_typeid);
+ COMPARE_SCALAR_FIELD(element_typeid);
+ COMPARE_NODE_FIELD(elements);
+ COMPARE_SCALAR_FIELD(multidims);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareRowExpr(RowExpr *a, RowExpr *b)
+ {
+ COMPARE_NODE_FIELD(args);
+ COMPARE_SCALAR_FIELD(row_typeid);
+
+ /*
+ * Special-case COERCE_DONTCARE, so that planner can build coercion nodes
+ * that are equal() to both explicit and implicit coercions.
+ */
+ if (a->row_format != COERCE_DONTCARE &&
+ b->row_format != COERCE_DONTCARE)
+ COMPARE_SCALAR_FIELD(row_format);
+
+ COMPARE_NODE_FIELD(colnames);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareRowCompareExpr(RowCompareExpr *a, RowCompareExpr *b)
+ {
+ COMPARE_SCALAR_FIELD(rctype);
+ COMPARE_NODE_FIELD(opnos);
+ COMPARE_NODE_FIELD(opfamilies);
+ COMPARE_NODE_FIELD(largs);
+ COMPARE_NODE_FIELD(rargs);
+
+ return 0;
+ }
+
+ static int
+ _compareCoalesceExpr(CoalesceExpr *a, CoalesceExpr *b)
+ {
+ COMPARE_SCALAR_FIELD(coalescetype);
+ COMPARE_NODE_FIELD(args);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareMinMaxExpr(MinMaxExpr *a, MinMaxExpr *b)
+ {
+ COMPARE_SCALAR_FIELD(minmaxtype);
+ COMPARE_SCALAR_FIELD(op);
+ COMPARE_NODE_FIELD(args);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareXmlExpr(XmlExpr *a, XmlExpr *b)
+ {
+ COMPARE_SCALAR_FIELD(op);
+ COMPARE_STRING_FIELD(name);
+ COMPARE_NODE_FIELD(named_args);
+ COMPARE_NODE_FIELD(arg_names);
+ COMPARE_NODE_FIELD(args);
+ COMPARE_SCALAR_FIELD(xmloption);
+ COMPARE_SCALAR_FIELD(type);
+ COMPARE_SCALAR_FIELD(typmod);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareNullIfExpr(NullIfExpr *a, NullIfExpr *b)
+ {
+ COMPARE_SCALAR_FIELD(opno);
+
+ /*
+ * Special-case opfuncid: it is allowable for it to differ if one node
+ * contains zero and the other doesn't. This just means that the one node
+ * isn't as far along in the parse/plan pipeline and hasn't had the
+ * opfuncid cache filled yet.
+ */
+ if (a->opfuncid != 0 &&
+ b->opfuncid != 0)
+ COMPARE_SCALAR_FIELD(opfuncid);
+
+ COMPARE_SCALAR_FIELD(opresulttype);
+ COMPARE_SCALAR_FIELD(opretset);
+ COMPARE_NODE_FIELD(args);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareNullTest(NullTest *a, NullTest *b)
+ {
+ COMPARE_NODE_FIELD(arg);
+ COMPARE_SCALAR_FIELD(nulltesttype);
+ COMPARE_SCALAR_FIELD(argisrow);
+
+ return 0;
+ }
+
+ static int
+ _compareBooleanTest(BooleanTest *a, BooleanTest *b)
+ {
+ COMPARE_NODE_FIELD(arg);
+ COMPARE_SCALAR_FIELD(booltesttype);
+
+ return 0;
+ }
+
+ static int
+ _compareCoerceToDomain(CoerceToDomain *a, CoerceToDomain *b)
+ {
+ COMPARE_NODE_FIELD(arg);
+ COMPARE_SCALAR_FIELD(resulttype);
+ COMPARE_SCALAR_FIELD(resulttypmod);
+
+ /*
+ * Special-case COERCE_DONTCARE, so that planner can build coercion nodes
+ * that are equal() to both explicit and implicit coercions.
+ */
+ if (a->coercionformat != COERCE_DONTCARE &&
+ b->coercionformat != COERCE_DONTCARE)
+ COMPARE_SCALAR_FIELD(coercionformat);
+
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareCoerceToDomainValue(CoerceToDomainValue *a, CoerceToDomainValue *b)
+ {
+ COMPARE_SCALAR_FIELD(typeId);
+ COMPARE_SCALAR_FIELD(typeMod);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareSetToDefault(SetToDefault *a, SetToDefault *b)
+ {
+ COMPARE_SCALAR_FIELD(typeId);
+ COMPARE_SCALAR_FIELD(typeMod);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareCurrentOfExpr(CurrentOfExpr *a, CurrentOfExpr *b)
+ {
+ COMPARE_SCALAR_FIELD(cvarno);
+ COMPARE_STRING_FIELD(cursor_name);
+ COMPARE_SCALAR_FIELD(cursor_param);
+
+ return 0;
+ }
+
+ static int
+ _compareTargetEntry(TargetEntry *a, TargetEntry *b)
+ {
+ COMPARE_NODE_FIELD(expr);
+ COMPARE_SCALAR_FIELD(resno);
+ COMPARE_STRING_FIELD(resname);
+ COMPARE_SCALAR_FIELD(ressortgroupref);
+ COMPARE_SCALAR_FIELD(resorigtbl);
+ COMPARE_SCALAR_FIELD(resorigcol);
+ COMPARE_SCALAR_FIELD(resjunk);
+
+ return 0;
+ }
+
+ static int
+ _compareRangeTblRef(RangeTblRef *a, RangeTblRef *b)
+ {
+ COMPARE_SCALAR_FIELD(rtindex);
+
+ return 0;
+ }
+
+ static int
+ _compareJoinExpr(JoinExpr *a, JoinExpr *b)
+ {
+ COMPARE_SCALAR_FIELD(jointype);
+ COMPARE_SCALAR_FIELD(isNatural);
+ COMPARE_NODE_FIELD(larg);
+ COMPARE_NODE_FIELD(rarg);
+ COMPARE_NODE_FIELD(usingClause);
+ COMPARE_NODE_FIELD(quals);
+ COMPARE_NODE_FIELD(alias);
+ COMPARE_SCALAR_FIELD(rtindex);
+
+ return 0;
+ }
+
+ static int
+ _compareFromExpr(FromExpr *a, FromExpr *b)
+ {
+ COMPARE_NODE_FIELD(fromlist);
+ COMPARE_NODE_FIELD(quals);
+
+ return 0;
+ }
+
+
+ /*
+ * Stuff from relation.h
+ */
+
+ static int
+ _comparePathKey(PathKey *a, PathKey *b)
+ {
+ /*
+ * This is normally used on non-canonicalized PathKeys, so must chase up
+ * to the topmost merged EquivalenceClass and see if those are the same
+ * (by pointer equality).
+ */
+ EquivalenceClass *a_eclass;
+ EquivalenceClass *b_eclass;
+
+ a_eclass = a->pk_eclass;
+ while (a_eclass->ec_merged)
+ a_eclass = a_eclass->ec_merged;
+ b_eclass = b->pk_eclass;
+ while (b_eclass->ec_merged)
+ b_eclass = b_eclass->ec_merged;
+ if (a_eclass < b_eclass)
+ return -1;
+ else if (a_eclass > b_eclass)
+ return 1;
+
+ COMPARE_SCALAR_FIELD(pk_opfamily);
+ COMPARE_SCALAR_FIELD(pk_strategy);
+ COMPARE_SCALAR_FIELD(pk_nulls_first);
+
+ return 0;
+ }
+
+ static int
+ _compareRestrictInfo(RestrictInfo *a, RestrictInfo *b)
+ {
+ COMPARE_NODE_FIELD(clause);
+ COMPARE_SCALAR_FIELD(is_pushed_down);
+ COMPARE_SCALAR_FIELD(outerjoin_delayed);
+ COMPARE_BITMAPSET_FIELD(required_relids);
+ COMPARE_BITMAPSET_FIELD(nullable_relids);
+
+ /*
+ * We ignore all the remaining fields, since they may not be set yet, and
+ * should be derivable from the clause anyway.
+ */
+
+ return 0;
+ }
+
+ static int
+ _comparePlaceHolderVar(PlaceHolderVar *a, PlaceHolderVar *b)
+ {
+ /*
+ * We intentionally do not compare phexpr. Two PlaceHolderVars with the
+ * same ID and levelsup should be considered equal even if the contained
+ * expressions have managed to mutate to different states. One way in
+ * which that can happen is that initplan sublinks would get replaced by
+ * differently-numbered Params when sublink folding is done. (The end
+ * result of such a situation would be some unreferenced initplans, which
+ * is annoying but not really a problem.)
+ *
+ * COMPARE_NODE_FIELD(phexpr);
+ */
+ COMPARE_BITMAPSET_FIELD(phrels);
+ COMPARE_SCALAR_FIELD(phid);
+ COMPARE_SCALAR_FIELD(phlevelsup);
+
+ return 0;
+ }
+
+ static int
+ _compareSpecialJoinInfo(SpecialJoinInfo *a, SpecialJoinInfo *b)
+ {
+ COMPARE_BITMAPSET_FIELD(min_lefthand);
+ COMPARE_BITMAPSET_FIELD(min_righthand);
+ COMPARE_BITMAPSET_FIELD(syn_lefthand);
+ COMPARE_BITMAPSET_FIELD(syn_righthand);
+ COMPARE_SCALAR_FIELD(jointype);
+ COMPARE_SCALAR_FIELD(lhs_strict);
+ COMPARE_SCALAR_FIELD(delay_upper_joins);
+ COMPARE_NODE_FIELD(join_quals);
+
+ return 0;
+ }
+
+ static int
+ _compareAppendRelInfo(AppendRelInfo *a, AppendRelInfo *b)
+ {
+ COMPARE_SCALAR_FIELD(parent_relid);
+ COMPARE_SCALAR_FIELD(child_relid);
+ COMPARE_SCALAR_FIELD(parent_reltype);
+ COMPARE_SCALAR_FIELD(child_reltype);
+ COMPARE_NODE_FIELD(translated_vars);
+ COMPARE_SCALAR_FIELD(parent_reloid);
+
+ return 0;
+ }
+
+ static int
+ _comparePlaceHolderInfo(PlaceHolderInfo *a, PlaceHolderInfo *b)
+ {
+ COMPARE_SCALAR_FIELD(phid);
+ COMPARE_NODE_FIELD(ph_var);
+ COMPARE_BITMAPSET_FIELD(ph_eval_at);
+ COMPARE_BITMAPSET_FIELD(ph_needed);
+ COMPARE_SCALAR_FIELD(ph_width);
+
+ return 0;
+ }
+
+
+ /*
+ * Stuff from parsenodes.h
+ */
+
+ static int
+ _compareQuery(Query *a, Query *b)
+ {
+ COMPARE_SCALAR_FIELD(commandType);
+ COMPARE_SCALAR_FIELD(querySource);
+ COMPARE_SCALAR_FIELD(canSetTag);
+ COMPARE_NODE_FIELD(utilityStmt);
+ COMPARE_SCALAR_FIELD(resultRelation);
+ COMPARE_NODE_FIELD(intoClause);
+ COMPARE_SCALAR_FIELD(hasAggs);
+ COMPARE_SCALAR_FIELD(hasWindowFuncs);
+ COMPARE_SCALAR_FIELD(hasSubLinks);
+ COMPARE_SCALAR_FIELD(hasDistinctOn);
+ COMPARE_SCALAR_FIELD(hasRecursive);
+ COMPARE_SCALAR_FIELD(hasForUpdate);
+ COMPARE_NODE_FIELD(cteList);
+ COMPARE_NODE_FIELD(rtable);
+ COMPARE_NODE_FIELD(jointree);
+ COMPARE_NODE_FIELD(targetList);
+ COMPARE_NODE_FIELD(returningList);
+ COMPARE_NODE_FIELD(groupClause);
+ COMPARE_NODE_FIELD(havingQual);
+ COMPARE_NODE_FIELD(windowClause);
+ COMPARE_NODE_FIELD(distinctClause);
+ COMPARE_NODE_FIELD(sortClause);
+ COMPARE_NODE_FIELD(limitOffset);
+ COMPARE_NODE_FIELD(limitCount);
+ COMPARE_NODE_FIELD(rowMarks);
+ COMPARE_NODE_FIELD(setOperations);
+
+ return 0;
+ }
+
+ static int
+ _compareInsertStmt(InsertStmt *a, InsertStmt *b)
+ {
+ COMPARE_NODE_FIELD(relation);
+ COMPARE_NODE_FIELD(cols);
+ COMPARE_NODE_FIELD(selectStmt);
+ COMPARE_NODE_FIELD(returningList);
+
+ return 0;
+ }
+
+ static int
+ _compareDeleteStmt(DeleteStmt *a, DeleteStmt *b)
+ {
+ COMPARE_NODE_FIELD(relation);
+ COMPARE_NODE_FIELD(usingClause);
+ COMPARE_NODE_FIELD(whereClause);
+ COMPARE_NODE_FIELD(returningList);
+
+ return 0;
+ }
+
+ static int
+ _compareUpdateStmt(UpdateStmt *a, UpdateStmt *b)
+ {
+ COMPARE_NODE_FIELD(relation);
+ COMPARE_NODE_FIELD(targetList);
+ COMPARE_NODE_FIELD(whereClause);
+ COMPARE_NODE_FIELD(fromClause);
+ COMPARE_NODE_FIELD(returningList);
+
+ return 0;
+ }
+
+ static int
+ _compareSelectStmt(SelectStmt *a, SelectStmt *b)
+ {
+ COMPARE_NODE_FIELD(distinctClause);
+ COMPARE_NODE_FIELD(intoClause);
+ COMPARE_NODE_FIELD(targetList);
+ COMPARE_NODE_FIELD(fromClause);
+ COMPARE_NODE_FIELD(whereClause);
+ COMPARE_NODE_FIELD(groupClause);
+ COMPARE_NODE_FIELD(havingClause);
+ COMPARE_NODE_FIELD(windowClause);
+ COMPARE_NODE_FIELD(withClause);
+ COMPARE_NODE_FIELD(valuesLists);
+ COMPARE_NODE_FIELD(sortClause);
+ COMPARE_NODE_FIELD(limitOffset);
+ COMPARE_NODE_FIELD(limitCount);
+ COMPARE_NODE_FIELD(lockingClause);
+ COMPARE_SCALAR_FIELD(op);
+ COMPARE_SCALAR_FIELD(all);
+ COMPARE_NODE_FIELD(larg);
+ COMPARE_NODE_FIELD(rarg);
+
+ return 0;
+ }
+
+ static int
+ _compareSetOperationStmt(SetOperationStmt *a, SetOperationStmt *b)
+ {
+ COMPARE_SCALAR_FIELD(op);
+ COMPARE_SCALAR_FIELD(all);
+ COMPARE_NODE_FIELD(larg);
+ COMPARE_NODE_FIELD(rarg);
+ COMPARE_NODE_FIELD(colTypes);
+ COMPARE_NODE_FIELD(colTypmods);
+ COMPARE_NODE_FIELD(groupClauses);
+
+ return 0;
+ }
+
+ static int
+ _compareAlterTableStmt(AlterTableStmt *a, AlterTableStmt *b)
+ {
+ COMPARE_NODE_FIELD(relation);
+ COMPARE_NODE_FIELD(cmds);
+ COMPARE_SCALAR_FIELD(relkind);
+
+ return 0;
+ }
+
+ static int
+ _compareAlterTableCmd(AlterTableCmd *a, AlterTableCmd *b)
+ {
+ COMPARE_SCALAR_FIELD(subtype);
+ COMPARE_STRING_FIELD(name);
+ COMPARE_NODE_FIELD(def);
+ COMPARE_NODE_FIELD(transform);
+ COMPARE_SCALAR_FIELD(behavior);
+ COMPARE_SCALAR_FIELD(missing_ok);
+
+ return 0;
+ }
+
+ static int
+ _compareAlterDomainStmt(AlterDomainStmt *a, AlterDomainStmt *b)
+ {
+ COMPARE_SCALAR_FIELD(subtype);
+ COMPARE_NODE_FIELD(typeName);
+ COMPARE_STRING_FIELD(name);
+ COMPARE_NODE_FIELD(def);
+ COMPARE_SCALAR_FIELD(behavior);
+
+ return 0;
+ }
+
+ static int
+ _compareGrantStmt(GrantStmt *a, GrantStmt *b)
+ {
+ COMPARE_SCALAR_FIELD(is_grant);
+ COMPARE_SCALAR_FIELD(targtype);
+ COMPARE_SCALAR_FIELD(objtype);
+ COMPARE_NODE_FIELD(objects);
+ COMPARE_NODE_FIELD(privileges);
+ COMPARE_NODE_FIELD(grantees);
+ COMPARE_SCALAR_FIELD(grant_option);
+ COMPARE_SCALAR_FIELD(behavior);
+
+ return 0;
+ }
+
+ static int
+ _comparePrivGrantee(PrivGrantee *a, PrivGrantee *b)
+ {
+ COMPARE_STRING_FIELD(rolname);
+
+ return 0;
+ }
+
+ static int
+ _compareFuncWithArgs(FuncWithArgs *a, FuncWithArgs *b)
+ {
+ COMPARE_NODE_FIELD(funcname);
+ COMPARE_NODE_FIELD(funcargs);
+
+ return 0;
+ }
+
+ static int
+ _compareAccessPriv(AccessPriv *a, AccessPriv *b)
+ {
+ COMPARE_STRING_FIELD(priv_name);
+ COMPARE_NODE_FIELD(cols);
+
+ return 0;
+ }
+
+ static int
+ _compareGrantRoleStmt(GrantRoleStmt *a, GrantRoleStmt *b)
+ {
+ COMPARE_NODE_FIELD(granted_roles);
+ COMPARE_NODE_FIELD(grantee_roles);
+ COMPARE_SCALAR_FIELD(is_grant);
+ COMPARE_SCALAR_FIELD(admin_opt);
+ COMPARE_STRING_FIELD(grantor);
+ COMPARE_SCALAR_FIELD(behavior);
+
+ return 0;
+ }
+
+ static int
+ _compareAlterDefaultPrivilegesStmt(AlterDefaultPrivilegesStmt *a, AlterDefaultPrivilegesStmt *b)
+ {
+ COMPARE_NODE_FIELD(options);
+ COMPARE_NODE_FIELD(action);
+
+ return 0;
+ }
+
+ static int
+ _compareDeclareCursorStmt(DeclareCursorStmt *a, DeclareCursorStmt *b)
+ {
+ COMPARE_STRING_FIELD(portalname);
+ COMPARE_SCALAR_FIELD(options);
+ COMPARE_NODE_FIELD(query);
+
+ return 0;
+ }
+
+ static int
+ _compareClosePortalStmt(ClosePortalStmt *a, ClosePortalStmt *b)
+ {
+ COMPARE_STRING_FIELD(portalname);
+
+ return 0;
+ }
+
+ static int
+ _compareClusterStmt(ClusterStmt *a, ClusterStmt *b)
+ {
+ COMPARE_NODE_FIELD(relation);
+ COMPARE_STRING_FIELD(indexname);
+ COMPARE_SCALAR_FIELD(verbose);
+
+ return 0;
+ }
+
+ static int
+ _compareCopyStmt(CopyStmt *a, CopyStmt *b)
+ {
+ COMPARE_NODE_FIELD(relation);
+ COMPARE_NODE_FIELD(query);
+ COMPARE_NODE_FIELD(attlist);
+ COMPARE_SCALAR_FIELD(is_from);
+ COMPARE_STRING_FIELD(filename);
+ COMPARE_NODE_FIELD(options);
+
+ return 0;
+ }
+
+ static int
+ _compareCreateStmt(CreateStmt *a, CreateStmt *b)
+ {
+ COMPARE_NODE_FIELD(relation);
+ COMPARE_NODE_FIELD(tableElts);
+ COMPARE_NODE_FIELD(inhRelations);
+ COMPARE_NODE_FIELD(ofTypename);
+ COMPARE_NODE_FIELD(constraints);
+ COMPARE_NODE_FIELD(options);
+ COMPARE_SCALAR_FIELD(oncommit);
+ COMPARE_STRING_FIELD(tablespacename);
+
+ return 0;
+ }
+
+ static int
+ _compareInhRelation(InhRelation *a, InhRelation *b)
+ {
+ COMPARE_NODE_FIELD(relation);
+ COMPARE_SCALAR_FIELD(options);
+
+ return 0;
+ }
+
+ static int
+ _compareDefineStmt(DefineStmt *a, DefineStmt *b)
+ {
+ COMPARE_SCALAR_FIELD(kind);
+ COMPARE_SCALAR_FIELD(oldstyle);
+ COMPARE_NODE_FIELD(defnames);
+ COMPARE_NODE_FIELD(args);
+ COMPARE_NODE_FIELD(definition);
+
+ return 0;
+ }
+
+ static int
+ _compareDropStmt(DropStmt *a, DropStmt *b)
+ {
+ COMPARE_NODE_FIELD(objects);
+ COMPARE_SCALAR_FIELD(removeType);
+ COMPARE_SCALAR_FIELD(behavior);
+ COMPARE_SCALAR_FIELD(missing_ok);
+
+ return 0;
+ }
+
+ static int
+ _compareTruncateStmt(TruncateStmt *a, TruncateStmt *b)
+ {
+ COMPARE_NODE_FIELD(relations);
+ COMPARE_SCALAR_FIELD(restart_seqs);
+ COMPARE_SCALAR_FIELD(behavior);
+
+ return 0;
+ }
+
+ static int
+ _compareCommentStmt(CommentStmt *a, CommentStmt *b)
+ {
+ COMPARE_SCALAR_FIELD(objtype);
+ COMPARE_NODE_FIELD(objname);
+ COMPARE_NODE_FIELD(objargs);
+ COMPARE_STRING_FIELD(comment);
+
+ return 0;
+ }
+
+ static int
+ _compareFetchStmt(FetchStmt *a, FetchStmt *b)
+ {
+ COMPARE_SCALAR_FIELD(direction);
+ COMPARE_SCALAR_FIELD(howMany);
+ COMPARE_STRING_FIELD(portalname);
+ COMPARE_SCALAR_FIELD(ismove);
+
+ return 0;
+ }
+
+ static int
+ _compareIndexStmt(IndexStmt *a, IndexStmt *b)
+ {
+ COMPARE_STRING_FIELD(idxname);
+ COMPARE_NODE_FIELD(relation);
+ COMPARE_STRING_FIELD(accessMethod);
+ COMPARE_STRING_FIELD(tableSpace);
+ COMPARE_NODE_FIELD(indexParams);
+ COMPARE_NODE_FIELD(options);
+ COMPARE_NODE_FIELD(whereClause);
+ COMPARE_NODE_FIELD(excludeOpNames);
+ COMPARE_SCALAR_FIELD(unique);
+ COMPARE_SCALAR_FIELD(primary);
+ COMPARE_SCALAR_FIELD(isconstraint);
+ COMPARE_SCALAR_FIELD(deferrable);
+ COMPARE_SCALAR_FIELD(initdeferred);
+ COMPARE_SCALAR_FIELD(concurrent);
+
+ return 0;
+ }
+
+ static int
+ _compareCreateFunctionStmt(CreateFunctionStmt *a, CreateFunctionStmt *b)
+ {
+ COMPARE_SCALAR_FIELD(replace);
+ COMPARE_NODE_FIELD(funcname);
+ COMPARE_NODE_FIELD(parameters);
+ COMPARE_NODE_FIELD(returnType);
+ COMPARE_NODE_FIELD(options);
+ COMPARE_NODE_FIELD(withClause);
+
+ return 0;
+ }
+
+ static int
+ _compareFunctionParameter(FunctionParameter *a, FunctionParameter *b)
+ {
+ COMPARE_STRING_FIELD(name);
+ COMPARE_NODE_FIELD(argType);
+ COMPARE_SCALAR_FIELD(mode);
+ COMPARE_NODE_FIELD(defexpr);
+
+ return 0;
+ }
+
+ static int
+ _compareAlterFunctionStmt(AlterFunctionStmt *a, AlterFunctionStmt *b)
+ {
+ COMPARE_NODE_FIELD(func);
+ COMPARE_NODE_FIELD(actions);
+
+ return 0;
+ }
+
+ static int
+ _compareRemoveFuncStmt(RemoveFuncStmt *a, RemoveFuncStmt *b)
+ {
+ COMPARE_SCALAR_FIELD(kind);
+ COMPARE_NODE_FIELD(name);
+ COMPARE_NODE_FIELD(args);
+ COMPARE_SCALAR_FIELD(behavior);
+ COMPARE_SCALAR_FIELD(missing_ok);
+
+ return 0;
+ }
+
+ static int
+ _compareDoStmt(DoStmt *a, DoStmt *b)
+ {
+ COMPARE_NODE_FIELD(args);
+
+ return 0;
+ }
+
+ static int
+ _compareRemoveOpClassStmt(RemoveOpClassStmt *a, RemoveOpClassStmt *b)
+ {
+ COMPARE_NODE_FIELD(opclassname);
+ COMPARE_STRING_FIELD(amname);
+ COMPARE_SCALAR_FIELD(behavior);
+ COMPARE_SCALAR_FIELD(missing_ok);
+
+ return 0;
+ }
+
+ static int
+ _compareRemoveOpFamilyStmt(RemoveOpFamilyStmt *a, RemoveOpFamilyStmt *b)
+ {
+ COMPARE_NODE_FIELD(opfamilyname);
+ COMPARE_STRING_FIELD(amname);
+ COMPARE_SCALAR_FIELD(behavior);
+ COMPARE_SCALAR_FIELD(missing_ok);
+
+ return 0;
+ }
+
+ static int
+ _compareRenameStmt(RenameStmt *a, RenameStmt *b)
+ {
+ COMPARE_SCALAR_FIELD(renameType);
+ COMPARE_NODE_FIELD(relation);
+ COMPARE_NODE_FIELD(object);
+ COMPARE_NODE_FIELD(objarg);
+ COMPARE_STRING_FIELD(subname);
+ COMPARE_STRING_FIELD(newname);
+
+ return 0;
+ }
+
+ static int
+ _compareAlterObjectSchemaStmt(AlterObjectSchemaStmt *a, AlterObjectSchemaStmt *b)
+ {
+ COMPARE_SCALAR_FIELD(objectType);
+ COMPARE_NODE_FIELD(relation);
+ COMPARE_NODE_FIELD(object);
+ COMPARE_NODE_FIELD(objarg);
+ COMPARE_STRING_FIELD(addname);
+ COMPARE_STRING_FIELD(newschema);
+
+ return 0;
+ }
+
+ static int
+ _compareAlterOwnerStmt(AlterOwnerStmt *a, AlterOwnerStmt *b)
+ {
+ COMPARE_SCALAR_FIELD(objectType);
+ COMPARE_NODE_FIELD(relation);
+ COMPARE_NODE_FIELD(object);
+ COMPARE_NODE_FIELD(objarg);
+ COMPARE_STRING_FIELD(addname);
+ COMPARE_STRING_FIELD(newowner);
+
+ return 0;
+ }
+
+ static int
+ _compareRuleStmt(RuleStmt *a, RuleStmt *b)
+ {
+ COMPARE_NODE_FIELD(relation);
+ COMPARE_STRING_FIELD(rulename);
+ COMPARE_NODE_FIELD(whereClause);
+ COMPARE_SCALAR_FIELD(event);
+ COMPARE_SCALAR_FIELD(instead);
+ COMPARE_NODE_FIELD(actions);
+ COMPARE_SCALAR_FIELD(replace);
+
+ return 0;
+ }
+
+ static int
+ _compareNotifyStmt(NotifyStmt *a, NotifyStmt *b)
+ {
+ COMPARE_STRING_FIELD(conditionname);
+ COMPARE_STRING_FIELD(payload);
+
+ return 0;
+ }
+
+ static int
+ _compareListenStmt(ListenStmt *a, ListenStmt *b)
+ {
+ COMPARE_STRING_FIELD(conditionname);
+
+ return 0;
+ }
+
+ static int
+ _compareUnlistenStmt(UnlistenStmt *a, UnlistenStmt *b)
+ {
+ COMPARE_STRING_FIELD(conditionname);
+
+ return 0;
+ }
+
+ static int
+ _compareTransactionStmt(TransactionStmt *a, TransactionStmt *b)
+ {
+ COMPARE_SCALAR_FIELD(kind);
+ COMPARE_NODE_FIELD(options);
+ COMPARE_STRING_FIELD(gid);
+
+ return 0;
+ }
+
+ static int
+ _compareCompositeTypeStmt(CompositeTypeStmt *a, CompositeTypeStmt *b)
+ {
+ COMPARE_NODE_FIELD(typevar);
+ COMPARE_NODE_FIELD(coldeflist);
+
+ return 0;
+ }
+
+ static int
+ _compareCreateEnumStmt(CreateEnumStmt *a, CreateEnumStmt *b)
+ {
+ COMPARE_NODE_FIELD(typeName);
+ COMPARE_NODE_FIELD(vals);
+
+ return 0;
+ }
+
+ static int
+ _compareViewStmt(ViewStmt *a, ViewStmt *b)
+ {
+ COMPARE_NODE_FIELD(view);
+ COMPARE_NODE_FIELD(aliases);
+ COMPARE_NODE_FIELD(query);
+ COMPARE_SCALAR_FIELD(replace);
+
+ return 0;
+ }
+
+ static int
+ _compareLoadStmt(LoadStmt *a, LoadStmt *b)
+ {
+ COMPARE_STRING_FIELD(filename);
+
+ return 0;
+ }
+
+ static int
+ _compareCreateDomainStmt(CreateDomainStmt *a, CreateDomainStmt *b)
+ {
+ COMPARE_NODE_FIELD(domainname);
+ COMPARE_NODE_FIELD(typeName);
+ COMPARE_NODE_FIELD(constraints);
+
+ return 0;
+ }
+
+ static int
+ _compareCreateOpClassStmt(CreateOpClassStmt *a, CreateOpClassStmt *b)
+ {
+ COMPARE_NODE_FIELD(opclassname);
+ COMPARE_NODE_FIELD(opfamilyname);
+ COMPARE_STRING_FIELD(amname);
+ COMPARE_NODE_FIELD(datatype);
+ COMPARE_NODE_FIELD(items);
+ COMPARE_SCALAR_FIELD(isDefault);
+
+ return 0;
+ }
+
+ static int
+ _compareCreateOpClassItem(CreateOpClassItem *a, CreateOpClassItem *b)
+ {
+ COMPARE_SCALAR_FIELD(itemtype);
+ COMPARE_NODE_FIELD(name);
+ COMPARE_NODE_FIELD(args);
+ COMPARE_SCALAR_FIELD(number);
+ COMPARE_NODE_FIELD(class_args);
+ COMPARE_NODE_FIELD(storedtype);
+
+ return 0;
+ }
+
+ static int
+ _compareCreateOpFamilyStmt(CreateOpFamilyStmt *a, CreateOpFamilyStmt *b)
+ {
+ COMPARE_NODE_FIELD(opfamilyname);
+ COMPARE_STRING_FIELD(amname);
+
+ return 0;
+ }
+
+ static int
+ _compareAlterOpFamilyStmt(AlterOpFamilyStmt *a, AlterOpFamilyStmt *b)
+ {
+ COMPARE_NODE_FIELD(opfamilyname);
+ COMPARE_STRING_FIELD(amname);
+ COMPARE_SCALAR_FIELD(isDrop);
+ COMPARE_NODE_FIELD(items);
+
+ return 0;
+ }
+
+ static int
+ _compareCreatedbStmt(CreatedbStmt *a, CreatedbStmt *b)
+ {
+ COMPARE_STRING_FIELD(dbname);
+ COMPARE_NODE_FIELD(options);
+
+ return 0;
+ }
+
+ static int
+ _compareAlterDatabaseStmt(AlterDatabaseStmt *a, AlterDatabaseStmt *b)
+ {
+ COMPARE_STRING_FIELD(dbname);
+ COMPARE_NODE_FIELD(options);
+
+ return 0;
+ }
+
+ static int
+ _compareAlterDatabaseSetStmt(AlterDatabaseSetStmt *a, AlterDatabaseSetStmt *b)
+ {
+ COMPARE_STRING_FIELD(dbname);
+ COMPARE_NODE_FIELD(setstmt);
+
+ return 0;
+ }
+
+ static int
+ _compareDropdbStmt(DropdbStmt *a, DropdbStmt *b)
+ {
+ COMPARE_STRING_FIELD(dbname);
+ COMPARE_SCALAR_FIELD(missing_ok);
+
+ return 0;
+ }
+
+ static int
+ _compareVacuumStmt(VacuumStmt *a, VacuumStmt *b)
+ {
+ COMPARE_SCALAR_FIELD(options);
+ COMPARE_SCALAR_FIELD(freeze_min_age);
+ COMPARE_SCALAR_FIELD(freeze_table_age);
+ COMPARE_NODE_FIELD(relation);
+ COMPARE_NODE_FIELD(va_cols);
+
+ return 0;
+ }
+
+ static int
+ _compareExplainStmt(ExplainStmt *a, ExplainStmt *b)
+ {
+ COMPARE_NODE_FIELD(query);
+ COMPARE_NODE_FIELD(options);
+
+ return 0;
+ }
+
+ static int
+ _compareCreateSeqStmt(CreateSeqStmt *a, CreateSeqStmt *b)
+ {
+ COMPARE_NODE_FIELD(sequence);
+ COMPARE_NODE_FIELD(options);
+ COMPARE_SCALAR_FIELD(ownerId);
+
+ return 0;
+ }
+
+ static int
+ _compareAlterSeqStmt(AlterSeqStmt *a, AlterSeqStmt *b)
+ {
+ COMPARE_NODE_FIELD(sequence);
+ COMPARE_NODE_FIELD(options);
+
+ return 0;
+ }
+
+ static int
+ _compareVariableSetStmt(VariableSetStmt *a, VariableSetStmt *b)
+ {
+ COMPARE_SCALAR_FIELD(kind);
+ COMPARE_STRING_FIELD(name);
+ COMPARE_NODE_FIELD(args);
+ COMPARE_SCALAR_FIELD(is_local);
+
+ return 0;
+ }
+
+ static int
+ _compareVariableShowStmt(VariableShowStmt *a, VariableShowStmt *b)
+ {
+ COMPARE_STRING_FIELD(name);
+
+ return 0;
+ }
+
+ static int
+ _compareDiscardStmt(DiscardStmt *a, DiscardStmt *b)
+ {
+ COMPARE_SCALAR_FIELD(target);
+
+ return 0;
+ }
+
+ static int
+ _compareCreateTableSpaceStmt(CreateTableSpaceStmt *a, CreateTableSpaceStmt *b)
+ {
+ COMPARE_STRING_FIELD(tablespacename);
+ COMPARE_STRING_FIELD(owner);
+ COMPARE_STRING_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareDropTableSpaceStmt(DropTableSpaceStmt *a, DropTableSpaceStmt *b)
+ {
+ COMPARE_STRING_FIELD(tablespacename);
+ COMPARE_SCALAR_FIELD(missing_ok);
+
+ return 0;
+ }
+
+ static int
+ _compareAlterTableSpaceOptionsStmt(AlterTableSpaceOptionsStmt *a,
+ AlterTableSpaceOptionsStmt *b)
+ {
+ COMPARE_STRING_FIELD(tablespacename);
+ COMPARE_NODE_FIELD(options);
+ COMPARE_SCALAR_FIELD(isReset);
+
+ return 0;
+ }
+
+ static int
+ _compareCreateFdwStmt(CreateFdwStmt *a, CreateFdwStmt *b)
+ {
+ COMPARE_STRING_FIELD(fdwname);
+ COMPARE_NODE_FIELD(validator);
+ COMPARE_NODE_FIELD(options);
+
+ return 0;
+ }
+
+ static int
+ _compareAlterFdwStmt(AlterFdwStmt *a, AlterFdwStmt *b)
+ {
+ COMPARE_STRING_FIELD(fdwname);
+ COMPARE_NODE_FIELD(validator);
+ COMPARE_SCALAR_FIELD(change_validator);
+ COMPARE_NODE_FIELD(options);
+
+ return 0;
+ }
+
+ static int
+ _compareDropFdwStmt(DropFdwStmt *a, DropFdwStmt *b)
+ {
+ COMPARE_STRING_FIELD(fdwname);
+ COMPARE_SCALAR_FIELD(missing_ok);
+ COMPARE_SCALAR_FIELD(behavior);
+
+ return 0;
+ }
+
+ static int
+ _compareCreateForeignServerStmt(CreateForeignServerStmt *a, CreateForeignServerStmt *b)
+ {
+ COMPARE_STRING_FIELD(servername);
+ COMPARE_STRING_FIELD(servertype);
+ COMPARE_STRING_FIELD(version);
+ COMPARE_STRING_FIELD(fdwname);
+ COMPARE_NODE_FIELD(options);
+
+ return 0;
+ }
+
+ static int
+ _compareAlterForeignServerStmt(AlterForeignServerStmt *a, AlterForeignServerStmt *b)
+ {
+ COMPARE_STRING_FIELD(servername);
+ COMPARE_STRING_FIELD(version);
+ COMPARE_NODE_FIELD(options);
+ COMPARE_SCALAR_FIELD(has_version);
+
+ return 0;
+ }
+
+ static int
+ _compareDropForeignServerStmt(DropForeignServerStmt *a, DropForeignServerStmt *b)
+ {
+ COMPARE_STRING_FIELD(servername);
+ COMPARE_SCALAR_FIELD(missing_ok);
+ COMPARE_SCALAR_FIELD(behavior);
+
+ return 0;
+ }
+
+ static int
+ _compareCreateUserMappingStmt(CreateUserMappingStmt *a, CreateUserMappingStmt *b)
+ {
+ COMPARE_STRING_FIELD(username);
+ COMPARE_STRING_FIELD(servername);
+ COMPARE_NODE_FIELD(options);
+
+ return 0;
+ }
+
+ static int
+ _compareAlterUserMappingStmt(AlterUserMappingStmt *a, AlterUserMappingStmt *b)
+ {
+ COMPARE_STRING_FIELD(username);
+ COMPARE_STRING_FIELD(servername);
+ COMPARE_NODE_FIELD(options);
+
+ return 0;
+ }
+
+ static int
+ _compareDropUserMappingStmt(DropUserMappingStmt *a, DropUserMappingStmt *b)
+ {
+ COMPARE_STRING_FIELD(username);
+ COMPARE_STRING_FIELD(servername);
+ COMPARE_SCALAR_FIELD(missing_ok);
+
+ return 0;
+ }
+
+ static int
+ _compareCreateTrigStmt(CreateTrigStmt *a, CreateTrigStmt *b)
+ {
+ COMPARE_STRING_FIELD(trigname);
+ COMPARE_NODE_FIELD(relation);
+ COMPARE_NODE_FIELD(funcname);
+ COMPARE_NODE_FIELD(args);
+ COMPARE_SCALAR_FIELD(row);
+ COMPARE_SCALAR_FIELD(timing);
+ COMPARE_SCALAR_FIELD(events);
+ COMPARE_NODE_FIELD(columns);
+ COMPARE_NODE_FIELD(whenClause);
+ COMPARE_SCALAR_FIELD(isconstraint);
+ COMPARE_SCALAR_FIELD(deferrable);
+ COMPARE_SCALAR_FIELD(initdeferred);
+ COMPARE_NODE_FIELD(constrrel);
+
+ return 0;
+ }
+
+ static int
+ _compareDropPropertyStmt(DropPropertyStmt *a, DropPropertyStmt *b)
+ {
+ COMPARE_NODE_FIELD(relation);
+ COMPARE_STRING_FIELD(property);
+ COMPARE_SCALAR_FIELD(removeType);
+ COMPARE_SCALAR_FIELD(behavior);
+ COMPARE_SCALAR_FIELD(missing_ok);
+
+ return 0;
+ }
+
+ static int
+ _compareCreatePLangStmt(CreatePLangStmt *a, CreatePLangStmt *b)
+ {
+ COMPARE_SCALAR_FIELD(replace);
+ COMPARE_STRING_FIELD(plname);
+ COMPARE_NODE_FIELD(plhandler);
+ COMPARE_NODE_FIELD(plinline);
+ COMPARE_NODE_FIELD(plvalidator);
+ COMPARE_SCALAR_FIELD(pltrusted);
+
+ return 0;
+ }
+
+ static int
+ _compareDropPLangStmt(DropPLangStmt *a, DropPLangStmt *b)
+ {
+ COMPARE_STRING_FIELD(plname);
+ COMPARE_SCALAR_FIELD(behavior);
+ COMPARE_SCALAR_FIELD(missing_ok);
+
+ return 0;
+ }
+
+ static int
+ _compareCreateRoleStmt(CreateRoleStmt *a, CreateRoleStmt *b)
+ {
+ COMPARE_SCALAR_FIELD(stmt_type);
+ COMPARE_STRING_FIELD(role);
+ COMPARE_NODE_FIELD(options);
+
+ return 0;
+ }
+
+ static int
+ _compareAlterRoleStmt(AlterRoleStmt *a, AlterRoleStmt *b)
+ {
+ COMPARE_STRING_FIELD(role);
+ COMPARE_NODE_FIELD(options);
+ COMPARE_SCALAR_FIELD(action);
+
+ return 0;
+ }
+
+ static int
+ _compareAlterRoleSetStmt(AlterRoleSetStmt *a, AlterRoleSetStmt *b)
+ {
+ COMPARE_STRING_FIELD(role);
+ COMPARE_STRING_FIELD(database);
+ COMPARE_NODE_FIELD(setstmt);
+
+ return 0;
+ }
+
+ static int
+ _compareDropRoleStmt(DropRoleStmt *a, DropRoleStmt *b)
+ {
+ COMPARE_NODE_FIELD(roles);
+ COMPARE_SCALAR_FIELD(missing_ok);
+
+ return 0;
+ }
+
+ static int
+ _compareLockStmt(LockStmt *a, LockStmt *b)
+ {
+ COMPARE_NODE_FIELD(relations);
+ COMPARE_SCALAR_FIELD(mode);
+ COMPARE_SCALAR_FIELD(nowait);
+
+ return 0;
+ }
+
+ static int
+ _compareConstraintsSetStmt(ConstraintsSetStmt *a, ConstraintsSetStmt *b)
+ {
+ COMPARE_NODE_FIELD(constraints);
+ COMPARE_SCALAR_FIELD(deferred);
+
+ return 0;
+ }
+
+ static int
+ _compareReindexStmt(ReindexStmt *a, ReindexStmt *b)
+ {
+ COMPARE_SCALAR_FIELD(kind);
+ COMPARE_NODE_FIELD(relation);
+ COMPARE_STRING_FIELD(name);
+ COMPARE_SCALAR_FIELD(do_system);
+ COMPARE_SCALAR_FIELD(do_user);
+
+ return 0;
+ }
+
+ static int
+ _compareCreateSchemaStmt(CreateSchemaStmt *a, CreateSchemaStmt *b)
+ {
+ COMPARE_STRING_FIELD(schemaname);
+ COMPARE_STRING_FIELD(authid);
+ COMPARE_NODE_FIELD(schemaElts);
+
+ return 0;
+ }
+
+ static int
+ _compareCreateConversionStmt(CreateConversionStmt *a, CreateConversionStmt *b)
+ {
+ COMPARE_NODE_FIELD(conversion_name);
+ COMPARE_STRING_FIELD(for_encoding_name);
+ COMPARE_STRING_FIELD(to_encoding_name);
+ COMPARE_NODE_FIELD(func_name);
+ COMPARE_SCALAR_FIELD(def);
+
+ return 0;
+ }
+
+ static int
+ _compareCreateCastStmt(CreateCastStmt *a, CreateCastStmt *b)
+ {
+ COMPARE_NODE_FIELD(sourcetype);
+ COMPARE_NODE_FIELD(targettype);
+ COMPARE_NODE_FIELD(func);
+ COMPARE_SCALAR_FIELD(context);
+ COMPARE_SCALAR_FIELD(inout);
+
+ return 0;
+ }
+
+ static int
+ _compareDropCastStmt(DropCastStmt *a, DropCastStmt *b)
+ {
+ COMPARE_NODE_FIELD(sourcetype);
+ COMPARE_NODE_FIELD(targettype);
+ COMPARE_SCALAR_FIELD(behavior);
+ COMPARE_SCALAR_FIELD(missing_ok);
+
+ return 0;
+ }
+
+ static int
+ _comparePrepareStmt(PrepareStmt *a, PrepareStmt *b)
+ {
+ COMPARE_STRING_FIELD(name);
+ COMPARE_NODE_FIELD(argtypes);
+ COMPARE_NODE_FIELD(query);
+
+ return 0;
+ }
+
+ static int
+ _compareExecuteStmt(ExecuteStmt *a, ExecuteStmt *b)
+ {
+ COMPARE_STRING_FIELD(name);
+ COMPARE_NODE_FIELD(into);
+ COMPARE_NODE_FIELD(params);
+
+ return 0;
+ }
+
+ static int
+ _compareDeallocateStmt(DeallocateStmt *a, DeallocateStmt *b)
+ {
+ COMPARE_STRING_FIELD(name);
+
+ return 0;
+ }
+
+ static int
+ _compareDropOwnedStmt(DropOwnedStmt *a, DropOwnedStmt *b)
+ {
+ COMPARE_NODE_FIELD(roles);
+ COMPARE_SCALAR_FIELD(behavior);
+
+ return 0;
+ }
+
+ static int
+ _compareReassignOwnedStmt(ReassignOwnedStmt *a, ReassignOwnedStmt *b)
+ {
+ COMPARE_NODE_FIELD(roles);
+ COMPARE_NODE_FIELD(newrole);
+
+ return 0;
+ }
+
+ static int
+ _compareAlterTSDictionaryStmt(AlterTSDictionaryStmt *a, AlterTSDictionaryStmt *b)
+ {
+ COMPARE_NODE_FIELD(dictname);
+ COMPARE_NODE_FIELD(options);
+
+ return 0;
+ }
+
+ static int
+ _compareAlterTSConfigurationStmt(AlterTSConfigurationStmt *a,
+ AlterTSConfigurationStmt *b)
+ {
+ COMPARE_NODE_FIELD(cfgname);
+ COMPARE_NODE_FIELD(tokentype);
+ COMPARE_NODE_FIELD(dicts);
+ COMPARE_SCALAR_FIELD(override);
+ COMPARE_SCALAR_FIELD(replace);
+ COMPARE_SCALAR_FIELD(missing_ok);
+
+ return 0;
+ }
+
+ static int
+ _compareAExpr(A_Expr *a, A_Expr *b)
+ {
+ COMPARE_SCALAR_FIELD(kind);
+ COMPARE_NODE_FIELD(name);
+ COMPARE_NODE_FIELD(lexpr);
+ COMPARE_NODE_FIELD(rexpr);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareColumnRef(ColumnRef *a, ColumnRef *b)
+ {
+ COMPARE_NODE_FIELD(fields);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareParamRef(ParamRef *a, ParamRef *b)
+ {
+ COMPARE_SCALAR_FIELD(number);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareAConst(A_Const *a, A_Const *b)
+ {
+ int ret;
+ if ((ret = compare(&a->val, &b->val)) != 0) /* hack for in-line Value field */
+ return ret;
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareFuncCall(FuncCall *a, FuncCall *b)
+ {
+ COMPARE_NODE_FIELD(funcname);
+ COMPARE_NODE_FIELD(args);
+ COMPARE_NODE_FIELD(agg_order);
+ COMPARE_SCALAR_FIELD(agg_star);
+ COMPARE_SCALAR_FIELD(agg_distinct);
+ COMPARE_SCALAR_FIELD(func_variadic);
+ COMPARE_NODE_FIELD(over);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareAStar(A_Star *a, A_Star *b)
+ {
+ return 0;
+ }
+
+ static int
+ _compareAIndices(A_Indices *a, A_Indices *b)
+ {
+ COMPARE_NODE_FIELD(lidx);
+ COMPARE_NODE_FIELD(uidx);
+
+ return 0;
+ }
+
+ static int
+ _compareA_Indirection(A_Indirection *a, A_Indirection *b)
+ {
+ COMPARE_NODE_FIELD(arg);
+ COMPARE_NODE_FIELD(indirection);
+
+ return 0;
+ }
+
+ static int
+ _compareA_ArrayExpr(A_ArrayExpr *a, A_ArrayExpr *b)
+ {
+ COMPARE_NODE_FIELD(elements);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareResTarget(ResTarget *a, ResTarget *b)
+ {
+ COMPARE_STRING_FIELD(name);
+ COMPARE_NODE_FIELD(indirection);
+ COMPARE_NODE_FIELD(val);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareTypeName(TypeName *a, TypeName *b)
+ {
+ COMPARE_NODE_FIELD(names);
+ COMPARE_SCALAR_FIELD(typeOid);
+ COMPARE_SCALAR_FIELD(setof);
+ COMPARE_SCALAR_FIELD(pct_type);
+ COMPARE_NODE_FIELD(typmods);
+ COMPARE_SCALAR_FIELD(typemod);
+ COMPARE_NODE_FIELD(arrayBounds);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareTypeCast(TypeCast *a, TypeCast *b)
+ {
+ COMPARE_NODE_FIELD(arg);
+ COMPARE_NODE_FIELD(typeName);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareSortBy(SortBy *a, SortBy *b)
+ {
+ COMPARE_NODE_FIELD(node);
+ COMPARE_SCALAR_FIELD(sortby_dir);
+ COMPARE_SCALAR_FIELD(sortby_nulls);
+ COMPARE_NODE_FIELD(useOp);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareWindowDef(WindowDef *a, WindowDef *b)
+ {
+ COMPARE_STRING_FIELD(name);
+ COMPARE_STRING_FIELD(refname);
+ COMPARE_NODE_FIELD(partitionClause);
+ COMPARE_NODE_FIELD(orderClause);
+ COMPARE_SCALAR_FIELD(frameOptions);
+ COMPARE_NODE_FIELD(startOffset);
+ COMPARE_NODE_FIELD(endOffset);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareRangeSubselect(RangeSubselect *a, RangeSubselect *b)
+ {
+ COMPARE_NODE_FIELD(subquery);
+ COMPARE_NODE_FIELD(alias);
+
+ return 0;
+ }
+
+ static int
+ _compareRangeFunction(RangeFunction *a, RangeFunction *b)
+ {
+ COMPARE_NODE_FIELD(funccallnode);
+ COMPARE_NODE_FIELD(alias);
+ COMPARE_NODE_FIELD(coldeflist);
+
+ return 0;
+ }
+
+ static int
+ _compareIndexElem(IndexElem *a, IndexElem *b)
+ {
+ COMPARE_STRING_FIELD(name);
+ COMPARE_NODE_FIELD(expr);
+ COMPARE_STRING_FIELD(indexcolname);
+ COMPARE_NODE_FIELD(opclass);
+ COMPARE_SCALAR_FIELD(ordering);
+ COMPARE_SCALAR_FIELD(nulls_ordering);
+
+ return 0;
+ }
+
+ static int
+ _compareColumnDef(ColumnDef *a, ColumnDef *b)
+ {
+ COMPARE_STRING_FIELD(colname);
+ COMPARE_NODE_FIELD(typeName);
+ COMPARE_SCALAR_FIELD(inhcount);
+ COMPARE_SCALAR_FIELD(is_local);
+ COMPARE_SCALAR_FIELD(is_not_null);
+ COMPARE_SCALAR_FIELD(storage);
+ COMPARE_NODE_FIELD(raw_default);
+ COMPARE_NODE_FIELD(cooked_default);
+ COMPARE_NODE_FIELD(constraints);
+
+ return 0;
+ }
+
+ static int
+ _compareConstraint(Constraint *a, Constraint *b)
+ {
+ COMPARE_SCALAR_FIELD(contype);
+ COMPARE_STRING_FIELD(conname);
+ COMPARE_SCALAR_FIELD(deferrable);
+ COMPARE_SCALAR_FIELD(initdeferred);
+ COMPARE_LOCATION_FIELD(location);
+ COMPARE_NODE_FIELD(raw_expr);
+ COMPARE_STRING_FIELD(cooked_expr);
+ COMPARE_NODE_FIELD(keys);
+ COMPARE_NODE_FIELD(exclusions);
+ COMPARE_NODE_FIELD(options);
+ COMPARE_STRING_FIELD(indexspace);
+ COMPARE_STRING_FIELD(access_method);
+ COMPARE_NODE_FIELD(where_clause);
+ COMPARE_NODE_FIELD(pktable);
+ COMPARE_NODE_FIELD(fk_attrs);
+ COMPARE_NODE_FIELD(pk_attrs);
+ COMPARE_SCALAR_FIELD(fk_matchtype);
+ COMPARE_SCALAR_FIELD(fk_upd_action);
+ COMPARE_SCALAR_FIELD(fk_del_action);
+ COMPARE_SCALAR_FIELD(skip_validation);
+
+ return 0;
+ }
+
+ static int
+ _compareDefElem(DefElem *a, DefElem *b)
+ {
+ COMPARE_STRING_FIELD(defnamespace);
+ COMPARE_STRING_FIELD(defname);
+ COMPARE_NODE_FIELD(arg);
+ COMPARE_SCALAR_FIELD(defaction);
+
+ return 0;
+ }
+
+ static int
+ _compareLockingClause(LockingClause *a, LockingClause *b)
+ {
+ COMPARE_NODE_FIELD(lockedRels);
+ COMPARE_SCALAR_FIELD(forUpdate);
+ COMPARE_SCALAR_FIELD(noWait);
+
+ return 0;
+ }
+
+ static int
+ _compareRangeTblEntry(RangeTblEntry *a, RangeTblEntry *b)
+ {
+ COMPARE_SCALAR_FIELD(rtekind);
+ COMPARE_SCALAR_FIELD(relid);
+ COMPARE_NODE_FIELD(subquery);
+ COMPARE_SCALAR_FIELD(jointype);
+ COMPARE_NODE_FIELD(joinaliasvars);
+ COMPARE_NODE_FIELD(funcexpr);
+ COMPARE_NODE_FIELD(funccoltypes);
+ COMPARE_NODE_FIELD(funccoltypmods);
+ COMPARE_NODE_FIELD(values_lists);
+ COMPARE_STRING_FIELD(ctename);
+ COMPARE_SCALAR_FIELD(ctelevelsup);
+ COMPARE_SCALAR_FIELD(self_reference);
+ COMPARE_NODE_FIELD(ctecoltypes);
+ COMPARE_NODE_FIELD(ctecoltypmods);
+ COMPARE_NODE_FIELD(alias);
+ COMPARE_NODE_FIELD(eref);
+ COMPARE_SCALAR_FIELD(inh);
+ COMPARE_SCALAR_FIELD(inFromCl);
+ COMPARE_SCALAR_FIELD(requiredPerms);
+ COMPARE_SCALAR_FIELD(checkAsUser);
+ COMPARE_BITMAPSET_FIELD(selectedCols);
+ COMPARE_BITMAPSET_FIELD(modifiedCols);
+
+ return 0;
+ }
+
+ static int
+ _compareSortGroupClause(SortGroupClause *a, SortGroupClause *b)
+ {
+ COMPARE_SCALAR_FIELD(tleSortGroupRef);
+ COMPARE_SCALAR_FIELD(eqop);
+ COMPARE_SCALAR_FIELD(sortop);
+ COMPARE_SCALAR_FIELD(nulls_first);
+
+ return 0;
+ }
+
+ static int
+ _compareWindowClause(WindowClause *a, WindowClause *b)
+ {
+ COMPARE_STRING_FIELD(name);
+ COMPARE_STRING_FIELD(refname);
+ COMPARE_NODE_FIELD(partitionClause);
+ COMPARE_NODE_FIELD(orderClause);
+ COMPARE_SCALAR_FIELD(frameOptions);
+ COMPARE_NODE_FIELD(startOffset);
+ COMPARE_NODE_FIELD(endOffset);
+ COMPARE_SCALAR_FIELD(winref);
+ COMPARE_SCALAR_FIELD(copiedOrder);
+
+ return 0;
+ }
+
+ static int
+ _compareRowMarkClause(RowMarkClause *a, RowMarkClause *b)
+ {
+ COMPARE_SCALAR_FIELD(rti);
+ COMPARE_SCALAR_FIELD(forUpdate);
+ COMPARE_SCALAR_FIELD(noWait);
+ COMPARE_SCALAR_FIELD(pushedDown);
+
+ return 0;
+ }
+
+ static int
+ _compareWithClause(WithClause *a, WithClause *b)
+ {
+ COMPARE_NODE_FIELD(ctes);
+ COMPARE_SCALAR_FIELD(recursive);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ static int
+ _compareCommonTableExpr(CommonTableExpr *a, CommonTableExpr *b)
+ {
+ COMPARE_STRING_FIELD(ctename);
+ COMPARE_NODE_FIELD(aliascolnames);
+ COMPARE_NODE_FIELD(ctequery);
+ COMPARE_LOCATION_FIELD(location);
+ COMPARE_SCALAR_FIELD(cterecursive);
+ COMPARE_SCALAR_FIELD(cterefcount);
+ COMPARE_NODE_FIELD(ctecolnames);
+ COMPARE_NODE_FIELD(ctecoltypes);
+ COMPARE_NODE_FIELD(ctecoltypmods);
+
+ return 0;
+ }
+
+ static int
+ _compareXmlSerialize(XmlSerialize *a, XmlSerialize *b)
+ {
+ COMPARE_SCALAR_FIELD(xmloption);
+ COMPARE_NODE_FIELD(expr);
+ COMPARE_NODE_FIELD(typeName);
+ COMPARE_LOCATION_FIELD(location);
+
+ return 0;
+ }
+
+ /*
+ * Stuff from pg_list.h
+ */
+
+ static int
+ _compareList(List *a, List *b)
+ {
+ ListCell *item_a;
+ ListCell *item_b;
+ int ret;
+
+ /*
+ * Try to reject by simple scalar checks before grovelling through all the
+ * list elements...
+ */
+ COMPARE_SCALAR_FIELD(type);
+ COMPARE_SCALAR_FIELD(length);
+
+ /*
+ * We place the switch outside the loop for the sake of efficiency; this
+ * may not be worth doing...
+ */
+ switch (a->type)
+ {
+ case T_List:
+ forboth(item_a, a, item_b, b)
+ {
+ ret = compare(lfirst(item_a), lfirst(item_b));
+ if (ret != 0)
+ return ret;
+ }
+ break;
+ case T_IntList:
+ forboth(item_a, a, item_b, b)
+ {
+ int val_a = lfirst_int(item_a);
+ int val_b = lfirst_int(item_b);
+
+ if (val_a < val_b)
+ return -1;
+ else if (val_a > val_b)
+ return 1;
+ }
+ break;
+ case T_OidList:
+ forboth(item_a, a, item_b, b)
+ {
+ Oid val_a = lfirst_oid(item_a);
+ Oid val_b = lfirst_oid(item_b);
+
+ if (val_a < val_b)
+ return -1;
+ else if (val_a > val_b)
+ return 1;
+ }
+ break;
+ default:
+ elog(ERROR, "unrecognized list node type: %d",
+ (int) a->type);
+ return 0; /* keep compiler quiet */
+ }
+
+ /*
+ * If we got here, we should have run out of elements of both lists
+ */
+ Assert(item_a == NULL);
+ Assert(item_b == NULL);
+
+ return 0;
+ }
+
+ /*
+ * Stuff from value.h
+ */
+
+ static int
+ _compareValue(Value *a, Value *b)
+ {
+ COMPARE_SCALAR_FIELD(type);
+
+ switch (a->type)
+ {
+ case T_Integer:
+ COMPARE_SCALAR_FIELD(val.ival);
+ break;
+ case T_Float:
+ case T_String:
+ case T_BitString:
+ COMPARE_STRING_FIELD(val.str);
+ break;
+ case T_Null:
+ /* nothing to do */
+ break;
+ default:
+ elog(ERROR, "unrecognized node type: %d", (int) a->type);
+ break;
+ }
+
+ return 0;
+ }
+
+ /*
+ * equal
+ * returns whether two nodes are equal
+ */
+ int
+ compare(void *a, void *b)
+ {
+ int retval;
+
+ if (a == b)
+ return 0;
+
+ /*
+ * note that a!=b, so only one of them can be NULL
+ */
+ if (a == NULL || b == NULL)
+ {
+ if (a < b)
+ return -1;
+ else if (a > b)
+ return 1;
+ }
+
+ /*
+ * are they the same type of nodes?
+ */
+ if (nodeTag(a) < nodeTag(b))
+ return -1;
+ else if (nodeTag(a) > nodeTag(b))
+ return 1;
+
+ switch (nodeTag(a))
+ {
+ /*
+ * PRIMITIVE NODES
+ */
+ case T_Alias:
+ retval = _compareAlias(a, b);
+ break;
+ case T_RangeVar:
+ retval = _compareRangeVar(a, b);
+ break;
+ case T_IntoClause:
+ retval = _compareIntoClause(a, b);
+ break;
+ case T_Var:
+ retval = _compareVar(a, b);
+ break;
+ case T_Const:
+ retval = _compareConst(a, b);
+ break;
+ case T_Param:
+ retval = _compareParam(a, b);
+ break;
+ case T_Aggref:
+ retval = _compareAggref(a, b);
+ break;
+ case T_WindowFunc:
+ retval = _compareWindowFunc(a, b);
+ break;
+ case T_ArrayRef:
+ retval = _compareArrayRef(a, b);
+ break;
+ case T_FuncExpr:
+ retval = _compareFuncExpr(a, b);
+ break;
+ case T_NamedArgExpr:
+ retval = _compareNamedArgExpr(a, b);
+ break;
+ case T_OpExpr:
+ retval = _compareOpExpr(a, b);
+ break;
+ case T_DistinctExpr:
+ retval = _compareDistinctExpr(a, b);
+ break;
+ case T_ScalarArrayOpExpr:
+ retval = _compareScalarArrayOpExpr(a, b);
+ break;
+ case T_BoolExpr:
+ retval = _compareBoolExpr(a, b);
+ break;
+ case T_SubLink:
+ retval = _compareSubLink(a, b);
+ break;
+ case T_SubPlan:
+ retval = _compareSubPlan(a, b);
+ break;
+ case T_AlternativeSubPlan:
+ retval = _compareAlternativeSubPlan(a, b);
+ break;
+ case T_FieldSelect:
+ retval = _compareFieldSelect(a, b);
+ break;
+ case T_FieldStore:
+ retval = _compareFieldStore(a, b);
+ break;
+ case T_RelabelType:
+ retval = _compareRelabelType(a, b);
+ break;
+ case T_CoerceViaIO:
+ retval = _compareCoerceViaIO(a, b);
+ break;
+ case T_ArrayCoerceExpr:
+ retval = _compareArrayCoerceExpr(a, b);
+ break;
+ case T_ConvertRowtypeExpr:
+ retval = _compareConvertRowtypeExpr(a, b);
+ break;
+ case T_CaseExpr:
+ retval = _compareCaseExpr(a, b);
+ break;
+ case T_CaseWhen:
+ retval = _compareCaseWhen(a, b);
+ break;
+ case T_CaseTestExpr:
+ retval = _compareCaseTestExpr(a, b);
+ break;
+ case T_ArrayExpr:
+ retval = _compareArrayExpr(a, b);
+ break;
+ case T_RowExpr:
+ retval = _compareRowExpr(a, b);
+ break;
+ case T_RowCompareExpr:
+ retval = _compareRowCompareExpr(a, b);
+ break;
+ case T_CoalesceExpr:
+ retval = _compareCoalesceExpr(a, b);
+ break;
+ case T_MinMaxExpr:
+ retval = _compareMinMaxExpr(a, b);
+ break;
+ case T_XmlExpr:
+ retval = _compareXmlExpr(a, b);
+ break;
+ case T_NullIfExpr:
+ retval = _compareNullIfExpr(a, b);
+ break;
+ case T_NullTest:
+ retval = _compareNullTest(a, b);
+ break;
+ case T_BooleanTest:
+ retval = _compareBooleanTest(a, b);
+ break;
+ case T_CoerceToDomain:
+ retval = _compareCoerceToDomain(a, b);
+ break;
+ case T_CoerceToDomainValue:
+ retval = _compareCoerceToDomainValue(a, b);
+ break;
+ case T_SetToDefault:
+ retval = _compareSetToDefault(a, b);
+ break;
+ case T_CurrentOfExpr:
+ retval = _compareCurrentOfExpr(a, b);
+ break;
+ case T_TargetEntry:
+ retval = _compareTargetEntry(a, b);
+ break;
+ case T_RangeTblRef:
+ retval = _compareRangeTblRef(a, b);
+ break;
+ case T_FromExpr:
+ retval = _compareFromExpr(a, b);
+ break;
+ case T_JoinExpr:
+ retval = _compareJoinExpr(a, b);
+ break;
+
+ /*
+ * RELATION NODES
+ */
+ case T_PathKey:
+ retval = _comparePathKey(a, b);
+ break;
+ case T_RestrictInfo:
+ retval = _compareRestrictInfo(a, b);
+ break;
+ case T_PlaceHolderVar:
+ retval = _comparePlaceHolderVar(a, b);
+ break;
+ case T_SpecialJoinInfo:
+ retval = _compareSpecialJoinInfo(a, b);
+ break;
+ case T_AppendRelInfo:
+ retval = _compareAppendRelInfo(a, b);
+ break;
+ case T_PlaceHolderInfo:
+ retval = _comparePlaceHolderInfo(a, b);
+ break;
+
+ case T_List:
+ case T_IntList:
+ case T_OidList:
+ retval = _compareList(a, b);
+ break;
+
+ case T_Integer:
+ case T_Float:
+ case T_String:
+ case T_BitString:
+ case T_Null:
+ retval = _compareValue(a, b);
+ break;
+
+ /*
+ * PARSE NODES
+ */
+ case T_Query:
+ retval = _compareQuery(a, b);
+ break;
+ case T_InsertStmt:
+ retval = _compareInsertStmt(a, b);
+ break;
+ case T_DeleteStmt:
+ retval = _compareDeleteStmt(a, b);
+ break;
+ case T_UpdateStmt:
+ retval = _compareUpdateStmt(a, b);
+ break;
+ case T_SelectStmt:
+ retval = _compareSelectStmt(a, b);
+ break;
+ case T_SetOperationStmt:
+ retval = _compareSetOperationStmt(a, b);
+ break;
+ case T_AlterTableStmt:
+ retval = _compareAlterTableStmt(a, b);
+ break;
+ case T_AlterTableCmd:
+ retval = _compareAlterTableCmd(a, b);
+ break;
+ case T_AlterDomainStmt:
+ retval = _compareAlterDomainStmt(a, b);
+ break;
+ case T_GrantStmt:
+ retval = _compareGrantStmt(a, b);
+ break;
+ case T_GrantRoleStmt:
+ retval = _compareGrantRoleStmt(a, b);
+ break;
+ case T_AlterDefaultPrivilegesStmt:
+ retval = _compareAlterDefaultPrivilegesStmt(a, b);
+ break;
+ case T_DeclareCursorStmt:
+ retval = _compareDeclareCursorStmt(a, b);
+ break;
+ case T_ClosePortalStmt:
+ retval = _compareClosePortalStmt(a, b);
+ break;
+ case T_ClusterStmt:
+ retval = _compareClusterStmt(a, b);
+ break;
+ case T_CopyStmt:
+ retval = _compareCopyStmt(a, b);
+ break;
+ case T_CreateStmt:
+ retval = _compareCreateStmt(a, b);
+ break;
+ case T_InhRelation:
+ retval = _compareInhRelation(a, b);
+ break;
+ case T_DefineStmt:
+ retval = _compareDefineStmt(a, b);
+ break;
+ case T_DropStmt:
+ retval = _compareDropStmt(a, b);
+ break;
+ case T_TruncateStmt:
+ retval = _compareTruncateStmt(a, b);
+ break;
+ case T_CommentStmt:
+ retval = _compareCommentStmt(a, b);
+ break;
+ case T_FetchStmt:
+ retval = _compareFetchStmt(a, b);
+ break;
+ case T_IndexStmt:
+ retval = _compareIndexStmt(a, b);
+ break;
+ case T_CreateFunctionStmt:
+ retval = _compareCreateFunctionStmt(a, b);
+ break;
+ case T_FunctionParameter:
+ retval = _compareFunctionParameter(a, b);
+ break;
+ case T_AlterFunctionStmt:
+ retval = _compareAlterFunctionStmt(a, b);
+ break;
+ case T_RemoveFuncStmt:
+ retval = _compareRemoveFuncStmt(a, b);
+ break;
+ case T_DoStmt:
+ retval = _compareDoStmt(a, b);
+ break;
+ case T_RemoveOpClassStmt:
+ retval = _compareRemoveOpClassStmt(a, b);
+ break;
+ case T_RemoveOpFamilyStmt:
+ retval = _compareRemoveOpFamilyStmt(a, b);
+ break;
+ case T_RenameStmt:
+ retval = _compareRenameStmt(a, b);
+ break;
+ case T_AlterObjectSchemaStmt:
+ retval = _compareAlterObjectSchemaStmt(a, b);
+ break;
+ case T_AlterOwnerStmt:
+ retval = _compareAlterOwnerStmt(a, b);
+ break;
+ case T_RuleStmt:
+ retval = _compareRuleStmt(a, b);
+ break;
+ case T_NotifyStmt:
+ retval = _compareNotifyStmt(a, b);
+ break;
+ case T_ListenStmt:
+ retval = _compareListenStmt(a, b);
+ break;
+ case T_UnlistenStmt:
+ retval = _compareUnlistenStmt(a, b);
+ break;
+ case T_TransactionStmt:
+ retval = _compareTransactionStmt(a, b);
+ break;
+ case T_CompositeTypeStmt:
+ retval = _compareCompositeTypeStmt(a, b);
+ break;
+ case T_CreateEnumStmt:
+ retval = _compareCreateEnumStmt(a, b);
+ break;
+ case T_ViewStmt:
+ retval = _compareViewStmt(a, b);
+ break;
+ case T_LoadStmt:
+ retval = _compareLoadStmt(a, b);
+ break;
+ case T_CreateDomainStmt:
+ retval = _compareCreateDomainStmt(a, b);
+ break;
+ case T_CreateOpClassStmt:
+ retval = _compareCreateOpClassStmt(a, b);
+ break;
+ case T_CreateOpClassItem:
+ retval = _compareCreateOpClassItem(a, b);
+ break;
+ case T_CreateOpFamilyStmt:
+ retval = _compareCreateOpFamilyStmt(a, b);
+ break;
+ case T_AlterOpFamilyStmt:
+ retval = _compareAlterOpFamilyStmt(a, b);
+ break;
+ case T_CreatedbStmt:
+ retval = _compareCreatedbStmt(a, b);
+ break;
+ case T_AlterDatabaseStmt:
+ retval = _compareAlterDatabaseStmt(a, b);
+ break;
+ case T_AlterDatabaseSetStmt:
+ retval = _compareAlterDatabaseSetStmt(a, b);
+ break;
+ case T_DropdbStmt:
+ retval = _compareDropdbStmt(a, b);
+ break;
+ case T_VacuumStmt:
+ retval = _compareVacuumStmt(a, b);
+ break;
+ case T_ExplainStmt:
+ retval = _compareExplainStmt(a, b);
+ break;
+ case T_CreateSeqStmt:
+ retval = _compareCreateSeqStmt(a, b);
+ break;
+ case T_AlterSeqStmt:
+ retval = _compareAlterSeqStmt(a, b);
+ break;
+ case T_VariableSetStmt:
+ retval = _compareVariableSetStmt(a, b);
+ break;
+ case T_VariableShowStmt:
+ retval = _compareVariableShowStmt(a, b);
+ break;
+ case T_DiscardStmt:
+ retval = _compareDiscardStmt(a, b);
+ break;
+ case T_CreateTableSpaceStmt:
+ retval = _compareCreateTableSpaceStmt(a, b);
+ break;
+ case T_DropTableSpaceStmt:
+ retval = _compareDropTableSpaceStmt(a, b);
+ break;
+ case T_AlterTableSpaceOptionsStmt:
+ retval = _compareAlterTableSpaceOptionsStmt(a, b);
+ break;
+ case T_CreateFdwStmt:
+ retval = _compareCreateFdwStmt(a, b);
+ break;
+ case T_AlterFdwStmt:
+ retval = _compareAlterFdwStmt(a, b);
+ break;
+ case T_DropFdwStmt:
+ retval = _compareDropFdwStmt(a, b);
+ break;
+ case T_CreateForeignServerStmt:
+ retval = _compareCreateForeignServerStmt(a, b);
+ break;
+ case T_AlterForeignServerStmt:
+ retval = _compareAlterForeignServerStmt(a, b);
+ break;
+ case T_DropForeignServerStmt:
+ retval = _compareDropForeignServerStmt(a, b);
+ break;
+ case T_CreateUserMappingStmt:
+ retval = _compareCreateUserMappingStmt(a, b);
+ break;
+ case T_AlterUserMappingStmt:
+ retval = _compareAlterUserMappingStmt(a, b);
+ break;
+ case T_DropUserMappingStmt:
+ retval = _compareDropUserMappingStmt(a, b);
+ break;
+ case T_CreateTrigStmt:
+ retval = _compareCreateTrigStmt(a, b);
+ break;
+ case T_DropPropertyStmt:
+ retval = _compareDropPropertyStmt(a, b);
+ break;
+ case T_CreatePLangStmt:
+ retval = _compareCreatePLangStmt(a, b);
+ break;
+ case T_DropPLangStmt:
+ retval = _compareDropPLangStmt(a, b);
+ break;
+ case T_CreateRoleStmt:
+ retval = _compareCreateRoleStmt(a, b);
+ break;
+ case T_AlterRoleStmt:
+ retval = _compareAlterRoleStmt(a, b);
+ break;
+ case T_AlterRoleSetStmt:
+ retval = _compareAlterRoleSetStmt(a, b);
+ break;
+ case T_DropRoleStmt:
+ retval = _compareDropRoleStmt(a, b);
+ break;
+ case T_LockStmt:
+ retval = _compareLockStmt(a, b);
+ break;
+ case T_ConstraintsSetStmt:
+ retval = _compareConstraintsSetStmt(a, b);
+ break;
+ case T_ReindexStmt:
+ retval = _compareReindexStmt(a, b);
+ break;
+ case T_CheckPointStmt:
+ retval = 0;
+ break;
+ case T_CreateSchemaStmt:
+ retval = _compareCreateSchemaStmt(a, b);
+ break;
+ case T_CreateConversionStmt:
+ retval = _compareCreateConversionStmt(a, b);
+ break;
+ case T_CreateCastStmt:
+ retval = _compareCreateCastStmt(a, b);
+ break;
+ case T_DropCastStmt:
+ retval = _compareDropCastStmt(a, b);
+ break;
+ case T_PrepareStmt:
+ retval = _comparePrepareStmt(a, b);
+ break;
+ case T_ExecuteStmt:
+ retval = _compareExecuteStmt(a, b);
+ break;
+ case T_DeallocateStmt:
+ retval = _compareDeallocateStmt(a, b);
+ break;
+ case T_DropOwnedStmt:
+ retval = _compareDropOwnedStmt(a, b);
+ break;
+ case T_ReassignOwnedStmt:
+ retval = _compareReassignOwnedStmt(a, b);
+ break;
+ case T_AlterTSDictionaryStmt:
+ retval = _compareAlterTSDictionaryStmt(a, b);
+ break;
+ case T_AlterTSConfigurationStmt:
+ retval = _compareAlterTSConfigurationStmt(a, b);
+ break;
+
+ case T_A_Expr:
+ retval = _compareAExpr(a, b);
+ break;
+ case T_ColumnRef:
+ retval = _compareColumnRef(a, b);
+ break;
+ case T_ParamRef:
+ retval = _compareParamRef(a, b);
+ break;
+ case T_A_Const:
+ retval = _compareAConst(a, b);
+ break;
+ case T_FuncCall:
+ retval = _compareFuncCall(a, b);
+ break;
+ case T_A_Star:
+ retval = _compareAStar(a, b);
+ break;
+ case T_A_Indices:
+ retval = _compareAIndices(a, b);
+ break;
+ case T_A_Indirection:
+ retval = _compareA_Indirection(a, b);
+ break;
+ case T_A_ArrayExpr:
+ retval = _compareA_ArrayExpr(a, b);
+ break;
+ case T_ResTarget:
+ retval = _compareResTarget(a, b);
+ break;
+ case T_TypeCast:
+ retval = _compareTypeCast(a, b);
+ break;
+ case T_SortBy:
+ retval = _compareSortBy(a, b);
+ break;
+ case T_WindowDef:
+ retval = _compareWindowDef(a, b);
+ break;
+ case T_RangeSubselect:
+ retval = _compareRangeSubselect(a, b);
+ break;
+ case T_RangeFunction:
+ retval = _compareRangeFunction(a, b);
+ break;
+ case T_TypeName:
+ retval = _compareTypeName(a, b);
+ break;
+ case T_IndexElem:
+ retval = _compareIndexElem(a, b);
+ break;
+ case T_ColumnDef:
+ retval = _compareColumnDef(a, b);
+ break;
+ case T_Constraint:
+ retval = _compareConstraint(a, b);
+ break;
+ case T_DefElem:
+ retval = _compareDefElem(a, b);
+ break;
+ case T_LockingClause:
+ retval = _compareLockingClause(a, b);
+ break;
+ case T_RangeTblEntry:
+ retval = _compareRangeTblEntry(a, b);
+ break;
+ case T_SortGroupClause:
+ retval = _compareSortGroupClause(a, b);
+ break;
+ case T_WindowClause:
+ retval = _compareWindowClause(a, b);
+ break;
+ case T_RowMarkClause:
+ retval = _compareRowMarkClause(a, b);
+ break;
+ case T_WithClause:
+ retval = _compareWithClause(a, b);
+ break;
+ case T_CommonTableExpr:
+ retval = _compareCommonTableExpr(a, b);
+ break;
+ case T_PrivGrantee:
+ retval = _comparePrivGrantee(a, b);
+ break;
+ case T_FuncWithArgs:
+ retval = _compareFuncWithArgs(a, b);
+ break;
+ case T_AccessPriv:
+ retval = _compareAccessPriv(a, b);
+ break;
+ case T_XmlSerialize:
+ retval = _compareXmlSerialize(a, b);
+ break;
+
+ default:
+ elog(ERROR, "unrecognized node type: %d",
+ (int) nodeTag(a));
+ retval = 0; /* keep compiler quiet */
+ break;
+ }
+
+ return retval;
+ }
diff -dcrpN postgresql.1/src/backend/nodes/Makefile postgresql.2/src/backend/nodes/Makefile
*** postgresql.1/src/backend/nodes/Makefile 2010-10-26 16:37:27.000000000 +0200
--- postgresql.2/src/backend/nodes/Makefile 2010-10-19 10:50:12.000000000 +0200
*************** top_builddir = ../../..
*** 13,19 ****
include $(top_builddir)/src/Makefile.global
OBJS = nodeFuncs.o nodes.o list.o tree.o bitmapset.o tidbitmap.o \
! copyfuncs.o equalfuncs.o makefuncs.o \
outfuncs.o readfuncs.o print.o read.o params.o value.o
include $(top_srcdir)/src/backend/common.mk
--- 13,19 ----
include $(top_builddir)/src/Makefile.global
OBJS = nodeFuncs.o nodes.o list.o tree.o bitmapset.o tidbitmap.o \
! comparefuncs.o copyfuncs.o equalfuncs.o makefuncs.o \
outfuncs.o readfuncs.o print.o read.o params.o value.o
include $(top_srcdir)/src/backend/common.mk
diff -dcrpN postgresql.1/src/backend/optimizer/geqo/geqo_pool.c postgresql.2/src/backend/optimizer/geqo/geqo_pool.c
*** postgresql.1/src/backend/optimizer/geqo/geqo_pool.c 2010-10-26 16:44:28.000000000 +0200
--- postgresql.2/src/backend/optimizer/geqo/geqo_pool.c 2010-10-19 11:02:57.000000000 +0200
***************
*** 32,38 ****
#include "optimizer/geqo_recombination.h"
! static int compare(const void *arg1, const void *arg2);
/*
* alloc_pool
--- 32,38 ----
#include "optimizer/geqo_recombination.h"
! static int geqo_pool_compare(const void *arg1, const void *arg2);
/*
* alloc_pool
*************** random_init_pool(PlannerInfo *root, Pool
*** 110,124 ****
void
sort_pool(PlannerInfo *root, Pool *pool)
{
! qsort(pool->data, pool->size, sizeof(Chromosome), compare);
}
/*
! * compare
* qsort comparison function for sort_pool
*/
static int
! compare(const void *arg1, const void *arg2)
{
const Chromosome *chromo1 = (const Chromosome *) arg1;
const Chromosome *chromo2 = (const Chromosome *) arg2;
--- 110,124 ----
void
sort_pool(PlannerInfo *root, Pool *pool)
{
! qsort(pool->data, pool->size, sizeof(Chromosome), geqo_pool_compare);
}
/*
! * geqo_pool_compare
* qsort comparison function for sort_pool
*/
static int
! geqo_pool_compare(const void *arg1, const void *arg2)
{
const Chromosome *chromo1 = (const Chromosome *) arg1;
const Chromosome *chromo2 = (const Chromosome *) arg2;
diff -dcrpN postgresql.1/src/backend/utils/adt/datum.c postgresql.2/src/backend/utils/adt/datum.c
*** postgresql.1/src/backend/utils/adt/datum.c 2010-10-26 16:44:48.000000000 +0200
--- postgresql.2/src/backend/utils/adt/datum.c 2010-10-19 10:54:09.000000000 +0200
*************** datumIsEqual(Datum value1, Datum value2,
*** 206,208 ****
--- 206,258 ----
}
return res;
}
+
+ /*-------------------------------------------------------------------------
+ * datumCompare
+ *
+ * Return -1/0/1 for less than/equal/greater than for two datums of the same type.
+ * This is for supporting RBTree search, not a logical comparison.
+ * The same NOTE applies as above in datumIsEqual.
+ *-------------------------------------------------------------------------
+ */
+ int
+ datumCompare(Datum value1, Datum value2, bool typByVal, int typLen)
+ {
+ if (typByVal)
+ {
+ /*
+ * just compare the two datums. NOTE: just comparing "len" bytes will
+ * not do the work, because we do not know how these bytes are aligned
+ * inside the "Datum". We assume instead that any given datatype is
+ * consistent about how it fills extraneous bits in the Datum.
+ */
+ if (value1 < value2)
+ return -1;
+ else if (value1 > value2)
+ return 1;
+ else
+ return 0;
+ }
+ else
+ {
+ Size size1,
+ size2;
+ char *s1,
+ *s2;
+
+ /*
+ * Compare the bytes pointed by the pointers stored in the datums.
+ * Do this only for datums of equal length to speed up the decision
+ * of inequality.
+ */
+ size1 = datumGetSize(value1, typByVal, typLen);
+ size2 = datumGetSize(value2, typByVal, typLen);
+ if (size1 < size2)
+ return -1;
+ else if (size1 > size2)
+ return 1;
+ s1 = (char *) DatumGetPointer(value1);
+ s2 = (char *) DatumGetPointer(value2);
+ return memcmp(s1, s2, size1);
+ }
+ }
diff -dcrpN postgresql.1/src/include/nodes/bitmapset.h postgresql.2/src/include/nodes/bitmapset.h
*** postgresql.1/src/include/nodes/bitmapset.h 2010-10-26 16:45:33.000000000 +0200
--- postgresql.2/src/include/nodes/bitmapset.h 2010-10-26 16:45:11.000000000 +0200
*************** typedef enum
*** 51,56 ****
--- 51,57 ----
extern Bitmapset *bms_copy(const Bitmapset *a);
extern bool bms_equal(const Bitmapset *a, const Bitmapset *b);
+ extern int bms_compare(const Bitmapset *a, const Bitmapset *b);
extern Bitmapset *bms_make_singleton(int x);
extern void bms_free(Bitmapset *a);
diff -dcrpN postgresql.1/src/include/nodes/nodes.h postgresql.2/src/include/nodes/nodes.h
*** postgresql.1/src/include/nodes/nodes.h 2010-10-26 16:45:56.000000000 +0200
--- postgresql.2/src/include/nodes/nodes.h 2010-10-19 10:51:24.000000000 +0200
*************** extern void *copyObject(void *obj);
*** 494,499 ****
--- 494,504 ----
*/
extern bool equal(void *a, void *b);
+ /*
+ * nodes/comparefuncs.c
+ */
+ extern int compare(void *a, void *b);
+
/*
* Typedefs for identifying qualifier selectivities and plan costs as such.
diff -dcrpN postgresql.1/src/include/utils/datum.h postgresql.2/src/include/utils/datum.h
*** postgresql.1/src/include/utils/datum.h 2010-10-26 16:48:02.000000000 +0200
--- postgresql.2/src/include/utils/datum.h 2010-10-19 10:53:03.000000000 +0200
*************** extern void datumFree(Datum value, bool
*** 46,49 ****
--- 46,58 ----
extern bool datumIsEqual(Datum value1, Datum value2,
bool typByVal, int typLen);
+ /*
+ * datumCompare
+ * return -1/0/+1 if for less/equal/greater than for two datums of the same type.
+ *
+ * XXX : See comments in the code for restrictions!
+ */
+ extern int datumCompare(Datum value1, Datum value2,
+ bool typByVal, int typLen);
+
#endif /* DATUM_H */
Binary files postgresql.1/src/test/regress/gmon.out and postgresql.2/src/test/regress/gmon.out differ
Binary files postgresql.1/src/timezone/gmon.out and postgresql.2/src/timezone/gmon.out differ