aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/cache
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/cache')
-rw-r--r--src/backend/utils/cache/lsyscache.c94
-rw-r--r--src/backend/utils/cache/relcache.c35
-rw-r--r--src/backend/utils/cache/syscache.c23
3 files changed, 152 insertions, 0 deletions
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 0a4144ba547..6af23429ad8 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -20,6 +20,7 @@
#include "bootstrap/bootstrap.h"
#include "catalog/pg_amop.h"
#include "catalog/pg_amproc.h"
+#include "catalog/pg_collation.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
@@ -903,6 +904,33 @@ get_atttypmod(Oid relid, AttrNumber attnum)
}
/*
+ * get_attcollation
+ *
+ * Given the relation id and the attribute number,
+ * return the "attcollation" field from the attribute relation.
+ */
+Oid
+get_attcollation(Oid relid, AttrNumber attnum)
+{
+ HeapTuple tp;
+
+ tp = SearchSysCache2(ATTNUM,
+ ObjectIdGetDatum(relid),
+ Int16GetDatum(attnum));
+ if (HeapTupleIsValid(tp))
+ {
+ Form_pg_attribute att_tup = (Form_pg_attribute) GETSTRUCT(tp);
+ Oid result;
+
+ result = att_tup->attcollation;
+ ReleaseSysCache(tp);
+ return result;
+ }
+ else
+ return InvalidOid;
+}
+
+/*
* get_atttypetypmod
*
* A two-fer: given the relation id and the attribute number,
@@ -931,6 +959,36 @@ get_atttypetypmod(Oid relid, AttrNumber attnum,
ReleaseSysCache(tp);
}
+/* ---------- COLLATION CACHE ---------- */
+
+/*
+ * get_collation_name
+ * Returns the name of a given pg_collation entry.
+ *
+ * Returns a palloc'd copy of the string, or NULL if no such constraint.
+ *
+ * NOTE: since collation name is not unique, be wary of code that uses this
+ * for anything except preparing error messages.
+ */
+char *
+get_collation_name(Oid colloid)
+{
+ HeapTuple tp;
+
+ tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(colloid));
+ if (HeapTupleIsValid(tp))
+ {
+ Form_pg_collation colltup = (Form_pg_collation) GETSTRUCT(tp);
+ char *result;
+
+ result = pstrdup(NameStr(colltup->collname));
+ ReleaseSysCache(tp);
+ return result;
+ }
+ else
+ return NULL;
+}
+
/* ---------- CONSTRAINT CACHE ---------- */
/*
@@ -2523,6 +2581,42 @@ get_typmodout(Oid typid)
}
#endif /* NOT_USED */
+/*
+ * get_typcollation
+ *
+ * Given the type OID, return the type's typcollation attribute.
+ */
+Oid
+get_typcollation(Oid typid)
+{
+ HeapTuple tp;
+
+ tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
+ if (HeapTupleIsValid(tp))
+ {
+ Form_pg_type typtup = (Form_pg_type) GETSTRUCT(tp);
+ Oid result;
+
+ result = typtup->typcollation;
+ ReleaseSysCache(tp);
+ return result;
+ }
+ else
+ return InvalidOid;
+}
+
+
+/*
+ * type_is_collatable
+ *
+ * Return whether the type cares about collations
+ */
+bool
+type_is_collatable(Oid typid)
+{
+ return OidIsValid(get_typcollation(typid));
+}
+
/* ---------- STATISTICS CACHE ---------- */
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 3b40acf4dfe..90464fd0663 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -976,9 +976,11 @@ RelationInitIndexAccessInfo(Relation relation)
{
HeapTuple tuple;
Form_pg_am aform;
+ Datum indcollDatum;
Datum indclassDatum;
Datum indoptionDatum;
bool isnull;
+ oidvector *indcoll;
oidvector *indclass;
int2vector *indoption;
MemoryContext indexcxt;
@@ -1061,10 +1063,26 @@ RelationInitIndexAccessInfo(Relation relation)
relation->rd_supportinfo = NULL;
}
+ relation->rd_indcollation = (Oid *)
+ MemoryContextAllocZero(indexcxt, natts * sizeof(Oid));
+
relation->rd_indoption = (int16 *)
MemoryContextAllocZero(indexcxt, natts * sizeof(int16));
/*
+ * indcollation cannot be referenced directly through the C struct, because it
+ * comes after the variable-width indkey field. Must extract the datum
+ * the hard way...
+ */
+ indcollDatum = fastgetattr(relation->rd_indextuple,
+ Anum_pg_index_indcollation,
+ GetPgIndexDescriptor(),
+ &isnull);
+ Assert(!isnull);
+ indcoll = (oidvector *) DatumGetPointer(indcollDatum);
+ memcpy(relation->rd_indcollation, indcoll->values, natts * sizeof(Oid));
+
+ /*
* indclass cannot be referenced directly through the C struct, because it
* comes after the variable-width indkey field. Must extract the datum
* the hard way...
@@ -3988,6 +4006,7 @@ load_relcache_init_file(bool shared)
RegProcedure *support;
int nsupport;
int16 *indoption;
+ Oid *indcollation;
/* Count nailed indexes to ensure we have 'em all */
if (rel->rd_isnailed)
@@ -4054,6 +4073,16 @@ load_relcache_init_file(bool shared)
rel->rd_support = support;
+ /* next, read the vector of collation OIDs */
+ if (fread(&len, 1, sizeof(len), fp) != sizeof(len))
+ goto read_failed;
+
+ indcollation = (Oid *) MemoryContextAlloc(indexcxt, len);
+ if (fread(indcollation, 1, len, fp) != len)
+ goto read_failed;
+
+ rel->rd_indcollation = indcollation;
+
/* finally, read the vector of indoption values */
if (fread(&len, 1, sizeof(len), fp) != sizeof(len))
goto read_failed;
@@ -4087,6 +4116,7 @@ load_relcache_init_file(bool shared)
Assert(rel->rd_support == NULL);
Assert(rel->rd_supportinfo == NULL);
Assert(rel->rd_indoption == NULL);
+ Assert(rel->rd_indcollation == NULL);
}
/*
@@ -4305,6 +4335,11 @@ write_relcache_init_file(bool shared)
relform->relnatts * (am->amsupport * sizeof(RegProcedure)),
fp);
+ /* next, write the vector of collation OIDs */
+ write_item(rel->rd_indcollation,
+ relform->relnatts * sizeof(Oid),
+ fp);
+
/* finally, write the vector of indoption values */
write_item(rel->rd_indoption,
relform->relnatts * sizeof(int16),
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index 191953b972c..715341f8420 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -28,6 +28,7 @@
#include "catalog/pg_auth_members.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_cast.h"
+#include "catalog/pg_collation.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_conversion.h"
#include "catalog/pg_database.h"
@@ -267,6 +268,28 @@ static const struct cachedesc cacheinfo[] = {
},
64
},
+ {CollationRelationId, /* COLLNAMEENCNSP */
+ CollationNameEncNspIndexId,
+ 3,
+ {
+ Anum_pg_collation_collname,
+ Anum_pg_collation_collencoding,
+ Anum_pg_collation_collnamespace,
+ 0
+ },
+ 256
+ },
+ {CollationRelationId, /* COLLOID */
+ CollationOidIndexId,
+ 1,
+ {
+ ObjectIdAttributeNumber,
+ 0,
+ 0,
+ 0
+ },
+ 256
+ },
{ConversionRelationId, /* CONDEFAULT */
ConversionDefaultIndexId,
4,