Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5a86e5e

Browse files
committed
Make CREATE INDEX run expression preprocessing on a proposed index expression
before it checks whether the expression is immutable. This covers two casesthat were previously handled poorly:1. SQL function inlining could reduce the apparent volatility of theexpression, allowing an expression to be accepted where it previously wouldnot have been. As an example, polymorphic functions must be marked with theworst-case volatility they have for any argument type, but for specificargument types they might not be so volatile, so indexing could be allowed.(Since the planner will refuse to inline functions in cases where theapparent volatility of the expression would increase, this won't breakany cases that were accepted before.)2. A nominally immutable function could have default arguments that arevolatile expressions. In such a case insertion of the defaults will increaseboth the apparent and actual volatility of the expression, so it is*necessary* to check this before allowing the expression to be indexed.Back-patch to 8.4, where default arguments were introduced.
1 parent77e50a6 commit5a86e5e

File tree

1 file changed

+31
-3
lines changed

1 file changed

+31
-3
lines changed

‎src/backend/commands/indexcmds.c

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* 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 $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -35,6 +35,7 @@
3535
#include"miscadmin.h"
3636
#include"nodes/nodeFuncs.h"
3737
#include"optimizer/clauses.h"
38+
#include"optimizer/planner.h"
3839
#include"parser/parse_coerce.h"
3940
#include"parser/parse_func.h"
4041
#include"parser/parse_oper.h"
@@ -775,6 +776,33 @@ DefineIndex(RangeVar *heapRelation,
775776
}
776777

777778

779+
/*
780+
* CheckMutability
781+
*Test whether given expression is mutable
782+
*/
783+
staticbool
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+
returncontain_mutable_functions((Node*)expr);
803+
}
804+
805+
778806
/*
779807
* CheckPredicate
780808
*Checks that the given partial-index predicate is valid.
@@ -806,7 +834,7 @@ CheckPredicate(Expr *predicate)
806834
* A predicate using mutable functions is probably wrong, for the same
807835
* reasons that we don't allow an index expression to use one.
808836
*/
809-
if (contain_mutable_functions((Node*)predicate))
837+
if (CheckMutability(predicate))
810838
ereport(ERROR,
811839
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
812840
errmsg("functions in index predicate must be marked IMMUTABLE")));
@@ -922,7 +950,7 @@ ComputeIndexAttrs(IndexInfo *indexInfo,
922950
* if you aren't going to get the same result for the same data
923951
* every time, it's not clear what the index entries mean at all.
924952
*/
925-
if (contain_mutable_functions(attribute->expr))
953+
if (CheckMutability((Expr*)attribute->expr))
926954
ereport(ERROR,
927955
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
928956
errmsg("functions in index expression must be marked IMMUTABLE")));

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp