9.1-planner-speedup-v5-extra-ifs.patch

text/x-patch

Filename: 9.1-planner-speedup-v5-extra-ifs.patch
Type: text/x-patch
Part: 1
Message: Re: plan time of MASSIVE partitioning ...

Patch

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