|
1 | 1 | /*-------------------------------------------------------------------------
|
2 | 2 | *
|
3 | 3 | * indexcmds.c
|
4 |
| - * POSTGRES define, extend and remove index code. |
| 4 | + * POSTGRES define and remove index code. |
5 | 5 | *
|
6 | 6 | * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
7 | 7 | * Portions Copyright (c) 1994, Regents of the University of California
|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.52 2001/07/16 05:06:57 tgl Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.53 2001/07/17 21:53:01 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
|
39 | 39 | #include "parser/parse_type.h"
|
40 | 40 | #include "utils/builtins.h"
|
41 | 41 | #include "utils/fmgroids.h"
|
| 42 | +#include "utils/lsyscache.h" |
42 | 43 | #include "utils/syscache.h"
|
43 | 44 |
|
| 45 | + |
44 | 46 | #define IsFuncIndex(ATTR_LIST) (((IndexElem*)lfirst(ATTR_LIST))->args != NIL)
|
45 | 47 |
|
46 | 48 | /* non-export function prototypes */
|
@@ -232,10 +234,21 @@ CheckPredicate(List *predList, List *rangeTable, Oid baseRelOid)
|
232 | 234 | elog(ERROR,
|
233 | 235 | "Partial-index predicates may refer only to the base relation");
|
234 | 236 |
|
| 237 | + /* |
| 238 | + * We don't currently support generation of an actual query plan for a |
| 239 | + * predicate, only simple scalar expressions; hence these restrictions. |
| 240 | + */ |
235 | 241 | if (contain_subplans((Node *) predList))
|
236 | 242 | elog(ERROR, "Cannot use subselect in index predicate");
|
237 | 243 | if (contain_agg_clause((Node *) predList))
|
238 | 244 | elog(ERROR, "Cannot use aggregate in index predicate");
|
| 245 | + |
| 246 | + /* |
| 247 | + * A predicate using noncachable functions is probably wrong, for the |
| 248 | + * same reasons that we don't allow a functional index to use one. |
| 249 | + */ |
| 250 | + if (contain_noncachable_functions((Node *) predList)) |
| 251 | + elog(ERROR, "Cannot use non-cachable function in index predicate"); |
239 | 252 | }
|
240 | 253 |
|
241 | 254 |
|
@@ -308,6 +321,15 @@ FuncIndexArgs(IndexInfo *indexInfo,
|
308 | 321 | "Index function must be binary-compatible with table datatype");
|
309 | 322 | }
|
310 | 323 |
|
| 324 | + /* |
| 325 | + * Require that the function be marked cachable. Using a noncachable |
| 326 | + * function for a functional index is highly questionable, since if you |
| 327 | + * aren't going to get the same result for the same data every time, |
| 328 | + * it's not clear what the index entries mean at all. |
| 329 | + */ |
| 330 | + if (!func_iscachable(funcid)) |
| 331 | + elog(ERROR, "DefineIndex: index function must be marked iscachable"); |
| 332 | + |
311 | 333 | /* Process opclass, using func return type as default type */
|
312 | 334 |
|
313 | 335 | classOidP[0] = GetAttrOpClass(funcIndex, rettype,
|
|
0 commit comments