]> granicus.if.org Git - postgresql/blobdiff - src/backend/nodes/equalfuncs.c
Update copyrights to 2003.
[postgresql] / src / backend / nodes / equalfuncs.c
index f417dec4886ce546320034639c90892e8f6214b2..a6b4889f74e69870c279a6c8a8c1ca8a0cc28e60 100644 (file)
@@ -3,38 +3,37 @@
  * equalfuncs.c
  *       Equality functions to compare node trees.
  *
- * NOTE: a general convention when copying or comparing plan nodes is
- * that we ignore the executor state subnode.  We do not need to look
- * at it because no current uses of copyObject() or equal() need to
- * deal with already-executing plan trees.     By leaving the state subnodes
- * out, we avoid needing to write copy/compare routines for all the
- * different executor state node types.
+ * NOTE: we currently support comparing all node types found in parse
+ * trees.  We do not support comparing executor state trees; there
+ * is no need for that, and no point in maintaining all the code that
+ * would be needed.  We also do not support comparing Path trees, mainly
+ * because the circular linkages between RelOptInfo and Path nodes can't
+ * be handled easily in a simple depth-first traversal.
  *
- * Currently, in fact, equal() doesn't know how to compare Plan nodes
- * at all, let alone their executor-state subnodes.  This will probably
- * need to be fixed someday, but presently there is no need to compare
- * plan trees.
+ * Currently, in fact, equal() doesn't know how to compare Plan trees
+ * either.     This might need to be fixed someday.
  *
  *
- * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.168 2002/11/25 03:33:27 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.206 2003/08/04 02:39:59 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
 
 #include "postgres.h"
 
-#include "nodes/plannodes.h"
+#include "nodes/params.h"
+#include "nodes/parsenodes.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
+ * 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 an Equal routine are
  * named 'a' and 'b'.
  */
                        return false; \
        } while (0)
 
+/* Compare a field that is a pointer to a list of Oids */
+#define COMPARE_OIDLIST_FIELD(fldname) \
+       do { \
+               if (!equalo(a->fldname, b->fldname)) \
+                       return false; \
+       } while (0)
+
+/* Compare a field that is a pointer to a Bitmapset */
+#define COMPARE_BITMAPSET_FIELD(fldname) \
+       do { \
+               if (!bms_equal(a->fldname, b->fldname)) \
+                       return false; \
+       } while (0)
+
 /* Compare a field that is a pointer to a C string, or perhaps NULL */
 #define COMPARE_STRING_FIELD(fldname) \
        do { \
@@ -91,25 +104,13 @@ _equalResdom(Resdom *a, Resdom *b)
        COMPARE_SCALAR_FIELD(restypmod);
        COMPARE_STRING_FIELD(resname);
        COMPARE_SCALAR_FIELD(ressortgroupref);
-       COMPARE_SCALAR_FIELD(reskey);
-       COMPARE_SCALAR_FIELD(reskeyop);
+       COMPARE_SCALAR_FIELD(resorigtbl);
+       COMPARE_SCALAR_FIELD(resorigcol);
        COMPARE_SCALAR_FIELD(resjunk);
 
        return true;
 }
 
-static bool
-_equalFjoin(Fjoin *a, Fjoin *b)
-{
-       COMPARE_SCALAR_FIELD(fj_initialized);
-       COMPARE_SCALAR_FIELD(fj_nNodes);
-       COMPARE_NODE_FIELD(fj_innerNode);
-       COMPARE_POINTER_FIELD(fj_results, a->fj_nNodes * sizeof(Datum));
-       COMPARE_POINTER_FIELD(fj_alwaysDone, a->fj_nNodes * sizeof(bool));
-
-       return true;
-}
-
 static bool
 _equalAlias(Alias *a, Alias *b)
 {
@@ -132,20 +133,12 @@ _equalRangeVar(RangeVar *a, RangeVar *b)
        return true;
 }
 
-static bool
-_equalExpr(Expr *a, Expr *b)
-{
-       /*
-        * We do not examine typeOid, since the optimizer often doesn't bother
-        * to set it in created nodes, and it is logically a derivative of the
-        * oper field anyway.
-        */
-       COMPARE_SCALAR_FIELD(opType);
-       COMPARE_NODE_FIELD(oper);
-       COMPARE_NODE_FIELD(args);
-
-       return true;
-}
+/*
+ * We don't need an _equalExpr 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 bool
 _equalVar(Var *a, Var *b)
@@ -161,28 +154,6 @@ _equalVar(Var *a, Var *b)
        return true;
 }
 
-static bool
-_equalOper(Oper *a, Oper *b)
-{
-       COMPARE_SCALAR_FIELD(opno);
-       COMPARE_SCALAR_FIELD(opresulttype);
-       COMPARE_SCALAR_FIELD(opretset);
-
-       /*
-        * We do not examine opid or op_fcache, since these are logically
-        * derived from opno, and they may not be set yet depending on how far
-        * along the node is in the parse/plan pipeline.
-        *
-        * (Besides, op_fcache is executor state, which we don't check --- see
-        * notes at head of file.)
-        *
-        * It's probably not really necessary to check opresulttype or opretset,
-        * either...
-        */
-
-       return true;
-}
-
 static bool
 _equalConst(Const *a, Const *b)
 {
@@ -190,7 +161,6 @@ _equalConst(Const *a, Const *b)
        COMPARE_SCALAR_FIELD(constlen);
        COMPARE_SCALAR_FIELD(constisnull);
        COMPARE_SCALAR_FIELD(constbyval);
-       /* XXX What about constisset and constiscast? */
 
        /*
         * We treat all NULL constants of the same type as equal. Someday this
@@ -212,21 +182,14 @@ _equalParam(Param *a, Param *b)
        switch (a->paramkind)
        {
                case PARAM_NAMED:
-               case PARAM_NEW:
-               case PARAM_OLD:
                        COMPARE_STRING_FIELD(paramname);
                        break;
                case PARAM_NUM:
                case PARAM_EXEC:
                        COMPARE_SCALAR_FIELD(paramid);
                        break;
-               case PARAM_INVALID:
-                       /*
-                        * XXX: Hmmm... What are we supposed to return in this case ??
-                        */
-                       break;
                default:
-                       elog(ERROR, "_equalParam: Invalid paramkind value: %d",
+                       elog(ERROR, "unrecognized paramkind: %d",
                                 a->paramkind);
        }
 
@@ -234,11 +197,39 @@ _equalParam(Param *a, Param *b)
 }
 
 static bool
-_equalFunc(Func *a, Func *b)
+_equalAggref(Aggref *a, Aggref *b)
+{
+       COMPARE_SCALAR_FIELD(aggfnoid);
+       COMPARE_SCALAR_FIELD(aggtype);
+       COMPARE_NODE_FIELD(target);
+       COMPARE_SCALAR_FIELD(agglevelsup);
+       COMPARE_SCALAR_FIELD(aggstar);
+       COMPARE_SCALAR_FIELD(aggdistinct);
+
+       return true;
+}
+
+static bool
+_equalArrayRef(ArrayRef *a, ArrayRef *b)
+{
+       COMPARE_SCALAR_FIELD(refrestype);
+       COMPARE_SCALAR_FIELD(refarraytype);
+       COMPARE_SCALAR_FIELD(refelemtype);
+       COMPARE_NODE_FIELD(refupperindexpr);
+       COMPARE_NODE_FIELD(reflowerindexpr);
+       COMPARE_NODE_FIELD(refexpr);
+       COMPARE_NODE_FIELD(refassgnexpr);
+
+       return true;
+}
+
+static bool
+_equalFuncExpr(FuncExpr * a, FuncExpr * b)
 {
        COMPARE_SCALAR_FIELD(funcid);
        COMPARE_SCALAR_FIELD(funcresulttype);
        COMPARE_SCALAR_FIELD(funcretset);
+
        /*
         * Special-case COERCE_DONTCARE, so that pathkeys can build coercion
         * nodes that are equal() to both explicit and implicit coercions.
@@ -248,20 +239,84 @@ _equalFunc(Func *a, Func *b)
                b->funcformat != COERCE_DONTCARE)
                return false;
 
-       /* Note we do not look at func_fcache; see notes for _equalOper */
+       COMPARE_NODE_FIELD(args);
 
        return true;
 }
 
 static bool
-_equalAggref(Aggref *a, Aggref *b)
+_equalOpExpr(OpExpr * a, OpExpr * b)
 {
-       COMPARE_SCALAR_FIELD(aggfnoid);
-       COMPARE_SCALAR_FIELD(aggtype);
-       COMPARE_NODE_FIELD(target);
-       COMPARE_SCALAR_FIELD(aggstar);
-       COMPARE_SCALAR_FIELD(aggdistinct);
-       /* ignore aggno, which is only a private field for the executor */
+       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 != b->opfuncid &&
+               a->opfuncid != 0 &&
+               b->opfuncid != 0)
+               return false;
+
+       COMPARE_SCALAR_FIELD(opresulttype);
+       COMPARE_SCALAR_FIELD(opretset);
+       COMPARE_NODE_FIELD(args);
+
+       return true;
+}
+
+static bool
+_equalDistinctExpr(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 != b->opfuncid &&
+               a->opfuncid != 0 &&
+               b->opfuncid != 0)
+               return false;
+
+       COMPARE_SCALAR_FIELD(opresulttype);
+       COMPARE_SCALAR_FIELD(opretset);
+       COMPARE_NODE_FIELD(args);
+
+       return true;
+}
+
+static bool
+_equalScalarArrayOpExpr(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 != b->opfuncid &&
+               a->opfuncid != 0 &&
+               b->opfuncid != 0)
+               return false;
+
+       COMPARE_SCALAR_FIELD(useOr);
+       COMPARE_NODE_FIELD(args);
+
+       return true;
+}
+
+static bool
+_equalBoolExpr(BoolExpr * a, BoolExpr * b)
+{
+       COMPARE_SCALAR_FIELD(boolop);
+       COMPARE_NODE_FIELD(args);
 
        return true;
 }
@@ -270,14 +325,34 @@ static bool
 _equalSubLink(SubLink *a, SubLink *b)
 {
        COMPARE_SCALAR_FIELD(subLinkType);
-       COMPARE_SCALAR_FIELD(useor);
+       COMPARE_SCALAR_FIELD(useOr);
        COMPARE_NODE_FIELD(lefthand);
-       COMPARE_NODE_FIELD(oper);
+       COMPARE_NODE_FIELD(operName);
+       COMPARE_OIDLIST_FIELD(operOids);
        COMPARE_NODE_FIELD(subselect);
 
        return true;
 }
 
+static bool
+_equalSubPlan(SubPlan *a, SubPlan *b)
+{
+       COMPARE_SCALAR_FIELD(subLinkType);
+       COMPARE_SCALAR_FIELD(useOr);
+       COMPARE_NODE_FIELD(exprs);
+       COMPARE_INTLIST_FIELD(paramIds);
+       /* should compare plans, but have to settle for comparing plan IDs */
+       COMPARE_SCALAR_FIELD(plan_id);
+       COMPARE_NODE_FIELD(rtable);
+       COMPARE_SCALAR_FIELD(useHashTable);
+       COMPARE_SCALAR_FIELD(unknownEqFalse);
+       COMPARE_INTLIST_FIELD(setParam);
+       COMPARE_INTLIST_FIELD(parParam);
+       COMPARE_NODE_FIELD(args);
+
+       return true;
+}
+
 static bool
 _equalFieldSelect(FieldSelect *a, FieldSelect *b)
 {
@@ -295,6 +370,7 @@ _equalRelabelType(RelabelType *a, RelabelType *b)
        COMPARE_NODE_FIELD(arg);
        COMPARE_SCALAR_FIELD(resulttype);
        COMPARE_SCALAR_FIELD(resulttypmod);
+
        /*
         * Special-case COERCE_DONTCARE, so that pathkeys can build coercion
         * nodes that are equal() to both explicit and implicit coercions.
@@ -308,206 +384,169 @@ _equalRelabelType(RelabelType *a, RelabelType *b)
 }
 
 static bool
-_equalRangeTblRef(RangeTblRef *a, RangeTblRef *b)
+_equalCaseExpr(CaseExpr *a, CaseExpr *b)
 {
-       COMPARE_SCALAR_FIELD(rtindex);
+       COMPARE_SCALAR_FIELD(casetype);
+       COMPARE_NODE_FIELD(arg);
+       COMPARE_NODE_FIELD(args);
+       COMPARE_NODE_FIELD(defresult);
 
        return true;
 }
 
 static bool
-_equalJoinExpr(JoinExpr *a, JoinExpr *b)
+_equalCaseWhen(CaseWhen *a, CaseWhen *b)
 {
-       COMPARE_SCALAR_FIELD(jointype);
-       COMPARE_SCALAR_FIELD(isNatural);
-       COMPARE_NODE_FIELD(larg);
-       COMPARE_NODE_FIELD(rarg);
-       COMPARE_NODE_FIELD(using);
-       COMPARE_NODE_FIELD(quals);
-       COMPARE_NODE_FIELD(alias);
-       COMPARE_SCALAR_FIELD(rtindex);
+       COMPARE_NODE_FIELD(expr);
+       COMPARE_NODE_FIELD(result);
 
        return true;
 }
 
 static bool
-_equalFromExpr(FromExpr *a, FromExpr *b)
+_equalArrayExpr(ArrayExpr * a, ArrayExpr * b)
 {
-       COMPARE_NODE_FIELD(fromlist);
-       COMPARE_NODE_FIELD(quals);
+       COMPARE_SCALAR_FIELD(array_typeid);
+       COMPARE_SCALAR_FIELD(element_typeid);
+       COMPARE_NODE_FIELD(elements);
+       COMPARE_SCALAR_FIELD(ndims);
 
        return true;
 }
 
 static bool
-_equalArrayRef(ArrayRef *a, ArrayRef *b)
+_equalCoalesceExpr(CoalesceExpr * a, CoalesceExpr * b)
 {
-       COMPARE_SCALAR_FIELD(refrestype);
-       COMPARE_SCALAR_FIELD(refattrlength);
-       COMPARE_SCALAR_FIELD(refelemlength);
-       COMPARE_SCALAR_FIELD(refelembyval);
-       COMPARE_SCALAR_FIELD(refelemalign);
-       COMPARE_NODE_FIELD(refupperindexpr);
-       COMPARE_NODE_FIELD(reflowerindexpr);
-       COMPARE_NODE_FIELD(refexpr);
-       COMPARE_NODE_FIELD(refassgnexpr);
+       COMPARE_SCALAR_FIELD(coalescetype);
+       COMPARE_NODE_FIELD(args);
 
        return true;
 }
 
-
-/*
- * Stuff from plannodes.h
- */
-
 static bool
-_equalSubPlan(SubPlan *a, SubPlan *b)
+_equalNullIfExpr(NullIfExpr * a, NullIfExpr * b)
 {
-       /* should compare plans, but have to settle for comparing plan IDs */
-       COMPARE_SCALAR_FIELD(plan_id);
-
-       COMPARE_NODE_FIELD(rtable);
-       COMPARE_NODE_FIELD(sublink);
-
-       return true;
-}
-
-
-/*
- * Stuff from relation.h
- */
+       COMPARE_SCALAR_FIELD(opno);
 
-static bool
-_equalRelOptInfo(RelOptInfo *a, RelOptInfo *b)
-{
        /*
-        * We treat RelOptInfos as equal if they refer to the same base rels
-        * joined in the same order.  Is this appropriate/sufficient?
+        * 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.
         */
-       COMPARE_INTLIST_FIELD(relids);
+       if (a->opfuncid != b->opfuncid &&
+               a->opfuncid != 0 &&
+               b->opfuncid != 0)
+               return false;
+
+       COMPARE_SCALAR_FIELD(opresulttype);
+       COMPARE_SCALAR_FIELD(opretset);
+       COMPARE_NODE_FIELD(args);
 
        return true;
 }
 
 static bool
-_equalIndexOptInfo(IndexOptInfo *a, IndexOptInfo *b)
+_equalNullTest(NullTest *a, NullTest *b)
 {
-       /*
-        * We treat IndexOptInfos as equal if they refer to the same index. Is
-        * this sufficient?
-        */
-       COMPARE_SCALAR_FIELD(indexoid);
+       COMPARE_NODE_FIELD(arg);
+       COMPARE_SCALAR_FIELD(nulltesttype);
 
        return true;
 }
 
 static bool
-_equalPath(Path *a, Path *b)
+_equalBooleanTest(BooleanTest *a, BooleanTest *b)
 {
-       /* This is safe only because _equalRelOptInfo is incomplete... */
-       COMPARE_NODE_FIELD(parent);
-       /*
-        * do not check path costs, since they may not be set yet, and being
-        * float values there are roundoff error issues anyway...
-        */
-       COMPARE_SCALAR_FIELD(pathtype);
-       COMPARE_NODE_FIELD(pathkeys);
+       COMPARE_NODE_FIELD(arg);
+       COMPARE_SCALAR_FIELD(booltesttype);
 
        return true;
 }
 
 static bool
-_equalIndexPath(IndexPath *a, IndexPath *b)
+_equalCoerceToDomain(CoerceToDomain * a, CoerceToDomain * b)
 {
-       if (!_equalPath((Path *) a, (Path *) b))
-               return false;
-       COMPARE_NODE_FIELD(indexinfo);
-       COMPARE_NODE_FIELD(indexqual);
-       COMPARE_SCALAR_FIELD(indexscandir);
+       COMPARE_NODE_FIELD(arg);
+       COMPARE_SCALAR_FIELD(resulttype);
+       COMPARE_SCALAR_FIELD(resulttypmod);
 
        /*
-        * Skip 'rows' because of possibility of floating-point roundoff
-        * error. It should be derivable from the other fields anyway.
+        * Special-case COERCE_DONTCARE, so that pathkeys can build coercion
+        * nodes that are equal() to both explicit and implicit coercions.
         */
-       return true;
-}
-
-static bool
-_equalTidPath(TidPath *a, TidPath *b)
-{
-       if (!_equalPath((Path *) a, (Path *) b))
+       if (a->coercionformat != b->coercionformat &&
+               a->coercionformat != COERCE_DONTCARE &&
+               b->coercionformat != COERCE_DONTCARE)
                return false;
-       COMPARE_NODE_FIELD(tideval);
-       COMPARE_INTLIST_FIELD(unjoined_relids);
 
        return true;
 }
 
 static bool
-_equalAppendPath(AppendPath *a, AppendPath *b)
+_equalCoerceToDomainValue(CoerceToDomainValue * a, CoerceToDomainValue * b)
 {
-       if (!_equalPath((Path *) a, (Path *) b))
-               return false;
-       COMPARE_NODE_FIELD(subpaths);
+       COMPARE_SCALAR_FIELD(typeId);
+       COMPARE_SCALAR_FIELD(typeMod);
 
        return true;
 }
 
 static bool
-_equalResultPath(ResultPath *a, ResultPath *b)
+_equalSetToDefault(SetToDefault * a, SetToDefault * b)
 {
-       if (!_equalPath((Path *) a, (Path *) b))
-               return false;
-       COMPARE_NODE_FIELD(subpath);
-       COMPARE_NODE_FIELD(constantqual);
+       COMPARE_SCALAR_FIELD(typeId);
+       COMPARE_SCALAR_FIELD(typeMod);
 
        return true;
 }
 
 static bool
-_equalJoinPath(JoinPath *a, JoinPath *b)
+_equalTargetEntry(TargetEntry *a, TargetEntry *b)
 {
-       if (!_equalPath((Path *) a, (Path *) b))
-               return false;
-       COMPARE_SCALAR_FIELD(jointype);
-       COMPARE_NODE_FIELD(outerjoinpath);
-       COMPARE_NODE_FIELD(innerjoinpath);
-       COMPARE_NODE_FIELD(joinrestrictinfo);
+       COMPARE_NODE_FIELD(resdom);
+       COMPARE_NODE_FIELD(expr);
 
        return true;
 }
 
 static bool
-_equalNestPath(NestPath *a, NestPath *b)
+_equalRangeTblRef(RangeTblRef *a, RangeTblRef *b)
 {
-       if (!_equalJoinPath((JoinPath *) a, (JoinPath *) b))
-               return false;
+       COMPARE_SCALAR_FIELD(rtindex);
 
        return true;
 }
 
 static bool
-_equalMergePath(MergePath *a, MergePath *b)
+_equalJoinExpr(JoinExpr *a, JoinExpr *b)
 {
-       if (!_equalJoinPath((JoinPath *) a, (JoinPath *) b))
-               return false;
-       COMPARE_NODE_FIELD(path_mergeclauses);
-       COMPARE_NODE_FIELD(outersortkeys);
-       COMPARE_NODE_FIELD(innersortkeys);
+       COMPARE_SCALAR_FIELD(jointype);
+       COMPARE_SCALAR_FIELD(isNatural);
+       COMPARE_NODE_FIELD(larg);
+       COMPARE_NODE_FIELD(rarg);
+       COMPARE_NODE_FIELD(using);
+       COMPARE_NODE_FIELD(quals);
+       COMPARE_NODE_FIELD(alias);
+       COMPARE_SCALAR_FIELD(rtindex);
 
        return true;
 }
 
 static bool
-_equalHashPath(HashPath *a, HashPath *b)
+_equalFromExpr(FromExpr *a, FromExpr *b)
 {
-       if (!_equalJoinPath((JoinPath *) a, (JoinPath *) b))
-               return false;
-       COMPARE_NODE_FIELD(path_hashclauses);
+       COMPARE_NODE_FIELD(fromlist);
+       COMPARE_NODE_FIELD(quals);
 
        return true;
 }
 
+
+/*
+ * Stuff from relation.h
+ */
+
 static bool
 _equalPathKeyItem(PathKeyItem *a, PathKeyItem *b)
 {
@@ -522,11 +561,13 @@ _equalRestrictInfo(RestrictInfo *a, RestrictInfo *b)
 {
        COMPARE_NODE_FIELD(clause);
        COMPARE_SCALAR_FIELD(ispusheddown);
+
        /*
-        * We ignore subclauseindices, eval_cost, this_selec, left/right_pathkey,
-        * and left/right_bucketsize, since they may not be set yet, and should be
-        * derivable from the clause anyway.  Probably it's not really necessary
-        * to compare any of these remaining fields ...
+        * We ignore subclauseindices, eval_cost, this_selec,
+        * left/right_relids, left/right_pathkey, and left/right_bucketsize,
+        * since they may not be set yet, and should be derivable from the
+        * clause anyway.  Probably it's not really necessary to compare any
+        * of these remaining fields ...
         */
        COMPARE_SCALAR_FIELD(mergejoinoperator);
        COMPARE_SCALAR_FIELD(left_sortop);
@@ -539,18 +580,18 @@ _equalRestrictInfo(RestrictInfo *a, RestrictInfo *b)
 static bool
 _equalJoinInfo(JoinInfo *a, JoinInfo *b)
 {
-       COMPARE_INTLIST_FIELD(unjoined_relids);
+       COMPARE_BITMAPSET_FIELD(unjoined_relids);
        COMPARE_NODE_FIELD(jinfo_restrictinfo);
 
        return true;
 }
 
 static bool
-_equalInnerIndexscanInfo(InnerIndexscanInfo *a, InnerIndexscanInfo *b)
+_equalInClauseInfo(InClauseInfo * a, InClauseInfo * b)
 {
-       COMPARE_INTLIST_FIELD(other_relids);
-       COMPARE_SCALAR_FIELD(isouterjoin);
-       COMPARE_NODE_FIELD(best_innerpath);
+       COMPARE_BITMAPSET_FIELD(lefthand);
+       COMPARE_BITMAPSET_FIELD(righthand);
+       COMPARE_NODE_FIELD(sub_targetlist);
 
        return true;
 }
@@ -565,11 +606,10 @@ _equalQuery(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(into);
-       COMPARE_SCALAR_FIELD(isPortal);
-       COMPARE_SCALAR_FIELD(isBinary);
        COMPARE_SCALAR_FIELD(hasAggs);
        COMPARE_SCALAR_FIELD(hasSubLinks);
        COMPARE_NODE_FIELD(rtable);
@@ -584,12 +624,14 @@ _equalQuery(Query *a, Query *b)
        COMPARE_NODE_FIELD(limitCount);
        COMPARE_NODE_FIELD(setOperations);
        COMPARE_INTLIST_FIELD(resultRelations);
+       COMPARE_NODE_FIELD(in_info_list);
+       COMPARE_SCALAR_FIELD(hasJoinRTEs);
 
        /*
-        * We do not check the internal-to-the-planner fields: base_rel_list,
-        * other_rel_list, join_rel_list, equi_key_list, query_pathkeys,
-        * hasJoinRTEs.  They might not be set yet, and in any case they should
-        * be derivable from the other fields.
+        * We do not check the other planner internal fields: base_rel_list,
+        * other_rel_list, join_rel_list, equi_key_list, query_pathkeys. They
+        * might not be set yet, and in any case they should be derivable from
+        * the other fields.
         */
        return true;
 }
@@ -637,8 +679,6 @@ _equalSelectStmt(SelectStmt *a, SelectStmt *b)
        COMPARE_NODE_FIELD(groupClause);
        COMPARE_NODE_FIELD(havingClause);
        COMPARE_NODE_FIELD(sortClause);
-       COMPARE_STRING_FIELD(portalname);
-       COMPARE_SCALAR_FIELD(binary);
        COMPARE_NODE_FIELD(limitOffset);
        COMPARE_NODE_FIELD(limitCount);
        COMPARE_NODE_FIELD(forUpdate);
@@ -657,7 +697,7 @@ _equalSetOperationStmt(SetOperationStmt *a, SetOperationStmt *b)
        COMPARE_SCALAR_FIELD(all);
        COMPARE_NODE_FIELD(larg);
        COMPARE_NODE_FIELD(rarg);
-       COMPARE_INTLIST_FIELD(colTypes);
+       COMPARE_OIDLIST_FIELD(colTypes);
 
        return true;
 }
@@ -674,6 +714,18 @@ _equalAlterTableStmt(AlterTableStmt *a, AlterTableStmt *b)
        return true;
 }
 
+static bool
+_equalAlterDomainStmt(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 true;
+}
+
 static bool
 _equalGrantStmt(GrantStmt *a, GrantStmt *b)
 {
@@ -682,6 +734,8 @@ _equalGrantStmt(GrantStmt *a, GrantStmt *b)
        COMPARE_NODE_FIELD(objects);
        COMPARE_INTLIST_FIELD(privileges);
        COMPARE_NODE_FIELD(grantees);
+       COMPARE_SCALAR_FIELD(grant_option);
+       COMPARE_SCALAR_FIELD(behavior);
 
        return true;
 }
@@ -705,8 +759,12 @@ _equalFuncWithArgs(FuncWithArgs *a, FuncWithArgs *b)
 }
 
 static bool
-_equalInsertDefault(InsertDefault *a, InsertDefault *b)
+_equalDeclareCursorStmt(DeclareCursorStmt * a, DeclareCursorStmt * b)
 {
+       COMPARE_STRING_FIELD(portalname);
+       COMPARE_SCALAR_FIELD(options);
+       COMPARE_NODE_FIELD(query);
+
        return true;
 }
 
@@ -752,10 +810,19 @@ _equalCreateStmt(CreateStmt *a, CreateStmt *b)
        return true;
 }
 
+static bool
+_equalInhRelation(InhRelation * a, InhRelation * b)
+{
+       COMPARE_NODE_FIELD(relation);
+       COMPARE_SCALAR_FIELD(including_defaults);
+
+       return true;
+}
+
 static bool
 _equalDefineStmt(DefineStmt *a, DefineStmt *b)
 {
-       COMPARE_SCALAR_FIELD(defType);
+       COMPARE_SCALAR_FIELD(kind);
        COMPARE_NODE_FIELD(defnames);
        COMPARE_NODE_FIELD(definition);
 
@@ -875,7 +942,9 @@ static bool
 _equalRenameStmt(RenameStmt *a, RenameStmt *b)
 {
        COMPARE_NODE_FIELD(relation);
-       COMPARE_STRING_FIELD(oldname);
+       COMPARE_NODE_FIELD(object);
+       COMPARE_NODE_FIELD(objarg);
+       COMPARE_STRING_FIELD(subname);
        COMPARE_STRING_FIELD(newname);
        COMPARE_SCALAR_FIELD(renameType);
 
@@ -923,7 +992,7 @@ _equalUnlistenStmt(UnlistenStmt *a, UnlistenStmt *b)
 static bool
 _equalTransactionStmt(TransactionStmt *a, TransactionStmt *b)
 {
-       COMPARE_SCALAR_FIELD(command);
+       COMPARE_SCALAR_FIELD(kind);
        COMPARE_NODE_FIELD(options);
 
        return true;
@@ -1052,6 +1121,15 @@ _equalCreateSeqStmt(CreateSeqStmt *a, CreateSeqStmt *b)
        return true;
 }
 
+static bool
+_equalAlterSeqStmt(AlterSeqStmt * a, AlterSeqStmt * b)
+{
+       COMPARE_NODE_FIELD(sequence);
+       COMPARE_NODE_FIELD(options);
+
+       return true;
+}
+
 static bool
 _equalVariableSetStmt(VariableSetStmt *a, VariableSetStmt *b)
 {
@@ -1087,7 +1165,7 @@ _equalCreateTrigStmt(CreateTrigStmt *a, CreateTrigStmt *b)
        COMPARE_NODE_FIELD(args);
        COMPARE_SCALAR_FIELD(before);
        COMPARE_SCALAR_FIELD(row);
-       if (strcmp(a->actions, b->actions) != 0) /* in-line string field */
+       if (strcmp(a->actions, b->actions) != 0)        /* in-line string field */
                return false;
        COMPARE_SCALAR_FIELD(isconstraint);
        COMPARE_SCALAR_FIELD(deferrable);
@@ -1212,7 +1290,7 @@ _equalDropGroupStmt(DropGroupStmt *a, DropGroupStmt *b)
 static bool
 _equalReindexStmt(ReindexStmt *a, ReindexStmt *b)
 {
-       COMPARE_SCALAR_FIELD(reindexType);
+       COMPARE_SCALAR_FIELD(kind);
        COMPARE_NODE_FIELD(relation);
        COMPARE_STRING_FIELD(name);
        COMPARE_SCALAR_FIELD(force);
@@ -1269,7 +1347,7 @@ _equalPrepareStmt(PrepareStmt *a, PrepareStmt *b)
 {
        COMPARE_STRING_FIELD(name);
        COMPARE_NODE_FIELD(argtypes);
-       COMPARE_INTLIST_FIELD(argtype_oids);
+       COMPARE_OIDLIST_FIELD(argtype_oids);
        COMPARE_NODE_FIELD(query);
 
        return true;
@@ -1301,7 +1379,7 @@ _equalDeallocateStmt(DeallocateStmt *a, DeallocateStmt *b)
 static bool
 _equalAExpr(A_Expr *a, A_Expr *b)
 {
-       COMPARE_SCALAR_FIELD(oper);
+       COMPARE_SCALAR_FIELD(kind);
        COMPARE_NODE_FIELD(name);
        COMPARE_NODE_FIELD(lexpr);
        COMPARE_NODE_FIELD(rexpr);
@@ -1331,7 +1409,7 @@ _equalParamRef(ParamRef *a, ParamRef *b)
 static bool
 _equalAConst(A_Const *a, A_Const *b)
 {
-       if (!equal(&a->val, &b->val)) /* hack for in-line Value field */
+       if (!equal(&a->val, &b->val))           /* hack for in-line Value field */
                return false;
        COMPARE_NODE_FIELD(typename);
 
@@ -1433,8 +1511,7 @@ static bool
 _equalIndexElem(IndexElem *a, IndexElem *b)
 {
        COMPARE_STRING_FIELD(name);
-       COMPARE_NODE_FIELD(funcname);
-       COMPARE_NODE_FIELD(args);
+       COMPARE_NODE_FIELD(expr);
        COMPARE_NODE_FIELD(opclass);
 
        return true;
@@ -1477,16 +1554,6 @@ _equalDefElem(DefElem *a, DefElem *b)
        return true;
 }
 
-static bool
-_equalTargetEntry(TargetEntry *a, TargetEntry *b)
-{
-       COMPARE_NODE_FIELD(resdom);
-       COMPARE_NODE_FIELD(fjoin);
-       COMPARE_NODE_FIELD(expr);
-
-       return true;
-}
-
 static bool
 _equalRangeTblEntry(RangeTblEntry *a, RangeTblEntry *b)
 {
@@ -1534,71 +1601,6 @@ _equalFkConstraint(FkConstraint *a, FkConstraint *b)
        return true;
 }
 
-static bool
-_equalCaseExpr(CaseExpr *a, CaseExpr *b)
-{
-       COMPARE_SCALAR_FIELD(casetype);
-       COMPARE_NODE_FIELD(arg);
-       COMPARE_NODE_FIELD(args);
-       COMPARE_NODE_FIELD(defresult);
-
-       return true;
-}
-
-static bool
-_equalCaseWhen(CaseWhen *a, CaseWhen *b)
-{
-       COMPARE_NODE_FIELD(expr);
-       COMPARE_NODE_FIELD(result);
-
-       return true;
-}
-
-static bool
-_equalNullTest(NullTest *a, NullTest *b)
-{
-       COMPARE_NODE_FIELD(arg);
-       COMPARE_SCALAR_FIELD(nulltesttype);
-
-       return true;
-}
-
-static bool
-_equalBooleanTest(BooleanTest *a, BooleanTest *b)
-{
-       COMPARE_NODE_FIELD(arg);
-       COMPARE_SCALAR_FIELD(booltesttype);
-
-       return true;
-}
-
-static bool
-_equalConstraintTest(ConstraintTest *a, ConstraintTest *b)
-{
-       COMPARE_NODE_FIELD(arg);
-       COMPARE_SCALAR_FIELD(testtype);
-       COMPARE_STRING_FIELD(name);
-       COMPARE_STRING_FIELD(domname);
-       COMPARE_NODE_FIELD(check_expr);
-
-       return true;
-}
-
-static bool
-_equalDomainConstraintValue(DomainConstraintValue *a, DomainConstraintValue *b)
-{
-       return true;
-}
-
-static bool
-_equalConstraintTestValue(ConstraintTestValue *a, ConstraintTestValue *b)
-{
-       COMPARE_SCALAR_FIELD(typeId);
-       COMPARE_SCALAR_FIELD(typeMod);
-
-       return true;
-}
-
 
 /*
  * Stuff from pg_list.h
@@ -1623,7 +1625,7 @@ _equalValue(Value *a, Value *b)
                        /* nothing to do */
                        break;
                default:
-                       elog(ERROR, "_equalValue: unknown node type %d", a->type);
+                       elog(ERROR, "unrecognized node type: %d", (int) a->type);
                        break;
        }
 
@@ -1637,7 +1639,7 @@ _equalValue(Value *a, Value *b)
 bool
 equal(void *a, void *b)
 {
-       bool            retval = false;
+       bool            retval;
 
        if (a == b)
                return true;
@@ -1656,25 +1658,21 @@ equal(void *a, void *b)
 
        switch (nodeTag(a))
        {
-               case T_SubPlan:
-                       retval = _equalSubPlan(a, b);
-                       break;
-
+                       /*
+                        * PRIMITIVE NODES
+                        */
                case T_Resdom:
                        retval = _equalResdom(a, b);
                        break;
-               case T_Fjoin:
-                       retval = _equalFjoin(a, b);
+               case T_Alias:
+                       retval = _equalAlias(a, b);
                        break;
-               case T_Expr:
-                       retval = _equalExpr(a, b);
+               case T_RangeVar:
+                       retval = _equalRangeVar(a, b);
                        break;
                case T_Var:
                        retval = _equalVar(a, b);
                        break;
-               case T_Oper:
-                       retval = _equalOper(a, b);
-                       break;
                case T_Const:
                        retval = _equalConst(a, b);
                        break;
@@ -1684,21 +1682,69 @@ equal(void *a, void *b)
                case T_Aggref:
                        retval = _equalAggref(a, b);
                        break;
+               case T_ArrayRef:
+                       retval = _equalArrayRef(a, b);
+                       break;
+               case T_FuncExpr:
+                       retval = _equalFuncExpr(a, b);
+                       break;
+               case T_OpExpr:
+                       retval = _equalOpExpr(a, b);
+                       break;
+               case T_DistinctExpr:
+                       retval = _equalDistinctExpr(a, b);
+                       break;
+               case T_ScalarArrayOpExpr:
+                       retval = _equalScalarArrayOpExpr(a, b);
+                       break;
+               case T_BoolExpr:
+                       retval = _equalBoolExpr(a, b);
+                       break;
                case T_SubLink:
                        retval = _equalSubLink(a, b);
                        break;
-               case T_Func:
-                       retval = _equalFunc(a, b);
+               case T_SubPlan:
+                       retval = _equalSubPlan(a, b);
                        break;
                case T_FieldSelect:
                        retval = _equalFieldSelect(a, b);
                        break;
-               case T_ArrayRef:
-                       retval = _equalArrayRef(a, b);
-                       break;
                case T_RelabelType:
                        retval = _equalRelabelType(a, b);
                        break;
+               case T_CaseExpr:
+                       retval = _equalCaseExpr(a, b);
+                       break;
+               case T_CaseWhen:
+                       retval = _equalCaseWhen(a, b);
+                       break;
+               case T_ArrayExpr:
+                       retval = _equalArrayExpr(a, b);
+                       break;
+               case T_CoalesceExpr:
+                       retval = _equalCoalesceExpr(a, b);
+                       break;
+               case T_NullIfExpr:
+                       retval = _equalNullIfExpr(a, b);
+                       break;
+               case T_NullTest:
+                       retval = _equalNullTest(a, b);
+                       break;
+               case T_BooleanTest:
+                       retval = _equalBooleanTest(a, b);
+                       break;
+               case T_CoerceToDomain:
+                       retval = _equalCoerceToDomain(a, b);
+                       break;
+               case T_CoerceToDomainValue:
+                       retval = _equalCoerceToDomainValue(a, b);
+                       break;
+               case T_SetToDefault:
+                       retval = _equalSetToDefault(a, b);
+                       break;
+               case T_TargetEntry:
+                       retval = _equalTargetEntry(a, b);
+                       break;
                case T_RangeTblRef:
                        retval = _equalRangeTblRef(a, b);
                        break;
@@ -1709,24 +1755,9 @@ equal(void *a, void *b)
                        retval = _equalJoinExpr(a, b);
                        break;
 
-               case T_RelOptInfo:
-                       retval = _equalRelOptInfo(a, b);
-                       break;
-               case T_Path:
-                       retval = _equalPath(a, b);
-                       break;
-               case T_IndexPath:
-                       retval = _equalIndexPath(a, b);
-                       break;
-               case T_NestPath:
-                       retval = _equalNestPath(a, b);
-                       break;
-               case T_MergePath:
-                       retval = _equalMergePath(a, b);
-                       break;
-               case T_HashPath:
-                       retval = _equalHashPath(a, b);
-                       break;
+                       /*
+                        * RELATION NODES
+                        */
                case T_PathKeyItem:
                        retval = _equalPathKeyItem(a, b);
                        break;
@@ -1736,22 +1767,13 @@ equal(void *a, void *b)
                case T_JoinInfo:
                        retval = _equalJoinInfo(a, b);
                        break;
-               case T_InnerIndexscanInfo:
-                       retval = _equalInnerIndexscanInfo(a, b);
-                       break;
-               case T_TidPath:
-                       retval = _equalTidPath(a, b);
-                       break;
-               case T_AppendPath:
-                       retval = _equalAppendPath(a, b);
-                       break;
-               case T_ResultPath:
-                       retval = _equalResultPath(a, b);
-                       break;
-               case T_IndexOptInfo:
-                       retval = _equalIndexOptInfo(a, b);
+               case T_InClauseInfo:
+                       retval = _equalInClauseInfo(a, b);
                        break;
 
+                       /*
+                        * LIST NODES
+                        */
                case T_List:
                        {
                                List       *la = (List *) a;
@@ -1782,6 +1804,9 @@ equal(void *a, void *b)
                        retval = _equalValue(a, b);
                        break;
 
+                       /*
+                        * PARSE NODES
+                        */
                case T_Query:
                        retval = _equalQuery(a, b);
                        break;
@@ -1803,9 +1828,15 @@ equal(void *a, void *b)
                case T_AlterTableStmt:
                        retval = _equalAlterTableStmt(a, b);
                        break;
+               case T_AlterDomainStmt:
+                       retval = _equalAlterDomainStmt(a, b);
+                       break;
                case T_GrantStmt:
                        retval = _equalGrantStmt(a, b);
                        break;
+               case T_DeclareCursorStmt:
+                       retval = _equalDeclareCursorStmt(a, b);
+                       break;
                case T_ClosePortalStmt:
                        retval = _equalClosePortalStmt(a, b);
                        break;
@@ -1818,6 +1849,9 @@ equal(void *a, void *b)
                case T_CreateStmt:
                        retval = _equalCreateStmt(a, b);
                        break;
+               case T_InhRelation:
+                       retval = _equalInhRelation(a, b);
+                       break;
                case T_DefineStmt:
                        retval = _equalDefineStmt(a, b);
                        break;
@@ -1905,6 +1939,9 @@ equal(void *a, void *b)
                case T_CreateSeqStmt:
                        retval = _equalCreateSeqStmt(a, b);
                        break;
+               case T_AlterSeqStmt:
+                       retval = _equalAlterSeqStmt(a, b);
+                       break;
                case T_VariableSetStmt:
                        retval = _equalVariableSetStmt(a, b);
                        break;
@@ -2011,12 +2048,6 @@ equal(void *a, void *b)
                case T_SortGroupBy:
                        retval = _equalSortGroupBy(a, b);
                        break;
-               case T_Alias:
-                       retval = _equalAlias(a, b);
-                       break;
-               case T_RangeVar:
-                       retval = _equalRangeVar(a, b);
-                       break;
                case T_RangeSubselect:
                        retval = _equalRangeSubselect(a, b);
                        break;
@@ -2038,9 +2069,6 @@ equal(void *a, void *b)
                case T_DefElem:
                        retval = _equalDefElem(a, b);
                        break;
-               case T_TargetEntry:
-                       retval = _equalTargetEntry(a, b);
-                       break;
                case T_RangeTblEntry:
                        retval = _equalRangeTblEntry(a, b);
                        break;
@@ -2051,24 +2079,6 @@ equal(void *a, void *b)
                        /* GroupClause is equivalent to SortClause */
                        retval = _equalSortClause(a, b);
                        break;
-               case T_CaseExpr:
-                       retval = _equalCaseExpr(a, b);
-                       break;
-               case T_CaseWhen:
-                       retval = _equalCaseWhen(a, b);
-                       break;
-               case T_NullTest:
-                       retval = _equalNullTest(a, b);
-                       break;
-               case T_BooleanTest:
-                       retval = _equalBooleanTest(a, b);
-                       break;
-               case T_ConstraintTest:
-                       retval = _equalConstraintTest(a, b);
-                       break;
-               case T_ConstraintTestValue:
-                       retval = _equalConstraintTestValue(a, b);
-                       break;
                case T_FkConstraint:
                        retval = _equalFkConstraint(a, b);
                        break;
@@ -2078,16 +2088,11 @@ equal(void *a, void *b)
                case T_FuncWithArgs:
                        retval = _equalFuncWithArgs(a, b);
                        break;
-               case T_InsertDefault:
-                       retval = _equalInsertDefault(a, b);
-                       break;
-               case T_DomainConstraintValue:
-                       retval = _equalDomainConstraintValue(a, b);
-                       break;
 
                default:
-                       elog(WARNING, "equal: don't know whether nodes of type %d are equal",
-                                nodeTag(a));
+                       elog(ERROR, "unrecognized node type: %d",
+                                (int) nodeTag(a));
+                       retval = false;         /* keep compiler quiet */
                        break;
        }