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