From 455a55fc291b75d0ec955909f8b44d100c751cca Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
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 6060f462e8f..3ebc1c650e8 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++;
-- 
GitLab