mirror of
https://github.com/postgres/postgres.git
synced 2025-04-25 21:42:33 +03:00
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;
This commit is contained in:
parent
9f82f9e459
commit
5729c3503d
@ -7,7 +7,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 *
|
static Node *
|
||||||
fix_indxqual_references(Node *clause, Path *index_path)
|
fix_indxqual_references(Node *clause, Path *index_path)
|
||||||
{
|
{
|
||||||
Node *newclause;
|
if (clause == NULL)
|
||||||
|
return NULL;
|
||||||
if (IsA(clause, Var))
|
else if (IsA(clause, Var))
|
||||||
{
|
{
|
||||||
if (lfirsti(index_path->parent->relids) == ((Var *) clause)->varno)
|
if (lfirsti(index_path->parent->relids) == ((Var *) clause)->varno)
|
||||||
{
|
{
|
||||||
|
Node *newclause;
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
int varatt = ((Var *) clause)->varattno;
|
int varatt = ((Var *) clause)->varattno;
|
||||||
int *indexkeys = ((IndexPath *) index_path)->indexkeys;
|
int *indexkeys = ((IndexPath *) index_path)->indexkeys;
|
||||||
@ -655,20 +663,18 @@ fix_indxqual_references(Node *clause, Path *index_path)
|
|||||||
((Var *) newclause)->varattno = pos + 1;
|
((Var *) newclause)->varattno = pos + 1;
|
||||||
return newclause;
|
return newclause;
|
||||||
}
|
}
|
||||||
else
|
/* The Var is not part of the indexed relation, leave it alone */
|
||||||
return clause;
|
return copyObject(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;
|
|
||||||
}
|
}
|
||||||
|
else if (single_node(clause))
|
||||||
|
return copyObject(clause);
|
||||||
else if (is_opclause(clause) &&
|
else if (is_opclause(clause) &&
|
||||||
is_funcclause((Node *) get_leftop((Expr *) clause)) &&
|
is_funcclause((Node *) get_leftop((Expr *) clause)) &&
|
||||||
((Func *) ((Expr *) get_leftop((Expr *) clause))->oper)->funcisindex)
|
((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),
|
Var *newvar = makeVar((Index) lfirsti(index_path->parent->relids),
|
||||||
1, /* func indices have one key */
|
1, /* func indices have one key */
|
||||||
((Func *) ((Expr *) clause)->oper)->functype,
|
((Func *) ((Expr *) clause)->oper)->functype,
|
||||||
@ -686,61 +692,60 @@ fix_indxqual_references(Node *clause, Path *index_path)
|
|||||||
{
|
{
|
||||||
Expr *expr = (Expr *) clause;
|
Expr *expr = (Expr *) clause;
|
||||||
List *new_subclauses = NIL;
|
List *new_subclauses = NIL;
|
||||||
Node *subclause = NULL;
|
List *i;
|
||||||
List *i = NIL;
|
|
||||||
|
|
||||||
foreach(i, expr->args)
|
foreach(i, expr->args)
|
||||||
{
|
{
|
||||||
subclause = lfirst(i);
|
Node *subclause = lfirst(i);
|
||||||
if (subclause)
|
new_subclauses = lappend(new_subclauses,
|
||||||
new_subclauses = lappend(new_subclauses,
|
fix_indxqual_references(subclause,
|
||||||
fix_indxqual_references(subclause,
|
index_path));
|
||||||
index_path));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
return (Node *) make_clause(expr->opType, expr->oper, new_subclauses);
|
||||||
* 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))
|
else if (IsA(clause, List))
|
||||||
{
|
{
|
||||||
elog(NOTICE,"optimizer: fix_indxqual_references sees CaseExpr");
|
List *new_subclauses = NIL;
|
||||||
return clause;
|
List *i;
|
||||||
|
|
||||||
|
foreach(i, (List *) clause)
|
||||||
|
{
|
||||||
|
Node *subclause = lfirst(i);
|
||||||
|
new_subclauses = lappend(new_subclauses,
|
||||||
|
fix_indxqual_references(subclause,
|
||||||
|
index_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
List *oldclauses = (List *) clause;
|
elog(ERROR, "fix_indxqual_references: Cannot handle node type %d",
|
||||||
List *new_subclauses = NIL;
|
nodeTag(clause));
|
||||||
Node *subclause = NULL;
|
return NULL;
|
||||||
List *i = NIL;
|
|
||||||
|
|
||||||
foreach(i, oldclauses)
|
|
||||||
{
|
|
||||||
subclause = lfirst(i);
|
|
||||||
if (subclause)
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user