diff options
Diffstat (limited to 'src/backend/optimizer/plan')
| -rw-r--r-- | src/backend/optimizer/plan/createplan.c | 8 | ||||
| -rw-r--r-- | src/backend/optimizer/plan/initsplan.c | 19 | ||||
| -rw-r--r-- | src/backend/optimizer/plan/planmain.c | 22 |
3 files changed, 37 insertions, 12 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index bf91b8d1a6..c049f5d86b 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.94 2000/07/12 02:37:08 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.95 2000/08/13 02:50:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -866,6 +866,12 @@ fix_indxqual_operand(Node *node, int baserelid, Form_pg_index index, Oid *opclass) { /* + * Remove any binary-compatible relabeling of the indexkey + */ + if (IsA(node, RelabelType)) + node = ((RelabelType *) node)->arg; + + /* * We represent index keys by Var nodes having the varno of the base * table but varattno equal to the index's attribute number (index * column position). This is a bit hokey ... would be cleaner to use diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index d2bbff7e60..8ffd35c9bb 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.48 2000/08/08 15:41:38 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.49 2000/08/13 02:50:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -184,7 +184,7 @@ add_restrict_and_join_to_rel(Query *root, Node *clause) /* * There is only one relation participating in 'clause', so - * 'clause' must be a restriction clause for that relation. + * 'clause' is a restriction clause for that relation. */ RelOptInfo *rel = get_base_rel(root, lfirsti(relids)); @@ -201,11 +201,11 @@ add_restrict_and_join_to_rel(Query *root, Node *clause) */ check_mergejoinable(restrictinfo); } - else + else if (relids != NIL) { /* - * 'clause' is a join clause, since there is more than one atom in + * 'clause' is a join clause, since there is more than one rel in * the relid list. Set additional RestrictInfo fields for * joining. * @@ -219,8 +219,6 @@ add_restrict_and_join_to_rel(Query *root, Node *clause) /* * Add clause to the join lists of all the relevant relations. - * (If, perchance, 'clause' contains NO vars, then nothing will - * happen...) */ add_join_info_to_rels(root, restrictinfo, relids); @@ -232,6 +230,15 @@ add_restrict_and_join_to_rel(Query *root, Node *clause) */ add_vars_to_targetlist(root, vars); } + else + { + /* + * 'clause' references no rels, and therefore we have no place to + * attach it. This means query_planner() screwed up --- it should + * treat variable-less clauses separately. + */ + elog(ERROR, "add_restrict_and_join_to_rel: can't cope with variable-free clause"); + } /* * If the clause has a mergejoinable operator, then the two sides diff --git a/src/backend/optimizer/plan/planmain.c b/src/backend/optimizer/plan/planmain.c index 6b6bc15bda..abb468aa8d 100644 --- a/src/backend/optimizer/plan/planmain.c +++ b/src/backend/optimizer/plan/planmain.c @@ -14,7 +14,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.57 2000/07/27 04:51:04 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planmain.c,v 1.58 2000/08/13 02:50:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -78,7 +78,8 @@ query_planner(Query *root, List *qual, double tuple_fraction) { - List *constant_qual = NIL; + List *noncachable_qual; + List *constant_qual; List *var_only_tlist; Plan *subplan; @@ -106,9 +107,14 @@ query_planner(Query *root, * have been optimized away by eval_const_expressions(). What we're * mostly interested in here is quals that depend only on outer-level * vars, although if the qual reduces to "WHERE FALSE" this path will - * also be taken. + * also be taken. We also need a special case for quals that contain + * noncachable functions but no vars, such as "WHERE random() < 0.5". + * These cannot be treated as normal restriction or join quals, but + * they're not constants either. Instead, attach them to the qpqual + * of the top-level plan, so that they get evaluated once per potential + * output tuple. */ - qual = pull_constant_clauses(qual, &constant_qual); + qual = pull_constant_clauses(qual, &noncachable_qual, &constant_qual); /* * Create a target list that consists solely of (resdom var) target @@ -129,6 +135,12 @@ query_planner(Query *root, subplan = subplanner(root, var_only_tlist, qual, tuple_fraction); /* + * Handle the noncachable quals. + */ + if (noncachable_qual) + subplan->qual = nconc(subplan->qual, noncachable_qual); + + /* * Build a result node to control the plan if we have constant quals. */ if (constant_qual) @@ -163,7 +175,7 @@ query_planner(Query *root, * for processing a single level of attributes. * * flat_tlist is the flattened target list - * qual is the qualification to be satisfied + * qual is the qualification to be satisfied (restrict and join quals only) * tuple_fraction is the fraction of tuples we expect will be retrieved * * See query_planner() comments about the interpretation of tuple_fraction. |
