From 5729c3503dc45bf4a30dba7a522163cbd9cae548 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 6 May 1999 01:30:58 +0000 Subject: [PATCH] fix_indxqual_references didn't cope with ArrayRef nodes, 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 | 117 +++++++++++++++++--------------- 1 file changed, 61 insertions(+), 56 deletions(-) diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 03708897b7..abf77b9db6 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -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; } } -- 2.11.0