]> granicus.if.org Git - postgresql/blob - src/backend/nodes/equalfuncs.c
Generalize TRUNCATE to support truncating multiple tables in one
[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.235 2005/01/27 03:17:45 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         COMPARE_NODE_FIELD(in_info_list);
665         COMPARE_SCALAR_FIELD(hasJoinRTEs);
666
667         /*
668          * We do not check the other planner internal fields: base_rel_list,
669          * other_rel_list, join_rel_list, equi_key_list, query_pathkeys. They
670          * might not be set yet, and in any case they should be derivable from
671          * the other fields.
672          */
673         return true;
674 }
675
676 static bool
677 _equalInsertStmt(InsertStmt *a, InsertStmt *b)
678 {
679         COMPARE_NODE_FIELD(relation);
680         COMPARE_NODE_FIELD(cols);
681         COMPARE_NODE_FIELD(targetList);
682         COMPARE_NODE_FIELD(selectStmt);
683
684         return true;
685 }
686
687 static bool
688 _equalDeleteStmt(DeleteStmt *a, DeleteStmt *b)
689 {
690         COMPARE_NODE_FIELD(relation);
691         COMPARE_NODE_FIELD(whereClause);
692
693         return true;
694 }
695
696 static bool
697 _equalUpdateStmt(UpdateStmt *a, UpdateStmt *b)
698 {
699         COMPARE_NODE_FIELD(relation);
700         COMPARE_NODE_FIELD(targetList);
701         COMPARE_NODE_FIELD(whereClause);
702         COMPARE_NODE_FIELD(fromClause);
703
704         return true;
705 }
706
707 static bool
708 _equalSelectStmt(SelectStmt *a, SelectStmt *b)
709 {
710         COMPARE_NODE_FIELD(distinctClause);
711         COMPARE_NODE_FIELD(into);
712         COMPARE_NODE_FIELD(intoColNames);
713         COMPARE_SCALAR_FIELD(intoHasOids);
714         COMPARE_NODE_FIELD(targetList);
715         COMPARE_NODE_FIELD(fromClause);
716         COMPARE_NODE_FIELD(whereClause);
717         COMPARE_NODE_FIELD(groupClause);
718         COMPARE_NODE_FIELD(havingClause);
719         COMPARE_NODE_FIELD(sortClause);
720         COMPARE_NODE_FIELD(limitOffset);
721         COMPARE_NODE_FIELD(limitCount);
722         COMPARE_NODE_FIELD(forUpdate);
723         COMPARE_SCALAR_FIELD(op);
724         COMPARE_SCALAR_FIELD(all);
725         COMPARE_NODE_FIELD(larg);
726         COMPARE_NODE_FIELD(rarg);
727
728         return true;
729 }
730
731 static bool
732 _equalSetOperationStmt(SetOperationStmt *a, SetOperationStmt *b)
733 {
734         COMPARE_SCALAR_FIELD(op);
735         COMPARE_SCALAR_FIELD(all);
736         COMPARE_NODE_FIELD(larg);
737         COMPARE_NODE_FIELD(rarg);
738         COMPARE_NODE_FIELD(colTypes);
739
740         return true;
741 }
742
743 static bool
744 _equalAlterTableStmt(AlterTableStmt *a, AlterTableStmt *b)
745 {
746         COMPARE_NODE_FIELD(relation);
747         COMPARE_NODE_FIELD(cmds);
748         COMPARE_SCALAR_FIELD(relkind);
749
750         return true;
751 }
752
753 static bool
754 _equalAlterTableCmd(AlterTableCmd *a, AlterTableCmd *b)
755 {
756         COMPARE_SCALAR_FIELD(subtype);
757         COMPARE_STRING_FIELD(name);
758         COMPARE_NODE_FIELD(def);
759         COMPARE_NODE_FIELD(transform);
760         COMPARE_SCALAR_FIELD(behavior);
761
762         return true;
763 }
764
765 static bool
766 _equalAlterDomainStmt(AlterDomainStmt *a, AlterDomainStmt *b)
767 {
768         COMPARE_SCALAR_FIELD(subtype);
769         COMPARE_NODE_FIELD(typename);
770         COMPARE_STRING_FIELD(name);
771         COMPARE_NODE_FIELD(def);
772         COMPARE_SCALAR_FIELD(behavior);
773
774         return true;
775 }
776
777 static bool
778 _equalGrantStmt(GrantStmt *a, GrantStmt *b)
779 {
780         COMPARE_SCALAR_FIELD(is_grant);
781         COMPARE_SCALAR_FIELD(objtype);
782         COMPARE_NODE_FIELD(objects);
783         COMPARE_NODE_FIELD(privileges);
784         COMPARE_NODE_FIELD(grantees);
785         COMPARE_SCALAR_FIELD(grant_option);
786         COMPARE_SCALAR_FIELD(behavior);
787
788         return true;
789 }
790
791 static bool
792 _equalPrivGrantee(PrivGrantee *a, PrivGrantee *b)
793 {
794         COMPARE_STRING_FIELD(username);
795         COMPARE_STRING_FIELD(groupname);
796
797         return true;
798 }
799
800 static bool
801 _equalFuncWithArgs(FuncWithArgs *a, FuncWithArgs *b)
802 {
803         COMPARE_NODE_FIELD(funcname);
804         COMPARE_NODE_FIELD(funcargs);
805
806         return true;
807 }
808
809 static bool
810 _equalDeclareCursorStmt(DeclareCursorStmt *a, DeclareCursorStmt *b)
811 {
812         COMPARE_STRING_FIELD(portalname);
813         COMPARE_SCALAR_FIELD(options);
814         COMPARE_NODE_FIELD(query);
815
816         return true;
817 }
818
819 static bool
820 _equalClosePortalStmt(ClosePortalStmt *a, ClosePortalStmt *b)
821 {
822         COMPARE_STRING_FIELD(portalname);
823
824         return true;
825 }
826
827 static bool
828 _equalClusterStmt(ClusterStmt *a, ClusterStmt *b)
829 {
830         COMPARE_NODE_FIELD(relation);
831         COMPARE_STRING_FIELD(indexname);
832
833         return true;
834 }
835
836 static bool
837 _equalCopyStmt(CopyStmt *a, CopyStmt *b)
838 {
839         COMPARE_NODE_FIELD(relation);
840         COMPARE_NODE_FIELD(attlist);
841         COMPARE_SCALAR_FIELD(is_from);
842         COMPARE_STRING_FIELD(filename);
843         COMPARE_NODE_FIELD(options);
844
845         return true;
846 }
847
848 static bool
849 _equalCreateStmt(CreateStmt *a, CreateStmt *b)
850 {
851         COMPARE_NODE_FIELD(relation);
852         COMPARE_NODE_FIELD(tableElts);
853         COMPARE_NODE_FIELD(inhRelations);
854         COMPARE_NODE_FIELD(constraints);
855         COMPARE_SCALAR_FIELD(hasoids);
856         COMPARE_SCALAR_FIELD(oncommit);
857         COMPARE_STRING_FIELD(tablespacename);
858
859         return true;
860 }
861
862 static bool
863 _equalInhRelation(InhRelation *a, InhRelation *b)
864 {
865         COMPARE_NODE_FIELD(relation);
866         COMPARE_SCALAR_FIELD(including_defaults);
867
868         return true;
869 }
870
871 static bool
872 _equalDefineStmt(DefineStmt *a, DefineStmt *b)
873 {
874         COMPARE_SCALAR_FIELD(kind);
875         COMPARE_NODE_FIELD(defnames);
876         COMPARE_NODE_FIELD(definition);
877
878         return true;
879 }
880
881 static bool
882 _equalDropStmt(DropStmt *a, DropStmt *b)
883 {
884         COMPARE_NODE_FIELD(objects);
885         COMPARE_SCALAR_FIELD(removeType);
886         COMPARE_SCALAR_FIELD(behavior);
887
888         return true;
889 }
890
891 static bool
892 _equalTruncateStmt(TruncateStmt *a, TruncateStmt *b)
893 {
894         COMPARE_NODE_FIELD(relations);
895
896         return true;
897 }
898
899 static bool
900 _equalCommentStmt(CommentStmt *a, CommentStmt *b)
901 {
902         COMPARE_SCALAR_FIELD(objtype);
903         COMPARE_NODE_FIELD(objname);
904         COMPARE_NODE_FIELD(objargs);
905         COMPARE_STRING_FIELD(comment);
906
907         return true;
908 }
909
910 static bool
911 _equalFetchStmt(FetchStmt *a, FetchStmt *b)
912 {
913         COMPARE_SCALAR_FIELD(direction);
914         COMPARE_SCALAR_FIELD(howMany);
915         COMPARE_STRING_FIELD(portalname);
916         COMPARE_SCALAR_FIELD(ismove);
917
918         return true;
919 }
920
921 static bool
922 _equalIndexStmt(IndexStmt *a, IndexStmt *b)
923 {
924         COMPARE_STRING_FIELD(idxname);
925         COMPARE_NODE_FIELD(relation);
926         COMPARE_STRING_FIELD(accessMethod);
927         COMPARE_STRING_FIELD(tableSpace);
928         COMPARE_NODE_FIELD(indexParams);
929         COMPARE_NODE_FIELD(whereClause);
930         COMPARE_NODE_FIELD(rangetable);
931         COMPARE_SCALAR_FIELD(unique);
932         COMPARE_SCALAR_FIELD(primary);
933         COMPARE_SCALAR_FIELD(isconstraint);
934
935         return true;
936 }
937
938 static bool
939 _equalCreateFunctionStmt(CreateFunctionStmt *a, CreateFunctionStmt *b)
940 {
941         COMPARE_SCALAR_FIELD(replace);
942         COMPARE_NODE_FIELD(funcname);
943         COMPARE_NODE_FIELD(parameters);
944         COMPARE_NODE_FIELD(returnType);
945         COMPARE_NODE_FIELD(options);
946         COMPARE_NODE_FIELD(withClause);
947
948         return true;
949 }
950
951 static bool
952 _equalFunctionParameter(FunctionParameter *a, FunctionParameter *b)
953 {
954         COMPARE_STRING_FIELD(name);
955         COMPARE_NODE_FIELD(argType);
956
957         return true;
958 }
959
960 static bool
961 _equalRemoveAggrStmt(RemoveAggrStmt *a, RemoveAggrStmt *b)
962 {
963         COMPARE_NODE_FIELD(aggname);
964         COMPARE_NODE_FIELD(aggtype);
965         COMPARE_SCALAR_FIELD(behavior);
966
967         return true;
968 }
969
970 static bool
971 _equalRemoveFuncStmt(RemoveFuncStmt *a, RemoveFuncStmt *b)
972 {
973         COMPARE_NODE_FIELD(funcname);
974         COMPARE_NODE_FIELD(args);
975         COMPARE_SCALAR_FIELD(behavior);
976
977         return true;
978 }
979
980 static bool
981 _equalRemoveOperStmt(RemoveOperStmt *a, RemoveOperStmt *b)
982 {
983         COMPARE_NODE_FIELD(opname);
984         COMPARE_NODE_FIELD(args);
985         COMPARE_SCALAR_FIELD(behavior);
986
987         return true;
988 }
989
990 static bool
991 _equalRemoveOpClassStmt(RemoveOpClassStmt *a, RemoveOpClassStmt *b)
992 {
993         COMPARE_NODE_FIELD(opclassname);
994         COMPARE_STRING_FIELD(amname);
995         COMPARE_SCALAR_FIELD(behavior);
996
997         return true;
998 }
999
1000 static bool
1001 _equalRenameStmt(RenameStmt *a, RenameStmt *b)
1002 {
1003         COMPARE_NODE_FIELD(relation);
1004         COMPARE_NODE_FIELD(object);
1005         COMPARE_NODE_FIELD(objarg);
1006         COMPARE_STRING_FIELD(subname);
1007         COMPARE_STRING_FIELD(newname);
1008         COMPARE_SCALAR_FIELD(renameType);
1009
1010         return true;
1011 }
1012
1013 static bool
1014 _equalAlterOwnerStmt(AlterOwnerStmt *a, AlterOwnerStmt *b)
1015 {
1016         COMPARE_NODE_FIELD(relation);
1017         COMPARE_NODE_FIELD(object);
1018         COMPARE_NODE_FIELD(objarg);
1019         COMPARE_STRING_FIELD(addname);
1020         COMPARE_STRING_FIELD(newowner);
1021         COMPARE_SCALAR_FIELD(objectType);
1022
1023         return true;
1024 }
1025
1026 static bool
1027 _equalRuleStmt(RuleStmt *a, RuleStmt *b)
1028 {
1029         COMPARE_NODE_FIELD(relation);
1030         COMPARE_STRING_FIELD(rulename);
1031         COMPARE_NODE_FIELD(whereClause);
1032         COMPARE_SCALAR_FIELD(event);
1033         COMPARE_SCALAR_FIELD(instead);
1034         COMPARE_NODE_FIELD(actions);
1035         COMPARE_SCALAR_FIELD(replace);
1036
1037         return true;
1038 }
1039
1040 static bool
1041 _equalNotifyStmt(NotifyStmt *a, NotifyStmt *b)
1042 {
1043         COMPARE_NODE_FIELD(relation);
1044
1045         return true;
1046 }
1047
1048 static bool
1049 _equalListenStmt(ListenStmt *a, ListenStmt *b)
1050 {
1051         COMPARE_NODE_FIELD(relation);
1052
1053         return true;
1054 }
1055
1056 static bool
1057 _equalUnlistenStmt(UnlistenStmt *a, UnlistenStmt *b)
1058 {
1059         COMPARE_NODE_FIELD(relation);
1060
1061         return true;
1062 }
1063
1064 static bool
1065 _equalTransactionStmt(TransactionStmt *a, TransactionStmt *b)
1066 {
1067         COMPARE_SCALAR_FIELD(kind);
1068         COMPARE_NODE_FIELD(options);
1069
1070         return true;
1071 }
1072
1073 static bool
1074 _equalCompositeTypeStmt(CompositeTypeStmt *a, CompositeTypeStmt *b)
1075 {
1076         COMPARE_NODE_FIELD(typevar);
1077         COMPARE_NODE_FIELD(coldeflist);
1078
1079         return true;
1080 }
1081
1082 static bool
1083 _equalViewStmt(ViewStmt *a, ViewStmt *b)
1084 {
1085         COMPARE_NODE_FIELD(view);
1086         COMPARE_NODE_FIELD(aliases);
1087         COMPARE_NODE_FIELD(query);
1088         COMPARE_SCALAR_FIELD(replace);
1089
1090         return true;
1091 }
1092
1093 static bool
1094 _equalLoadStmt(LoadStmt *a, LoadStmt *b)
1095 {
1096         COMPARE_STRING_FIELD(filename);
1097
1098         return true;
1099 }
1100
1101 static bool
1102 _equalCreateDomainStmt(CreateDomainStmt *a, CreateDomainStmt *b)
1103 {
1104         COMPARE_NODE_FIELD(domainname);
1105         COMPARE_NODE_FIELD(typename);
1106         COMPARE_NODE_FIELD(constraints);
1107
1108         return true;
1109 }
1110
1111 static bool
1112 _equalCreateOpClassStmt(CreateOpClassStmt *a, CreateOpClassStmt *b)
1113 {
1114         COMPARE_NODE_FIELD(opclassname);
1115         COMPARE_STRING_FIELD(amname);
1116         COMPARE_NODE_FIELD(datatype);
1117         COMPARE_NODE_FIELD(items);
1118         COMPARE_SCALAR_FIELD(isDefault);
1119
1120         return true;
1121 }
1122
1123 static bool
1124 _equalCreateOpClassItem(CreateOpClassItem *a, CreateOpClassItem *b)
1125 {
1126         COMPARE_SCALAR_FIELD(itemtype);
1127         COMPARE_NODE_FIELD(name);
1128         COMPARE_NODE_FIELD(args);
1129         COMPARE_SCALAR_FIELD(number);
1130         COMPARE_SCALAR_FIELD(recheck);
1131         COMPARE_NODE_FIELD(storedtype);
1132
1133         return true;
1134 }
1135
1136 static bool
1137 _equalCreatedbStmt(CreatedbStmt *a, CreatedbStmt *b)
1138 {
1139         COMPARE_STRING_FIELD(dbname);
1140         COMPARE_NODE_FIELD(options);
1141
1142         return true;
1143 }
1144
1145 static bool
1146 _equalAlterDatabaseSetStmt(AlterDatabaseSetStmt *a, AlterDatabaseSetStmt *b)
1147 {
1148         COMPARE_STRING_FIELD(dbname);
1149         COMPARE_STRING_FIELD(variable);
1150         COMPARE_NODE_FIELD(value);
1151
1152         return true;
1153 }
1154
1155 static bool
1156 _equalDropdbStmt(DropdbStmt *a, DropdbStmt *b)
1157 {
1158         COMPARE_STRING_FIELD(dbname);
1159
1160         return true;
1161 }
1162
1163 static bool
1164 _equalVacuumStmt(VacuumStmt *a, VacuumStmt *b)
1165 {
1166         COMPARE_SCALAR_FIELD(vacuum);
1167         COMPARE_SCALAR_FIELD(full);
1168         COMPARE_SCALAR_FIELD(analyze);
1169         COMPARE_SCALAR_FIELD(freeze);
1170         COMPARE_SCALAR_FIELD(verbose);
1171         COMPARE_NODE_FIELD(relation);
1172         COMPARE_NODE_FIELD(va_cols);
1173
1174         return true;
1175 }
1176
1177 static bool
1178 _equalExplainStmt(ExplainStmt *a, ExplainStmt *b)
1179 {
1180         COMPARE_NODE_FIELD(query);
1181         COMPARE_SCALAR_FIELD(verbose);
1182         COMPARE_SCALAR_FIELD(analyze);
1183
1184         return true;
1185 }
1186
1187 static bool
1188 _equalCreateSeqStmt(CreateSeqStmt *a, CreateSeqStmt *b)
1189 {
1190         COMPARE_NODE_FIELD(sequence);
1191         COMPARE_NODE_FIELD(options);
1192
1193         return true;
1194 }
1195
1196 static bool
1197 _equalAlterSeqStmt(AlterSeqStmt *a, AlterSeqStmt *b)
1198 {
1199         COMPARE_NODE_FIELD(sequence);
1200         COMPARE_NODE_FIELD(options);
1201
1202         return true;
1203 }
1204
1205 static bool
1206 _equalVariableSetStmt(VariableSetStmt *a, VariableSetStmt *b)
1207 {
1208         COMPARE_STRING_FIELD(name);
1209         COMPARE_NODE_FIELD(args);
1210         COMPARE_SCALAR_FIELD(is_local);
1211
1212         return true;
1213 }
1214
1215 static bool
1216 _equalVariableShowStmt(VariableShowStmt *a, VariableShowStmt *b)
1217 {
1218         COMPARE_STRING_FIELD(name);
1219
1220         return true;
1221 }
1222
1223 static bool
1224 _equalVariableResetStmt(VariableResetStmt *a, VariableResetStmt *b)
1225 {
1226         COMPARE_STRING_FIELD(name);
1227
1228         return true;
1229 }
1230
1231 static bool
1232 _equalCreateTableSpaceStmt(CreateTableSpaceStmt *a, CreateTableSpaceStmt *b)
1233 {
1234         COMPARE_STRING_FIELD(tablespacename);
1235         COMPARE_STRING_FIELD(owner);
1236         COMPARE_STRING_FIELD(location);
1237
1238         return true;
1239 }
1240
1241 static bool
1242 _equalDropTableSpaceStmt(DropTableSpaceStmt *a, DropTableSpaceStmt *b)
1243 {
1244         COMPARE_STRING_FIELD(tablespacename);
1245
1246         return true;
1247 }
1248
1249 static bool
1250 _equalCreateTrigStmt(CreateTrigStmt *a, CreateTrigStmt *b)
1251 {
1252         COMPARE_STRING_FIELD(trigname);
1253         COMPARE_NODE_FIELD(relation);
1254         COMPARE_NODE_FIELD(funcname);
1255         COMPARE_NODE_FIELD(args);
1256         COMPARE_SCALAR_FIELD(before);
1257         COMPARE_SCALAR_FIELD(row);
1258         if (strcmp(a->actions, b->actions) != 0)        /* in-line string field */
1259                 return false;
1260         COMPARE_SCALAR_FIELD(isconstraint);
1261         COMPARE_SCALAR_FIELD(deferrable);
1262         COMPARE_SCALAR_FIELD(initdeferred);
1263         COMPARE_NODE_FIELD(constrrel);
1264
1265         return true;
1266 }
1267
1268 static bool
1269 _equalDropPropertyStmt(DropPropertyStmt *a, DropPropertyStmt *b)
1270 {
1271         COMPARE_NODE_FIELD(relation);
1272         COMPARE_STRING_FIELD(property);
1273         COMPARE_SCALAR_FIELD(removeType);
1274         COMPARE_SCALAR_FIELD(behavior);
1275
1276         return true;
1277 }
1278
1279 static bool
1280 _equalCreatePLangStmt(CreatePLangStmt *a, CreatePLangStmt *b)
1281 {
1282         COMPARE_STRING_FIELD(plname);
1283         COMPARE_NODE_FIELD(plhandler);
1284         COMPARE_NODE_FIELD(plvalidator);
1285         COMPARE_SCALAR_FIELD(pltrusted);
1286
1287         return true;
1288 }
1289
1290 static bool
1291 _equalDropPLangStmt(DropPLangStmt *a, DropPLangStmt *b)
1292 {
1293         COMPARE_STRING_FIELD(plname);
1294         COMPARE_SCALAR_FIELD(behavior);
1295
1296         return true;
1297 }
1298
1299 static bool
1300 _equalCreateUserStmt(CreateUserStmt *a, CreateUserStmt *b)
1301 {
1302         COMPARE_STRING_FIELD(user);
1303         COMPARE_NODE_FIELD(options);
1304
1305         return true;
1306 }
1307
1308 static bool
1309 _equalAlterUserStmt(AlterUserStmt *a, AlterUserStmt *b)
1310 {
1311         COMPARE_STRING_FIELD(user);
1312         COMPARE_NODE_FIELD(options);
1313
1314         return true;
1315 }
1316
1317 static bool
1318 _equalAlterUserSetStmt(AlterUserSetStmt *a, AlterUserSetStmt *b)
1319 {
1320         COMPARE_STRING_FIELD(user);
1321         COMPARE_STRING_FIELD(variable);
1322         COMPARE_NODE_FIELD(value);
1323
1324         return true;
1325 }
1326
1327 static bool
1328 _equalDropUserStmt(DropUserStmt *a, DropUserStmt *b)
1329 {
1330         COMPARE_NODE_FIELD(users);
1331
1332         return true;
1333 }
1334
1335 static bool
1336 _equalLockStmt(LockStmt *a, LockStmt *b)
1337 {
1338         COMPARE_NODE_FIELD(relations);
1339         COMPARE_SCALAR_FIELD(mode);
1340         COMPARE_SCALAR_FIELD(nowait);
1341
1342         return true;
1343 }
1344
1345 static bool
1346 _equalConstraintsSetStmt(ConstraintsSetStmt *a, ConstraintsSetStmt *b)
1347 {
1348         COMPARE_NODE_FIELD(constraints);
1349         COMPARE_SCALAR_FIELD(deferred);
1350
1351         return true;
1352 }
1353
1354 static bool
1355 _equalCreateGroupStmt(CreateGroupStmt *a, CreateGroupStmt *b)
1356 {
1357         COMPARE_STRING_FIELD(name);
1358         COMPARE_NODE_FIELD(options);
1359
1360         return true;
1361 }
1362
1363 static bool
1364 _equalAlterGroupStmt(AlterGroupStmt *a, AlterGroupStmt *b)
1365 {
1366         COMPARE_STRING_FIELD(name);
1367         COMPARE_SCALAR_FIELD(action);
1368         COMPARE_NODE_FIELD(listUsers);
1369
1370         return true;
1371 }
1372
1373 static bool
1374 _equalDropGroupStmt(DropGroupStmt *a, DropGroupStmt *b)
1375 {
1376         COMPARE_STRING_FIELD(name);
1377
1378         return true;
1379 }
1380
1381 static bool
1382 _equalReindexStmt(ReindexStmt *a, ReindexStmt *b)
1383 {
1384         COMPARE_SCALAR_FIELD(kind);
1385         COMPARE_NODE_FIELD(relation);
1386         COMPARE_STRING_FIELD(name);
1387         COMPARE_SCALAR_FIELD(force);
1388         COMPARE_SCALAR_FIELD(all);
1389
1390         return true;
1391 }
1392
1393 static bool
1394 _equalCreateSchemaStmt(CreateSchemaStmt *a, CreateSchemaStmt *b)
1395 {
1396         COMPARE_STRING_FIELD(schemaname);
1397         COMPARE_STRING_FIELD(authid);
1398         COMPARE_NODE_FIELD(schemaElts);
1399
1400         return true;
1401 }
1402
1403 static bool
1404 _equalCreateConversionStmt(CreateConversionStmt *a, CreateConversionStmt *b)
1405 {
1406         COMPARE_NODE_FIELD(conversion_name);
1407         COMPARE_STRING_FIELD(for_encoding_name);
1408         COMPARE_STRING_FIELD(to_encoding_name);
1409         COMPARE_NODE_FIELD(func_name);
1410         COMPARE_SCALAR_FIELD(def);
1411
1412         return true;
1413 }
1414
1415 static bool
1416 _equalCreateCastStmt(CreateCastStmt *a, CreateCastStmt *b)
1417 {
1418         COMPARE_NODE_FIELD(sourcetype);
1419         COMPARE_NODE_FIELD(targettype);
1420         COMPARE_NODE_FIELD(func);
1421         COMPARE_SCALAR_FIELD(context);
1422
1423         return true;
1424 }
1425
1426 static bool
1427 _equalDropCastStmt(DropCastStmt *a, DropCastStmt *b)
1428 {
1429         COMPARE_NODE_FIELD(sourcetype);
1430         COMPARE_NODE_FIELD(targettype);
1431         COMPARE_SCALAR_FIELD(behavior);
1432
1433         return true;
1434 }
1435
1436 static bool
1437 _equalPrepareStmt(PrepareStmt *a, PrepareStmt *b)
1438 {
1439         COMPARE_STRING_FIELD(name);
1440         COMPARE_NODE_FIELD(argtypes);
1441         COMPARE_NODE_FIELD(argtype_oids);
1442         COMPARE_NODE_FIELD(query);
1443
1444         return true;
1445 }
1446
1447 static bool
1448 _equalExecuteStmt(ExecuteStmt *a, ExecuteStmt *b)
1449 {
1450         COMPARE_STRING_FIELD(name);
1451         COMPARE_NODE_FIELD(into);
1452         COMPARE_NODE_FIELD(params);
1453
1454         return true;
1455 }
1456
1457 static bool
1458 _equalDeallocateStmt(DeallocateStmt *a, DeallocateStmt *b)
1459 {
1460         COMPARE_STRING_FIELD(name);
1461
1462         return true;
1463 }
1464
1465
1466 /*
1467  * stuff from parsenodes.h
1468  */
1469
1470 static bool
1471 _equalAExpr(A_Expr *a, A_Expr *b)
1472 {
1473         COMPARE_SCALAR_FIELD(kind);
1474         COMPARE_NODE_FIELD(name);
1475         COMPARE_NODE_FIELD(lexpr);
1476         COMPARE_NODE_FIELD(rexpr);
1477
1478         return true;
1479 }
1480
1481 static bool
1482 _equalColumnRef(ColumnRef *a, ColumnRef *b)
1483 {
1484         COMPARE_NODE_FIELD(fields);
1485
1486         return true;
1487 }
1488
1489 static bool
1490 _equalParamRef(ParamRef *a, ParamRef *b)
1491 {
1492         COMPARE_SCALAR_FIELD(number);
1493
1494         return true;
1495 }
1496
1497 static bool
1498 _equalAConst(A_Const *a, A_Const *b)
1499 {
1500         if (!equal(&a->val, &b->val))           /* hack for in-line Value field */
1501                 return false;
1502         COMPARE_NODE_FIELD(typename);
1503
1504         return true;
1505 }
1506
1507 static bool
1508 _equalFuncCall(FuncCall *a, FuncCall *b)
1509 {
1510         COMPARE_NODE_FIELD(funcname);
1511         COMPARE_NODE_FIELD(args);
1512         COMPARE_SCALAR_FIELD(agg_star);
1513         COMPARE_SCALAR_FIELD(agg_distinct);
1514
1515         return true;
1516 }
1517
1518 static bool
1519 _equalAIndices(A_Indices *a, A_Indices *b)
1520 {
1521         COMPARE_NODE_FIELD(lidx);
1522         COMPARE_NODE_FIELD(uidx);
1523
1524         return true;
1525 }
1526
1527 static bool
1528 _equalA_Indirection(A_Indirection *a, A_Indirection *b)
1529 {
1530         COMPARE_NODE_FIELD(arg);
1531         COMPARE_NODE_FIELD(indirection);
1532
1533         return true;
1534 }
1535
1536 static bool
1537 _equalResTarget(ResTarget *a, ResTarget *b)
1538 {
1539         COMPARE_STRING_FIELD(name);
1540         COMPARE_NODE_FIELD(indirection);
1541         COMPARE_NODE_FIELD(val);
1542
1543         return true;
1544 }
1545
1546 static bool
1547 _equalTypeName(TypeName *a, TypeName *b)
1548 {
1549         COMPARE_NODE_FIELD(names);
1550         COMPARE_SCALAR_FIELD(typeid);
1551         COMPARE_SCALAR_FIELD(timezone);
1552         COMPARE_SCALAR_FIELD(setof);
1553         COMPARE_SCALAR_FIELD(pct_type);
1554         COMPARE_SCALAR_FIELD(typmod);
1555         COMPARE_NODE_FIELD(arrayBounds);
1556
1557         return true;
1558 }
1559
1560 static bool
1561 _equalTypeCast(TypeCast *a, TypeCast *b)
1562 {
1563         COMPARE_NODE_FIELD(arg);
1564         COMPARE_NODE_FIELD(typename);
1565
1566         return true;
1567 }
1568
1569 static bool
1570 _equalSortBy(SortBy *a, SortBy *b)
1571 {
1572         COMPARE_SCALAR_FIELD(sortby_kind);
1573         COMPARE_NODE_FIELD(useOp);
1574         COMPARE_NODE_FIELD(node);
1575
1576         return true;
1577 }
1578
1579 static bool
1580 _equalRangeSubselect(RangeSubselect *a, RangeSubselect *b)
1581 {
1582         COMPARE_NODE_FIELD(subquery);
1583         COMPARE_NODE_FIELD(alias);
1584
1585         return true;
1586 }
1587
1588 static bool
1589 _equalRangeFunction(RangeFunction *a, RangeFunction *b)
1590 {
1591         COMPARE_NODE_FIELD(funccallnode);
1592         COMPARE_NODE_FIELD(alias);
1593         COMPARE_NODE_FIELD(coldeflist);
1594
1595         return true;
1596 }
1597
1598 static bool
1599 _equalIndexElem(IndexElem *a, IndexElem *b)
1600 {
1601         COMPARE_STRING_FIELD(name);
1602         COMPARE_NODE_FIELD(expr);
1603         COMPARE_NODE_FIELD(opclass);
1604
1605         return true;
1606 }
1607
1608 static bool
1609 _equalColumnDef(ColumnDef *a, ColumnDef *b)
1610 {
1611         COMPARE_STRING_FIELD(colname);
1612         COMPARE_NODE_FIELD(typename);
1613         COMPARE_SCALAR_FIELD(inhcount);
1614         COMPARE_SCALAR_FIELD(is_local);
1615         COMPARE_SCALAR_FIELD(is_not_null);
1616         COMPARE_NODE_FIELD(raw_default);
1617         COMPARE_STRING_FIELD(cooked_default);
1618         COMPARE_NODE_FIELD(constraints);
1619         COMPARE_NODE_FIELD(support);
1620
1621         return true;
1622 }
1623
1624 static bool
1625 _equalConstraint(Constraint *a, Constraint *b)
1626 {
1627         COMPARE_SCALAR_FIELD(contype);
1628         COMPARE_STRING_FIELD(name);
1629         COMPARE_NODE_FIELD(raw_expr);
1630         COMPARE_STRING_FIELD(cooked_expr);
1631         COMPARE_NODE_FIELD(keys);
1632         COMPARE_STRING_FIELD(indexspace);
1633
1634         return true;
1635 }
1636
1637 static bool
1638 _equalDefElem(DefElem *a, DefElem *b)
1639 {
1640         COMPARE_STRING_FIELD(defname);
1641         COMPARE_NODE_FIELD(arg);
1642
1643         return true;
1644 }
1645
1646 static bool
1647 _equalRangeTblEntry(RangeTblEntry *a, RangeTblEntry *b)
1648 {
1649         COMPARE_SCALAR_FIELD(rtekind);
1650         COMPARE_SCALAR_FIELD(relid);
1651         COMPARE_NODE_FIELD(subquery);
1652         COMPARE_NODE_FIELD(funcexpr);
1653         COMPARE_NODE_FIELD(coldeflist);
1654         COMPARE_SCALAR_FIELD(jointype);
1655         COMPARE_NODE_FIELD(joinaliasvars);
1656         COMPARE_NODE_FIELD(alias);
1657         COMPARE_NODE_FIELD(eref);
1658         COMPARE_SCALAR_FIELD(inh);
1659         COMPARE_SCALAR_FIELD(inFromCl);
1660         COMPARE_SCALAR_FIELD(requiredPerms);
1661         COMPARE_SCALAR_FIELD(checkAsUser);
1662
1663         return true;
1664 }
1665
1666 static bool
1667 _equalSortClause(SortClause *a, SortClause *b)
1668 {
1669         COMPARE_SCALAR_FIELD(tleSortGroupRef);
1670         COMPARE_SCALAR_FIELD(sortop);
1671
1672         return true;
1673 }
1674
1675 static bool
1676 _equalFkConstraint(FkConstraint *a, FkConstraint *b)
1677 {
1678         COMPARE_STRING_FIELD(constr_name);
1679         COMPARE_NODE_FIELD(pktable);
1680         COMPARE_NODE_FIELD(fk_attrs);
1681         COMPARE_NODE_FIELD(pk_attrs);
1682         COMPARE_SCALAR_FIELD(fk_matchtype);
1683         COMPARE_SCALAR_FIELD(fk_upd_action);
1684         COMPARE_SCALAR_FIELD(fk_del_action);
1685         COMPARE_SCALAR_FIELD(deferrable);
1686         COMPARE_SCALAR_FIELD(initdeferred);
1687         COMPARE_SCALAR_FIELD(skip_validation);
1688
1689         return true;
1690 }
1691
1692
1693 /*
1694  * Stuff from pg_list.h
1695  */
1696
1697 static bool
1698 _equalList(List *a, List *b)
1699 {
1700         ListCell   *item_a;
1701         ListCell   *item_b;
1702
1703         /*
1704          * Try to reject by simple scalar checks before grovelling through all
1705          * the list elements...
1706          */
1707         COMPARE_SCALAR_FIELD(type);
1708         COMPARE_SCALAR_FIELD(length);
1709
1710         /*
1711          * We place the switch outside the loop for the sake of efficiency;
1712          * this may not be worth doing...
1713          */
1714         switch (a->type)
1715         {
1716                 case T_List:
1717                         forboth(item_a, a, item_b, b)
1718                         {
1719                                 if (!equal(lfirst(item_a), lfirst(item_b)))
1720                                         return false;
1721                         }
1722                         break;
1723                 case T_IntList:
1724                         forboth(item_a, a, item_b, b)
1725                         {
1726                                 if (lfirst_int(item_a) != lfirst_int(item_b))
1727                                         return false;
1728                         }
1729                         break;
1730                 case T_OidList:
1731                         forboth(item_a, a, item_b, b)
1732                         {
1733                                 if (lfirst_oid(item_a) != lfirst_oid(item_b))
1734                                         return false;
1735                         }
1736                         break;
1737                 default:
1738                         elog(ERROR, "unrecognized list node type: %d",
1739                                  (int) a->type);
1740                         return false;           /* keep compiler quiet */
1741         }
1742
1743         /*
1744          * If we got here, we should have run out of elements of both lists
1745          */
1746         Assert(item_a == NULL);
1747         Assert(item_b == NULL);
1748
1749         return true;
1750 }
1751
1752 /*
1753  * Stuff from value.h
1754  */
1755
1756 static bool
1757 _equalValue(Value *a, Value *b)
1758 {
1759         COMPARE_SCALAR_FIELD(type);
1760
1761         switch (a->type)
1762         {
1763                 case T_Integer:
1764                         COMPARE_SCALAR_FIELD(val.ival);
1765                         break;
1766                 case T_Float:
1767                 case T_String:
1768                 case T_BitString:
1769                         COMPARE_STRING_FIELD(val.str);
1770                         break;
1771                 case T_Null:
1772                         /* nothing to do */
1773                         break;
1774                 default:
1775                         elog(ERROR, "unrecognized node type: %d", (int) a->type);
1776                         break;
1777         }
1778
1779         return true;
1780 }
1781
1782 /*
1783  * equal
1784  *        returns whether two nodes are equal
1785  */
1786 bool
1787 equal(void *a, void *b)
1788 {
1789         bool            retval;
1790
1791         if (a == b)
1792                 return true;
1793
1794         /*
1795          * note that a!=b, so only one of them can be NULL
1796          */
1797         if (a == NULL || b == NULL)
1798                 return false;
1799
1800         /*
1801          * are they the same type of nodes?
1802          */
1803         if (nodeTag(a) != nodeTag(b))
1804                 return false;
1805
1806         switch (nodeTag(a))
1807         {
1808                         /*
1809                          * PRIMITIVE NODES
1810                          */
1811                 case T_Resdom:
1812                         retval = _equalResdom(a, b);
1813                         break;
1814                 case T_Alias:
1815                         retval = _equalAlias(a, b);
1816                         break;
1817                 case T_RangeVar:
1818                         retval = _equalRangeVar(a, b);
1819                         break;
1820                 case T_Var:
1821                         retval = _equalVar(a, b);
1822                         break;
1823                 case T_Const:
1824                         retval = _equalConst(a, b);
1825                         break;
1826                 case T_Param:
1827                         retval = _equalParam(a, b);
1828                         break;
1829                 case T_Aggref:
1830                         retval = _equalAggref(a, b);
1831                         break;
1832                 case T_ArrayRef:
1833                         retval = _equalArrayRef(a, b);
1834                         break;
1835                 case T_FuncExpr:
1836                         retval = _equalFuncExpr(a, b);
1837                         break;
1838                 case T_OpExpr:
1839                         retval = _equalOpExpr(a, b);
1840                         break;
1841                 case T_DistinctExpr:
1842                         retval = _equalDistinctExpr(a, b);
1843                         break;
1844                 case T_ScalarArrayOpExpr:
1845                         retval = _equalScalarArrayOpExpr(a, b);
1846                         break;
1847                 case T_BoolExpr:
1848                         retval = _equalBoolExpr(a, b);
1849                         break;
1850                 case T_SubLink:
1851                         retval = _equalSubLink(a, b);
1852                         break;
1853                 case T_SubPlan:
1854                         retval = _equalSubPlan(a, b);
1855                         break;
1856                 case T_FieldSelect:
1857                         retval = _equalFieldSelect(a, b);
1858                         break;
1859                 case T_FieldStore:
1860                         retval = _equalFieldStore(a, b);
1861                         break;
1862                 case T_RelabelType:
1863                         retval = _equalRelabelType(a, b);
1864                         break;
1865                 case T_ConvertRowtypeExpr:
1866                         retval = _equalConvertRowtypeExpr(a, b);
1867                         break;
1868                 case T_CaseExpr:
1869                         retval = _equalCaseExpr(a, b);
1870                         break;
1871                 case T_CaseWhen:
1872                         retval = _equalCaseWhen(a, b);
1873                         break;
1874                 case T_CaseTestExpr:
1875                         retval = _equalCaseTestExpr(a, b);
1876                         break;
1877                 case T_ArrayExpr:
1878                         retval = _equalArrayExpr(a, b);
1879                         break;
1880                 case T_RowExpr:
1881                         retval = _equalRowExpr(a, b);
1882                         break;
1883                 case T_CoalesceExpr:
1884                         retval = _equalCoalesceExpr(a, b);
1885                         break;
1886                 case T_NullIfExpr:
1887                         retval = _equalNullIfExpr(a, b);
1888                         break;
1889                 case T_NullTest:
1890                         retval = _equalNullTest(a, b);
1891                         break;
1892                 case T_BooleanTest:
1893                         retval = _equalBooleanTest(a, b);
1894                         break;
1895                 case T_CoerceToDomain:
1896                         retval = _equalCoerceToDomain(a, b);
1897                         break;
1898                 case T_CoerceToDomainValue:
1899                         retval = _equalCoerceToDomainValue(a, b);
1900                         break;
1901                 case T_SetToDefault:
1902                         retval = _equalSetToDefault(a, b);
1903                         break;
1904                 case T_TargetEntry:
1905                         retval = _equalTargetEntry(a, b);
1906                         break;
1907                 case T_RangeTblRef:
1908                         retval = _equalRangeTblRef(a, b);
1909                         break;
1910                 case T_FromExpr:
1911                         retval = _equalFromExpr(a, b);
1912                         break;
1913                 case T_JoinExpr:
1914                         retval = _equalJoinExpr(a, b);
1915                         break;
1916
1917                         /*
1918                          * RELATION NODES
1919                          */
1920                 case T_PathKeyItem:
1921                         retval = _equalPathKeyItem(a, b);
1922                         break;
1923                 case T_RestrictInfo:
1924                         retval = _equalRestrictInfo(a, b);
1925                         break;
1926                 case T_JoinInfo:
1927                         retval = _equalJoinInfo(a, b);
1928                         break;
1929                 case T_InClauseInfo:
1930                         retval = _equalInClauseInfo(a, b);
1931                         break;
1932                 case T_List:
1933                 case T_IntList:
1934                 case T_OidList:
1935                         retval = _equalList(a, b);
1936                         break;
1937
1938                 case T_Integer:
1939                 case T_Float:
1940                 case T_String:
1941                 case T_BitString:
1942                 case T_Null:
1943                         retval = _equalValue(a, b);
1944                         break;
1945
1946                         /*
1947                          * PARSE NODES
1948                          */
1949                 case T_Query:
1950                         retval = _equalQuery(a, b);
1951                         break;
1952                 case T_InsertStmt:
1953                         retval = _equalInsertStmt(a, b);
1954                         break;
1955                 case T_DeleteStmt:
1956                         retval = _equalDeleteStmt(a, b);
1957                         break;
1958                 case T_UpdateStmt:
1959                         retval = _equalUpdateStmt(a, b);
1960                         break;
1961                 case T_SelectStmt:
1962                         retval = _equalSelectStmt(a, b);
1963                         break;
1964                 case T_SetOperationStmt:
1965                         retval = _equalSetOperationStmt(a, b);
1966                         break;
1967                 case T_AlterTableStmt:
1968                         retval = _equalAlterTableStmt(a, b);
1969                         break;
1970                 case T_AlterTableCmd:
1971                         retval = _equalAlterTableCmd(a, b);
1972                         break;
1973                 case T_AlterDomainStmt:
1974                         retval = _equalAlterDomainStmt(a, b);
1975                         break;
1976                 case T_GrantStmt:
1977                         retval = _equalGrantStmt(a, b);
1978                         break;
1979                 case T_DeclareCursorStmt:
1980                         retval = _equalDeclareCursorStmt(a, b);
1981                         break;
1982                 case T_ClosePortalStmt:
1983                         retval = _equalClosePortalStmt(a, b);
1984                         break;
1985                 case T_ClusterStmt:
1986                         retval = _equalClusterStmt(a, b);
1987                         break;
1988                 case T_CopyStmt:
1989                         retval = _equalCopyStmt(a, b);
1990                         break;
1991                 case T_CreateStmt:
1992                         retval = _equalCreateStmt(a, b);
1993                         break;
1994                 case T_InhRelation:
1995                         retval = _equalInhRelation(a, b);
1996                         break;
1997                 case T_DefineStmt:
1998                         retval = _equalDefineStmt(a, b);
1999                         break;
2000                 case T_DropStmt:
2001                         retval = _equalDropStmt(a, b);
2002                         break;
2003                 case T_TruncateStmt:
2004                         retval = _equalTruncateStmt(a, b);
2005                         break;
2006                 case T_CommentStmt:
2007                         retval = _equalCommentStmt(a, b);
2008                         break;
2009                 case T_FetchStmt:
2010                         retval = _equalFetchStmt(a, b);
2011                         break;
2012                 case T_IndexStmt:
2013                         retval = _equalIndexStmt(a, b);
2014                         break;
2015                 case T_CreateFunctionStmt:
2016                         retval = _equalCreateFunctionStmt(a, b);
2017                         break;
2018                 case T_FunctionParameter:
2019                         retval = _equalFunctionParameter(a, b);
2020                         break;
2021                 case T_RemoveAggrStmt:
2022                         retval = _equalRemoveAggrStmt(a, b);
2023                         break;
2024                 case T_RemoveFuncStmt:
2025                         retval = _equalRemoveFuncStmt(a, b);
2026                         break;
2027                 case T_RemoveOperStmt:
2028                         retval = _equalRemoveOperStmt(a, b);
2029                         break;
2030                 case T_RemoveOpClassStmt:
2031                         retval = _equalRemoveOpClassStmt(a, b);
2032                         break;
2033                 case T_RenameStmt:
2034                         retval = _equalRenameStmt(a, b);
2035                         break;
2036                 case T_AlterOwnerStmt:
2037                         retval = _equalAlterOwnerStmt(a, b);
2038                         break;
2039                 case T_RuleStmt:
2040                         retval = _equalRuleStmt(a, b);
2041                         break;
2042                 case T_NotifyStmt:
2043                         retval = _equalNotifyStmt(a, b);
2044                         break;
2045                 case T_ListenStmt:
2046                         retval = _equalListenStmt(a, b);
2047                         break;
2048                 case T_UnlistenStmt:
2049                         retval = _equalUnlistenStmt(a, b);
2050                         break;
2051                 case T_TransactionStmt:
2052                         retval = _equalTransactionStmt(a, b);
2053                         break;
2054                 case T_CompositeTypeStmt:
2055                         retval = _equalCompositeTypeStmt(a, b);
2056                         break;
2057                 case T_ViewStmt:
2058                         retval = _equalViewStmt(a, b);
2059                         break;
2060                 case T_LoadStmt:
2061                         retval = _equalLoadStmt(a, b);
2062                         break;
2063                 case T_CreateDomainStmt:
2064                         retval = _equalCreateDomainStmt(a, b);
2065                         break;
2066                 case T_CreateOpClassStmt:
2067                         retval = _equalCreateOpClassStmt(a, b);
2068                         break;
2069                 case T_CreateOpClassItem:
2070                         retval = _equalCreateOpClassItem(a, b);
2071                         break;
2072                 case T_CreatedbStmt:
2073                         retval = _equalCreatedbStmt(a, b);
2074                         break;
2075                 case T_AlterDatabaseSetStmt:
2076                         retval = _equalAlterDatabaseSetStmt(a, b);
2077                         break;
2078                 case T_DropdbStmt:
2079                         retval = _equalDropdbStmt(a, b);
2080                         break;
2081                 case T_VacuumStmt:
2082                         retval = _equalVacuumStmt(a, b);
2083                         break;
2084                 case T_ExplainStmt:
2085                         retval = _equalExplainStmt(a, b);
2086                         break;
2087                 case T_CreateSeqStmt:
2088                         retval = _equalCreateSeqStmt(a, b);
2089                         break;
2090                 case T_AlterSeqStmt:
2091                         retval = _equalAlterSeqStmt(a, b);
2092                         break;
2093                 case T_VariableSetStmt:
2094                         retval = _equalVariableSetStmt(a, b);
2095                         break;
2096                 case T_VariableShowStmt:
2097                         retval = _equalVariableShowStmt(a, b);
2098                         break;
2099                 case T_VariableResetStmt:
2100                         retval = _equalVariableResetStmt(a, b);
2101                         break;
2102                 case T_CreateTableSpaceStmt:
2103                         retval = _equalCreateTableSpaceStmt(a, b);
2104                         break;
2105                 case T_DropTableSpaceStmt:
2106                         retval = _equalDropTableSpaceStmt(a, b);
2107                         break;
2108                 case T_CreateTrigStmt:
2109                         retval = _equalCreateTrigStmt(a, b);
2110                         break;
2111                 case T_DropPropertyStmt:
2112                         retval = _equalDropPropertyStmt(a, b);
2113                         break;
2114                 case T_CreatePLangStmt:
2115                         retval = _equalCreatePLangStmt(a, b);
2116                         break;
2117                 case T_DropPLangStmt:
2118                         retval = _equalDropPLangStmt(a, b);
2119                         break;
2120                 case T_CreateUserStmt:
2121                         retval = _equalCreateUserStmt(a, b);
2122                         break;
2123                 case T_AlterUserStmt:
2124                         retval = _equalAlterUserStmt(a, b);
2125                         break;
2126                 case T_AlterUserSetStmt:
2127                         retval = _equalAlterUserSetStmt(a, b);
2128                         break;
2129                 case T_DropUserStmt:
2130                         retval = _equalDropUserStmt(a, b);
2131                         break;
2132                 case T_LockStmt:
2133                         retval = _equalLockStmt(a, b);
2134                         break;
2135                 case T_ConstraintsSetStmt:
2136                         retval = _equalConstraintsSetStmt(a, b);
2137                         break;
2138                 case T_CreateGroupStmt:
2139                         retval = _equalCreateGroupStmt(a, b);
2140                         break;
2141                 case T_AlterGroupStmt:
2142                         retval = _equalAlterGroupStmt(a, b);
2143                         break;
2144                 case T_DropGroupStmt:
2145                         retval = _equalDropGroupStmt(a, b);
2146                         break;
2147                 case T_ReindexStmt:
2148                         retval = _equalReindexStmt(a, b);
2149                         break;
2150                 case T_CheckPointStmt:
2151                         retval = true;
2152                         break;
2153                 case T_CreateSchemaStmt:
2154                         retval = _equalCreateSchemaStmt(a, b);
2155                         break;
2156                 case T_CreateConversionStmt:
2157                         retval = _equalCreateConversionStmt(a, b);
2158                         break;
2159                 case T_CreateCastStmt:
2160                         retval = _equalCreateCastStmt(a, b);
2161                         break;
2162                 case T_DropCastStmt:
2163                         retval = _equalDropCastStmt(a, b);
2164                         break;
2165                 case T_PrepareStmt:
2166                         retval = _equalPrepareStmt(a, b);
2167                         break;
2168                 case T_ExecuteStmt:
2169                         retval = _equalExecuteStmt(a, b);
2170                         break;
2171                 case T_DeallocateStmt:
2172                         retval = _equalDeallocateStmt(a, b);
2173                         break;
2174
2175                 case T_A_Expr:
2176                         retval = _equalAExpr(a, b);
2177                         break;
2178                 case T_ColumnRef:
2179                         retval = _equalColumnRef(a, b);
2180                         break;
2181                 case T_ParamRef:
2182                         retval = _equalParamRef(a, b);
2183                         break;
2184                 case T_A_Const:
2185                         retval = _equalAConst(a, b);
2186                         break;
2187                 case T_FuncCall:
2188                         retval = _equalFuncCall(a, b);
2189                         break;
2190                 case T_A_Indices:
2191                         retval = _equalAIndices(a, b);
2192                         break;
2193                 case T_A_Indirection:
2194                         retval = _equalA_Indirection(a, b);
2195                         break;
2196                 case T_ResTarget:
2197                         retval = _equalResTarget(a, b);
2198                         break;
2199                 case T_TypeCast:
2200                         retval = _equalTypeCast(a, b);
2201                         break;
2202                 case T_SortBy:
2203                         retval = _equalSortBy(a, b);
2204                         break;
2205                 case T_RangeSubselect:
2206                         retval = _equalRangeSubselect(a, b);
2207                         break;
2208                 case T_RangeFunction:
2209                         retval = _equalRangeFunction(a, b);
2210                         break;
2211                 case T_TypeName:
2212                         retval = _equalTypeName(a, b);
2213                         break;
2214                 case T_IndexElem:
2215                         retval = _equalIndexElem(a, b);
2216                         break;
2217                 case T_ColumnDef:
2218                         retval = _equalColumnDef(a, b);
2219                         break;
2220                 case T_Constraint:
2221                         retval = _equalConstraint(a, b);
2222                         break;
2223                 case T_DefElem:
2224                         retval = _equalDefElem(a, b);
2225                         break;
2226                 case T_RangeTblEntry:
2227                         retval = _equalRangeTblEntry(a, b);
2228                         break;
2229                 case T_SortClause:
2230                         retval = _equalSortClause(a, b);
2231                         break;
2232                 case T_GroupClause:
2233                         /* GroupClause is equivalent to SortClause */
2234                         retval = _equalSortClause(a, b);
2235                         break;
2236                 case T_FkConstraint:
2237                         retval = _equalFkConstraint(a, b);
2238                         break;
2239                 case T_PrivGrantee:
2240                         retval = _equalPrivGrantee(a, b);
2241                         break;
2242                 case T_FuncWithArgs:
2243                         retval = _equalFuncWithArgs(a, b);
2244                         break;
2245
2246                 default:
2247                         elog(ERROR, "unrecognized node type: %d",
2248                                  (int) nodeTag(a));
2249                         retval = false;         /* keep compiler quiet */
2250                         break;
2251         }
2252
2253         return retval;
2254 }