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