aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/cache/typcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/cache/typcache.c')
-rw-r--r--src/backend/utils/cache/typcache.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c
index 924ee573025..8e334740ed2 100644
--- a/src/backend/utils/cache/typcache.c
+++ b/src/backend/utils/cache/typcache.c
@@ -51,6 +51,7 @@
#include "catalog/indexing.h"
#include "catalog/pg_enum.h"
#include "catalog/pg_operator.h"
+#include "catalog/pg_range.h"
#include "catalog/pg_type.h"
#include "commands/defrem.h"
#include "utils/builtins.h"
@@ -120,6 +121,7 @@ static int32 RecordCacheArrayLen = 0; /* allocated length of array */
static int32 NextRecordTypmod = 0; /* number of entries used */
static void load_typcache_tupdesc(TypeCacheEntry *typentry);
+static void load_rangetype_info(TypeCacheEntry *typentry);
static bool array_element_has_equality(TypeCacheEntry *typentry);
static bool array_element_has_compare(TypeCacheEntry *typentry);
static bool array_element_has_hashing(TypeCacheEntry *typentry);
@@ -205,6 +207,7 @@ lookup_type_cache(Oid type_id, int flags)
typentry->typlen = typtup->typlen;
typentry->typbyval = typtup->typbyval;
typentry->typalign = typtup->typalign;
+ typentry->typstorage = typtup->typstorage;
typentry->typtype = typtup->typtype;
typentry->typrelid = typtup->typrelid;
@@ -448,6 +451,16 @@ lookup_type_cache(Oid type_id, int flags)
load_typcache_tupdesc(typentry);
}
+ /*
+ * If requested, get information about a range type
+ */
+ if ((flags & TYPECACHE_RANGE_INFO) &&
+ typentry->rngelemtype == NULL &&
+ typentry->typtype == TYPTYPE_RANGE)
+ {
+ load_rangetype_info(typentry);
+ }
+
return typentry;
}
@@ -479,6 +492,62 @@ load_typcache_tupdesc(TypeCacheEntry *typentry)
relation_close(rel, AccessShareLock);
}
+/*
+ * load_rangetype_info --- helper routine to set up range type information
+ */
+static void
+load_rangetype_info(TypeCacheEntry *typentry)
+{
+ Form_pg_range pg_range;
+ HeapTuple tup;
+ Oid subtypeOid;
+ Oid opclassOid;
+ Oid canonicalOid;
+ Oid subdiffOid;
+ Oid opfamilyOid;
+ Oid opcintype;
+ Oid cmpFnOid;
+
+ /* get information from pg_range */
+ tup = SearchSysCache1(RANGETYPE, ObjectIdGetDatum(typentry->type_id));
+ /* should not fail, since we already checked typtype ... */
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for range type %u",
+ typentry->type_id);
+ pg_range = (Form_pg_range) GETSTRUCT(tup);
+
+ subtypeOid = pg_range->rngsubtype;
+ typentry->rng_collation = pg_range->rngcollation;
+ opclassOid = pg_range->rngsubopc;
+ canonicalOid = pg_range->rngcanonical;
+ subdiffOid = pg_range->rngsubdiff;
+
+ ReleaseSysCache(tup);
+
+ /* get opclass properties and look up the comparison function */
+ opfamilyOid = get_opclass_family(opclassOid);
+ opcintype = get_opclass_input_type(opclassOid);
+
+ cmpFnOid = get_opfamily_proc(opfamilyOid, opcintype, opcintype,
+ BTORDER_PROC);
+ if (!RegProcedureIsValid(cmpFnOid))
+ elog(ERROR, "missing support function %d(%u,%u) in opfamily %u",
+ BTORDER_PROC, opcintype, opcintype, opfamilyOid);
+
+ /* set up cached fmgrinfo structs */
+ fmgr_info_cxt(cmpFnOid, &typentry->rng_cmp_proc_finfo,
+ CacheMemoryContext);
+ if (OidIsValid(canonicalOid))
+ fmgr_info_cxt(canonicalOid, &typentry->rng_canonical_finfo,
+ CacheMemoryContext);
+ if (OidIsValid(subdiffOid))
+ fmgr_info_cxt(subdiffOid, &typentry->rng_subdiff_finfo,
+ CacheMemoryContext);
+
+ /* Lastly, set up link to the element type --- this marks data valid */
+ typentry->rngelemtype = lookup_type_cache(subtypeOid, 0);
+}
+
/*
* array_element_has_equality and friends are helper routines to check