diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2000-05-23 16:56:37 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2000-05-23 16:56:37 +0000 |
commit | 1c5b902018bc3b045e933817603ccdb7c0205c48 (patch) | |
tree | 73bb2303dfe593baa59cb107e3a435d4f7add3a6 /src/backend/executor/nodeIndexscan.c | |
parent | 1c8244ec678dc4c2dffdcffd5cb51c04e9fc5dfc (diff) | |
download | postgresql-1c5b902018bc3b045e933817603ccdb7c0205c48.tar.gz postgresql-1c5b902018bc3b045e933817603ccdb7c0205c48.zip |
Fix problem in which sloppily-coded test in ExecInitIndexScan would
think that both sides of indexqual look like index keys. An example is
create table inside (f1 float8 primary key);
create table outside (g1 float8, g2 float8);
select * from inside,outside where f1 = atan2(g1+1, g2);
ERROR: ExecInitIndexScan: both left and right ops are rel-vars
(note that failure is potentially platform-dependent). Solution is a
cleanup I had had in mind to make anyway: functional index keys should
be represented as Var nodes in the fixed indexqual, just like regular
index keys.
Diffstat (limited to 'src/backend/executor/nodeIndexscan.c')
-rw-r--r-- | src/backend/executor/nodeIndexscan.c | 63 |
1 files changed, 17 insertions, 46 deletions
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c index d6fdce309de..472378de44e 100644 --- a/src/backend/executor/nodeIndexscan.c +++ b/src/backend/executor/nodeIndexscan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.49 2000/04/12 17:15:09 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.50 2000/05/23 16:56:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -734,8 +734,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) */ for (j = 0; j < n_keys; j++) { - Expr *clause; /* one part of index qual */ - Oper *op; /* operator used in scan.. */ + Expr *clause; /* one clause of index qual */ + Oper *op; /* operator used in clause */ Node *leftop; /* expr on lhs of operator */ Node *rightop;/* expr on rhs ... */ bits16 flags = 0; @@ -794,6 +794,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) */ scanvar = NO_OP; + run_keys[j] = NO_OP; /* ---------------- * determine information in leftop @@ -803,7 +804,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) Assert(leftop != NULL); - if (IsA(leftop, Var) &&var_is_rel((Var *) leftop)) + if (IsA(leftop, Var) && var_is_rel((Var *) leftop)) { /* ---------------- * if the leftop is a "rel-var", then it means @@ -814,19 +815,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) varattno = ((Var *) leftop)->varattno; scanvar = LEFT_OP; } - else if (is_funcclause(leftop) && - var_is_rel(lfirst(((Expr *) leftop)->args))) - { - /* ---------------- - * if the leftop is a func node then it means - * it identifies the value to place in our scan key. - * Since functional indices have only one attribute - * the attno must always be set to 1. - * ---------------- - */ - varattno = 1; - scanvar = LEFT_OP; - } else if (IsA(leftop, Const)) { /* ---------------- @@ -834,8 +822,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) * it identifies the value to place in our scan key. * ---------------- */ - run_keys[j] = NO_OP; scanvalue = ((Const *) leftop)->constvalue; + if (((Const *) leftop)->constisnull) + flags |= SK_ISNULL; } else if (IsA(leftop, Param)) { @@ -850,32 +839,31 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) /* Life was so easy before ... subselects */ if (((Param *) leftop)->paramkind == PARAM_EXEC) { + /* treat Param as runtime key */ have_runtime_keys = true; run_keys[j] = LEFT_OP; execParam = lappendi(execParam, ((Param *) leftop)->paramid); } else { + /* treat Param like a constant */ scanvalue = ExecEvalParam((Param *) leftop, scanstate->cstate.cs_ExprContext, &isnull); if (isnull) flags |= SK_ISNULL; - - run_keys[j] = NO_OP; } } else { /* ---------------- - * otherwise, the leftop contains information usable + * otherwise, the leftop contains an expression evaluable * at runtime to figure out the value to place in our * scan key. * ---------------- */ have_runtime_keys = true; run_keys[j] = LEFT_OP; - scanvalue = Int32GetDatum((int32) true); } /* ---------------- @@ -886,7 +874,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) Assert(rightop != NULL); - if (IsA(rightop, Var) &&var_is_rel((Var *) rightop)) + if (IsA(rightop, Var) && var_is_rel((Var *) rightop)) { /* ---------------- * here we make sure only one op identifies the @@ -906,23 +894,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) varattno = ((Var *) rightop)->varattno; scanvar = RIGHT_OP; } - else if (is_funcclause(rightop) && - var_is_rel(lfirst(((Expr *) rightop)->args))) - { - /* ---------------- - * if the rightop is a func node then it means - * it identifies the value to place in our scan key. - * Since functional indices have only one attribute - * the attno must always be set to 1. - * ---------------- - */ - if (scanvar == LEFT_OP) - elog(ERROR, "ExecInitIndexScan: %s", - "both left and right ops are rel-vars"); - - varattno = 1; - scanvar = RIGHT_OP; - } else if (IsA(rightop, Const)) { /* ---------------- @@ -930,8 +901,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) * it identifies the value to place in our scan key. * ---------------- */ - run_keys[j] = NO_OP; scanvalue = ((Const *) rightop)->constvalue; + if (((Const *) rightop)->constisnull) + flags |= SK_ISNULL; } else if (IsA(rightop, Param)) { @@ -946,32 +918,31 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) /* Life was so easy before ... subselects */ if (((Param *) rightop)->paramkind == PARAM_EXEC) { + /* treat Param as runtime key */ have_runtime_keys = true; run_keys[j] = RIGHT_OP; execParam = lappendi(execParam, ((Param *) rightop)->paramid); } else { + /* treat Param like a constant */ scanvalue = ExecEvalParam((Param *) rightop, scanstate->cstate.cs_ExprContext, &isnull); if (isnull) flags |= SK_ISNULL; - - run_keys[j] = NO_OP; } } else { /* ---------------- - * otherwise, the rightop contains information usable + * otherwise, the rightop contains an expression evaluable * at runtime to figure out the value to place in our * scan key. * ---------------- */ have_runtime_keys = true; run_keys[j] = RIGHT_OP; - scanvalue = Int32GetDatum((int32) true); } /* ---------------- @@ -992,7 +963,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent) varattno, /* attribute number to * scan */ (RegProcedure) opid, /* reg proc to use */ - (Datum) scanvalue); /* constant */ + scanvalue); /* constant */ } /* ---------------- |