Tighten inline_function's test for overly complex parameters. This
should catch most situations where repeated inlining blows up the expression complexity unreasonably, as in Joe Conway's recent example.
This commit is contained in:
parent
c1c7b338ee
commit
455a55fc29
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.148 2003/07/28 18:33:18 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.149 2003/08/03 23:46:37 tgl Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -26,6 +26,7 @@
|
|||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "nodes/makefuncs.h"
|
#include "nodes/makefuncs.h"
|
||||||
#include "optimizer/clauses.h"
|
#include "optimizer/clauses.h"
|
||||||
|
#include "optimizer/cost.h"
|
||||||
#include "optimizer/planmain.h"
|
#include "optimizer/planmain.h"
|
||||||
#include "optimizer/var.h"
|
#include "optimizer/var.h"
|
||||||
#include "parser/analyze.h"
|
#include "parser/analyze.h"
|
||||||
@ -1710,8 +1711,12 @@ evaluate_function(Oid funcid, Oid result_type, List *args,
|
|||||||
* so we keep track of which functions we are already expanding and
|
* so we keep track of which functions we are already expanding and
|
||||||
* do not re-expand them. Also, if a parameter is used more than once
|
* do not re-expand them. Also, if a parameter is used more than once
|
||||||
* in the SQL-function body, we require it not to contain any volatile
|
* in the SQL-function body, we require it not to contain any volatile
|
||||||
* functions or sublinks --- volatiles might deliver inconsistent answers,
|
* functions (volatiles might deliver inconsistent answers) nor to be
|
||||||
* and subplans might be unreasonably expensive to evaluate multiple times.
|
* unreasonably expensive to evaluate. The expensiveness check not only
|
||||||
|
* prevents us from doing multiple evaluations of an expensive parameter
|
||||||
|
* at runtime, but is a safety value to limit growth of an expression due
|
||||||
|
* to repeated inlining.
|
||||||
|
*
|
||||||
* We must also beware of changing the volatility or strictness status of
|
* We must also beware of changing the volatility or strictness status of
|
||||||
* functions by inlining them.
|
* functions by inlining them.
|
||||||
*
|
*
|
||||||
@ -1912,9 +1917,26 @@ inline_function(Oid funcid, Oid result_type, List *args,
|
|||||||
}
|
}
|
||||||
else if (usecounts[i] != 1)
|
else if (usecounts[i] != 1)
|
||||||
{
|
{
|
||||||
/* Param used multiple times: uncool if volatile or expensive */
|
/* Param used multiple times: uncool if expensive or volatile */
|
||||||
if (contain_volatile_functions(param) ||
|
QualCost eval_cost;
|
||||||
contain_subplans(param))
|
|
||||||
|
/*
|
||||||
|
* We define "expensive" as "contains any subplan or more than
|
||||||
|
* 10 operators". Note that the subplan search has to be done
|
||||||
|
* explicitly, since cost_qual_eval() will barf on unplanned
|
||||||
|
* subselects.
|
||||||
|
*/
|
||||||
|
if (contain_subplans(param))
|
||||||
|
goto fail;
|
||||||
|
cost_qual_eval(&eval_cost, makeList1(param));
|
||||||
|
if (eval_cost.startup + eval_cost.per_tuple >
|
||||||
|
10 * cpu_operator_cost)
|
||||||
|
goto fail;
|
||||||
|
/*
|
||||||
|
* Check volatility last since this is more expensive than the
|
||||||
|
* above tests
|
||||||
|
*/
|
||||||
|
if (contain_volatile_functions(param))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user