* be handled easily in a simple depth-first traversal.
*
* Currently, in fact, equal() doesn't know how to compare Plan trees
- * either. This might need to be fixed someday.
+ * 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.177 2002/12/14 00:17:51 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.206 2003/08/04 02:39:59 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
- * 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;
/*
* We don't need an _equalExpr because Expr is an abstract supertype which
- * should never actually get instantiated. Also, since it has no common
+ * 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...
*/
COMPARE_SCALAR_FIELD(paramid);
break;
default:
- elog(ERROR, "_equalParam: Invalid paramkind value: %d",
+ elog(ERROR, "unrecognized paramkind: %d",
a->paramkind);
}
COMPARE_SCALAR_FIELD(aggfnoid);
COMPARE_SCALAR_FIELD(aggtype);
COMPARE_NODE_FIELD(target);
+ COMPARE_SCALAR_FIELD(agglevelsup);
COMPARE_SCALAR_FIELD(aggstar);
COMPARE_SCALAR_FIELD(aggdistinct);
_equalArrayRef(ArrayRef *a, ArrayRef *b)
{
COMPARE_SCALAR_FIELD(refrestype);
- COMPARE_SCALAR_FIELD(refattrlength);
- COMPARE_SCALAR_FIELD(refelemlength);
- COMPARE_SCALAR_FIELD(refelembyval);
- COMPARE_SCALAR_FIELD(refelemalign);
+ COMPARE_SCALAR_FIELD(refarraytype);
+ COMPARE_SCALAR_FIELD(refelemtype);
COMPARE_NODE_FIELD(refupperindexpr);
COMPARE_NODE_FIELD(reflowerindexpr);
COMPARE_NODE_FIELD(refexpr);
}
static bool
-_equalFuncExpr(FuncExpr *a, FuncExpr *b)
+_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.
}
static bool
-_equalOpExpr(OpExpr *a, OpExpr *b)
+_equalOpExpr(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.
+ * 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 &&
}
static bool
-_equalDistinctExpr(DistinctExpr *a, DistinctExpr *b)
+_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.
+ * 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 &&
}
static bool
-_equalBoolExpr(BoolExpr *a, BoolExpr *b)
+_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);
_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;
_equalSubPlan(SubPlan *a, SubPlan *b)
{
COMPARE_SCALAR_FIELD(subLinkType);
- COMPARE_SCALAR_FIELD(useor);
- COMPARE_NODE_FIELD(oper);
+ 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);
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.
return true;
}
+static bool
+_equalArrayExpr(ArrayExpr * a, ArrayExpr * b)
+{
+ COMPARE_SCALAR_FIELD(array_typeid);
+ COMPARE_SCALAR_FIELD(element_typeid);
+ COMPARE_NODE_FIELD(elements);
+ COMPARE_SCALAR_FIELD(ndims);
+
+ return true;
+}
+
+static bool
+_equalCoalesceExpr(CoalesceExpr * a, CoalesceExpr * b)
+{
+ COMPARE_SCALAR_FIELD(coalescetype);
+ COMPARE_NODE_FIELD(args);
+
+ return true;
+}
+
+static bool
+_equalNullIfExpr(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 != 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
_equalNullTest(NullTest *a, NullTest *b)
{
}
static bool
-_equalConstraintTest(ConstraintTest *a, ConstraintTest *b)
+_equalCoerceToDomain(CoerceToDomain * a, CoerceToDomain * b)
{
COMPARE_NODE_FIELD(arg);
- COMPARE_SCALAR_FIELD(testtype);
- COMPARE_STRING_FIELD(name);
- COMPARE_STRING_FIELD(domname);
- COMPARE_NODE_FIELD(check_expr);
+ 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.
+ */
+ if (a->coercionformat != b->coercionformat &&
+ a->coercionformat != COERCE_DONTCARE &&
+ b->coercionformat != COERCE_DONTCARE)
+ return false;
+
+ return true;
+}
+
+static bool
+_equalCoerceToDomainValue(CoerceToDomainValue * a, CoerceToDomainValue * b)
+{
+ COMPARE_SCALAR_FIELD(typeId);
+ COMPARE_SCALAR_FIELD(typeMod);
return true;
}
static bool
-_equalConstraintTestValue(ConstraintTestValue *a, ConstraintTestValue *b)
+_equalSetToDefault(SetToDefault * a, SetToDefault * b)
{
COMPARE_SCALAR_FIELD(typeId);
COMPARE_SCALAR_FIELD(typeMod);
{
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
+_equalInClauseInfo(InClauseInfo * a, InClauseInfo * b)
+{
+ COMPARE_BITMAPSET_FIELD(lefthand);
+ COMPARE_BITMAPSET_FIELD(righthand);
+ COMPARE_NODE_FIELD(sub_targetlist);
+
+ return true;
+}
+
/*
* Stuff from parsenodes.h
{
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;
}
}
static bool
-_equalAlterDomainStmt(AlterDomainStmt *a, AlterDomainStmt *b)
+_equalAlterDomainStmt(AlterDomainStmt * a, AlterDomainStmt * b)
{
COMPARE_SCALAR_FIELD(subtype);
COMPARE_NODE_FIELD(typename);
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;
/* 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))
{
- /*
- * PRIMITIVE NODES
- */
+ /*
+ * PRIMITIVE NODES
+ */
case T_Resdom:
retval = _equalResdom(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_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_ConstraintTest:
- retval = _equalConstraintTest(a, b);
+ case T_CoerceToDomain:
+ retval = _equalCoerceToDomain(a, b);
+ break;
+ case T_CoerceToDomainValue:
+ retval = _equalCoerceToDomainValue(a, b);
break;
- case T_ConstraintTestValue:
- retval = _equalConstraintTestValue(a, b);
+ case T_SetToDefault:
+ retval = _equalSetToDefault(a, b);
break;
case T_TargetEntry:
retval = _equalTargetEntry(a, b);
case T_JoinInfo:
retval = _equalJoinInfo(a, b);
break;
+ case T_InClauseInfo:
+ retval = _equalInClauseInfo(a, b);
+ break;
/*
* LIST NODES
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_FuncWithArgs:
retval = _equalFuncWithArgs(a, b);
break;
- case T_InsertDefault:
- retval = _equalInsertDefault(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;
}