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