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