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