⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 equalfuncs.c

📁 PostgreSQL7.4.6 for Linux
💻 C
📖 第 1 页 / 共 3 页
字号:
/*------------------------------------------------------------------------- * * equalfuncs.c *	  Equality functions to compare node trees. * * 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 trees * either.	This might need to be fixed someday. * * * 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.209 2003/08/17 23:43:26 tgl Exp $ * *------------------------------------------------------------------------- */#include "postgres.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 * hard-wire the convention that the local variables in an Equal 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 false; \	} while (0)/* Compare a field that is a pointer to some kind of Node or Node tree */#define COMPARE_NODE_FIELD(fldname) \	do { \		if (!equal(a->fldname, b->fldname)) \			return false; \	} while (0)/* Compare a field that is a pointer to a list of integers */#define COMPARE_INTLIST_FIELD(fldname) \	do { \		if (!equali(a->fldname, b->fldname)) \			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 { \		if (!equalstr(a->fldname, b->fldname)) \			return false; \	} while (0)/* Macro for comparing string fields that might be NULL */#define equalstr(a, b)	\	(((a) != NULL && (b) != NULL) ? (strcmp(a, b) == 0) : (a) == (b))/* Compare a field that is a pointer to a simple palloc'd object of size sz */#define COMPARE_POINTER_FIELD(fldname, sz) \	do { \		if (memcmp(a->fldname, b->fldname, (sz)) != 0) \			return false; \	} while (0)/* *	Stuff from primnodes.h */static bool_equalResdom(Resdom *a, Resdom *b){	COMPARE_SCALAR_FIELD(resno);	COMPARE_SCALAR_FIELD(restype);	COMPARE_SCALAR_FIELD(restypmod);	COMPARE_STRING_FIELD(resname);	COMPARE_SCALAR_FIELD(ressortgroupref);	COMPARE_SCALAR_FIELD(resorigtbl);	COMPARE_SCALAR_FIELD(resorigcol);	COMPARE_SCALAR_FIELD(resjunk);	return true;}static bool_equalAlias(Alias *a, Alias *b){	COMPARE_STRING_FIELD(aliasname);	COMPARE_NODE_FIELD(colnames);	return true;}static bool_equalRangeVar(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);	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){	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);	return true;}static bool_equalConst(Const *a, Const *b){	COMPARE_SCALAR_FIELD(consttype);	COMPARE_SCALAR_FIELD(constlen);	COMPARE_SCALAR_FIELD(constisnull);	COMPARE_SCALAR_FIELD(constbyval);	/*	 * We treat all NULL constants of the same type as equal. Someday this	 * might need to change?  But datumIsEqual doesn't work on nulls,	 * so...	 */	if (a->constisnull)		return true;	return datumIsEqual(a->constvalue, b->constvalue,						a->constbyval, a->constlen);}static bool_equalParam(Param *a, Param *b){	COMPARE_SCALAR_FIELD(paramkind);	COMPARE_SCALAR_FIELD(paramtype);	switch (a->paramkind)	{		case PARAM_NAMED:			COMPARE_STRING_FIELD(paramname);			break;		case PARAM_NUM:		case PARAM_EXEC:			COMPARE_SCALAR_FIELD(paramid);			break;		default:			elog(ERROR, "unrecognized paramkind: %d",				 a->paramkind);	}	return true;}static bool_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.	 */	if (a->funcformat != b->funcformat &&		a->funcformat != COERCE_DONTCARE &&		b->funcformat != COERCE_DONTCARE)		return false;	COMPARE_NODE_FIELD(args);	return true;}static bool_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.	 */	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;}static bool_equalSubLink(SubLink *a, SubLink *b){	COMPARE_SCALAR_FIELD(subLinkType);	COMPARE_SCALAR_FIELD(useOr);	COMPARE_NODE_FIELD(lefthand);	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(fieldnum);	COMPARE_SCALAR_FIELD(resulttype);	COMPARE_SCALAR_FIELD(resulttypmod);	return true;}static bool_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.	 */	if (a->relabelformat != b->relabelformat &&		a->relabelformat != COERCE_DONTCARE &&		b->relabelformat != COERCE_DONTCARE)		return false;	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_equalArrayExpr(ArrayExpr *a, ArrayExpr *b){	COMPARE_SCALAR_FIELD(array_typeid);	COMPARE_SCALAR_FIELD(element_typeid);	COMPARE_NODE_FIELD(elements);	COMPARE_SCALAR_FIELD(multidims);	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){	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_equalCoerceToDomain(CoerceToDomain *a, CoerceToDomain *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.	 */	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_equalSetToDefault(SetToDefault *a, SetToDefault *b){	COMPARE_SCALAR_FIELD(typeId);	COMPARE_SCALAR_FIELD(typeMod);	return true;}static bool_equalTargetEntry(TargetEntry *a, TargetEntry *b){	COMPARE_NODE_FIELD(resdom);	COMPARE_NODE_FIELD(expr);	return true;}static bool_equalRangeTblRef(RangeTblRef *a, RangeTblRef *b){	COMPARE_SCALAR_FIELD(rtindex);	return true;}static bool_equalJoinExpr(JoinExpr *a, JoinExpr *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);	return true;}static bool_equalFromExpr(FromExpr *a, FromExpr *b){	COMPARE_NODE_FIELD(fromlist);	COMPARE_NODE_FIELD(quals);	return true;}/* * Stuff from relation.h */static bool_equalPathKeyItem(PathKeyItem *a, PathKeyItem *b){	COMPARE_NODE_FIELD(key);	COMPARE_SCALAR_FIELD(sortop);	return true;}static bool_equalRestrictInfo(RestrictInfo *a, RestrictInfo *b){	COMPARE_NODE_FIELD(clause);	COMPARE_SCALAR_FIELD(ispusheddown);	/*	 * 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);	COMPARE_SCALAR_FIELD(right_sortop);	COMPARE_SCALAR_FIELD(hashjoinoperator);	return true;}static bool_equalJoinInfo(JoinInfo *a, JoinInfo *b){	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 */static bool_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(hasAggs);	COMPARE_SCALAR_FIELD(hasSubLinks);	COMPARE_NODE_FIELD(rtable);	COMPARE_NODE_FIELD(jointree);	COMPARE_INTLIST_FIELD(rowMarks);	COMPARE_NODE_FIELD(targetList);	COMPARE_NODE_FIELD(groupClause);	COMPARE_NODE_FIELD(havingQual);	COMPARE_NODE_FIELD(distinctClause);	COMPARE_NODE_FIELD(sortClause);	COMPARE_NODE_FIELD(limitOffset);	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 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;}static bool_equalInsertStmt(InsertStmt *a, InsertStmt *b){	COMPARE_NODE_FIELD(relation);	COMPARE_NODE_FIELD(cols);	COMPARE_NODE_FIELD(targetList);	COMPARE_NODE_FIELD(selectStmt);	return true;}static bool_equalDeleteStmt(DeleteStmt *a, DeleteStmt *b){	COMPARE_NODE_FIELD(relation);	COMPARE_NODE_FIELD(whereClause);	return true;}static bool_equalUpdateStmt(UpdateStmt *a, UpdateStmt *b){	COMPARE_NODE_FIELD(relation);	COMPARE_NODE_FIELD(targetList);	COMPARE_NODE_FIELD(whereClause);	COMPARE_NODE_FIELD(fromClause);	return true;}static bool_equalSelectStmt(SelectStmt *a, SelectStmt *b){	COMPARE_NODE_FIELD(distinctClause);	COMPARE_NODE_FIELD(into);	COMPARE_NODE_FIELD(intoColNames);	COMPARE_NODE_FIELD(targetList);	COMPARE_NODE_FIELD(fromClause);	COMPARE_NODE_FIELD(whereClause);	COMPARE_NODE_FIELD(groupClause);	COMPARE_NODE_FIELD(havingClause);	COMPARE_NODE_FIELD(sortClause);	COMPARE_NODE_FIELD(limitOffset);	COMPARE_NODE_FIELD(limitCount);	COMPARE_NODE_FIELD(forUpdate);	COMPARE_SCALAR_FIELD(op);	COMPARE_SCALAR_FIELD(all);	COMPARE_NODE_FIELD(larg);	COMPARE_NODE_FIELD(rarg);	return true;}static bool_equalSetOperationStmt(SetOperationStmt *a, SetOperationStmt *b){	COMPARE_SCALAR_FIELD(op);	COMPARE_SCALAR_FIELD(all);	COMPARE_NODE_FIELD(larg);	COMPARE_NODE_FIELD(rarg);	COMPARE_OIDLIST_FIELD(colTypes);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -