|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.148 2003/07/28 18:33:18 tgl Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.149 2003/08/03 23:46:37 tgl Exp $ |
12 | 12 | *
|
13 | 13 | * HISTORY
|
14 | 14 | * AUTHOR DATE MAJOR EVENT
|
|
26 | 26 | #include "miscadmin.h"
|
27 | 27 | #include "nodes/makefuncs.h"
|
28 | 28 | #include "optimizer/clauses.h"
|
| 29 | +#include "optimizer/cost.h" |
29 | 30 | #include "optimizer/planmain.h"
|
30 | 31 | #include "optimizer/var.h"
|
31 | 32 | #include "parser/analyze.h"
|
@@ -1710,8 +1711,12 @@ evaluate_function(Oid funcid, Oid result_type, List *args,
|
1710 | 1711 | * so we keep track of which functions we are already expanding and
|
1711 | 1712 | * do not re-expand them. Also, if a parameter is used more than once
|
1712 | 1713 | * in the SQL-function body, we require it not to contain any volatile
|
1713 |
| - * functions or sublinks --- volatiles might deliver inconsistent answers, |
1714 |
| - * and subplans might be unreasonably expensive to evaluate multiple times. |
| 1714 | + * functions (volatiles might deliver inconsistent answers) nor to be |
| 1715 | + * unreasonably expensive to evaluate. The expensiveness check not only |
| 1716 | + * prevents us from doing multiple evaluations of an expensive parameter |
| 1717 | + * at runtime, but is a safety value to limit growth of an expression due |
| 1718 | + * to repeated inlining. |
| 1719 | + * |
1715 | 1720 | * We must also beware of changing the volatility or strictness status of
|
1716 | 1721 | * functions by inlining them.
|
1717 | 1722 | *
|
@@ -1912,9 +1917,26 @@ inline_function(Oid funcid, Oid result_type, List *args,
|
1912 | 1917 | }
|
1913 | 1918 | else if (usecounts[i] != 1)
|
1914 | 1919 | {
|
1915 |
| - /* Param used multiple times: uncool if volatile or expensive */ |
1916 |
| - if (contain_volatile_functions(param) || |
1917 |
| - contain_subplans(param)) |
| 1920 | + /* Param used multiple times: uncool if expensive or volatile */ |
| 1921 | + QualCost eval_cost; |
| 1922 | + |
| 1923 | + /* |
| 1924 | + * We define "expensive" as "contains any subplan or more than |
| 1925 | + * 10 operators". Note that the subplan search has to be done |
| 1926 | + * explicitly, since cost_qual_eval() will barf on unplanned |
| 1927 | + * subselects. |
| 1928 | + */ |
| 1929 | + if (contain_subplans(param)) |
| 1930 | + goto fail; |
| 1931 | + cost_qual_eval(&eval_cost, makeList1(param)); |
| 1932 | + if (eval_cost.startup + eval_cost.per_tuple > |
| 1933 | + 10 * cpu_operator_cost) |
| 1934 | + goto fail; |
| 1935 | + /* |
| 1936 | + * Check volatility last since this is more expensive than the |
| 1937 | + * above tests |
| 1938 | + */ |
| 1939 | + if (contain_volatile_functions(param)) |
1918 | 1940 | goto fail;
|
1919 | 1941 | }
|
1920 | 1942 | i++;
|
|
0 commit comments