OSDN Git Service

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