1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-06 07:49:08 +03:00

Add COST and ROWS options to CREATE/ALTER FUNCTION, plus underlying pg_proc

columns procost and prorows, to allow simple user adjustment of the estimated
cost of a function call, as well as control of the estimated number of rows
returned by a set-returning function.  We might eventually wish to extend this
to allow function-specific estimation routines, but there seems to be
consensus that we should try a simple constant estimate first.  In particular
this provides a relatively simple way to control the order in which different
WHERE clauses are applied in a plan node, which is a Good Thing in view of the
fact that the recent EquivalenceClass planner rewrite made that much less
predictable than before.
This commit is contained in:
Tom Lane
2007-01-22 01:35:23 +00:00
parent a85e9c61e5
commit 5a7471c307
27 changed files with 2550 additions and 2090 deletions

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.230 2007/01/17 17:25:52 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.231 2007/01/22 01:35:20 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -64,6 +64,7 @@ typedef struct
static bool contain_agg_clause_walker(Node *node, void *context);
static bool count_agg_clauses_walker(Node *node, AggClauseCounts *counts);
static bool expression_returns_set_walker(Node *node, void *context);
static bool expression_returns_set_rows_walker(Node *node, double *count);
static bool contain_subplans_walker(Node *node, void *context);
static bool contain_mutable_functions_walker(Node *node, void *context);
static bool contain_volatile_functions_walker(Node *node, void *context);
@@ -566,6 +567,78 @@ expression_returns_set_walker(Node *node, void *context)
context);
}
/*
* expression_returns_set_rows
* Estimate the number of rows in a set result.
*
* We use the product of the rowcount estimates of all the functions in
* the given tree. The result is 1 if there are no set-returning functions.
*/
double
expression_returns_set_rows(Node *clause)
{
double result = 1;
(void) expression_returns_set_rows_walker(clause, &result);
return result;
}
static bool
expression_returns_set_rows_walker(Node *node, double *count)
{
if (node == NULL)
return false;
if (IsA(node, FuncExpr))
{
FuncExpr *expr = (FuncExpr *) node;
if (expr->funcretset)
*count *= get_func_rows(expr->funcid);
}
if (IsA(node, OpExpr))
{
OpExpr *expr = (OpExpr *) node;
if (expr->opretset)
{
set_opfuncid(expr);
*count *= get_func_rows(expr->opfuncid);
}
}
/* Avoid recursion for some cases that can't return a set */
if (IsA(node, Aggref))
return false;
if (IsA(node, DistinctExpr))
return false;
if (IsA(node, ScalarArrayOpExpr))
return false;
if (IsA(node, BoolExpr))
return false;
if (IsA(node, SubLink))
return false;
if (IsA(node, SubPlan))
return false;
if (IsA(node, ArrayExpr))
return false;
if (IsA(node, RowExpr))
return false;
if (IsA(node, RowCompareExpr))
return false;
if (IsA(node, CoalesceExpr))
return false;
if (IsA(node, MinMaxExpr))
return false;
if (IsA(node, XmlExpr))
return false;
if (IsA(node, NullIfExpr))
return false;
return expression_tree_walker(node, expression_returns_set_rows_walker,
(void *) count);
}
/*****************************************************************************
* Subplan clause manipulation
*****************************************************************************/