OSDN Git Service

fix_indxqual_references didn't cope with ArrayRef nodes,
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 6 May 1999 01:30:58 +0000 (01:30 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 6 May 1999 01:30:58 +0000 (01:30 +0000)
meaning that this failed:
select proname,typname,prosrc from pg_proc,pg_type
where proname = 'float8' and pg_proc.proargtypes[0] = pg_type.oid;

src/backend/optimizer/plan/createplan.c

index 0370889..abf77b9 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.52 1999/05/01 19:47:40 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.53 1999/05/06 01:30:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -629,15 +629,23 @@ create_hashjoin_node(HashPath *best_path,
  *
  *****************************************************************************/
 
+/*
+ * fix_indxqual_references
+ *     Adjust a qual clause to refer to an index instead of the original relation.
+ *
+ * Returns a modified copy of the given clause --- the original is not changed.
+ */
+
 static Node *
 fix_indxqual_references(Node *clause, Path *index_path)
 {
-       Node       *newclause;
-
-       if (IsA(clause, Var))
+       if (clause == NULL)
+               return NULL;
+       else if (IsA(clause, Var))
        {
                if (lfirsti(index_path->parent->relids) == ((Var *) clause)->varno)
                {
+                       Node       *newclause;
                        int                     pos = 0;
                        int                     varatt = ((Var *) clause)->varattno;
                        int                *indexkeys = ((IndexPath *) index_path)->indexkeys;
@@ -655,20 +663,18 @@ fix_indxqual_references(Node *clause, Path *index_path)
                        ((Var *) newclause)->varattno = pos + 1;
                        return newclause;
                }
-               else
-                       return clause;
-       }
-       else if (IsA(clause, Const))
-               return clause;
-       else if (IsA(clause, Param))
-       {
-               /* Function parameter used as index scan arg.  DZ - 27-8-1996 */
-               return clause;
+               /* The Var is not part of the indexed relation, leave it alone */
+               return copyObject(clause);
        }
+       else if (single_node(clause))
+               return copyObject(clause);
        else if (is_opclause(clause) &&
                         is_funcclause((Node *) get_leftop((Expr *) clause)) &&
        ((Func *) ((Expr *) get_leftop((Expr *) clause))->oper)->funcisindex)
        {
+               /* This looks pretty seriously wrong to me, but I'm not sure what it's
+                * supposed to be doing ... tgl 5/99
+                */
                Var                *newvar = makeVar((Index) lfirsti(index_path->parent->relids),
                                1,                              /* func indices have one key */
                                ((Func *) ((Expr *) clause)->oper)->functype,
@@ -686,61 +692,60 @@ fix_indxqual_references(Node *clause, Path *index_path)
        {
                Expr       *expr = (Expr *) clause;
                List       *new_subclauses = NIL;
-               Node       *subclause = NULL;
-               List       *i = NIL;
+               List       *i;
 
                foreach(i, expr->args)
                {
-                       subclause = lfirst(i);
-                       if (subclause)
-                               new_subclauses = lappend(new_subclauses,
-                                                       fix_indxqual_references(subclause,
-                                                                                                       index_path));
-
+                       Node       *subclause = lfirst(i);
+                       new_subclauses = lappend(new_subclauses,
+                                                                        fix_indxqual_references(subclause,
+                                                                                                                        index_path));
                }
 
-               /*
-                * XXX new_subclauses should be a list of the form: ( (var var)
-                * (var const) ...) ?
-                */
-               if (new_subclauses)
-               {
-                       return (Node *)
-                                       make_clause(expr->opType, expr->oper, new_subclauses);
-               }
-               else
-                       return clause;
-       }
-       else if (IsA(clause, CaseExpr))
-       {
-               elog(NOTICE,"optimizer: fix_indxqual_references sees CaseExpr");
-               return clause;
+               return (Node *) make_clause(expr->opType, expr->oper, new_subclauses);
        }
-       else
+       else if (IsA(clause, List))
        {
-               List       *oldclauses = (List *) clause;
                List       *new_subclauses = NIL;
-               Node       *subclause = NULL;
-               List       *i = NIL;
+               List       *i;
 
-               foreach(i, oldclauses)
+               foreach(i, (List *) clause)
                {
-                       subclause = lfirst(i);
-                       if (subclause)
-                               new_subclauses = lappend(new_subclauses,
-                                                       fix_indxqual_references(subclause,
-                                                                                                       index_path));
-
+                       Node       *subclause = lfirst(i);
+                       new_subclauses = lappend(new_subclauses,
+                                                                        fix_indxqual_references(subclause,
+                                                                                                                        index_path));
                }
 
-               /*
-                * XXX new_subclauses should be a list of the form: ( (var var)
-                * (var const) ...) ?
-                */
-               if (new_subclauses)
-                       return (Node *) new_subclauses;
-               else
-                       return clause;
+               return (Node *) new_subclauses;
+       }
+       else if (IsA(clause, ArrayRef))
+       {
+               ArrayRef   *oldnode = (ArrayRef *) clause;
+               ArrayRef   *newnode = makeNode(ArrayRef);
+
+               newnode->refattrlength = oldnode->refattrlength;
+               newnode->refelemlength = oldnode->refelemlength;
+               newnode->refelemtype = oldnode->refelemtype;
+               newnode->refelembyval = oldnode->refelembyval;
+               newnode->refupperindexpr = (List *)
+                       fix_indxqual_references((Node *) oldnode->refupperindexpr,
+                                                                       index_path);
+               newnode->reflowerindexpr = (List *)
+                       fix_indxqual_references((Node *) oldnode->reflowerindexpr,
+                                                                       index_path);
+               newnode->refexpr =
+                       fix_indxqual_references(oldnode->refexpr, index_path);
+               newnode->refassgnexpr =
+                       fix_indxqual_references(oldnode->refassgnexpr, index_path);
+
+               return (Node *) newnode;
+       }
+       else
+       {
+               elog(ERROR, "fix_indxqual_references: Cannot handle node type %d",
+                        nodeTag(clause));
+               return NULL;
        }
 }