]> granicus.if.org Git - postgresql/blob - src/backend/nodes/equalfuncs.c
6d727a6327831a4ca4599ee2f53c3fbd7b716555
[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.250 2005/07/31 17:19:18 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 _equalAlterDatabaseStmt(AlterDatabaseStmt *a, AlterDatabaseStmt *b)
1156 {
1157         COMPARE_STRING_FIELD(dbname);
1158         COMPARE_NODE_FIELD(options);
1159
1160         return true;
1161 }
1162
1163 static bool
1164 _equalAlterDatabaseSetStmt(AlterDatabaseSetStmt *a, AlterDatabaseSetStmt *b)
1165 {
1166         COMPARE_STRING_FIELD(dbname);
1167         COMPARE_STRING_FIELD(variable);
1168         COMPARE_NODE_FIELD(value);
1169
1170         return true;
1171 }
1172
1173 static bool
1174 _equalDropdbStmt(DropdbStmt *a, DropdbStmt *b)
1175 {
1176         COMPARE_STRING_FIELD(dbname);
1177
1178         return true;
1179 }
1180
1181 static bool
1182 _equalVacuumStmt(VacuumStmt *a, VacuumStmt *b)
1183 {
1184         COMPARE_SCALAR_FIELD(vacuum);
1185         COMPARE_SCALAR_FIELD(full);
1186         COMPARE_SCALAR_FIELD(analyze);
1187         COMPARE_SCALAR_FIELD(freeze);
1188         COMPARE_SCALAR_FIELD(verbose);
1189         COMPARE_NODE_FIELD(relation);
1190         COMPARE_NODE_FIELD(va_cols);
1191
1192         return true;
1193 }
1194
1195 static bool
1196 _equalExplainStmt(ExplainStmt *a, ExplainStmt *b)
1197 {
1198         COMPARE_NODE_FIELD(query);
1199         COMPARE_SCALAR_FIELD(verbose);
1200         COMPARE_SCALAR_FIELD(analyze);
1201
1202         return true;
1203 }
1204
1205 static bool
1206 _equalCreateSeqStmt(CreateSeqStmt *a, CreateSeqStmt *b)
1207 {
1208         COMPARE_NODE_FIELD(sequence);
1209         COMPARE_NODE_FIELD(options);
1210
1211         return true;
1212 }
1213
1214 static bool
1215 _equalAlterSeqStmt(AlterSeqStmt *a, AlterSeqStmt *b)
1216 {
1217         COMPARE_NODE_FIELD(sequence);
1218         COMPARE_NODE_FIELD(options);
1219
1220         return true;
1221 }
1222
1223 static bool
1224 _equalVariableSetStmt(VariableSetStmt *a, VariableSetStmt *b)
1225 {
1226         COMPARE_STRING_FIELD(name);
1227         COMPARE_NODE_FIELD(args);
1228         COMPARE_SCALAR_FIELD(is_local);
1229
1230         return true;
1231 }
1232
1233 static bool
1234 _equalVariableShowStmt(VariableShowStmt *a, VariableShowStmt *b)
1235 {
1236         COMPARE_STRING_FIELD(name);
1237
1238         return true;
1239 }
1240
1241 static bool
1242 _equalVariableResetStmt(VariableResetStmt *a, VariableResetStmt *b)
1243 {
1244         COMPARE_STRING_FIELD(name);
1245
1246         return true;
1247 }
1248
1249 static bool
1250 _equalCreateTableSpaceStmt(CreateTableSpaceStmt *a, CreateTableSpaceStmt *b)
1251 {
1252         COMPARE_STRING_FIELD(tablespacename);
1253         COMPARE_STRING_FIELD(owner);
1254         COMPARE_STRING_FIELD(location);
1255
1256         return true;
1257 }
1258
1259 static bool
1260 _equalDropTableSpaceStmt(DropTableSpaceStmt *a, DropTableSpaceStmt *b)
1261 {
1262         COMPARE_STRING_FIELD(tablespacename);
1263
1264         return true;
1265 }
1266
1267 static bool
1268 _equalCreateTrigStmt(CreateTrigStmt *a, CreateTrigStmt *b)
1269 {
1270         COMPARE_STRING_FIELD(trigname);
1271         COMPARE_NODE_FIELD(relation);
1272         COMPARE_NODE_FIELD(funcname);
1273         COMPARE_NODE_FIELD(args);
1274         COMPARE_SCALAR_FIELD(before);
1275         COMPARE_SCALAR_FIELD(row);
1276         if (strcmp(a->actions, b->actions) != 0)        /* in-line string field */
1277                 return false;
1278         COMPARE_SCALAR_FIELD(isconstraint);
1279         COMPARE_SCALAR_FIELD(deferrable);
1280         COMPARE_SCALAR_FIELD(initdeferred);
1281         COMPARE_NODE_FIELD(constrrel);
1282
1283         return true;
1284 }
1285
1286 static bool
1287 _equalDropPropertyStmt(DropPropertyStmt *a, DropPropertyStmt *b)
1288 {
1289         COMPARE_NODE_FIELD(relation);
1290         COMPARE_STRING_FIELD(property);
1291         COMPARE_SCALAR_FIELD(removeType);
1292         COMPARE_SCALAR_FIELD(behavior);
1293
1294         return true;
1295 }
1296
1297 static bool
1298 _equalCreatePLangStmt(CreatePLangStmt *a, CreatePLangStmt *b)
1299 {
1300         COMPARE_STRING_FIELD(plname);
1301         COMPARE_NODE_FIELD(plhandler);
1302         COMPARE_NODE_FIELD(plvalidator);
1303         COMPARE_SCALAR_FIELD(pltrusted);
1304
1305         return true;
1306 }
1307
1308 static bool
1309 _equalDropPLangStmt(DropPLangStmt *a, DropPLangStmt *b)
1310 {
1311         COMPARE_STRING_FIELD(plname);
1312         COMPARE_SCALAR_FIELD(behavior);
1313
1314         return true;
1315 }
1316
1317 static bool
1318 _equalCreateRoleStmt(CreateRoleStmt *a, CreateRoleStmt *b)
1319 {
1320         COMPARE_SCALAR_FIELD(stmt_type);
1321         COMPARE_STRING_FIELD(role);
1322         COMPARE_NODE_FIELD(options);
1323
1324         return true;
1325 }
1326
1327 static bool
1328 _equalAlterRoleStmt(AlterRoleStmt *a, AlterRoleStmt *b)
1329 {
1330         COMPARE_STRING_FIELD(role);
1331         COMPARE_NODE_FIELD(options);
1332         COMPARE_SCALAR_FIELD(action);
1333
1334         return true;
1335 }
1336
1337 static bool
1338 _equalAlterRoleSetStmt(AlterRoleSetStmt *a, AlterRoleSetStmt *b)
1339 {
1340         COMPARE_STRING_FIELD(role);
1341         COMPARE_STRING_FIELD(variable);
1342         COMPARE_NODE_FIELD(value);
1343
1344         return true;
1345 }
1346
1347 static bool
1348 _equalDropRoleStmt(DropRoleStmt *a, DropRoleStmt *b)
1349 {
1350         COMPARE_NODE_FIELD(roles);
1351
1352         return true;
1353 }
1354
1355 static bool
1356 _equalLockStmt(LockStmt *a, LockStmt *b)
1357 {
1358         COMPARE_NODE_FIELD(relations);
1359         COMPARE_SCALAR_FIELD(mode);
1360         COMPARE_SCALAR_FIELD(nowait);
1361
1362         return true;
1363 }
1364
1365 static bool
1366 _equalConstraintsSetStmt(ConstraintsSetStmt *a, ConstraintsSetStmt *b)
1367 {
1368         COMPARE_NODE_FIELD(constraints);
1369         COMPARE_SCALAR_FIELD(deferred);
1370
1371         return true;
1372 }
1373
1374 static bool
1375 _equalReindexStmt(ReindexStmt *a, ReindexStmt *b)
1376 {
1377         COMPARE_SCALAR_FIELD(kind);
1378         COMPARE_NODE_FIELD(relation);
1379         COMPARE_STRING_FIELD(name);
1380         COMPARE_SCALAR_FIELD(do_system);
1381         COMPARE_SCALAR_FIELD(do_user);
1382
1383         return true;
1384 }
1385
1386 static bool
1387 _equalCreateSchemaStmt(CreateSchemaStmt *a, CreateSchemaStmt *b)
1388 {
1389         COMPARE_STRING_FIELD(schemaname);
1390         COMPARE_STRING_FIELD(authid);
1391         COMPARE_NODE_FIELD(schemaElts);
1392
1393         return true;
1394 }
1395
1396 static bool
1397 _equalCreateConversionStmt(CreateConversionStmt *a, CreateConversionStmt *b)
1398 {
1399         COMPARE_NODE_FIELD(conversion_name);
1400         COMPARE_STRING_FIELD(for_encoding_name);
1401         COMPARE_STRING_FIELD(to_encoding_name);
1402         COMPARE_NODE_FIELD(func_name);
1403         COMPARE_SCALAR_FIELD(def);
1404
1405         return true;
1406 }
1407
1408 static bool
1409 _equalCreateCastStmt(CreateCastStmt *a, CreateCastStmt *b)
1410 {
1411         COMPARE_NODE_FIELD(sourcetype);
1412         COMPARE_NODE_FIELD(targettype);
1413         COMPARE_NODE_FIELD(func);
1414         COMPARE_SCALAR_FIELD(context);
1415
1416         return true;
1417 }
1418
1419 static bool
1420 _equalDropCastStmt(DropCastStmt *a, DropCastStmt *b)
1421 {
1422         COMPARE_NODE_FIELD(sourcetype);
1423         COMPARE_NODE_FIELD(targettype);
1424         COMPARE_SCALAR_FIELD(behavior);
1425
1426         return true;
1427 }
1428
1429 static bool
1430 _equalPrepareStmt(PrepareStmt *a, PrepareStmt *b)
1431 {
1432         COMPARE_STRING_FIELD(name);
1433         COMPARE_NODE_FIELD(argtypes);
1434         COMPARE_NODE_FIELD(argtype_oids);
1435         COMPARE_NODE_FIELD(query);
1436
1437         return true;
1438 }
1439
1440 static bool
1441 _equalExecuteStmt(ExecuteStmt *a, ExecuteStmt *b)
1442 {
1443         COMPARE_STRING_FIELD(name);
1444         COMPARE_NODE_FIELD(into);
1445         COMPARE_NODE_FIELD(params);
1446
1447         return true;
1448 }
1449
1450 static bool
1451 _equalDeallocateStmt(DeallocateStmt *a, DeallocateStmt *b)
1452 {
1453         COMPARE_STRING_FIELD(name);
1454
1455         return true;
1456 }
1457
1458
1459 /*
1460  * stuff from parsenodes.h
1461  */
1462
1463 static bool
1464 _equalAExpr(A_Expr *a, A_Expr *b)
1465 {
1466         COMPARE_SCALAR_FIELD(kind);
1467         COMPARE_NODE_FIELD(name);
1468         COMPARE_NODE_FIELD(lexpr);
1469         COMPARE_NODE_FIELD(rexpr);
1470
1471         return true;
1472 }
1473
1474 static bool
1475 _equalColumnRef(ColumnRef *a, ColumnRef *b)
1476 {
1477         COMPARE_NODE_FIELD(fields);
1478
1479         return true;
1480 }
1481
1482 static bool
1483 _equalParamRef(ParamRef *a, ParamRef *b)
1484 {
1485         COMPARE_SCALAR_FIELD(number);
1486
1487         return true;
1488 }
1489
1490 static bool
1491 _equalAConst(A_Const *a, A_Const *b)
1492 {
1493         if (!equal(&a->val, &b->val))           /* hack for in-line Value field */
1494                 return false;
1495         COMPARE_NODE_FIELD(typename);
1496
1497         return true;
1498 }
1499
1500 static bool
1501 _equalFuncCall(FuncCall *a, FuncCall *b)
1502 {
1503         COMPARE_NODE_FIELD(funcname);
1504         COMPARE_NODE_FIELD(args);
1505         COMPARE_SCALAR_FIELD(agg_star);
1506         COMPARE_SCALAR_FIELD(agg_distinct);
1507
1508         return true;
1509 }
1510
1511 static bool
1512 _equalAIndices(A_Indices *a, A_Indices *b)
1513 {
1514         COMPARE_NODE_FIELD(lidx);
1515         COMPARE_NODE_FIELD(uidx);
1516
1517         return true;
1518 }
1519
1520 static bool
1521 _equalA_Indirection(A_Indirection *a, A_Indirection *b)
1522 {
1523         COMPARE_NODE_FIELD(arg);
1524         COMPARE_NODE_FIELD(indirection);
1525
1526         return true;
1527 }
1528
1529 static bool
1530 _equalResTarget(ResTarget *a, ResTarget *b)
1531 {
1532         COMPARE_STRING_FIELD(name);
1533         COMPARE_NODE_FIELD(indirection);
1534         COMPARE_NODE_FIELD(val);
1535
1536         return true;
1537 }
1538
1539 static bool
1540 _equalTypeName(TypeName *a, TypeName *b)
1541 {
1542         COMPARE_NODE_FIELD(names);
1543         COMPARE_SCALAR_FIELD(typeid);
1544         COMPARE_SCALAR_FIELD(timezone);
1545         COMPARE_SCALAR_FIELD(setof);
1546         COMPARE_SCALAR_FIELD(pct_type);
1547         COMPARE_SCALAR_FIELD(typmod);
1548         COMPARE_NODE_FIELD(arrayBounds);
1549
1550         return true;
1551 }
1552
1553 static bool
1554 _equalTypeCast(TypeCast *a, TypeCast *b)
1555 {
1556         COMPARE_NODE_FIELD(arg);
1557         COMPARE_NODE_FIELD(typename);
1558
1559         return true;
1560 }
1561
1562 static bool
1563 _equalSortBy(SortBy *a, SortBy *b)
1564 {
1565         COMPARE_SCALAR_FIELD(sortby_kind);
1566         COMPARE_NODE_FIELD(useOp);
1567         COMPARE_NODE_FIELD(node);
1568
1569         return true;
1570 }
1571
1572 static bool
1573 _equalRangeSubselect(RangeSubselect *a, RangeSubselect *b)
1574 {
1575         COMPARE_NODE_FIELD(subquery);
1576         COMPARE_NODE_FIELD(alias);
1577
1578         return true;
1579 }
1580
1581 static bool
1582 _equalRangeFunction(RangeFunction *a, RangeFunction *b)
1583 {
1584         COMPARE_NODE_FIELD(funccallnode);
1585         COMPARE_NODE_FIELD(alias);
1586         COMPARE_NODE_FIELD(coldeflist);
1587
1588         return true;
1589 }
1590
1591 static bool
1592 _equalIndexElem(IndexElem *a, IndexElem *b)
1593 {
1594         COMPARE_STRING_FIELD(name);
1595         COMPARE_NODE_FIELD(expr);
1596         COMPARE_NODE_FIELD(opclass);
1597
1598         return true;
1599 }
1600
1601 static bool
1602 _equalColumnDef(ColumnDef *a, ColumnDef *b)
1603 {
1604         COMPARE_STRING_FIELD(colname);
1605         COMPARE_NODE_FIELD(typename);
1606         COMPARE_SCALAR_FIELD(inhcount);
1607         COMPARE_SCALAR_FIELD(is_local);
1608         COMPARE_SCALAR_FIELD(is_not_null);
1609         COMPARE_NODE_FIELD(raw_default);
1610         COMPARE_STRING_FIELD(cooked_default);
1611         COMPARE_NODE_FIELD(constraints);
1612         COMPARE_NODE_FIELD(support);
1613
1614         return true;
1615 }
1616
1617 static bool
1618 _equalConstraint(Constraint *a, Constraint *b)
1619 {
1620         COMPARE_SCALAR_FIELD(contype);
1621         COMPARE_STRING_FIELD(name);
1622         COMPARE_NODE_FIELD(raw_expr);
1623         COMPARE_STRING_FIELD(cooked_expr);
1624         COMPARE_NODE_FIELD(keys);
1625         COMPARE_STRING_FIELD(indexspace);
1626
1627         return true;
1628 }
1629
1630 static bool
1631 _equalDefElem(DefElem *a, DefElem *b)
1632 {
1633         COMPARE_STRING_FIELD(defname);
1634         COMPARE_NODE_FIELD(arg);
1635
1636         return true;
1637 }
1638
1639 static bool
1640 _equalRangeTblEntry(RangeTblEntry *a, RangeTblEntry *b)
1641 {
1642         COMPARE_SCALAR_FIELD(rtekind);
1643         COMPARE_SCALAR_FIELD(relid);
1644         COMPARE_NODE_FIELD(subquery);
1645         COMPARE_NODE_FIELD(funcexpr);
1646         COMPARE_NODE_FIELD(coldeflist);
1647         COMPARE_SCALAR_FIELD(jointype);
1648         COMPARE_NODE_FIELD(joinaliasvars);
1649         COMPARE_NODE_FIELD(alias);
1650         COMPARE_NODE_FIELD(eref);
1651         COMPARE_SCALAR_FIELD(inh);
1652         COMPARE_SCALAR_FIELD(inFromCl);
1653         COMPARE_SCALAR_FIELD(requiredPerms);
1654         COMPARE_SCALAR_FIELD(checkAsUser);
1655
1656         return true;
1657 }
1658
1659 static bool
1660 _equalSortClause(SortClause *a, SortClause *b)
1661 {
1662         COMPARE_SCALAR_FIELD(tleSortGroupRef);
1663         COMPARE_SCALAR_FIELD(sortop);
1664
1665         return true;
1666 }
1667
1668 static bool
1669 _equalFkConstraint(FkConstraint *a, FkConstraint *b)
1670 {
1671         COMPARE_STRING_FIELD(constr_name);
1672         COMPARE_NODE_FIELD(pktable);
1673         COMPARE_NODE_FIELD(fk_attrs);
1674         COMPARE_NODE_FIELD(pk_attrs);
1675         COMPARE_SCALAR_FIELD(fk_matchtype);
1676         COMPARE_SCALAR_FIELD(fk_upd_action);
1677         COMPARE_SCALAR_FIELD(fk_del_action);
1678         COMPARE_SCALAR_FIELD(deferrable);
1679         COMPARE_SCALAR_FIELD(initdeferred);
1680         COMPARE_SCALAR_FIELD(skip_validation);
1681
1682         return true;
1683 }
1684
1685
1686 /*
1687  * Stuff from pg_list.h
1688  */
1689
1690 static bool
1691 _equalList(List *a, List *b)
1692 {
1693         ListCell   *item_a;
1694         ListCell   *item_b;
1695
1696         /*
1697          * Try to reject by simple scalar checks before grovelling through all
1698          * the list elements...
1699          */
1700         COMPARE_SCALAR_FIELD(type);
1701         COMPARE_SCALAR_FIELD(length);
1702
1703         /*
1704          * We place the switch outside the loop for the sake of efficiency;
1705          * this may not be worth doing...
1706          */
1707         switch (a->type)
1708         {
1709                 case T_List:
1710                         forboth(item_a, a, item_b, b)
1711                         {
1712                                 if (!equal(lfirst(item_a), lfirst(item_b)))
1713                                         return false;
1714                         }
1715                         break;
1716                 case T_IntList:
1717                         forboth(item_a, a, item_b, b)
1718                         {
1719                                 if (lfirst_int(item_a) != lfirst_int(item_b))
1720                                         return false;
1721                         }
1722                         break;
1723                 case T_OidList:
1724                         forboth(item_a, a, item_b, b)
1725                         {
1726                                 if (lfirst_oid(item_a) != lfirst_oid(item_b))
1727                                         return false;
1728                         }
1729                         break;
1730                 default:
1731                         elog(ERROR, "unrecognized list node type: %d",
1732                                  (int) a->type);
1733                         return false;           /* keep compiler quiet */
1734         }
1735
1736         /*
1737          * If we got here, we should have run out of elements of both lists
1738          */
1739         Assert(item_a == NULL);
1740         Assert(item_b == NULL);
1741
1742         return true;
1743 }
1744
1745 /*
1746  * Stuff from value.h
1747  */
1748
1749 static bool
1750 _equalValue(Value *a, Value *b)
1751 {
1752         COMPARE_SCALAR_FIELD(type);
1753
1754         switch (a->type)
1755         {
1756                 case T_Integer:
1757                         COMPARE_SCALAR_FIELD(val.ival);
1758                         break;
1759                 case T_Float:
1760                 case T_String:
1761                 case T_BitString:
1762                         COMPARE_STRING_FIELD(val.str);
1763                         break;
1764                 case T_Null:
1765                         /* nothing to do */
1766                         break;
1767                 default:
1768                         elog(ERROR, "unrecognized node type: %d", (int) a->type);
1769                         break;
1770         }
1771
1772         return true;
1773 }
1774
1775 /*
1776  * equal
1777  *        returns whether two nodes are equal
1778  */
1779 bool
1780 equal(void *a, void *b)
1781 {
1782         bool            retval;
1783
1784         if (a == b)
1785                 return true;
1786
1787         /*
1788          * note that a!=b, so only one of them can be NULL
1789          */
1790         if (a == NULL || b == NULL)
1791                 return false;
1792
1793         /*
1794          * are they the same type of nodes?
1795          */
1796         if (nodeTag(a) != nodeTag(b))
1797                 return false;
1798
1799         switch (nodeTag(a))
1800         {
1801                         /*
1802                          * PRIMITIVE NODES
1803                          */
1804                 case T_Alias:
1805                         retval = _equalAlias(a, b);
1806                         break;
1807                 case T_RangeVar:
1808                         retval = _equalRangeVar(a, b);
1809                         break;
1810                 case T_Var:
1811                         retval = _equalVar(a, b);
1812                         break;
1813                 case T_Const:
1814                         retval = _equalConst(a, b);
1815                         break;
1816                 case T_Param:
1817                         retval = _equalParam(a, b);
1818                         break;
1819                 case T_Aggref:
1820                         retval = _equalAggref(a, b);
1821                         break;
1822                 case T_ArrayRef:
1823                         retval = _equalArrayRef(a, b);
1824                         break;
1825                 case T_FuncExpr:
1826                         retval = _equalFuncExpr(a, b);
1827                         break;
1828                 case T_OpExpr:
1829                         retval = _equalOpExpr(a, b);
1830                         break;
1831                 case T_DistinctExpr:
1832                         retval = _equalDistinctExpr(a, b);
1833                         break;
1834                 case T_ScalarArrayOpExpr:
1835                         retval = _equalScalarArrayOpExpr(a, b);
1836                         break;
1837                 case T_BoolExpr:
1838                         retval = _equalBoolExpr(a, b);
1839                         break;
1840                 case T_SubLink:
1841                         retval = _equalSubLink(a, b);
1842                         break;
1843                 case T_SubPlan:
1844                         retval = _equalSubPlan(a, b);
1845                         break;
1846                 case T_FieldSelect:
1847                         retval = _equalFieldSelect(a, b);
1848                         break;
1849                 case T_FieldStore:
1850                         retval = _equalFieldStore(a, b);
1851                         break;
1852                 case T_RelabelType:
1853                         retval = _equalRelabelType(a, b);
1854                         break;
1855                 case T_ConvertRowtypeExpr:
1856                         retval = _equalConvertRowtypeExpr(a, b);
1857                         break;
1858                 case T_CaseExpr:
1859                         retval = _equalCaseExpr(a, b);
1860                         break;
1861                 case T_CaseWhen:
1862                         retval = _equalCaseWhen(a, b);
1863                         break;
1864                 case T_CaseTestExpr:
1865                         retval = _equalCaseTestExpr(a, b);
1866                         break;
1867                 case T_ArrayExpr:
1868                         retval = _equalArrayExpr(a, b);
1869                         break;
1870                 case T_RowExpr:
1871                         retval = _equalRowExpr(a, b);
1872                         break;
1873                 case T_CoalesceExpr:
1874                         retval = _equalCoalesceExpr(a, b);
1875                         break;
1876                 case T_MinMaxExpr:
1877                         retval = _equalMinMaxExpr(a, b);
1878                         break;
1879                 case T_NullIfExpr:
1880                         retval = _equalNullIfExpr(a, b);
1881                         break;
1882                 case T_NullTest:
1883                         retval = _equalNullTest(a, b);
1884                         break;
1885                 case T_BooleanTest:
1886                         retval = _equalBooleanTest(a, b);
1887                         break;
1888                 case T_CoerceToDomain:
1889                         retval = _equalCoerceToDomain(a, b);
1890                         break;
1891                 case T_CoerceToDomainValue:
1892                         retval = _equalCoerceToDomainValue(a, b);
1893                         break;
1894                 case T_SetToDefault:
1895                         retval = _equalSetToDefault(a, b);
1896                         break;
1897                 case T_TargetEntry:
1898                         retval = _equalTargetEntry(a, b);
1899                         break;
1900                 case T_RangeTblRef:
1901                         retval = _equalRangeTblRef(a, b);
1902                         break;
1903                 case T_FromExpr:
1904                         retval = _equalFromExpr(a, b);
1905                         break;
1906                 case T_JoinExpr:
1907                         retval = _equalJoinExpr(a, b);
1908                         break;
1909
1910                         /*
1911                          * RELATION NODES
1912                          */
1913                 case T_PathKeyItem:
1914                         retval = _equalPathKeyItem(a, b);
1915                         break;
1916                 case T_RestrictInfo:
1917                         retval = _equalRestrictInfo(a, b);
1918                         break;
1919                 case T_InClauseInfo:
1920                         retval = _equalInClauseInfo(a, b);
1921                         break;
1922                 case T_List:
1923                 case T_IntList:
1924                 case T_OidList:
1925                         retval = _equalList(a, b);
1926                         break;
1927
1928                 case T_Integer:
1929                 case T_Float:
1930                 case T_String:
1931                 case T_BitString:
1932                 case T_Null:
1933                         retval = _equalValue(a, b);
1934                         break;
1935
1936                         /*
1937                          * PARSE NODES
1938                          */
1939                 case T_Query:
1940                         retval = _equalQuery(a, b);
1941                         break;
1942                 case T_InsertStmt:
1943                         retval = _equalInsertStmt(a, b);
1944                         break;
1945                 case T_DeleteStmt:
1946                         retval = _equalDeleteStmt(a, b);
1947                         break;
1948                 case T_UpdateStmt:
1949                         retval = _equalUpdateStmt(a, b);
1950                         break;
1951                 case T_SelectStmt:
1952                         retval = _equalSelectStmt(a, b);
1953                         break;
1954                 case T_SetOperationStmt:
1955                         retval = _equalSetOperationStmt(a, b);
1956                         break;
1957                 case T_AlterTableStmt:
1958                         retval = _equalAlterTableStmt(a, b);
1959                         break;
1960                 case T_AlterTableCmd:
1961                         retval = _equalAlterTableCmd(a, b);
1962                         break;
1963                 case T_AlterDomainStmt:
1964                         retval = _equalAlterDomainStmt(a, b);
1965                         break;
1966                 case T_GrantStmt:
1967                         retval = _equalGrantStmt(a, b);
1968                         break;
1969                 case T_GrantRoleStmt:
1970                         retval = _equalGrantRoleStmt(a, b);
1971                         break;
1972                 case T_DeclareCursorStmt:
1973                         retval = _equalDeclareCursorStmt(a, b);
1974                         break;
1975                 case T_ClosePortalStmt:
1976                         retval = _equalClosePortalStmt(a, b);
1977                         break;
1978                 case T_ClusterStmt:
1979                         retval = _equalClusterStmt(a, b);
1980                         break;
1981                 case T_CopyStmt:
1982                         retval = _equalCopyStmt(a, b);
1983                         break;
1984                 case T_CreateStmt:
1985                         retval = _equalCreateStmt(a, b);
1986                         break;
1987                 case T_InhRelation:
1988                         retval = _equalInhRelation(a, b);
1989                         break;
1990                 case T_DefineStmt:
1991                         retval = _equalDefineStmt(a, b);
1992                         break;
1993                 case T_DropStmt:
1994                         retval = _equalDropStmt(a, b);
1995                         break;
1996                 case T_TruncateStmt:
1997                         retval = _equalTruncateStmt(a, b);
1998                         break;
1999                 case T_CommentStmt:
2000                         retval = _equalCommentStmt(a, b);
2001                         break;
2002                 case T_FetchStmt:
2003                         retval = _equalFetchStmt(a, b);
2004                         break;
2005                 case T_IndexStmt:
2006                         retval = _equalIndexStmt(a, b);
2007                         break;
2008                 case T_CreateFunctionStmt:
2009                         retval = _equalCreateFunctionStmt(a, b);
2010                         break;
2011                 case T_FunctionParameter:
2012                         retval = _equalFunctionParameter(a, b);
2013                         break;
2014                 case T_AlterFunctionStmt:
2015                         retval = _equalAlterFunctionStmt(a, b);
2016                         break;
2017                 case T_RemoveAggrStmt:
2018                         retval = _equalRemoveAggrStmt(a, b);
2019                         break;
2020                 case T_RemoveFuncStmt:
2021                         retval = _equalRemoveFuncStmt(a, b);
2022                         break;
2023                 case T_RemoveOperStmt:
2024                         retval = _equalRemoveOperStmt(a, b);
2025                         break;
2026                 case T_RemoveOpClassStmt:
2027                         retval = _equalRemoveOpClassStmt(a, b);
2028                         break;
2029                 case T_RenameStmt:
2030                         retval = _equalRenameStmt(a, b);
2031                         break;
2032                 case T_AlterOwnerStmt:
2033                         retval = _equalAlterOwnerStmt(a, b);
2034                         break;
2035                 case T_RuleStmt:
2036                         retval = _equalRuleStmt(a, b);
2037                         break;
2038                 case T_NotifyStmt:
2039                         retval = _equalNotifyStmt(a, b);
2040                         break;
2041                 case T_ListenStmt:
2042                         retval = _equalListenStmt(a, b);
2043                         break;
2044                 case T_UnlistenStmt:
2045                         retval = _equalUnlistenStmt(a, b);
2046                         break;
2047                 case T_TransactionStmt:
2048                         retval = _equalTransactionStmt(a, b);
2049                         break;
2050                 case T_CompositeTypeStmt:
2051                         retval = _equalCompositeTypeStmt(a, b);
2052                         break;
2053                 case T_ViewStmt:
2054                         retval = _equalViewStmt(a, b);
2055                         break;
2056                 case T_LoadStmt:
2057                         retval = _equalLoadStmt(a, b);
2058                         break;
2059                 case T_CreateDomainStmt:
2060                         retval = _equalCreateDomainStmt(a, b);
2061                         break;
2062                 case T_CreateOpClassStmt:
2063                         retval = _equalCreateOpClassStmt(a, b);
2064                         break;
2065                 case T_CreateOpClassItem:
2066                         retval = _equalCreateOpClassItem(a, b);
2067                         break;
2068                 case T_CreatedbStmt:
2069                         retval = _equalCreatedbStmt(a, b);
2070                         break;
2071                 case T_AlterDatabaseStmt:
2072                         retval = _equalAlterDatabaseStmt(a, b);
2073                         break;
2074                 case T_AlterDatabaseSetStmt:
2075                         retval = _equalAlterDatabaseSetStmt(a, b);
2076                         break;
2077                 case T_DropdbStmt:
2078                         retval = _equalDropdbStmt(a, b);
2079                         break;
2080                 case T_VacuumStmt:
2081                         retval = _equalVacuumStmt(a, b);
2082                         break;
2083                 case T_ExplainStmt:
2084                         retval = _equalExplainStmt(a, b);
2085                         break;
2086                 case T_CreateSeqStmt:
2087                         retval = _equalCreateSeqStmt(a, b);
2088                         break;
2089                 case T_AlterSeqStmt:
2090                         retval = _equalAlterSeqStmt(a, b);
2091                         break;
2092                 case T_VariableSetStmt:
2093                         retval = _equalVariableSetStmt(a, b);
2094                         break;
2095                 case T_VariableShowStmt:
2096                         retval = _equalVariableShowStmt(a, b);
2097                         break;
2098                 case T_VariableResetStmt:
2099                         retval = _equalVariableResetStmt(a, b);
2100                         break;
2101                 case T_CreateTableSpaceStmt:
2102                         retval = _equalCreateTableSpaceStmt(a, b);
2103                         break;
2104                 case T_DropTableSpaceStmt:
2105                         retval = _equalDropTableSpaceStmt(a, b);
2106                         break;
2107                 case T_CreateTrigStmt:
2108                         retval = _equalCreateTrigStmt(a, b);
2109                         break;
2110                 case T_DropPropertyStmt:
2111                         retval = _equalDropPropertyStmt(a, b);
2112                         break;
2113                 case T_CreatePLangStmt:
2114                         retval = _equalCreatePLangStmt(a, b);
2115                         break;
2116                 case T_DropPLangStmt:
2117                         retval = _equalDropPLangStmt(a, b);
2118                         break;
2119                 case T_CreateRoleStmt:
2120                         retval = _equalCreateRoleStmt(a, b);
2121                         break;
2122                 case T_AlterRoleStmt:
2123                         retval = _equalAlterRoleStmt(a, b);
2124                         break;
2125                 case T_AlterRoleSetStmt:
2126                         retval = _equalAlterRoleSetStmt(a, b);
2127                         break;
2128                 case T_DropRoleStmt:
2129                         retval = _equalDropRoleStmt(a, b);
2130                         break;
2131                 case T_LockStmt:
2132                         retval = _equalLockStmt(a, b);
2133                         break;
2134                 case T_ConstraintsSetStmt:
2135                         retval = _equalConstraintsSetStmt(a, b);
2136                         break;
2137                 case T_ReindexStmt:
2138                         retval = _equalReindexStmt(a, b);
2139                         break;
2140                 case T_CheckPointStmt:
2141                         retval = true;
2142                         break;
2143                 case T_CreateSchemaStmt:
2144                         retval = _equalCreateSchemaStmt(a, b);
2145                         break;
2146                 case T_CreateConversionStmt:
2147                         retval = _equalCreateConversionStmt(a, b);
2148                         break;
2149                 case T_CreateCastStmt:
2150                         retval = _equalCreateCastStmt(a, b);
2151                         break;
2152                 case T_DropCastStmt:
2153                         retval = _equalDropCastStmt(a, b);
2154                         break;
2155                 case T_PrepareStmt:
2156                         retval = _equalPrepareStmt(a, b);
2157                         break;
2158                 case T_ExecuteStmt:
2159                         retval = _equalExecuteStmt(a, b);
2160                         break;
2161                 case T_DeallocateStmt:
2162                         retval = _equalDeallocateStmt(a, b);
2163                         break;
2164
2165                 case T_A_Expr:
2166                         retval = _equalAExpr(a, b);
2167                         break;
2168                 case T_ColumnRef:
2169                         retval = _equalColumnRef(a, b);
2170                         break;
2171                 case T_ParamRef:
2172                         retval = _equalParamRef(a, b);
2173                         break;
2174                 case T_A_Const:
2175                         retval = _equalAConst(a, b);
2176                         break;
2177                 case T_FuncCall:
2178                         retval = _equalFuncCall(a, b);
2179                         break;
2180                 case T_A_Indices:
2181                         retval = _equalAIndices(a, b);
2182                         break;
2183                 case T_A_Indirection:
2184                         retval = _equalA_Indirection(a, b);
2185                         break;
2186                 case T_ResTarget:
2187                         retval = _equalResTarget(a, b);
2188                         break;
2189                 case T_TypeCast:
2190                         retval = _equalTypeCast(a, b);
2191                         break;
2192                 case T_SortBy:
2193                         retval = _equalSortBy(a, b);
2194                         break;
2195                 case T_RangeSubselect:
2196                         retval = _equalRangeSubselect(a, b);
2197                         break;
2198                 case T_RangeFunction:
2199                         retval = _equalRangeFunction(a, b);
2200                         break;
2201                 case T_TypeName:
2202                         retval = _equalTypeName(a, b);
2203                         break;
2204                 case T_IndexElem:
2205                         retval = _equalIndexElem(a, b);
2206                         break;
2207                 case T_ColumnDef:
2208                         retval = _equalColumnDef(a, b);
2209                         break;
2210                 case T_Constraint:
2211                         retval = _equalConstraint(a, b);
2212                         break;
2213                 case T_DefElem:
2214                         retval = _equalDefElem(a, b);
2215                         break;
2216                 case T_RangeTblEntry:
2217                         retval = _equalRangeTblEntry(a, b);
2218                         break;
2219                 case T_SortClause:
2220                         retval = _equalSortClause(a, b);
2221                         break;
2222                 case T_GroupClause:
2223                         /* GroupClause is equivalent to SortClause */
2224                         retval = _equalSortClause(a, b);
2225                         break;
2226                 case T_FkConstraint:
2227                         retval = _equalFkConstraint(a, b);
2228                         break;
2229                 case T_PrivGrantee:
2230                         retval = _equalPrivGrantee(a, b);
2231                         break;
2232                 case T_FuncWithArgs:
2233                         retval = _equalFuncWithArgs(a, b);
2234                         break;
2235
2236                 default:
2237                         elog(ERROR, "unrecognized node type: %d",
2238                                  (int) nodeTag(a));
2239                         retval = false;         /* keep compiler quiet */
2240                         break;
2241         }
2242
2243         return retval;
2244 }