]> granicus.if.org Git - postgresql/blob - src/backend/nodes/equalfuncs.c
f80da7572b5270f03987a7752c82a828371444b7
[postgresql] / src / backend / nodes / equalfuncs.c
1 /*-------------------------------------------------------------------------
2  *
3  * equalfuncs.c
4  *        Equality functions to compare node trees.
5  *
6  * NOTE: we currently support comparing all node types found in parse
7  * trees.  We do not support comparing executor state trees; there
8  * is no need for that, and no point in maintaining all the code that
9  * would be needed.  We also do not support comparing Path trees, mainly
10  * because the circular linkages between RelOptInfo and Path nodes can't
11  * be handled easily in a simple depth-first traversal.
12  *
13  * Currently, in fact, equal() doesn't know how to compare Plan trees
14  * either.      This might need to be fixed someday.
15  *
16  *
17  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
18  * Portions Copyright (c) 1994, Regents of the University of California
19  *
20  * IDENTIFICATION
21  *        $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.236 2005/03/10 23:21:21 tgl Exp $
22  *
23  *-------------------------------------------------------------------------
24  */
25
26 #include "postgres.h"
27
28 #include "nodes/params.h"
29 #include "nodes/parsenodes.h"
30 #include "nodes/relation.h"
31 #include "utils/datum.h"
32
33
34 /*
35  * Macros to simplify comparison of different kinds of fields.  Use these
36  * wherever possible to reduce the chance for silly typos.      Note that these
37  * hard-wire the convention that the local variables in an Equal routine are
38  * named 'a' and 'b'.
39  */
40
41 /* Compare a simple scalar field (int, float, bool, enum, etc) */
42 #define COMPARE_SCALAR_FIELD(fldname) \
43         do { \
44                 if (a->fldname != b->fldname) \
45                         return false; \
46         } while (0)
47
48 /* Compare a field that is a pointer to some kind of Node or Node tree */
49 #define COMPARE_NODE_FIELD(fldname) \
50         do { \
51                 if (!equal(a->fldname, b->fldname)) \
52                         return false; \
53         } while (0)
54
55 /* Compare a field that is a pointer to a Bitmapset */
56 #define COMPARE_BITMAPSET_FIELD(fldname) \
57         do { \
58                 if (!bms_equal(a->fldname, b->fldname)) \
59                         return false; \
60         } while (0)
61
62 /* Compare a field that is a pointer to a C string, or perhaps NULL */
63 #define COMPARE_STRING_FIELD(fldname) \
64         do { \
65                 if (!equalstr(a->fldname, b->fldname)) \
66                         return false; \
67         } while (0)
68
69 /* Macro for comparing string fields that might be NULL */
70 #define equalstr(a, b)  \
71         (((a) != NULL && (b) != NULL) ? (strcmp(a, b) == 0) : (a) == (b))
72
73 /* Compare a field that is a pointer to a simple palloc'd object of size sz */
74 #define COMPARE_POINTER_FIELD(fldname, sz) \
75         do { \
76                 if (memcmp(a->fldname, b->fldname, (sz)) != 0) \
77                         return false; \
78         } while (0)
79
80
81 /*
82  *      Stuff from primnodes.h
83  */
84
85 static bool
86 _equalResdom(Resdom *a, Resdom *b)
87 {
88         COMPARE_SCALAR_FIELD(resno);
89         COMPARE_SCALAR_FIELD(restype);
90         COMPARE_SCALAR_FIELD(restypmod);
91         COMPARE_STRING_FIELD(resname);
92         COMPARE_SCALAR_FIELD(ressortgroupref);
93         COMPARE_SCALAR_FIELD(resorigtbl);
94         COMPARE_SCALAR_FIELD(resorigcol);
95         COMPARE_SCALAR_FIELD(resjunk);
96
97         return true;
98 }
99
100 static bool
101 _equalAlias(Alias *a, Alias *b)
102 {
103         COMPARE_STRING_FIELD(aliasname);
104         COMPARE_NODE_FIELD(colnames);
105
106         return true;
107 }
108
109 static bool
110 _equalRangeVar(RangeVar *a, RangeVar *b)
111 {
112         COMPARE_STRING_FIELD(catalogname);
113         COMPARE_STRING_FIELD(schemaname);
114         COMPARE_STRING_FIELD(relname);
115         COMPARE_SCALAR_FIELD(inhOpt);
116         COMPARE_SCALAR_FIELD(istemp);
117         COMPARE_NODE_FIELD(alias);
118
119         return true;
120 }
121
122 /*
123  * We don't need an _equalExpr because Expr is an abstract supertype which
124  * should never actually get instantiated.      Also, since it has no common
125  * fields except NodeTag, there's no need for a helper routine to factor
126  * out comparing the common fields...
127  */
128
129 static bool
130 _equalVar(Var *a, Var *b)
131 {
132         COMPARE_SCALAR_FIELD(varno);
133         COMPARE_SCALAR_FIELD(varattno);
134         COMPARE_SCALAR_FIELD(vartype);
135         COMPARE_SCALAR_FIELD(vartypmod);
136         COMPARE_SCALAR_FIELD(varlevelsup);
137         COMPARE_SCALAR_FIELD(varnoold);
138         COMPARE_SCALAR_FIELD(varoattno);
139
140         return true;
141 }
142
143 static bool
144 _equalConst(Const *a, Const *b)
145 {
146         COMPARE_SCALAR_FIELD(consttype);
147         COMPARE_SCALAR_FIELD(constlen);
148         COMPARE_SCALAR_FIELD(constisnull);
149         COMPARE_SCALAR_FIELD(constbyval);
150
151         /*
152          * We treat all NULL constants of the same type as equal. Someday this
153          * might need to change?  But datumIsEqual doesn't work on nulls,
154          * so...
155          */
156         if (a->constisnull)
157                 return true;
158         return datumIsEqual(a->constvalue, b->constvalue,
159                                                 a->constbyval, a->constlen);
160 }
161
162 static bool
163 _equalParam(Param *a, Param *b)
164 {
165         COMPARE_SCALAR_FIELD(paramkind);
166         COMPARE_SCALAR_FIELD(paramtype);
167
168         switch (a->paramkind)
169         {
170                 case PARAM_NAMED:
171                         COMPARE_STRING_FIELD(paramname);
172                         break;
173                 case PARAM_NUM:
174                 case PARAM_EXEC:
175                         COMPARE_SCALAR_FIELD(paramid);
176                         break;
177                 default:
178                         elog(ERROR, "unrecognized paramkind: %d",
179                                  a->paramkind);
180         }
181
182         return true;
183 }
184
185 static bool
186 _equalAggref(Aggref *a, Aggref *b)
187 {
188         COMPARE_SCALAR_FIELD(aggfnoid);
189         COMPARE_SCALAR_FIELD(aggtype);
190         COMPARE_NODE_FIELD(target);
191         COMPARE_SCALAR_FIELD(agglevelsup);
192         COMPARE_SCALAR_FIELD(aggstar);
193         COMPARE_SCALAR_FIELD(aggdistinct);
194
195         return true;
196 }
197
198 static bool
199 _equalArrayRef(ArrayRef *a, ArrayRef *b)
200 {
201         COMPARE_SCALAR_FIELD(refrestype);
202         COMPARE_SCALAR_FIELD(refarraytype);
203         COMPARE_SCALAR_FIELD(refelemtype);
204         COMPARE_NODE_FIELD(refupperindexpr);
205         COMPARE_NODE_FIELD(reflowerindexpr);
206         COMPARE_NODE_FIELD(refexpr);
207         COMPARE_NODE_FIELD(refassgnexpr);
208
209         return true;
210 }
211
212 static bool
213 _equalFuncExpr(FuncExpr *a, FuncExpr *b)
214 {
215         COMPARE_SCALAR_FIELD(funcid);
216         COMPARE_SCALAR_FIELD(funcresulttype);
217         COMPARE_SCALAR_FIELD(funcretset);
218
219         /*
220          * Special-case COERCE_DONTCARE, so that planner can build coercion
221          * nodes that are equal() to both explicit and implicit coercions.
222          */
223         if (a->funcformat != b->funcformat &&
224                 a->funcformat != COERCE_DONTCARE &&
225                 b->funcformat != COERCE_DONTCARE)
226                 return false;
227
228         COMPARE_NODE_FIELD(args);
229
230         return true;
231 }
232
233 static bool
234 _equalOpExpr(OpExpr *a, OpExpr *b)
235 {
236         COMPARE_SCALAR_FIELD(opno);
237
238         /*
239          * Special-case opfuncid: it is allowable for it to differ if one node
240          * contains zero and the other doesn't.  This just means that the one
241          * node isn't as far along in the parse/plan pipeline and hasn't had
242          * the opfuncid cache filled yet.
243          */
244         if (a->opfuncid != b->opfuncid &&
245                 a->opfuncid != 0 &&
246                 b->opfuncid != 0)
247                 return false;
248
249         COMPARE_SCALAR_FIELD(opresulttype);
250         COMPARE_SCALAR_FIELD(opretset);
251         COMPARE_NODE_FIELD(args);
252
253         return true;
254 }
255
256 static bool
257 _equalDistinctExpr(DistinctExpr *a, DistinctExpr *b)
258 {
259         COMPARE_SCALAR_FIELD(opno);
260
261         /*
262          * Special-case opfuncid: it is allowable for it to differ if one node
263          * contains zero and the other doesn't.  This just means that the one
264          * node isn't as far along in the parse/plan pipeline and hasn't had
265          * the opfuncid cache filled yet.
266          */
267         if (a->opfuncid != b->opfuncid &&
268                 a->opfuncid != 0 &&
269                 b->opfuncid != 0)
270                 return false;
271
272         COMPARE_SCALAR_FIELD(opresulttype);
273         COMPARE_SCALAR_FIELD(opretset);
274         COMPARE_NODE_FIELD(args);
275
276         return true;
277 }
278
279 static bool
280 _equalScalarArrayOpExpr(ScalarArrayOpExpr *a, ScalarArrayOpExpr *b)
281 {
282         COMPARE_SCALAR_FIELD(opno);
283
284         /*
285          * Special-case opfuncid: it is allowable for it to differ if one node
286          * contains zero and the other doesn't.  This just means that the one
287          * node isn't as far along in the parse/plan pipeline and hasn't had
288          * the opfuncid cache filled yet.
289          */
290         if (a->opfuncid != b->opfuncid &&
291                 a->opfuncid != 0 &&
292                 b->opfuncid != 0)
293                 return false;
294
295         COMPARE_SCALAR_FIELD(useOr);
296         COMPARE_NODE_FIELD(args);
297
298         return true;
299 }
300
301 static bool
302 _equalBoolExpr(BoolExpr *a, BoolExpr *b)
303 {
304         COMPARE_SCALAR_FIELD(boolop);
305         COMPARE_NODE_FIELD(args);
306
307         return true;
308 }
309
310 static bool
311 _equalSubLink(SubLink *a, SubLink *b)
312 {
313         COMPARE_SCALAR_FIELD(subLinkType);
314         COMPARE_SCALAR_FIELD(useOr);
315         COMPARE_NODE_FIELD(lefthand);
316         COMPARE_NODE_FIELD(operName);
317         COMPARE_NODE_FIELD(operOids);
318         COMPARE_NODE_FIELD(subselect);
319
320         return true;
321 }
322
323 static bool
324 _equalSubPlan(SubPlan *a, SubPlan *b)
325 {
326         COMPARE_SCALAR_FIELD(subLinkType);
327         COMPARE_SCALAR_FIELD(useOr);
328         COMPARE_NODE_FIELD(exprs);
329         COMPARE_NODE_FIELD(paramIds);
330         /* should compare plans, but have to settle for comparing plan IDs */
331         COMPARE_SCALAR_FIELD(plan_id);
332         COMPARE_NODE_FIELD(rtable);
333         COMPARE_SCALAR_FIELD(useHashTable);
334         COMPARE_SCALAR_FIELD(unknownEqFalse);
335         COMPARE_NODE_FIELD(setParam);
336         COMPARE_NODE_FIELD(parParam);
337         COMPARE_NODE_FIELD(args);
338
339         return true;
340 }
341
342 static bool
343 _equalFieldSelect(FieldSelect *a, FieldSelect *b)
344 {
345         COMPARE_NODE_FIELD(arg);
346         COMPARE_SCALAR_FIELD(fieldnum);
347         COMPARE_SCALAR_FIELD(resulttype);
348         COMPARE_SCALAR_FIELD(resulttypmod);
349
350         return true;
351 }
352
353 static bool
354 _equalFieldStore(FieldStore *a, FieldStore *b)
355 {
356         COMPARE_NODE_FIELD(arg);
357         COMPARE_NODE_FIELD(newvals);
358         COMPARE_NODE_FIELD(fieldnums);
359         COMPARE_SCALAR_FIELD(resulttype);
360
361         return true;
362 }
363
364 static bool
365 _equalRelabelType(RelabelType *a, RelabelType *b)
366 {
367         COMPARE_NODE_FIELD(arg);
368         COMPARE_SCALAR_FIELD(resulttype);
369         COMPARE_SCALAR_FIELD(resulttypmod);
370
371         /*
372          * Special-case COERCE_DONTCARE, so that planner can build coercion
373          * nodes that are equal() to both explicit and implicit coercions.
374          */
375         if (a->relabelformat != b->relabelformat &&
376                 a->relabelformat != COERCE_DONTCARE &&
377                 b->relabelformat != COERCE_DONTCARE)
378                 return false;
379
380         return true;
381 }
382
383 static bool
384 _equalConvertRowtypeExpr(ConvertRowtypeExpr *a, ConvertRowtypeExpr *b)
385 {
386         COMPARE_NODE_FIELD(arg);
387         COMPARE_SCALAR_FIELD(resulttype);
388
389         /*
390          * Special-case COERCE_DONTCARE, so that planner can build coercion
391          * nodes that are equal() to both explicit and implicit coercions.
392          */
393         if (a->convertformat != b->convertformat &&
394                 a->convertformat != COERCE_DONTCARE &&
395                 b->convertformat != COERCE_DONTCARE)
396                 return false;
397
398         return true;
399 }
400
401 static bool
402 _equalCaseExpr(CaseExpr *a, CaseExpr *b)
403 {
404         COMPARE_SCALAR_FIELD(casetype);
405         COMPARE_NODE_FIELD(arg);
406         COMPARE_NODE_FIELD(args);
407         COMPARE_NODE_FIELD(defresult);
408
409         return true;
410 }
411
412 static bool
413 _equalCaseWhen(CaseWhen *a, CaseWhen *b)
414 {
415         COMPARE_NODE_FIELD(expr);
416         COMPARE_NODE_FIELD(result);
417
418         return true;
419 }
420
421 static bool
422 _equalCaseTestExpr(CaseTestExpr *a, CaseTestExpr *b)
423 {
424         COMPARE_SCALAR_FIELD(typeId);
425         COMPARE_SCALAR_FIELD(typeMod);
426
427         return true;
428 }
429
430 static bool
431 _equalArrayExpr(ArrayExpr *a, ArrayExpr *b)
432 {
433         COMPARE_SCALAR_FIELD(array_typeid);
434         COMPARE_SCALAR_FIELD(element_typeid);
435         COMPARE_NODE_FIELD(elements);
436         COMPARE_SCALAR_FIELD(multidims);
437
438         return true;
439 }
440
441 static bool
442 _equalRowExpr(RowExpr *a, RowExpr *b)
443 {
444         COMPARE_NODE_FIELD(args);
445         COMPARE_SCALAR_FIELD(row_typeid);
446
447         /*
448          * Special-case COERCE_DONTCARE, so that planner can build coercion
449          * nodes that are equal() to both explicit and implicit coercions.
450          */
451         if (a->row_format != b->row_format &&
452                 a->row_format != COERCE_DONTCARE &&
453                 b->row_format != COERCE_DONTCARE)
454                 return false;
455
456         return true;
457 }
458
459 static bool
460 _equalCoalesceExpr(CoalesceExpr *a, CoalesceExpr *b)
461 {
462         COMPARE_SCALAR_FIELD(coalescetype);
463         COMPARE_NODE_FIELD(args);
464
465         return true;
466 }
467
468 static bool
469 _equalNullIfExpr(NullIfExpr *a, NullIfExpr *b)
470 {
471         COMPARE_SCALAR_FIELD(opno);
472
473         /*
474          * Special-case opfuncid: it is allowable for it to differ if one node
475          * contains zero and the other doesn't.  This just means that the one
476          * node isn't as far along in the parse/plan pipeline and hasn't had
477          * the opfuncid cache filled yet.
478          */
479         if (a->opfuncid != b->opfuncid &&
480                 a->opfuncid != 0 &&
481                 b->opfuncid != 0)
482                 return false;
483
484         COMPARE_SCALAR_FIELD(opresulttype);
485         COMPARE_SCALAR_FIELD(opretset);
486         COMPARE_NODE_FIELD(args);
487
488         return true;
489 }
490
491 static bool
492 _equalNullTest(NullTest *a, NullTest *b)
493 {
494         COMPARE_NODE_FIELD(arg);
495         COMPARE_SCALAR_FIELD(nulltesttype);
496
497         return true;
498 }
499
500 static bool
501 _equalBooleanTest(BooleanTest *a, BooleanTest *b)
502 {
503         COMPARE_NODE_FIELD(arg);
504         COMPARE_SCALAR_FIELD(booltesttype);
505
506         return true;
507 }
508
509 static bool
510 _equalCoerceToDomain(CoerceToDomain *a, CoerceToDomain *b)
511 {
512         COMPARE_NODE_FIELD(arg);
513         COMPARE_SCALAR_FIELD(resulttype);
514         COMPARE_SCALAR_FIELD(resulttypmod);
515
516         /*
517          * Special-case COERCE_DONTCARE, so that planner can build coercion
518          * nodes that are equal() to both explicit and implicit coercions.
519          */
520         if (a->coercionformat != b->coercionformat &&
521                 a->coercionformat != COERCE_DONTCARE &&
522                 b->coercionformat != COERCE_DONTCARE)
523                 return false;
524
525         return true;
526 }
527
528 static bool
529 _equalCoerceToDomainValue(CoerceToDomainValue *a, CoerceToDomainValue *b)
530 {
531         COMPARE_SCALAR_FIELD(typeId);
532         COMPARE_SCALAR_FIELD(typeMod);
533
534         return true;
535 }
536
537 static bool
538 _equalSetToDefault(SetToDefault *a, SetToDefault *b)
539 {
540         COMPARE_SCALAR_FIELD(typeId);
541         COMPARE_SCALAR_FIELD(typeMod);
542
543         return true;
544 }
545
546 static bool
547 _equalTargetEntry(TargetEntry *a, TargetEntry *b)
548 {
549         COMPARE_NODE_FIELD(resdom);
550         COMPARE_NODE_FIELD(expr);
551
552         return true;
553 }
554
555 static bool
556 _equalRangeTblRef(RangeTblRef *a, RangeTblRef *b)
557 {
558         COMPARE_SCALAR_FIELD(rtindex);
559
560         return true;
561 }
562
563 static bool
564 _equalJoinExpr(JoinExpr *a, JoinExpr *b)
565 {
566         COMPARE_SCALAR_FIELD(jointype);
567         COMPARE_SCALAR_FIELD(isNatural);
568         COMPARE_NODE_FIELD(larg);
569         COMPARE_NODE_FIELD(rarg);
570         COMPARE_NODE_FIELD(using);
571         COMPARE_NODE_FIELD(quals);
572         COMPARE_NODE_FIELD(alias);
573         COMPARE_SCALAR_FIELD(rtindex);
574
575         return true;
576 }
577
578 static bool
579 _equalFromExpr(FromExpr *a, FromExpr *b)
580 {
581         COMPARE_NODE_FIELD(fromlist);
582         COMPARE_NODE_FIELD(quals);
583
584         return true;
585 }
586
587
588 /*
589  * Stuff from relation.h
590  */
591
592 static bool
593 _equalPathKeyItem(PathKeyItem *a, PathKeyItem *b)
594 {
595         COMPARE_NODE_FIELD(key);
596         COMPARE_SCALAR_FIELD(sortop);
597
598         return true;
599 }
600
601 static bool
602 _equalRestrictInfo(RestrictInfo *a, RestrictInfo *b)
603 {
604         COMPARE_NODE_FIELD(clause);
605         COMPARE_SCALAR_FIELD(is_pushed_down);
606         COMPARE_SCALAR_FIELD(valid_everywhere);
607
608         /*
609          * We ignore all the remaining fields, since they may not be set yet,
610          * and should be derivable from the clause anyway.
611          */
612
613         return true;
614 }
615
616 static bool
617 _equalJoinInfo(JoinInfo *a, JoinInfo *b)
618 {
619         COMPARE_BITMAPSET_FIELD(unjoined_relids);
620         COMPARE_NODE_FIELD(jinfo_restrictinfo);
621
622         return true;
623 }
624
625 static bool
626 _equalInClauseInfo(InClauseInfo *a, InClauseInfo *b)
627 {
628         COMPARE_BITMAPSET_FIELD(lefthand);
629         COMPARE_BITMAPSET_FIELD(righthand);
630         COMPARE_NODE_FIELD(sub_targetlist);
631
632         return true;
633 }
634
635
636 /*
637  * Stuff from parsenodes.h
638  */
639
640 static bool
641 _equalQuery(Query *a, Query *b)
642 {
643         COMPARE_SCALAR_FIELD(commandType);
644         COMPARE_SCALAR_FIELD(querySource);
645         COMPARE_SCALAR_FIELD(canSetTag);
646         COMPARE_NODE_FIELD(utilityStmt);
647         COMPARE_SCALAR_FIELD(resultRelation);
648         COMPARE_NODE_FIELD(into);
649         COMPARE_SCALAR_FIELD(intoHasOids);
650         COMPARE_SCALAR_FIELD(hasAggs);
651         COMPARE_SCALAR_FIELD(hasSubLinks);
652         COMPARE_NODE_FIELD(rtable);
653         COMPARE_NODE_FIELD(jointree);
654         COMPARE_NODE_FIELD(rowMarks);
655         COMPARE_NODE_FIELD(targetList);
656         COMPARE_NODE_FIELD(groupClause);
657         COMPARE_NODE_FIELD(havingQual);
658         COMPARE_NODE_FIELD(distinctClause);
659         COMPARE_NODE_FIELD(sortClause);
660         COMPARE_NODE_FIELD(limitOffset);
661         COMPARE_NODE_FIELD(limitCount);
662         COMPARE_NODE_FIELD(setOperations);
663         COMPARE_NODE_FIELD(resultRelations);
664
665         /*
666          * We do not check the planner-internal fields.  They might not be set
667          * yet, and in any case they should be derivable from the other fields.
668          */
669         return true;
670 }
671
672 static bool
673 _equalInsertStmt(InsertStmt *a, InsertStmt *b)
674 {
675         COMPARE_NODE_FIELD(relation);
676         COMPARE_NODE_FIELD(cols);
677         COMPARE_NODE_FIELD(targetList);
678         COMPARE_NODE_FIELD(selectStmt);
679
680         return true;
681 }
682
683 static bool
684 _equalDeleteStmt(DeleteStmt *a, DeleteStmt *b)
685 {
686         COMPARE_NODE_FIELD(relation);
687         COMPARE_NODE_FIELD(whereClause);
688
689         return true;
690 }
691
692 static bool
693 _equalUpdateStmt(UpdateStmt *a, UpdateStmt *b)
694 {
695         COMPARE_NODE_FIELD(relation);
696         COMPARE_NODE_FIELD(targetList);
697         COMPARE_NODE_FIELD(whereClause);
698         COMPARE_NODE_FIELD(fromClause);
699
700         return true;
701 }
702
703 static bool
704 _equalSelectStmt(SelectStmt *a, SelectStmt *b)
705 {
706         COMPARE_NODE_FIELD(distinctClause);
707         COMPARE_NODE_FIELD(into);
708         COMPARE_NODE_FIELD(intoColNames);
709         COMPARE_SCALAR_FIELD(intoHasOids);
710         COMPARE_NODE_FIELD(targetList);
711         COMPARE_NODE_FIELD(fromClause);
712         COMPARE_NODE_FIELD(whereClause);
713         COMPARE_NODE_FIELD(groupClause);
714         COMPARE_NODE_FIELD(havingClause);
715         COMPARE_NODE_FIELD(sortClause);
716         COMPARE_NODE_FIELD(limitOffset);
717         COMPARE_NODE_FIELD(limitCount);
718         COMPARE_NODE_FIELD(forUpdate);
719         COMPARE_SCALAR_FIELD(op);
720         COMPARE_SCALAR_FIELD(all);
721         COMPARE_NODE_FIELD(larg);
722         COMPARE_NODE_FIELD(rarg);
723
724         return true;
725 }
726
727 static bool
728 _equalSetOperationStmt(SetOperationStmt *a, SetOperationStmt *b)
729 {
730         COMPARE_SCALAR_FIELD(op);
731         COMPARE_SCALAR_FIELD(all);
732         COMPARE_NODE_FIELD(larg);
733         COMPARE_NODE_FIELD(rarg);
734         COMPARE_NODE_FIELD(colTypes);
735
736         return true;
737 }
738
739 static bool
740 _equalAlterTableStmt(AlterTableStmt *a, AlterTableStmt *b)
741 {
742         COMPARE_NODE_FIELD(relation);
743         COMPARE_NODE_FIELD(cmds);
744         COMPARE_SCALAR_FIELD(relkind);
745
746         return true;
747 }
748
749 static bool
750 _equalAlterTableCmd(AlterTableCmd *a, AlterTableCmd *b)
751 {
752         COMPARE_SCALAR_FIELD(subtype);
753         COMPARE_STRING_FIELD(name);
754         COMPARE_NODE_FIELD(def);
755         COMPARE_NODE_FIELD(transform);
756         COMPARE_SCALAR_FIELD(behavior);
757
758         return true;
759 }
760
761 static bool
762 _equalAlterDomainStmt(AlterDomainStmt *a, AlterDomainStmt *b)
763 {
764         COMPARE_SCALAR_FIELD(subtype);
765         COMPARE_NODE_FIELD(typename);
766         COMPARE_STRING_FIELD(name);
767         COMPARE_NODE_FIELD(def);
768         COMPARE_SCALAR_FIELD(behavior);
769
770         return true;
771 }
772
773 static bool
774 _equalGrantStmt(GrantStmt *a, GrantStmt *b)
775 {
776         COMPARE_SCALAR_FIELD(is_grant);
777         COMPARE_SCALAR_FIELD(objtype);
778         COMPARE_NODE_FIELD(objects);
779         COMPARE_NODE_FIELD(privileges);
780         COMPARE_NODE_FIELD(grantees);
781         COMPARE_SCALAR_FIELD(grant_option);
782         COMPARE_SCALAR_FIELD(behavior);
783
784         return true;
785 }
786
787 static bool
788 _equalPrivGrantee(PrivGrantee *a, PrivGrantee *b)
789 {
790         COMPARE_STRING_FIELD(username);
791         COMPARE_STRING_FIELD(groupname);
792
793         return true;
794 }
795
796 static bool
797 _equalFuncWithArgs(FuncWithArgs *a, FuncWithArgs *b)
798 {
799         COMPARE_NODE_FIELD(funcname);
800         COMPARE_NODE_FIELD(funcargs);
801
802         return true;
803 }
804
805 static bool
806 _equalDeclareCursorStmt(DeclareCursorStmt *a, DeclareCursorStmt *b)
807 {
808         COMPARE_STRING_FIELD(portalname);
809         COMPARE_SCALAR_FIELD(options);
810         COMPARE_NODE_FIELD(query);
811
812         return true;
813 }
814
815 static bool
816 _equalClosePortalStmt(ClosePortalStmt *a, ClosePortalStmt *b)
817 {
818         COMPARE_STRING_FIELD(portalname);
819
820         return true;
821 }
822
823 static bool
824 _equalClusterStmt(ClusterStmt *a, ClusterStmt *b)
825 {
826         COMPARE_NODE_FIELD(relation);
827         COMPARE_STRING_FIELD(indexname);
828
829         return true;
830 }
831
832 static bool
833 _equalCopyStmt(CopyStmt *a, CopyStmt *b)
834 {
835         COMPARE_NODE_FIELD(relation);
836         COMPARE_NODE_FIELD(attlist);
837         COMPARE_SCALAR_FIELD(is_from);
838         COMPARE_STRING_FIELD(filename);
839         COMPARE_NODE_FIELD(options);
840
841         return true;
842 }
843
844 static bool
845 _equalCreateStmt(CreateStmt *a, CreateStmt *b)
846 {
847         COMPARE_NODE_FIELD(relation);
848         COMPARE_NODE_FIELD(tableElts);
849         COMPARE_NODE_FIELD(inhRelations);
850         COMPARE_NODE_FIELD(constraints);
851         COMPARE_SCALAR_FIELD(hasoids);
852         COMPARE_SCALAR_FIELD(oncommit);
853         COMPARE_STRING_FIELD(tablespacename);
854
855         return true;
856 }
857
858 static bool
859 _equalInhRelation(InhRelation *a, InhRelation *b)
860 {
861         COMPARE_NODE_FIELD(relation);
862         COMPARE_SCALAR_FIELD(including_defaults);
863
864         return true;
865 }
866
867 static bool
868 _equalDefineStmt(DefineStmt *a, DefineStmt *b)
869 {
870         COMPARE_SCALAR_FIELD(kind);
871         COMPARE_NODE_FIELD(defnames);
872         COMPARE_NODE_FIELD(definition);
873
874         return true;
875 }
876
877 static bool
878 _equalDropStmt(DropStmt *a, DropStmt *b)
879 {
880         COMPARE_NODE_FIELD(objects);
881         COMPARE_SCALAR_FIELD(removeType);
882         COMPARE_SCALAR_FIELD(behavior);
883
884         return true;
885 }
886
887 static bool
888 _equalTruncateStmt(TruncateStmt *a, TruncateStmt *b)
889 {
890         COMPARE_NODE_FIELD(relations);
891
892         return true;
893 }
894
895 static bool
896 _equalCommentStmt(CommentStmt *a, CommentStmt *b)
897 {
898         COMPARE_SCALAR_FIELD(objtype);
899         COMPARE_NODE_FIELD(objname);
900         COMPARE_NODE_FIELD(objargs);
901         COMPARE_STRING_FIELD(comment);
902
903         return true;
904 }
905
906 static bool
907 _equalFetchStmt(FetchStmt *a, FetchStmt *b)
908 {
909         COMPARE_SCALAR_FIELD(direction);
910         COMPARE_SCALAR_FIELD(howMany);
911         COMPARE_STRING_FIELD(portalname);
912         COMPARE_SCALAR_FIELD(ismove);
913
914         return true;
915 }
916
917 static bool
918 _equalIndexStmt(IndexStmt *a, IndexStmt *b)
919 {
920         COMPARE_STRING_FIELD(idxname);
921         COMPARE_NODE_FIELD(relation);
922         COMPARE_STRING_FIELD(accessMethod);
923         COMPARE_STRING_FIELD(tableSpace);
924         COMPARE_NODE_FIELD(indexParams);
925         COMPARE_NODE_FIELD(whereClause);
926         COMPARE_NODE_FIELD(rangetable);
927         COMPARE_SCALAR_FIELD(unique);
928         COMPARE_SCALAR_FIELD(primary);
929         COMPARE_SCALAR_FIELD(isconstraint);
930
931         return true;
932 }
933
934 static bool
935 _equalCreateFunctionStmt(CreateFunctionStmt *a, CreateFunctionStmt *b)
936 {
937         COMPARE_SCALAR_FIELD(replace);
938         COMPARE_NODE_FIELD(funcname);
939         COMPARE_NODE_FIELD(parameters);
940         COMPARE_NODE_FIELD(returnType);
941         COMPARE_NODE_FIELD(options);
942         COMPARE_NODE_FIELD(withClause);
943
944         return true;
945 }
946
947 static bool
948 _equalFunctionParameter(FunctionParameter *a, FunctionParameter *b)
949 {
950         COMPARE_STRING_FIELD(name);
951         COMPARE_NODE_FIELD(argType);
952
953         return true;
954 }
955
956 static bool
957 _equalRemoveAggrStmt(RemoveAggrStmt *a, RemoveAggrStmt *b)
958 {
959         COMPARE_NODE_FIELD(aggname);
960         COMPARE_NODE_FIELD(aggtype);
961         COMPARE_SCALAR_FIELD(behavior);
962
963         return true;
964 }
965
966 static bool
967 _equalRemoveFuncStmt(RemoveFuncStmt *a, RemoveFuncStmt *b)
968 {
969         COMPARE_NODE_FIELD(funcname);
970         COMPARE_NODE_FIELD(args);
971         COMPARE_SCALAR_FIELD(behavior);
972
973         return true;
974 }
975
976 static bool
977 _equalRemoveOperStmt(RemoveOperStmt *a, RemoveOperStmt *b)
978 {
979         COMPARE_NODE_FIELD(opname);
980         COMPARE_NODE_FIELD(args);
981         COMPARE_SCALAR_FIELD(behavior);
982
983         return true;
984 }
985
986 static bool
987 _equalRemoveOpClassStmt(RemoveOpClassStmt *a, RemoveOpClassStmt *b)
988 {
989         COMPARE_NODE_FIELD(opclassname);
990         COMPARE_STRING_FIELD(amname);
991         COMPARE_SCALAR_FIELD(behavior);
992
993         return true;
994 }
995
996 static bool
997 _equalRenameStmt(RenameStmt *a, RenameStmt *b)
998 {
999         COMPARE_NODE_FIELD(relation);
1000         COMPARE_NODE_FIELD(object);
1001         COMPARE_NODE_FIELD(objarg);
1002         COMPARE_STRING_FIELD(subname);
1003         COMPARE_STRING_FIELD(newname);
1004         COMPARE_SCALAR_FIELD(renameType);
1005
1006         return true;
1007 }
1008
1009 static bool
1010 _equalAlterOwnerStmt(AlterOwnerStmt *a, AlterOwnerStmt *b)
1011 {
1012         COMPARE_NODE_FIELD(relation);
1013         COMPARE_NODE_FIELD(object);
1014         COMPARE_NODE_FIELD(objarg);
1015         COMPARE_STRING_FIELD(addname);
1016         COMPARE_STRING_FIELD(newowner);
1017         COMPARE_SCALAR_FIELD(objectType);
1018
1019         return true;
1020 }
1021
1022 static bool
1023 _equalRuleStmt(RuleStmt *a, RuleStmt *b)
1024 {
1025         COMPARE_NODE_FIELD(relation);
1026         COMPARE_STRING_FIELD(rulename);
1027         COMPARE_NODE_FIELD(whereClause);
1028         COMPARE_SCALAR_FIELD(event);
1029         COMPARE_SCALAR_FIELD(instead);
1030         COMPARE_NODE_FIELD(actions);
1031         COMPARE_SCALAR_FIELD(replace);
1032
1033         return true;
1034 }
1035
1036 static bool
1037 _equalNotifyStmt(NotifyStmt *a, NotifyStmt *b)
1038 {
1039         COMPARE_NODE_FIELD(relation);
1040
1041         return true;
1042 }
1043
1044 static bool
1045 _equalListenStmt(ListenStmt *a, ListenStmt *b)
1046 {
1047         COMPARE_NODE_FIELD(relation);
1048
1049         return true;
1050 }
1051
1052 static bool
1053 _equalUnlistenStmt(UnlistenStmt *a, UnlistenStmt *b)
1054 {
1055         COMPARE_NODE_FIELD(relation);
1056
1057         return true;
1058 }
1059
1060 static bool
1061 _equalTransactionStmt(TransactionStmt *a, TransactionStmt *b)
1062 {
1063         COMPARE_SCALAR_FIELD(kind);
1064         COMPARE_NODE_FIELD(options);
1065
1066         return true;
1067 }
1068
1069 static bool
1070 _equalCompositeTypeStmt(CompositeTypeStmt *a, CompositeTypeStmt *b)
1071 {
1072         COMPARE_NODE_FIELD(typevar);
1073         COMPARE_NODE_FIELD(coldeflist);
1074
1075         return true;
1076 }
1077
1078 static bool
1079 _equalViewStmt(ViewStmt *a, ViewStmt *b)
1080 {
1081         COMPARE_NODE_FIELD(view);
1082         COMPARE_NODE_FIELD(aliases);
1083         COMPARE_NODE_FIELD(query);
1084         COMPARE_SCALAR_FIELD(replace);
1085
1086         return true;
1087 }
1088
1089 static bool
1090 _equalLoadStmt(LoadStmt *a, LoadStmt *b)
1091 {
1092         COMPARE_STRING_FIELD(filename);
1093
1094         return true;
1095 }
1096
1097 static bool
1098 _equalCreateDomainStmt(CreateDomainStmt *a, CreateDomainStmt *b)
1099 {
1100         COMPARE_NODE_FIELD(domainname);
1101         COMPARE_NODE_FIELD(typename);
1102         COMPARE_NODE_FIELD(constraints);
1103
1104         return true;
1105 }
1106
1107 static bool
1108 _equalCreateOpClassStmt(CreateOpClassStmt *a, CreateOpClassStmt *b)
1109 {
1110         COMPARE_NODE_FIELD(opclassname);
1111         COMPARE_STRING_FIELD(amname);
1112         COMPARE_NODE_FIELD(datatype);
1113         COMPARE_NODE_FIELD(items);
1114         COMPARE_SCALAR_FIELD(isDefault);
1115
1116         return true;
1117 }
1118
1119 static bool
1120 _equalCreateOpClassItem(CreateOpClassItem *a, CreateOpClassItem *b)
1121 {
1122         COMPARE_SCALAR_FIELD(itemtype);
1123         COMPARE_NODE_FIELD(name);
1124         COMPARE_NODE_FIELD(args);
1125         COMPARE_SCALAR_FIELD(number);
1126         COMPARE_SCALAR_FIELD(recheck);
1127         COMPARE_NODE_FIELD(storedtype);
1128
1129         return true;
1130 }
1131
1132 static bool
1133 _equalCreatedbStmt(CreatedbStmt *a, CreatedbStmt *b)
1134 {
1135         COMPARE_STRING_FIELD(dbname);
1136         COMPARE_NODE_FIELD(options);
1137
1138         return true;
1139 }
1140
1141 static bool
1142 _equalAlterDatabaseSetStmt(AlterDatabaseSetStmt *a, AlterDatabaseSetStmt *b)
1143 {
1144         COMPARE_STRING_FIELD(dbname);
1145         COMPARE_STRING_FIELD(variable);
1146         COMPARE_NODE_FIELD(value);
1147
1148         return true;
1149 }
1150
1151 static bool
1152 _equalDropdbStmt(DropdbStmt *a, DropdbStmt *b)
1153 {
1154         COMPARE_STRING_FIELD(dbname);
1155
1156         return true;
1157 }
1158
1159 static bool
1160 _equalVacuumStmt(VacuumStmt *a, VacuumStmt *b)
1161 {
1162         COMPARE_SCALAR_FIELD(vacuum);
1163         COMPARE_SCALAR_FIELD(full);
1164         COMPARE_SCALAR_FIELD(analyze);
1165         COMPARE_SCALAR_FIELD(freeze);
1166         COMPARE_SCALAR_FIELD(verbose);
1167         COMPARE_NODE_FIELD(relation);
1168         COMPARE_NODE_FIELD(va_cols);
1169
1170         return true;
1171 }
1172
1173 static bool
1174 _equalExplainStmt(ExplainStmt *a, ExplainStmt *b)
1175 {
1176         COMPARE_NODE_FIELD(query);
1177         COMPARE_SCALAR_FIELD(verbose);
1178         COMPARE_SCALAR_FIELD(analyze);
1179
1180         return true;
1181 }
1182
1183 static bool
1184 _equalCreateSeqStmt(CreateSeqStmt *a, CreateSeqStmt *b)
1185 {
1186         COMPARE_NODE_FIELD(sequence);
1187         COMPARE_NODE_FIELD(options);
1188
1189         return true;
1190 }
1191
1192 static bool
1193 _equalAlterSeqStmt(AlterSeqStmt *a, AlterSeqStmt *b)
1194 {
1195         COMPARE_NODE_FIELD(sequence);
1196         COMPARE_NODE_FIELD(options);
1197
1198         return true;
1199 }
1200
1201 static bool
1202 _equalVariableSetStmt(VariableSetStmt *a, VariableSetStmt *b)
1203 {
1204         COMPARE_STRING_FIELD(name);
1205         COMPARE_NODE_FIELD(args);
1206         COMPARE_SCALAR_FIELD(is_local);
1207
1208         return true;
1209 }
1210
1211 static bool
1212 _equalVariableShowStmt(VariableShowStmt *a, VariableShowStmt *b)
1213 {
1214         COMPARE_STRING_FIELD(name);
1215
1216         return true;
1217 }
1218
1219 static bool
1220 _equalVariableResetStmt(VariableResetStmt *a, VariableResetStmt *b)
1221 {
1222         COMPARE_STRING_FIELD(name);
1223
1224         return true;
1225 }
1226
1227 static bool
1228 _equalCreateTableSpaceStmt(CreateTableSpaceStmt *a, CreateTableSpaceStmt *b)
1229 {
1230         COMPARE_STRING_FIELD(tablespacename);
1231         COMPARE_STRING_FIELD(owner);
1232         COMPARE_STRING_FIELD(location);
1233
1234         return true;
1235 }
1236
1237 static bool
1238 _equalDropTableSpaceStmt(DropTableSpaceStmt *a, DropTableSpaceStmt *b)
1239 {
1240         COMPARE_STRING_FIELD(tablespacename);
1241
1242         return true;
1243 }
1244
1245 static bool
1246 _equalCreateTrigStmt(CreateTrigStmt *a, CreateTrigStmt *b)
1247 {
1248         COMPARE_STRING_FIELD(trigname);
1249         COMPARE_NODE_FIELD(relation);
1250         COMPARE_NODE_FIELD(funcname);
1251         COMPARE_NODE_FIELD(args);
1252         COMPARE_SCALAR_FIELD(before);
1253         COMPARE_SCALAR_FIELD(row);
1254         if (strcmp(a->actions, b->actions) != 0)        /* in-line string field */
1255                 return false;
1256         COMPARE_SCALAR_FIELD(isconstraint);
1257         COMPARE_SCALAR_FIELD(deferrable);
1258         COMPARE_SCALAR_FIELD(initdeferred);
1259         COMPARE_NODE_FIELD(constrrel);
1260
1261         return true;
1262 }
1263
1264 static bool
1265 _equalDropPropertyStmt(DropPropertyStmt *a, DropPropertyStmt *b)
1266 {
1267         COMPARE_NODE_FIELD(relation);
1268         COMPARE_STRING_FIELD(property);
1269         COMPARE_SCALAR_FIELD(removeType);
1270         COMPARE_SCALAR_FIELD(behavior);
1271
1272         return true;
1273 }
1274
1275 static bool
1276 _equalCreatePLangStmt(CreatePLangStmt *a, CreatePLangStmt *b)
1277 {
1278         COMPARE_STRING_FIELD(plname);
1279         COMPARE_NODE_FIELD(plhandler);
1280         COMPARE_NODE_FIELD(plvalidator);
1281         COMPARE_SCALAR_FIELD(pltrusted);
1282
1283         return true;
1284 }
1285
1286 static bool
1287 _equalDropPLangStmt(DropPLangStmt *a, DropPLangStmt *b)
1288 {
1289         COMPARE_STRING_FIELD(plname);
1290         COMPARE_SCALAR_FIELD(behavior);
1291
1292         return true;
1293 }
1294
1295 static bool
1296 _equalCreateUserStmt(CreateUserStmt *a, CreateUserStmt *b)
1297 {
1298         COMPARE_STRING_FIELD(user);
1299         COMPARE_NODE_FIELD(options);
1300
1301         return true;
1302 }
1303
1304 static bool
1305 _equalAlterUserStmt(AlterUserStmt *a, AlterUserStmt *b)
1306 {
1307         COMPARE_STRING_FIELD(user);
1308         COMPARE_NODE_FIELD(options);
1309
1310         return true;
1311 }
1312
1313 static bool
1314 _equalAlterUserSetStmt(AlterUserSetStmt *a, AlterUserSetStmt *b)
1315 {
1316         COMPARE_STRING_FIELD(user);
1317         COMPARE_STRING_FIELD(variable);
1318         COMPARE_NODE_FIELD(value);
1319
1320         return true;
1321 }
1322
1323 static bool
1324 _equalDropUserStmt(DropUserStmt *a, DropUserStmt *b)
1325 {
1326         COMPARE_NODE_FIELD(users);
1327
1328         return true;
1329 }
1330
1331 static bool
1332 _equalLockStmt(LockStmt *a, LockStmt *b)
1333 {
1334         COMPARE_NODE_FIELD(relations);
1335         COMPARE_SCALAR_FIELD(mode);
1336         COMPARE_SCALAR_FIELD(nowait);
1337
1338         return true;
1339 }
1340
1341 static bool
1342 _equalConstraintsSetStmt(ConstraintsSetStmt *a, ConstraintsSetStmt *b)
1343 {
1344         COMPARE_NODE_FIELD(constraints);
1345         COMPARE_SCALAR_FIELD(deferred);
1346
1347         return true;
1348 }
1349
1350 static bool
1351 _equalCreateGroupStmt(CreateGroupStmt *a, CreateGroupStmt *b)
1352 {
1353         COMPARE_STRING_FIELD(name);
1354         COMPARE_NODE_FIELD(options);
1355
1356         return true;
1357 }
1358
1359 static bool
1360 _equalAlterGroupStmt(AlterGroupStmt *a, AlterGroupStmt *b)
1361 {
1362         COMPARE_STRING_FIELD(name);
1363         COMPARE_SCALAR_FIELD(action);
1364         COMPARE_NODE_FIELD(listUsers);
1365
1366         return true;
1367 }
1368
1369 static bool
1370 _equalDropGroupStmt(DropGroupStmt *a, DropGroupStmt *b)
1371 {
1372         COMPARE_STRING_FIELD(name);
1373
1374         return true;
1375 }
1376
1377 static bool
1378 _equalReindexStmt(ReindexStmt *a, ReindexStmt *b)
1379 {
1380         COMPARE_SCALAR_FIELD(kind);
1381         COMPARE_NODE_FIELD(relation);
1382         COMPARE_STRING_FIELD(name);
1383         COMPARE_SCALAR_FIELD(force);
1384         COMPARE_SCALAR_FIELD(all);
1385
1386         return true;
1387 }
1388
1389 static bool
1390 _equalCreateSchemaStmt(CreateSchemaStmt *a, CreateSchemaStmt *b)
1391 {
1392         COMPARE_STRING_FIELD(schemaname);
1393         COMPARE_STRING_FIELD(authid);
1394         COMPARE_NODE_FIELD(schemaElts);
1395
1396         return true;
1397 }
1398
1399 static bool
1400 _equalCreateConversionStmt(CreateConversionStmt *a, CreateConversionStmt *b)
1401 {
1402         COMPARE_NODE_FIELD(conversion_name);
1403         COMPARE_STRING_FIELD(for_encoding_name);
1404         COMPARE_STRING_FIELD(to_encoding_name);
1405         COMPARE_NODE_FIELD(func_name);
1406         COMPARE_SCALAR_FIELD(def);
1407
1408         return true;
1409 }
1410
1411 static bool
1412 _equalCreateCastStmt(CreateCastStmt *a, CreateCastStmt *b)
1413 {
1414         COMPARE_NODE_FIELD(sourcetype);
1415         COMPARE_NODE_FIELD(targettype);
1416         COMPARE_NODE_FIELD(func);
1417         COMPARE_SCALAR_FIELD(context);
1418
1419         return true;
1420 }
1421
1422 static bool
1423 _equalDropCastStmt(DropCastStmt *a, DropCastStmt *b)
1424 {
1425         COMPARE_NODE_FIELD(sourcetype);
1426         COMPARE_NODE_FIELD(targettype);
1427         COMPARE_SCALAR_FIELD(behavior);
1428
1429         return true;
1430 }
1431
1432 static bool
1433 _equalPrepareStmt(PrepareStmt *a, PrepareStmt *b)
1434 {
1435         COMPARE_STRING_FIELD(name);
1436         COMPARE_NODE_FIELD(argtypes);
1437         COMPARE_NODE_FIELD(argtype_oids);
1438         COMPARE_NODE_FIELD(query);
1439
1440         return true;
1441 }
1442
1443 static bool
1444 _equalExecuteStmt(ExecuteStmt *a, ExecuteStmt *b)
1445 {
1446         COMPARE_STRING_FIELD(name);
1447         COMPARE_NODE_FIELD(into);
1448         COMPARE_NODE_FIELD(params);
1449
1450         return true;
1451 }
1452
1453 static bool
1454 _equalDeallocateStmt(DeallocateStmt *a, DeallocateStmt *b)
1455 {
1456         COMPARE_STRING_FIELD(name);
1457
1458         return true;
1459 }
1460
1461
1462 /*
1463  * stuff from parsenodes.h
1464  */
1465
1466 static bool
1467 _equalAExpr(A_Expr *a, A_Expr *b)
1468 {
1469         COMPARE_SCALAR_FIELD(kind);
1470         COMPARE_NODE_FIELD(name);
1471         COMPARE_NODE_FIELD(lexpr);
1472         COMPARE_NODE_FIELD(rexpr);
1473
1474         return true;
1475 }
1476
1477 static bool
1478 _equalColumnRef(ColumnRef *a, ColumnRef *b)
1479 {
1480         COMPARE_NODE_FIELD(fields);
1481
1482         return true;
1483 }
1484
1485 static bool
1486 _equalParamRef(ParamRef *a, ParamRef *b)
1487 {
1488         COMPARE_SCALAR_FIELD(number);
1489
1490         return true;
1491 }
1492
1493 static bool
1494 _equalAConst(A_Const *a, A_Const *b)
1495 {
1496         if (!equal(&a->val, &b->val))           /* hack for in-line Value field */
1497                 return false;
1498         COMPARE_NODE_FIELD(typename);
1499
1500         return true;
1501 }
1502
1503 static bool
1504 _equalFuncCall(FuncCall *a, FuncCall *b)
1505 {
1506         COMPARE_NODE_FIELD(funcname);
1507         COMPARE_NODE_FIELD(args);
1508         COMPARE_SCALAR_FIELD(agg_star);
1509         COMPARE_SCALAR_FIELD(agg_distinct);
1510
1511         return true;
1512 }
1513
1514 static bool
1515 _equalAIndices(A_Indices *a, A_Indices *b)
1516 {
1517         COMPARE_NODE_FIELD(lidx);
1518         COMPARE_NODE_FIELD(uidx);
1519
1520         return true;
1521 }
1522
1523 static bool
1524 _equalA_Indirection(A_Indirection *a, A_Indirection *b)
1525 {
1526         COMPARE_NODE_FIELD(arg);
1527         COMPARE_NODE_FIELD(indirection);
1528
1529         return true;
1530 }
1531
1532 static bool
1533 _equalResTarget(ResTarget *a, ResTarget *b)
1534 {
1535         COMPARE_STRING_FIELD(name);
1536         COMPARE_NODE_FIELD(indirection);
1537         COMPARE_NODE_FIELD(val);
1538
1539         return true;
1540 }
1541
1542 static bool
1543 _equalTypeName(TypeName *a, TypeName *b)
1544 {
1545         COMPARE_NODE_FIELD(names);
1546         COMPARE_SCALAR_FIELD(typeid);
1547         COMPARE_SCALAR_FIELD(timezone);
1548         COMPARE_SCALAR_FIELD(setof);
1549         COMPARE_SCALAR_FIELD(pct_type);
1550         COMPARE_SCALAR_FIELD(typmod);
1551         COMPARE_NODE_FIELD(arrayBounds);
1552
1553         return true;
1554 }
1555
1556 static bool
1557 _equalTypeCast(TypeCast *a, TypeCast *b)
1558 {
1559         COMPARE_NODE_FIELD(arg);
1560         COMPARE_NODE_FIELD(typename);
1561
1562         return true;
1563 }
1564
1565 static bool
1566 _equalSortBy(SortBy *a, SortBy *b)
1567 {
1568         COMPARE_SCALAR_FIELD(sortby_kind);
1569         COMPARE_NODE_FIELD(useOp);
1570         COMPARE_NODE_FIELD(node);
1571
1572         return true;
1573 }
1574
1575 static bool
1576 _equalRangeSubselect(RangeSubselect *a, RangeSubselect *b)
1577 {
1578         COMPARE_NODE_FIELD(subquery);
1579         COMPARE_NODE_FIELD(alias);
1580
1581         return true;
1582 }
1583
1584 static bool
1585 _equalRangeFunction(RangeFunction *a, RangeFunction *b)
1586 {
1587         COMPARE_NODE_FIELD(funccallnode);
1588         COMPARE_NODE_FIELD(alias);
1589         COMPARE_NODE_FIELD(coldeflist);
1590
1591         return true;
1592 }
1593
1594 static bool
1595 _equalIndexElem(IndexElem *a, IndexElem *b)
1596 {
1597         COMPARE_STRING_FIELD(name);
1598         COMPARE_NODE_FIELD(expr);
1599         COMPARE_NODE_FIELD(opclass);
1600
1601         return true;
1602 }
1603
1604 static bool
1605 _equalColumnDef(ColumnDef *a, ColumnDef *b)
1606 {
1607         COMPARE_STRING_FIELD(colname);
1608         COMPARE_NODE_FIELD(typename);
1609         COMPARE_SCALAR_FIELD(inhcount);
1610         COMPARE_SCALAR_FIELD(is_local);
1611         COMPARE_SCALAR_FIELD(is_not_null);
1612         COMPARE_NODE_FIELD(raw_default);
1613         COMPARE_STRING_FIELD(cooked_default);
1614         COMPARE_NODE_FIELD(constraints);
1615         COMPARE_NODE_FIELD(support);
1616
1617         return true;
1618 }
1619
1620 static bool
1621 _equalConstraint(Constraint *a, Constraint *b)
1622 {
1623         COMPARE_SCALAR_FIELD(contype);
1624         COMPARE_STRING_FIELD(name);
1625         COMPARE_NODE_FIELD(raw_expr);
1626         COMPARE_STRING_FIELD(cooked_expr);
1627         COMPARE_NODE_FIELD(keys);
1628         COMPARE_STRING_FIELD(indexspace);
1629
1630         return true;
1631 }
1632
1633 static bool
1634 _equalDefElem(DefElem *a, DefElem *b)
1635 {
1636         COMPARE_STRING_FIELD(defname);
1637         COMPARE_NODE_FIELD(arg);
1638
1639         return true;
1640 }
1641
1642 static bool
1643 _equalRangeTblEntry(RangeTblEntry *a, RangeTblEntry *b)
1644 {
1645         COMPARE_SCALAR_FIELD(rtekind);
1646         COMPARE_SCALAR_FIELD(relid);
1647         COMPARE_NODE_FIELD(subquery);
1648         COMPARE_NODE_FIELD(funcexpr);
1649         COMPARE_NODE_FIELD(coldeflist);
1650         COMPARE_SCALAR_FIELD(jointype);
1651         COMPARE_NODE_FIELD(joinaliasvars);
1652         COMPARE_NODE_FIELD(alias);
1653         COMPARE_NODE_FIELD(eref);
1654         COMPARE_SCALAR_FIELD(inh);
1655         COMPARE_SCALAR_FIELD(inFromCl);
1656         COMPARE_SCALAR_FIELD(requiredPerms);
1657         COMPARE_SCALAR_FIELD(checkAsUser);
1658
1659         return true;
1660 }
1661
1662 static bool
1663 _equalSortClause(SortClause *a, SortClause *b)
1664 {
1665         COMPARE_SCALAR_FIELD(tleSortGroupRef);
1666         COMPARE_SCALAR_FIELD(sortop);
1667
1668         return true;
1669 }
1670
1671 static bool
1672 _equalFkConstraint(FkConstraint *a, FkConstraint *b)
1673 {
1674         COMPARE_STRING_FIELD(constr_name);
1675         COMPARE_NODE_FIELD(pktable);
1676         COMPARE_NODE_FIELD(fk_attrs);
1677         COMPARE_NODE_FIELD(pk_attrs);
1678         COMPARE_SCALAR_FIELD(fk_matchtype);
1679         COMPARE_SCALAR_FIELD(fk_upd_action);
1680         COMPARE_SCALAR_FIELD(fk_del_action);
1681         COMPARE_SCALAR_FIELD(deferrable);
1682         COMPARE_SCALAR_FIELD(initdeferred);
1683         COMPARE_SCALAR_FIELD(skip_validation);
1684
1685         return true;
1686 }
1687
1688
1689 /*
1690  * Stuff from pg_list.h
1691  */
1692
1693 static bool
1694 _equalList(List *a, List *b)
1695 {
1696         ListCell   *item_a;
1697         ListCell   *item_b;
1698
1699         /*
1700          * Try to reject by simple scalar checks before grovelling through all
1701          * the list elements...
1702          */
1703         COMPARE_SCALAR_FIELD(type);
1704         COMPARE_SCALAR_FIELD(length);
1705
1706         /*
1707          * We place the switch outside the loop for the sake of efficiency;
1708          * this may not be worth doing...
1709          */
1710         switch (a->type)
1711         {
1712                 case T_List:
1713                         forboth(item_a, a, item_b, b)
1714                         {
1715                                 if (!equal(lfirst(item_a), lfirst(item_b)))
1716                                         return false;
1717                         }
1718                         break;
1719                 case T_IntList:
1720                         forboth(item_a, a, item_b, b)
1721                         {
1722                                 if (lfirst_int(item_a) != lfirst_int(item_b))
1723                                         return false;
1724                         }
1725                         break;
1726                 case T_OidList:
1727                         forboth(item_a, a, item_b, b)
1728                         {
1729                                 if (lfirst_oid(item_a) != lfirst_oid(item_b))
1730                                         return false;
1731                         }
1732                         break;
1733                 default:
1734                         elog(ERROR, "unrecognized list node type: %d",
1735                                  (int) a->type);
1736                         return false;           /* keep compiler quiet */
1737         }
1738
1739         /*
1740          * If we got here, we should have run out of elements of both lists
1741          */
1742         Assert(item_a == NULL);
1743         Assert(item_b == NULL);
1744
1745         return true;
1746 }
1747
1748 /*
1749  * Stuff from value.h
1750  */
1751
1752 static bool
1753 _equalValue(Value *a, Value *b)
1754 {
1755         COMPARE_SCALAR_FIELD(type);
1756
1757         switch (a->type)
1758         {
1759                 case T_Integer:
1760                         COMPARE_SCALAR_FIELD(val.ival);
1761                         break;
1762                 case T_Float:
1763                 case T_String:
1764                 case T_BitString:
1765                         COMPARE_STRING_FIELD(val.str);
1766                         break;
1767                 case T_Null:
1768                         /* nothing to do */
1769                         break;
1770                 default:
1771                         elog(ERROR, "unrecognized node type: %d", (int) a->type);
1772                         break;
1773         }
1774
1775         return true;
1776 }
1777
1778 /*
1779  * equal
1780  *        returns whether two nodes are equal
1781  */
1782 bool
1783 equal(void *a, void *b)
1784 {
1785         bool            retval;
1786
1787         if (a == b)
1788                 return true;
1789
1790         /*
1791          * note that a!=b, so only one of them can be NULL
1792          */
1793         if (a == NULL || b == NULL)
1794                 return false;
1795
1796         /*
1797          * are they the same type of nodes?
1798          */
1799         if (nodeTag(a) != nodeTag(b))
1800                 return false;
1801
1802         switch (nodeTag(a))
1803         {
1804                         /*
1805                          * PRIMITIVE NODES
1806                          */
1807                 case T_Resdom:
1808                         retval = _equalResdom(a, b);
1809                         break;
1810                 case T_Alias:
1811                         retval = _equalAlias(a, b);
1812                         break;
1813                 case T_RangeVar:
1814                         retval = _equalRangeVar(a, b);
1815                         break;
1816                 case T_Var:
1817                         retval = _equalVar(a, b);
1818                         break;
1819                 case T_Const:
1820                         retval = _equalConst(a, b);
1821                         break;
1822                 case T_Param:
1823                         retval = _equalParam(a, b);
1824                         break;
1825                 case T_Aggref:
1826                         retval = _equalAggref(a, b);
1827                         break;
1828                 case T_ArrayRef:
1829                         retval = _equalArrayRef(a, b);
1830                         break;
1831                 case T_FuncExpr:
1832                         retval = _equalFuncExpr(a, b);
1833                         break;
1834                 case T_OpExpr:
1835                         retval = _equalOpExpr(a, b);
1836                         break;
1837                 case T_DistinctExpr:
1838                         retval = _equalDistinctExpr(a, b);
1839                         break;
1840                 case T_ScalarArrayOpExpr:
1841                         retval = _equalScalarArrayOpExpr(a, b);
1842                         break;
1843                 case T_BoolExpr:
1844                         retval = _equalBoolExpr(a, b);
1845                         break;
1846                 case T_SubLink:
1847                         retval = _equalSubLink(a, b);
1848                         break;
1849                 case T_SubPlan:
1850                         retval = _equalSubPlan(a, b);
1851                         break;
1852                 case T_FieldSelect:
1853                         retval = _equalFieldSelect(a, b);
1854                         break;
1855                 case T_FieldStore:
1856                         retval = _equalFieldStore(a, b);
1857                         break;
1858                 case T_RelabelType:
1859                         retval = _equalRelabelType(a, b);
1860                         break;
1861                 case T_ConvertRowtypeExpr:
1862                         retval = _equalConvertRowtypeExpr(a, b);
1863                         break;
1864                 case T_CaseExpr:
1865                         retval = _equalCaseExpr(a, b);
1866                         break;
1867                 case T_CaseWhen:
1868                         retval = _equalCaseWhen(a, b);
1869                         break;
1870                 case T_CaseTestExpr:
1871                         retval = _equalCaseTestExpr(a, b);
1872                         break;
1873                 case T_ArrayExpr:
1874                         retval = _equalArrayExpr(a, b);
1875                         break;
1876                 case T_RowExpr:
1877                         retval = _equalRowExpr(a, b);
1878                         break;
1879                 case T_CoalesceExpr:
1880                         retval = _equalCoalesceExpr(a, b);
1881                         break;
1882                 case T_NullIfExpr:
1883                         retval = _equalNullIfExpr(a, b);
1884                         break;
1885                 case T_NullTest:
1886                         retval = _equalNullTest(a, b);
1887                         break;
1888                 case T_BooleanTest:
1889                         retval = _equalBooleanTest(a, b);
1890                         break;
1891                 case T_CoerceToDomain:
1892                         retval = _equalCoerceToDomain(a, b);
1893                         break;
1894                 case T_CoerceToDomainValue:
1895                         retval = _equalCoerceToDomainValue(a, b);
1896                         break;
1897                 case T_SetToDefault:
1898                         retval = _equalSetToDefault(a, b);
1899                         break;
1900                 case T_TargetEntry:
1901                         retval = _equalTargetEntry(a, b);
1902                         break;
1903                 case T_RangeTblRef:
1904                         retval = _equalRangeTblRef(a, b);
1905                         break;
1906                 case T_FromExpr:
1907                         retval = _equalFromExpr(a, b);
1908                         break;
1909                 case T_JoinExpr:
1910                         retval = _equalJoinExpr(a, b);
1911                         break;
1912
1913                         /*
1914                          * RELATION NODES
1915                          */
1916                 case T_PathKeyItem:
1917                         retval = _equalPathKeyItem(a, b);
1918                         break;
1919                 case T_RestrictInfo:
1920                         retval = _equalRestrictInfo(a, b);
1921                         break;
1922                 case T_JoinInfo:
1923                         retval = _equalJoinInfo(a, b);
1924                         break;
1925                 case T_InClauseInfo:
1926                         retval = _equalInClauseInfo(a, b);
1927                         break;
1928                 case T_List:
1929                 case T_IntList:
1930                 case T_OidList:
1931                         retval = _equalList(a, b);
1932                         break;
1933
1934                 case T_Integer:
1935                 case T_Float:
1936                 case T_String:
1937                 case T_BitString:
1938                 case T_Null:
1939                         retval = _equalValue(a, b);
1940                         break;
1941
1942                         /*
1943                          * PARSE NODES
1944                          */
1945                 case T_Query:
1946                         retval = _equalQuery(a, b);
1947                         break;
1948                 case T_InsertStmt:
1949                         retval = _equalInsertStmt(a, b);
1950                         break;
1951                 case T_DeleteStmt:
1952                         retval = _equalDeleteStmt(a, b);
1953                         break;
1954                 case T_UpdateStmt:
1955                         retval = _equalUpdateStmt(a, b);
1956                         break;
1957                 case T_SelectStmt:
1958                         retval = _equalSelectStmt(a, b);
1959                         break;
1960                 case T_SetOperationStmt:
1961                         retval = _equalSetOperationStmt(a, b);
1962                         break;
1963                 case T_AlterTableStmt:
1964                         retval = _equalAlterTableStmt(a, b);
1965                         break;
1966                 case T_AlterTableCmd:
1967                         retval = _equalAlterTableCmd(a, b);
1968                         break;
1969                 case T_AlterDomainStmt:
1970                         retval = _equalAlterDomainStmt(a, b);
1971                         break;
1972                 case T_GrantStmt:
1973                         retval = _equalGrantStmt(a, b);
1974                         break;
1975                 case T_DeclareCursorStmt:
1976                         retval = _equalDeclareCursorStmt(a, b);
1977                         break;
1978                 case T_ClosePortalStmt:
1979                         retval = _equalClosePortalStmt(a, b);
1980                         break;
1981                 case T_ClusterStmt:
1982                         retval = _equalClusterStmt(a, b);
1983                         break;
1984                 case T_CopyStmt:
1985                         retval = _equalCopyStmt(a, b);
1986                         break;
1987                 case T_CreateStmt:
1988                         retval = _equalCreateStmt(a, b);
1989                         break;
1990                 case T_InhRelation:
1991                         retval = _equalInhRelation(a, b);
1992                         break;
1993                 case T_DefineStmt:
1994                         retval = _equalDefineStmt(a, b);
1995                         break;
1996                 case T_DropStmt:
1997                         retval = _equalDropStmt(a, b);
1998                         break;
1999                 case T_TruncateStmt:
2000                         retval = _equalTruncateStmt(a, b);
2001                         break;
2002                 case T_CommentStmt:
2003                         retval = _equalCommentStmt(a, b);
2004                         break;
2005                 case T_FetchStmt:
2006                         retval = _equalFetchStmt(a, b);
2007                         break;
2008                 case T_IndexStmt:
2009                         retval = _equalIndexStmt(a, b);
2010                         break;
2011                 case T_CreateFunctionStmt:
2012                         retval = _equalCreateFunctionStmt(a, b);
2013                         break;
2014                 case T_FunctionParameter:
2015                         retval = _equalFunctionParameter(a, b);
2016                         break;
2017                 case T_RemoveAggrStmt:
2018                         retval = _equalRemoveAggrStmt(a, b);
2019                         break;
2020                 case T_RemoveFuncStmt:
2021                         retval = _equalRemoveFuncStmt(a, b);
2022                         break;
2023                 case T_RemoveOperStmt:
2024                         retval = _equalRemoveOperStmt(a, b);
2025                         break;
2026                 case T_RemoveOpClassStmt:
2027                         retval = _equalRemoveOpClassStmt(a, b);
2028                         break;
2029                 case T_RenameStmt:
2030                         retval = _equalRenameStmt(a, b);
2031                         break;
2032                 case T_AlterOwnerStmt:
2033                         retval = _equalAlterOwnerStmt(a, b);
2034                         break;
2035                 case T_RuleStmt:
2036                         retval = _equalRuleStmt(a, b);
2037                         break;
2038                 case T_NotifyStmt:
2039                         retval = _equalNotifyStmt(a, b);
2040                         break;
2041                 case T_ListenStmt:
2042                         retval = _equalListenStmt(a, b);
2043                         break;
2044                 case T_UnlistenStmt:
2045                         retval = _equalUnlistenStmt(a, b);
2046                         break;
2047                 case T_TransactionStmt:
2048                         retval = _equalTransactionStmt(a, b);
2049                         break;
2050                 case T_CompositeTypeStmt:
2051                         retval = _equalCompositeTypeStmt(a, b);
2052                         break;
2053                 case T_ViewStmt:
2054                         retval = _equalViewStmt(a, b);
2055                         break;
2056                 case T_LoadStmt:
2057                         retval = _equalLoadStmt(a, b);
2058                         break;
2059                 case T_CreateDomainStmt:
2060                         retval = _equalCreateDomainStmt(a, b);
2061                         break;
2062                 case T_CreateOpClassStmt:
2063                         retval = _equalCreateOpClassStmt(a, b);
2064                         break;
2065                 case T_CreateOpClassItem:
2066                         retval = _equalCreateOpClassItem(a, b);
2067                         break;
2068                 case T_CreatedbStmt:
2069                         retval = _equalCreatedbStmt(a, b);
2070                         break;
2071                 case T_AlterDatabaseSetStmt:
2072                         retval = _equalAlterDatabaseSetStmt(a, b);
2073                         break;
2074                 case T_DropdbStmt:
2075                         retval = _equalDropdbStmt(a, b);
2076                         break;
2077                 case T_VacuumStmt:
2078                         retval = _equalVacuumStmt(a, b);
2079                         break;
2080                 case T_ExplainStmt:
2081                         retval = _equalExplainStmt(a, b);
2082                         break;
2083                 case T_CreateSeqStmt:
2084                         retval = _equalCreateSeqStmt(a, b);
2085                         break;
2086                 case T_AlterSeqStmt:
2087                         retval = _equalAlterSeqStmt(a, b);
2088                         break;
2089                 case T_VariableSetStmt:
2090                         retval = _equalVariableSetStmt(a, b);
2091                         break;
2092                 case T_VariableShowStmt:
2093                         retval = _equalVariableShowStmt(a, b);
2094                         break;
2095                 case T_VariableResetStmt:
2096                         retval = _equalVariableResetStmt(a, b);
2097                         break;
2098                 case T_CreateTableSpaceStmt:
2099                         retval = _equalCreateTableSpaceStmt(a, b);
2100                         break;
2101                 case T_DropTableSpaceStmt:
2102                         retval = _equalDropTableSpaceStmt(a, b);
2103                         break;
2104                 case T_CreateTrigStmt:
2105                         retval = _equalCreateTrigStmt(a, b);
2106                         break;
2107                 case T_DropPropertyStmt:
2108                         retval = _equalDropPropertyStmt(a, b);
2109                         break;
2110                 case T_CreatePLangStmt:
2111                         retval = _equalCreatePLangStmt(a, b);
2112                         break;
2113                 case T_DropPLangStmt:
2114                         retval = _equalDropPLangStmt(a, b);
2115                         break;
2116                 case T_CreateUserStmt:
2117                         retval = _equalCreateUserStmt(a, b);
2118                         break;
2119                 case T_AlterUserStmt:
2120                         retval = _equalAlterUserStmt(a, b);
2121                         break;
2122                 case T_AlterUserSetStmt:
2123                         retval = _equalAlterUserSetStmt(a, b);
2124                         break;
2125                 case T_DropUserStmt:
2126                         retval = _equalDropUserStmt(a, b);
2127                         break;
2128                 case T_LockStmt:
2129                         retval = _equalLockStmt(a, b);
2130                         break;
2131                 case T_ConstraintsSetStmt:
2132                         retval = _equalConstraintsSetStmt(a, b);
2133                         break;
2134                 case T_CreateGroupStmt:
2135                         retval = _equalCreateGroupStmt(a, b);
2136                         break;
2137                 case T_AlterGroupStmt:
2138                         retval = _equalAlterGroupStmt(a, b);
2139                         break;
2140                 case T_DropGroupStmt:
2141                         retval = _equalDropGroupStmt(a, b);
2142                         break;
2143                 case T_ReindexStmt:
2144                         retval = _equalReindexStmt(a, b);
2145                         break;
2146                 case T_CheckPointStmt:
2147                         retval = true;
2148                         break;
2149                 case T_CreateSchemaStmt:
2150                         retval = _equalCreateSchemaStmt(a, b);
2151                         break;
2152                 case T_CreateConversionStmt:
2153                         retval = _equalCreateConversionStmt(a, b);
2154                         break;
2155                 case T_CreateCastStmt:
2156                         retval = _equalCreateCastStmt(a, b);
2157                         break;
2158                 case T_DropCastStmt:
2159                         retval = _equalDropCastStmt(a, b);
2160                         break;
2161                 case T_PrepareStmt:
2162                         retval = _equalPrepareStmt(a, b);
2163                         break;
2164                 case T_ExecuteStmt:
2165                         retval = _equalExecuteStmt(a, b);
2166                         break;
2167                 case T_DeallocateStmt:
2168                         retval = _equalDeallocateStmt(a, b);
2169                         break;
2170
2171                 case T_A_Expr:
2172                         retval = _equalAExpr(a, b);
2173                         break;
2174                 case T_ColumnRef:
2175                         retval = _equalColumnRef(a, b);
2176                         break;
2177                 case T_ParamRef:
2178                         retval = _equalParamRef(a, b);
2179                         break;
2180                 case T_A_Const:
2181                         retval = _equalAConst(a, b);
2182                         break;
2183                 case T_FuncCall:
2184                         retval = _equalFuncCall(a, b);
2185                         break;
2186                 case T_A_Indices:
2187                         retval = _equalAIndices(a, b);
2188                         break;
2189                 case T_A_Indirection:
2190                         retval = _equalA_Indirection(a, b);
2191                         break;
2192                 case T_ResTarget:
2193                         retval = _equalResTarget(a, b);
2194                         break;
2195                 case T_TypeCast:
2196                         retval = _equalTypeCast(a, b);
2197                         break;
2198                 case T_SortBy:
2199                         retval = _equalSortBy(a, b);
2200                         break;
2201                 case T_RangeSubselect:
2202                         retval = _equalRangeSubselect(a, b);
2203                         break;
2204                 case T_RangeFunction:
2205                         retval = _equalRangeFunction(a, b);
2206                         break;
2207                 case T_TypeName:
2208                         retval = _equalTypeName(a, b);
2209                         break;
2210                 case T_IndexElem:
2211                         retval = _equalIndexElem(a, b);
2212                         break;
2213                 case T_ColumnDef:
2214                         retval = _equalColumnDef(a, b);
2215                         break;
2216                 case T_Constraint:
2217                         retval = _equalConstraint(a, b);
2218                         break;
2219                 case T_DefElem:
2220                         retval = _equalDefElem(a, b);
2221                         break;
2222                 case T_RangeTblEntry:
2223                         retval = _equalRangeTblEntry(a, b);
2224                         break;
2225                 case T_SortClause:
2226                         retval = _equalSortClause(a, b);
2227                         break;
2228                 case T_GroupClause:
2229                         /* GroupClause is equivalent to SortClause */
2230                         retval = _equalSortClause(a, b);
2231                         break;
2232                 case T_FkConstraint:
2233                         retval = _equalFkConstraint(a, b);
2234                         break;
2235                 case T_PrivGrantee:
2236                         retval = _equalPrivGrantee(a, b);
2237                         break;
2238                 case T_FuncWithArgs:
2239                         retval = _equalFuncWithArgs(a, b);
2240                         break;
2241
2242                 default:
2243                         elog(ERROR, "unrecognized node type: %d",
2244                                  (int) nodeTag(a));
2245                         retval = false;         /* keep compiler quiet */
2246                         break;
2247         }
2248
2249         return retval;
2250 }