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