summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan')
-rw-r--r--src/backend/optimizer/plan/createplan.c8
-rw-r--r--src/backend/optimizer/plan/initsplan.c19
-rw-r--r--src/backend/optimizer/plan/planmain.c22
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.