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