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