|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.195 2010/03/22 15:24:11 sriggs Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.196 2010/05/27 15:59:10 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
|
35 | 35 | #include "miscadmin.h"
|
36 | 36 | #include "nodes/nodeFuncs.h"
|
37 | 37 | #include "optimizer/clauses.h"
|
| 38 | +#include "optimizer/planner.h" |
38 | 39 | #include "parser/parse_coerce.h"
|
39 | 40 | #include "parser/parse_func.h"
|
40 | 41 | #include "parser/parse_oper.h"
|
@@ -775,6 +776,33 @@ DefineIndex(RangeVar *heapRelation,
|
775 | 776 | }
|
776 | 777 |
|
777 | 778 |
|
| 779 | +/* |
| 780 | + * CheckMutability |
| 781 | + * Test whether given expression is mutable |
| 782 | + */ |
| 783 | +static bool |
| 784 | +CheckMutability(Expr *expr) |
| 785 | +{ |
| 786 | + /* |
| 787 | + * First run the expression through the planner. This has a couple of |
| 788 | + * important consequences. First, function default arguments will get |
| 789 | + * inserted, which may affect volatility (consider "default now()"). |
| 790 | + * Second, inline-able functions will get inlined, which may allow us to |
| 791 | + * conclude that the function is really less volatile than it's marked. |
| 792 | + * As an example, polymorphic functions must be marked with the most |
| 793 | + * volatile behavior that they have for any input type, but once we |
| 794 | + * inline the function we may be able to conclude that it's not so |
| 795 | + * volatile for the particular input type we're dealing with. |
| 796 | + * |
| 797 | + * We assume here that expression_planner() won't scribble on its input. |
| 798 | + */ |
| 799 | + expr = expression_planner(expr); |
| 800 | + |
| 801 | + /* Now we can search for non-immutable functions */ |
| 802 | + return contain_mutable_functions((Node *) expr); |
| 803 | +} |
| 804 | + |
| 805 | + |
778 | 806 | /*
|
779 | 807 | * CheckPredicate
|
780 | 808 | * Checks that the given partial-index predicate is valid.
|
@@ -806,7 +834,7 @@ CheckPredicate(Expr *predicate)
|
806 | 834 | * A predicate using mutable functions is probably wrong, for the same
|
807 | 835 | * reasons that we don't allow an index expression to use one.
|
808 | 836 | */
|
809 |
| - if (contain_mutable_functions((Node *) predicate)) |
| 837 | + if (CheckMutability(predicate)) |
810 | 838 | ereport(ERROR,
|
811 | 839 | (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
812 | 840 | errmsg("functions in index predicate must be marked IMMUTABLE")));
|
@@ -922,7 +950,7 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
|
922 | 950 | * if you aren't going to get the same result for the same data
|
923 | 951 | * every time, it's not clear what the index entries mean at all.
|
924 | 952 | */
|
925 |
| - if (contain_mutable_functions(attribute->expr)) |
| 953 | + if (CheckMutability((Expr *) attribute->expr)) |
926 | 954 | ereport(ERROR,
|
927 | 955 | (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
928 | 956 | errmsg("functions in index expression must be marked IMMUTABLE")));
|
|
0 commit comments