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