diff options
Diffstat (limited to 'src/backend/utils/cache')
-rw-r--r-- | src/backend/utils/cache/lsyscache.c | 94 | ||||
-rw-r--r-- | src/backend/utils/cache/relcache.c | 35 | ||||
-rw-r--r-- | src/backend/utils/cache/syscache.c | 23 |
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, |