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