]> granicus.if.org Git - postgresql/commitdiff
Add equal() funcs for Case nodes ... amazing we had not
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 29 Jul 1999 02:45:36 +0000 (02:45 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 29 Jul 1999 02:45:36 +0000 (02:45 +0000)
detected this omission before.  Miscellaneous other cleanups.

src/backend/nodes/equalfuncs.c

index 5560deaea53a5569099118f9a120ab7cf8efc1da..576601faf57021958405b59fced01cada4c1496a 100644 (file)
@@ -1,13 +1,13 @@
 /*-------------------------------------------------------------------------
  *
  * equalfuncs.c
- *       equal functions to compare the nodes
+ *       equality functions to compare node trees
  *
  * Copyright (c) 1994, Regents of the University of California
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.44 1999/07/24 23:21:06 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.45 1999/07/29 02:45:36 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 
 static bool equali(List *a, List *b);
 
+
 /*
  *     Stuff from primnodes.h
  */
 
-/*
- *     Resdom is a subclass of Node.
- */
 static bool
 _equalResdom(Resdom *a, Resdom *b)
 {
@@ -40,10 +38,11 @@ _equalResdom(Resdom *a, Resdom *b)
                return false;
        if (a->reskey != b->reskey)
                return false;
-       if (a->resgroupref != b->resgroupref)
-               return false;
        if (a->reskeyop != b->reskeyop)
                return false;
+       if (a->resgroupref != b->resgroupref)
+               return false;
+       /* we ignore resjunk flag ... is this correct? */
 
        return true;
 }
@@ -69,12 +68,13 @@ _equalFjoin(Fjoin *a, Fjoin *b)
        return true;
 }
 
-/*
- *     Expr is a subclass of Node.
- */
 static bool
 _equalExpr(Expr *a, Expr *b)
 {
+       /* We do not examine typeOid, since the optimizer often doesn't
+        * bother to set it in created nodes, and it is logically a
+        * derivative of the oper field anyway.
+        */
        if (a->opType != b->opType)
                return false;
        if (!equal(a->oper, b->oper))
@@ -85,35 +85,6 @@ _equalExpr(Expr *a, Expr *b)
        return true;
 }
 
-static bool
-_equalIter(Iter *a, Iter *b)
-{
-       return equal(a->iterexpr, b->iterexpr);
-}
-
-static bool
-_equalStream(Stream *a, Stream *b)
-{
-       if (a->clausetype != b->clausetype)
-               return false;
-       if (a->groupup != b->groupup)
-               return false;
-       if (a->groupcost != b->groupcost)
-               return false;
-       if (a->groupsel != b->groupsel)
-               return false;
-       if (!equal(a->pathptr, b->pathptr))
-               return false;
-       if (!equal(a->cinfo, b->cinfo))
-               return false;
-       if (!equal(a->upstream, b->upstream))
-               return false;
-       return equal(a->downstream, b->downstream);
-}
-
-/*
- *     Var is a subclass of Expr.
- */
 static bool
 _equalVar(Var *a, Var *b)
 {
@@ -135,45 +106,6 @@ _equalVar(Var *a, Var *b)
        return true;
 }
 
-static bool
-_equalArray(Array *a, Array *b)
-{
-       if (a->arrayelemtype != b->arrayelemtype)
-               return false;
-       if (a->arrayndim != b->arrayndim)
-               return false;
-       if (a->arraylow.indx[0] != b->arraylow.indx[0])
-               return false;
-       if (a->arrayhigh.indx[0] != b->arrayhigh.indx[0])
-               return false;
-       if (a->arraylen != b->arraylen)
-               return false;
-       return TRUE;
-}
-
-static bool
-_equalArrayRef(ArrayRef *a, ArrayRef *b)
-{
-       if (a->refelemtype != b->refelemtype)
-               return false;
-       if (a->refattrlength != b->refattrlength)
-               return false;
-       if (a->refelemlength != b->refelemlength)
-               return false;
-       if (a->refelembyval != b->refelembyval)
-               return false;
-       if (!equal(a->refupperindexpr, b->refupperindexpr))
-               return false;
-       if (!equal(a->reflowerindexpr, b->reflowerindexpr))
-               return false;
-       if (!equal(a->refexpr, b->refexpr))
-               return false;
-       return equal(a->refassgnexpr, b->refassgnexpr);
-}
-
-/*
- *     Oper is a subclass of Expr.
- */
 static bool
 _equalOper(Oper *a, Oper *b)
 {
@@ -181,21 +113,19 @@ _equalOper(Oper *a, Oper *b)
                return false;
        if (a->opresulttype != b->opresulttype)
                return false;
+       /* We do not examine opid, opsize, or op_fcache, since these are
+        * logically derived from opno, and they may not be set yet depending
+        * on how far along the node is in the parse/plan pipeline.
+        *
+        * It's probably not really necessary to check opresulttype either...
+        */
 
        return true;
 }
 
-/*
- *     Const is a subclass of Expr.
- */
 static bool
 _equalConst(Const *a, Const *b)
 {
-
-       /*
-        * * this function used to do a pointer compare on a and b.  That's *
-        * ridiculous.  -- JMH, 7/11/92
-        */
        if (a->consttype != b->consttype)
                return false;
        if (a->constlen != b->constlen)
@@ -204,13 +134,11 @@ _equalConst(Const *a, Const *b)
                return false;
        if (a->constbyval != b->constbyval)
                return false;
+       /* XXX What about constisset and constiscast? */
        return (datumIsEqual(a->constvalue, b->constvalue,
                                                 a->consttype, a->constbyval, a->constlen));
 }
 
-/*
- *     Param is a subclass of Expr.
- */
 static bool
 _equalParam(Param *a, Param *b)
 {
@@ -249,9 +177,26 @@ _equalParam(Param *a, Param *b)
        return true;
 }
 
-/*
- *     Aggref is a subclass of Expr.
- */
+static bool
+_equalFunc(Func *a, Func *b)
+{
+       if (a->funcid != b->funcid)
+               return false;
+       if (a->functype != b->functype)
+               return false;
+       if (a->funcisindex != b->funcisindex)
+               return false;
+       if (a->funcsize != b->funcsize)
+               return false;
+       /* Note we do not look at func_fcache */
+       if (!equal(a->func_tlist, b->func_tlist))
+               return false;
+       if (!equal(a->func_planlist, b->func_planlist))
+               return false;
+
+       return true;
+}
+
 static bool
 _equalAggref(Aggref *a, Aggref *b)
 {
@@ -270,68 +215,61 @@ _equalAggref(Aggref *a, Aggref *b)
        return true;
 }
 
-/*
- *     Func is a subclass of Expr.
- */
 static bool
-_equalFunc(Func *a, Func *b)
+_equalArray(Array *a, Array *b)
 {
-       if (a->funcid != b->funcid)
-               return false;
-       if (a->functype != b->functype)
+       if (a->arrayelemtype != b->arrayelemtype)
                return false;
-       if (a->funcisindex != b->funcisindex)
+       /* We need not check arrayelemlength, arrayelembyval if types match */
+       if (a->arrayndim != b->arrayndim)
                return false;
-       if (a->funcsize != b->funcsize)
+       /* XXX shouldn't we be checking all indices??? */
+       if (a->arraylow.indx[0] != b->arraylow.indx[0])
                return false;
-       if (!equal(a->func_tlist, b->func_tlist))
+       if (a->arrayhigh.indx[0] != b->arrayhigh.indx[0])
                return false;
-       if (!equal(a->func_planlist, b->func_planlist))
+       if (a->arraylen != b->arraylen)
                return false;
 
        return true;
 }
 
-/*
- * RestrictInfo is a subclass of Node.
- */
 static bool
-_equalRestrictInfo(RestrictInfo *a, RestrictInfo *b)
+_equalArrayRef(ArrayRef *a, ArrayRef *b)
 {
-       Assert(IsA(a, RestrictInfo));
-       Assert(IsA(b, RestrictInfo));
-
-       if (!equal(a->clause, b->clause))
+       if (a->refelemtype != b->refelemtype)
                return false;
-       if (a->selectivity != b->selectivity)
+       if (a->refattrlength != b->refattrlength)
                return false;
-#ifdef EqualMergeOrderExists
-       if (!EqualMergeOrder(a->mergejoinorder, b->mergejoinorder))
+       if (a->refelemlength != b->refelemlength)
                return false;
-#endif
-       if (a->hashjoinoperator != b->hashjoinoperator)
+       if (a->refelembyval != b->refelembyval)
                return false;
-       return equal(a->indexids, b->indexids);
+       if (!equal(a->refupperindexpr, b->refupperindexpr))
+               return false;
+       if (!equal(a->reflowerindexpr, b->reflowerindexpr))
+               return false;
+       if (!equal(a->refexpr, b->refexpr))
+               return false;
+       return equal(a->refassgnexpr, b->refassgnexpr);
 }
 
 /*
- * RelOptInfo is a subclass of Node.
+ * Stuff from relation.h
  */
+
 static bool
 _equalRelOptInfo(RelOptInfo *a, RelOptInfo *b)
 {
-       Assert(IsA(a, RelOptInfo));
-       Assert(IsA(b, RelOptInfo));
-
+       /* We treat RelOptInfos as equal if they refer to the same base rels
+        * joined in the same order.  Is this sufficient?
+        */
        return equal(a->relids, b->relids);
 }
 
 static bool
 _equalJoinMethod(JoinMethod *a, JoinMethod *b)
 {
-       Assert(IsA(a, JoinMethod));
-       Assert(IsA(b, JoinMethod));
-
        if (!equal(a->jmkeys, b->jmkeys))
                return false;
        if (!equal(a->clauses, b->clauses))
@@ -344,16 +282,17 @@ _equalPath(Path *a, Path *b)
 {
        if (a->pathtype != b->pathtype)
                return false;
-       if (a->parent != b->parent)
+       if (a->parent != b->parent)     /* should this use equal() ? */
                return false;
-
-       /*
-        * if (a->path_cost != b->path_cost) return(false);
+       /* do not check path_cost, since it may not be set yet, and being
+        * a float there are roundoff error issues anyway...
         */
+
+       /* XXX this should probably be in an _equalPathOrder function... */
+       if (a->pathorder->ordtype != b->pathorder->ordtype)
+               return false;
        if (a->pathorder->ordtype == SORTOP_ORDER)
        {
-               int                     i = 0;
-
                if (a->pathorder->ord.sortop == NULL ||
                        b->pathorder->ord.sortop == NULL)
                {
@@ -362,15 +301,15 @@ _equalPath(Path *a, Path *b)
                }
                else
                {
-                       while (a->pathorder->ord.sortop[i] != 0 &&
-                                  b->pathorder->ord.sortop[i] != 0)
+                       int                     i = 0;
+
+                       while (a->pathorder->ord.sortop[i] != 0)
                        {
                                if (a->pathorder->ord.sortop[i] != b->pathorder->ord.sortop[i])
                                        return false;
                                i++;
                        }
-                       if (a->pathorder->ord.sortop[i] != 0 ||
-                               b->pathorder->ord.sortop[i] != 0)
+                       if (b->pathorder->ord.sortop[i] != 0)
                                return false;
                }
        }
@@ -379,12 +318,10 @@ _equalPath(Path *a, Path *b)
                if (!equal(a->pathorder->ord.merge, b->pathorder->ord.merge))
                        return false;
        }
+
        if (!equal(a->pathkeys, b->pathkeys))
                return false;
-
-       /*
-        * if (a->outerjoincost != b->outerjoincost) return(false);
-        */
+       /* do not check outerjoincost either */
        if (!equali(a->joinid, b->joinid))
                return false;
        return true;
@@ -399,15 +336,13 @@ _equalIndexPath(IndexPath *a, IndexPath *b)
                return false;
        if (!equal(a->indexqual, b->indexqual))
                return false;
+       /* We do not need to check indexkeys */
        return true;
 }
 
 static bool
 _equalNestPath(NestPath *a, NestPath *b)
 {
-       Assert(IsA_JoinPath(a));
-       Assert(IsA_JoinPath(b));
-
        if (!_equalPath((Path *) a, (Path *) b))
                return false;
        if (!equal(a->pathinfo, b->pathinfo))
@@ -422,9 +357,6 @@ _equalNestPath(NestPath *a, NestPath *b)
 static bool
 _equalMergePath(MergePath *a, MergePath *b)
 {
-       Assert(IsA(a, MergePath));
-       Assert(IsA(b, MergePath));
-
        if (!_equalNestPath((NestPath *) a, (NestPath *) b))
                return false;
        if (!equal(a->path_mergeclauses, b->path_mergeclauses))
@@ -439,12 +371,9 @@ _equalMergePath(MergePath *a, MergePath *b)
 static bool
 _equalHashPath(HashPath *a, HashPath *b)
 {
-       Assert(IsA(a, HashPath));
-       Assert(IsA(b, HashPath));
-
        if (!_equalNestPath((NestPath *) a, (NestPath *) b))
                return false;
-       if (!equal((a->path_hashclauses), (b->path_hashclauses)))
+       if (!equal(a->path_hashclauses, b->path_hashclauses))
                return false;
        if (!equal(a->outerhashkeys, b->outerhashkeys))
                return false;
@@ -456,9 +385,6 @@ _equalHashPath(HashPath *a, HashPath *b)
 static bool
 _equalJoinKey(JoinKey *a, JoinKey *b)
 {
-       Assert(IsA(a, JoinKey));
-       Assert(IsA(b, JoinKey));
-
        if (!equal(a->outer, b->outer))
                return false;
        if (!equal(a->inner, b->inner))
@@ -469,11 +395,6 @@ _equalJoinKey(JoinKey *a, JoinKey *b)
 static bool
 _equalMergeOrder(MergeOrder *a, MergeOrder *b)
 {
-       if (a == (MergeOrder *) NULL && b == (MergeOrder *) NULL)
-               return true;
-       Assert(IsA(a, MergeOrder));
-       Assert(IsA(b, MergeOrder));
-
        if (a->join_operator != b->join_operator)
                return false;
        if (a->left_operator != b->left_operator)
@@ -490,9 +411,8 @@ _equalMergeOrder(MergeOrder *a, MergeOrder *b)
 static bool
 _equalHashInfo(HashInfo *a, HashInfo *b)
 {
-       Assert(IsA(a, HashInfo));
-       Assert(IsA(b, HashInfo));
-
+       if (!_equalJoinMethod((JoinMethod *) a, (JoinMethod *) b))
+               return false;
        if (a->hashop != b->hashop)
                return false;
        return true;
@@ -500,13 +420,13 @@ _equalHashInfo(HashInfo *a, HashInfo *b)
 
 /* XXX This equality function is a quick hack, should be
  *             fixed to compare all fields.
+ *
+ * XXX  Why is this even here?  We don't have equal() funcs for
+ *      any other kinds of Plan nodes... likely this is dead code...
  */
 static bool
 _equalIndexScan(IndexScan *a, IndexScan *b)
 {
-       Assert(IsA(a, IndexScan));
-       Assert(IsA(b, IndexScan));
-
        /*
         * if(a->scan.plan.cost != b->scan.plan.cost) return(false);
         */
@@ -537,8 +457,6 @@ _equalSubPlan(SubPlan *a, SubPlan *b)
 static bool
 _equalJoinInfo(JoinInfo *a, JoinInfo *b)
 {
-       Assert(IsA(a, JoinInfo));
-       Assert(IsA(b, JoinInfo));
        if (!equal(a->unjoined_relids, b->unjoined_relids))
                return false;
        if (!equal(a->jinfo_restrictinfo, b->jinfo_restrictinfo))
@@ -550,6 +468,45 @@ _equalJoinInfo(JoinInfo *a, JoinInfo *b)
        return true;
 }
 
+static bool
+_equalRestrictInfo(RestrictInfo *a, RestrictInfo *b)
+{
+       if (!equal(a->clause, b->clause))
+               return false;
+       /* do not check selectivity because of roundoff error worries */
+       if (!equal(a->mergejoinorder, b->mergejoinorder))
+               return false;
+       if (a->hashjoinoperator != b->hashjoinoperator)
+               return false;
+       return equal(a->indexids, b->indexids);
+}
+
+static bool
+_equalIter(Iter *a, Iter *b)
+{
+       return equal(a->iterexpr, b->iterexpr);
+}
+
+static bool
+_equalStream(Stream *a, Stream *b)
+{
+       if (a->clausetype != b->clausetype)
+               return false;
+       if (a->groupup != b->groupup)
+               return false;
+       if (a->groupcost != b->groupcost)
+               return false;
+       if (a->groupsel != b->groupsel)
+               return false;
+       if (!equal(a->pathptr, b->pathptr))
+               return false;
+       if (!equal(a->cinfo, b->cinfo))
+               return false;
+       if (!equal(a->upstream, b->upstream))
+               return false;
+       return equal(a->downstream, b->downstream);
+}
+
 /*
  *     Stuff from execnodes.h
  */
@@ -696,6 +653,32 @@ _equalTargetEntry(TargetEntry *a, TargetEntry *b)
        return true;
 }
 
+static bool
+_equalCaseExpr(CaseExpr *a, CaseExpr *b)
+{
+       if (a->casetype != b->casetype)
+               return false;
+       if (!equal(a->arg, b->arg))
+               return false;
+       if (!equal(a->args, b->args))
+               return false;
+       if (!equal(a->defresult, b->defresult))
+               return false;
+
+       return true;
+}
+
+static bool
+_equalCaseWhen(CaseWhen *a, CaseWhen *b)
+{
+       if (!equal(a->expr, b->expr))
+               return false;
+       if (!equal(a->result, b->result))
+               return false;
+
+       return true;
+}
+
 /*
  * Stuff from pg_list.h
  */
@@ -842,9 +825,10 @@ equal(void *a, void *b)
                                List       *lb = (List *) b;
                                List       *l;
 
-                               if (a == NULL && b == NULL)
-                                       return true;
-                               if (length(a) != length(b))
+                               /* Try to reject by length check before we grovel through
+                                * all the elements...
+                                */
+                               if (length(la) != length(lb))
                                        return false;
                                foreach(l, la)
                                {
@@ -864,6 +848,12 @@ equal(void *a, void *b)
                case T_TargetEntry:
                        retval = _equalTargetEntry(a, b);
                        break;
+               case T_CaseExpr:
+                       retval = _equalCaseExpr(a, b);
+                       break;
+               case T_CaseWhen:
+                       retval = _equalCaseWhen(a, b);
+                       break;
                default:
                        elog(NOTICE, "equal: don't know whether nodes of type %d are equal",
                                 nodeTag(a));
@@ -876,25 +866,21 @@ equal(void *a, void *b)
 /*
  * equali
  *       compares two lists of integers
- *
- * XXX temp hack. needs something like T_IntList
  */
 static bool
 equali(List *a, List *b)
 {
-       List       *la = (List *) a;
-       List       *lb = (List *) b;
        List       *l;
 
-       if (a == NULL && b == NULL)
-               return true;
-       if (length(a) != length(b))
-               return false;
-       foreach(l, la)
+       foreach(l, a)
        {
-               if (lfirsti(l) != lfirsti(lb))
+               if (b == NIL)
+                       return false;
+               if (lfirsti(l) != lfirsti(b))
                        return false;
-               lb = lnext(lb);
+               b = lnext(b);
        }
+       if (b != NIL)
+               return false;
        return true;
 }