aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/ri_triggers.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-08-17 19:58:06 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-08-17 19:58:06 +0000
commitec646dbc65afc8c55118cb3fb75cb6fd18d78dd8 (patch)
treebd256cf157c4636382d59938162326fccc70b62c /src/backend/utils/adt/ri_triggers.c
parentd89578ccbefb83aa9f9d1c00269cd866be2cc857 (diff)
downloadpostgresql-ec646dbc65afc8c55118cb3fb75cb6fd18d78dd8.tar.gz
postgresql-ec646dbc65afc8c55118cb3fb75cb6fd18d78dd8.zip
Create a 'type cache' that keeps track of the data needed for any particular
datatype by array_eq and array_cmp; use this to solve problems with memory leaks in array indexing support. The parser's equality_oper and ordering_oper routines also use the cache. Change the operator search algorithms to look for appropriate btree or hash index opclasses, instead of assuming operators named '<' or '=' have the right semantics. (ORDER BY ASC/DESC now also look at opclasses, instead of assuming '<' and '>' are the right things.) Add several more index opclasses so that there is no regression in functionality for base datatypes. initdb forced due to catalog additions.
Diffstat (limited to 'src/backend/utils/adt/ri_triggers.c')
-rw-r--r--src/backend/utils/adt/ri_triggers.c76
1 files changed, 13 insertions, 63 deletions
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index 7476204d89f..55a6944971e 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -17,7 +17,7 @@
*
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
*
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.54 2003/08/04 02:40:05 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ri_triggers.c,v 1.55 2003/08/17 19:58:05 tgl Exp $
*
* ----------
*/
@@ -39,6 +39,7 @@
#include "parser/parse_oper.h"
#include "rewrite/rewriteHandler.h"
#include "utils/lsyscache.h"
+#include "utils/typcache.h"
#include "miscadmin.h"
@@ -48,7 +49,6 @@
*/
#define RI_INIT_QUERYHASHSIZE 128
-#define RI_INIT_OPREQHASHSIZE 128
#define RI_MATCH_TYPE_UNSPECIFIED 0
#define RI_MATCH_TYPE_FULL 1
@@ -109,20 +109,11 @@ typedef struct RI_QueryHashEntry
} RI_QueryHashEntry;
-typedef struct RI_OpreqHashEntry
-{
- Oid typeid;
- FmgrInfo oprfmgrinfo;
-} RI_OpreqHashEntry;
-
-
-
/* ----------
* Local data
* ----------
*/
static HTAB *ri_query_cache = (HTAB *) NULL;
-static HTAB *ri_opreq_cache = (HTAB *) NULL;
/* ----------
@@ -3197,8 +3188,8 @@ ri_NullCheck(Relation rel, HeapTuple tup, RI_QueryKey *key, int pairidx)
/* ----------
* ri_InitHashTables -
*
- * Initialize our internal hash tables for prepared
- * query plans and equal operators.
+ * Initialize our internal hash table for prepared
+ * query plans.
* ----------
*/
static void
@@ -3212,12 +3203,6 @@ ri_InitHashTables(void)
ctl.hash = tag_hash;
ri_query_cache = hash_create("RI query cache", RI_INIT_QUERYHASHSIZE,
&ctl, HASH_ELEM | HASH_FUNCTION);
-
- ctl.keysize = sizeof(Oid);
- ctl.entrysize = sizeof(RI_OpreqHashEntry);
- ctl.hash = tag_hash;
- ri_opreq_cache = hash_create("RI OpReq cache", RI_INIT_OPREQHASHSIZE,
- &ctl, HASH_ELEM | HASH_FUNCTION);
}
@@ -3438,57 +3423,22 @@ ri_OneKeyEqual(Relation rel, int column, HeapTuple oldtup, HeapTuple newtup,
static bool
ri_AttributesEqual(Oid typeid, Datum oldvalue, Datum newvalue)
{
- RI_OpreqHashEntry *entry;
- bool found;
+ TypeCacheEntry *typentry;
/*
- * On the first call initialize the hashtable
+ * Find the data type in the typcache, and ask for eq_opr info.
*/
- if (!ri_opreq_cache)
- ri_InitHashTables();
+ typentry = lookup_type_cache(typeid, TYPECACHE_EQ_OPR_FINFO);
- /*
- * Try to find the '=' operator for this type in our cache
- */
- entry = (RI_OpreqHashEntry *) hash_search(ri_opreq_cache,
- (void *) &typeid,
- HASH_FIND, NULL);
-
- /*
- * If not found, lookup the operator, then do the function manager
- * lookup, and remember that info.
- */
- if (!entry)
- {
- Oid opr_proc;
- FmgrInfo finfo;
-
- opr_proc = equality_oper_funcid(typeid);
-
- /*
- * Since fmgr_info could fail, call it *before* creating the
- * hashtable entry --- otherwise we could ereport leaving an
- * incomplete entry in the hashtable. Also, because this will be
- * a permanent table entry, we must make sure any subsidiary
- * structures of the fmgr record are kept in TopMemoryContext.
- */
- fmgr_info_cxt(opr_proc, &finfo, TopMemoryContext);
-
- entry = (RI_OpreqHashEntry *) hash_search(ri_opreq_cache,
- (void *) &typeid,
- HASH_ENTER, &found);
- if (entry == NULL)
- ereport(ERROR,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of memory")));
-
- entry->typeid = typeid;
- memcpy(&(entry->oprfmgrinfo), &finfo, sizeof(FmgrInfo));
- }
+ if (!OidIsValid(typentry->eq_opr_finfo.fn_oid))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_FUNCTION),
+ errmsg("could not identify an equality operator for type %s",
+ format_type_be(typeid))));
/*
* Call the type specific '=' function
*/
- return DatumGetBool(FunctionCall2(&(entry->oprfmgrinfo),
+ return DatumGetBool(FunctionCall2(&(typentry->eq_opr_finfo),
oldvalue, newvalue));
}