From 455a55fc291b75d0ec955909f8b44d100c751cca Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 3 Aug 2003 23:46:37 +0000 Subject: [PATCH] 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. --- src/backend/optimizer/util/clauses.c | 34 +++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 6060f462e8..3ebc1c650e 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -8,7 +8,7 @@ * * * 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 * AUTHOR DATE MAJOR EVENT @@ -26,6 +26,7 @@ #include "miscadmin.h" #include "nodes/makefuncs.h" #include "optimizer/clauses.h" +#include "optimizer/cost.h" #include "optimizer/planmain.h" #include "optimizer/var.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 * 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 - * functions or sublinks --- volatiles might deliver inconsistent answers, - * and subplans might be unreasonably expensive to evaluate multiple times. + * functions (volatiles might deliver inconsistent answers) nor to be + * 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 * functions by inlining them. * @@ -1912,9 +1917,26 @@ inline_function(Oid funcid, Oid result_type, List *args, } else if (usecounts[i] != 1) { - /* Param used multiple times: uncool if volatile or expensive */ - if (contain_volatile_functions(param) || - contain_subplans(param)) + /* Param used multiple times: uncool if expensive or volatile */ + QualCost eval_cost; + + /* + * 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; } i++; -- 2.40.0