Disallow non-cachable functions in functional indexes and in index
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 17 Jul 2001 21:53:01 +0000 (21:53 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 17 Jul 2001 21:53:01 +0000 (21:53 +0000)
predicates.  Per suggestion from Hiroshi.

src/backend/commands/indexcmds.c

index 6a85324bdc02cffd1a71b2548a057d5a90856dac..0080a4fe776b2ac67982e32856ea879131141684 100644 (file)
@@ -1,14 +1,14 @@
 /*-------------------------------------------------------------------------
  *
  * indexcmds.c
- *       POSTGRES define, extend and remove index code.
+ *       POSTGRES define and remove index code.
  *
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.52 2001/07/16 05:06:57 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.53 2001/07/17 21:53:01 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "parser/parse_type.h"
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
+#include "utils/lsyscache.h"
 #include "utils/syscache.h"
 
+
 #define IsFuncIndex(ATTR_LIST) (((IndexElem*)lfirst(ATTR_LIST))->args != NIL)
 
 /* non-export function prototypes */
@@ -232,10 +234,21 @@ CheckPredicate(List *predList, List *rangeTable, Oid baseRelOid)
                elog(ERROR,
                         "Partial-index predicates may refer only to the base relation");
 
+       /*
+        * We don't currently support generation of an actual query plan for a
+        * predicate, only simple scalar expressions; hence these restrictions.
+        */
        if (contain_subplans((Node *) predList))
                elog(ERROR, "Cannot use subselect in index predicate");
        if (contain_agg_clause((Node *) predList))
                elog(ERROR, "Cannot use aggregate in index predicate");
+
+       /*
+        * A predicate using noncachable functions is probably wrong, for the
+        * same reasons that we don't allow a functional index to use one.
+        */
+       if (contain_noncachable_functions((Node *) predList))
+               elog(ERROR, "Cannot use non-cachable function in index predicate");
 }
 
 
@@ -308,6 +321,15 @@ FuncIndexArgs(IndexInfo *indexInfo,
                                           "Index function must be binary-compatible with table datatype");
        }
 
+       /*
+        * Require that the function be marked cachable.  Using a noncachable
+        * function for a functional index is highly questionable, since if you
+        * aren't going to get the same result for the same data every time,
+        * it's not clear what the index entries mean at all.
+        */
+       if (!func_iscachable(funcid))
+               elog(ERROR, "DefineIndex: index function must be marked iscachable");
+
        /* Process opclass, using func return type as default type */
 
        classOidP[0] = GetAttrOpClass(funcIndex, rettype,