* 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 { \
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)
{
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)
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)
{
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
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);
}
}
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.
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;
}
_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)
{
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.
}
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)
{
{
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);
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;
}
{
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);
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;
}
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);
COMPARE_SCALAR_FIELD(all);
COMPARE_NODE_FIELD(larg);
COMPARE_NODE_FIELD(rarg);
- COMPARE_INTLIST_FIELD(colTypes);
+ COMPARE_OIDLIST_FIELD(colTypes);
return true;
}
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)
{
COMPARE_NODE_FIELD(objects);
COMPARE_INTLIST_FIELD(privileges);
COMPARE_NODE_FIELD(grantees);
+ COMPARE_SCALAR_FIELD(grant_option);
+ COMPARE_SCALAR_FIELD(behavior);
return true;
}
}
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;
}
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);
_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);
static bool
_equalTransactionStmt(TransactionStmt *a, TransactionStmt *b)
{
- COMPARE_SCALAR_FIELD(command);
+ COMPARE_SCALAR_FIELD(kind);
COMPARE_NODE_FIELD(options);
return true;
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)
{
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);
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);
{
COMPARE_STRING_FIELD(name);
COMPARE_NODE_FIELD(argtypes);
- COMPARE_INTLIST_FIELD(argtype_oids);
+ COMPARE_OIDLIST_FIELD(argtype_oids);
COMPARE_NODE_FIELD(query);
return true;
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);
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);
_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;
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)
{
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
/* nothing to do */
break;
default:
- elog(ERROR, "_equalValue: unknown node type %d", a->type);
+ elog(ERROR, "unrecognized node type: %d", (int) a->type);
break;
}
bool
equal(void *a, void *b)
{
- bool retval = false;
+ bool retval;
if (a == b)
return true;
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;
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;
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;
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;
retval = _equalValue(a, b);
break;
+ /*
+ * PARSE NODES
+ */
case T_Query:
retval = _equalQuery(a, b);
break;
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;
case T_CreateStmt:
retval = _equalCreateStmt(a, b);
break;
+ case T_InhRelation:
+ retval = _equalInhRelation(a, b);
+ break;
case T_DefineStmt:
retval = _equalDefineStmt(a, b);
break;
case T_CreateSeqStmt:
retval = _equalCreateSeqStmt(a, b);
break;
+ case T_AlterSeqStmt:
+ retval = _equalAlterSeqStmt(a, b);
+ break;
case T_VariableSetStmt:
retval = _equalVariableSetStmt(a, b);
break;
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;
case T_DefElem:
retval = _equalDefElem(a, b);
break;
- case T_TargetEntry:
- retval = _equalTargetEntry(a, b);
- break;
case T_RangeTblEntry:
retval = _equalRangeTblEntry(a, b);
break;
/* 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;
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;
}