*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.154 2003/06/06 15:04:02 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.157 2003/07/25 00:01:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#define EXPRKIND_QUAL 0
#define EXPRKIND_TARGET 1
#define EXPRKIND_RTFUNC 2
-#define EXPRKIND_ININFO 3
+#define EXPRKIND_LIMIT 3
+#define EXPRKIND_ININFO 4
static Node *preprocess_expression(Query *parse, Node *expr, int kind);
parse->havingQual = preprocess_expression(parse, parse->havingQual,
EXPRKIND_QUAL);
+ parse->limitOffset = preprocess_expression(parse, parse->limitOffset,
+ EXPRKIND_LIMIT);
+ parse->limitCount = preprocess_expression(parse, parse->limitCount,
+ EXPRKIND_LIMIT);
+
parse->in_info_list = (List *)
preprocess_expression(parse, (Node *) parse->in_info_list,
EXPRKIND_ININFO);
j->quals = preprocess_expression(parse, j->quals, EXPRKIND_QUAL);
}
else
- elog(ERROR, "preprocess_qual_conditions: unexpected node type %d",
- nodeTag(jtnode));
+ elog(ERROR, "unrecognized node type: %d",
+ (int) nodeTag(jtnode));
}
/*--------------------
* already, but let's make sure).
*/
if (parse->rowMarks)
- elog(ERROR, "SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT");
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("SELECT FOR UPDATE is not allowed with UNION/INTERSECT/EXCEPT")));
/*
* We set current_pathkeys NIL indicating we do not know sort
* level
*/
if (PlannerQueryLevel > 1)
- elog(ERROR, "SELECT FOR UPDATE is not allowed in subselects");
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("SELECT FOR UPDATE is not allowed in subselects")));
foreach(l, parse->rowMarks)
{
if (parse->groupClause)
{
List *groupExprs;
+ double cheapest_path_rows;
+ int cheapest_path_width;
+
+ /*
+ * Beware in this section of the possibility that
+ * cheapest_path->parent is NULL. This could happen if user
+ * does something silly like SELECT 'foo' GROUP BY 1;
+ */
+ if (cheapest_path->parent)
+ {
+ cheapest_path_rows = cheapest_path->parent->rows;
+ cheapest_path_width = cheapest_path->parent->width;
+ }
+ else
+ {
+ cheapest_path_rows = 1; /* assume non-set result */
+ cheapest_path_width = 100; /* arbitrary */
+ }
/*
* Always estimate the number of groups. We can't do this until
parse->targetList);
dNumGroups = estimate_num_groups(parse,
groupExprs,
- cheapest_path->parent->rows);
+ cheapest_path_rows);
/* Also want it as a long int --- but 'ware overflow! */
numGroups = (long) Min(dNumGroups, (double) LONG_MAX);
* assume it is 100 bytes. Also set the overhead per hashtable
* entry at 64 bytes.
*/
- int hashentrysize = cheapest_path->parent->width + 64 +
- numAggs * 100;
+ int hashentrysize = cheapest_path_width + 64 + numAggs * 100;
if (hashentrysize * dNumGroups <= SortMem * 1024L)
{
numGroupCols, dNumGroups,
cheapest_path->startup_cost,
cheapest_path->total_cost,
- cheapest_path->parent->rows);
+ cheapest_path_rows);
/* Result of hashed agg is always unsorted */
if (sort_pathkeys)
cost_sort(&hashed_p, parse, sort_pathkeys,
hashed_p.total_cost,
dNumGroups,
- cheapest_path->parent->width);
+ cheapest_path_width);
if (sorted_path)
{
{
cost_sort(&sorted_p, parse, group_pathkeys,
sorted_p.total_cost,
- cheapest_path->parent->rows,
- cheapest_path->parent->width);
+ cheapest_path_rows,
+ cheapest_path_width);
current_pathkeys = group_pathkeys;
}
if (parse->hasAggs)
numGroupCols, dNumGroups,
sorted_p.startup_cost,
sorted_p.total_cost,
- cheapest_path->parent->rows);
+ cheapest_path_rows);
else
cost_group(&sorted_p, parse,
numGroupCols, dNumGroups,
sorted_p.startup_cost,
sorted_p.total_cost,
- cheapest_path->parent->rows);
+ cheapest_path_rows);
/* The Agg or Group node will preserve ordering */
if (sort_pathkeys &&
!pathkeys_contained_in(sort_pathkeys,
cost_sort(&sorted_p, parse, sort_pathkeys,
sorted_p.total_cost,
dNumGroups,
- cheapest_path->parent->width);
+ cheapest_path_width);
}
/*
break;
}
if (!sl)
- elog(ERROR, "locate_grouping_columns: failed");
+ elog(ERROR, "failed to locate grouping columns");
groupColIdx[keyno++] = te->resdom->resno;
}
* We need to transpose sort key info from the orig_tlist into new_tlist.
* NOTE: this would not be good enough if we supported resjunk sort keys
* for results of set operations --- then, we'd need to project a whole
- * new tlist to evaluate the resjunk columns. For now, just elog if we
+ * new tlist to evaluate the resjunk columns. For now, just ereport if we
* find any resjunk columns in orig_tlist.
*/
static List *
Assert(orig_tlist != NIL);
orig_tle = (TargetEntry *) lfirst(orig_tlist);
orig_tlist = lnext(orig_tlist);
- if (orig_tle->resdom->resjunk)
- elog(ERROR, "postprocess_setop_tlist: resjunk output columns not implemented");
+ if (orig_tle->resdom->resjunk) /* should not happen */
+ elog(ERROR, "resjunk output columns are not implemented");
Assert(new_tle->resdom->resno == orig_tle->resdom->resno);
Assert(new_tle->resdom->restype == orig_tle->resdom->restype);
new_tle->resdom->ressortgroupref = orig_tle->resdom->ressortgroupref;
}
if (orig_tlist != NIL)
- elog(ERROR, "postprocess_setop_tlist: resjunk output columns not implemented");
+ elog(ERROR, "resjunk output columns are not implemented");
return new_tlist;
}