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