diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2011-03-26 16:35:25 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2011-03-26 16:35:25 -0400 |
commit | 0c9d9e8dd655fff7bcfc401e82838b8c20c16939 (patch) | |
tree | a439a1dc07a6beee9e04d5a26911a8787b9e4740 /src/backend/parser/parse_utilcmd.c | |
parent | b23c9fa9293c54a3829093d207be37a7b42cb630 (diff) | |
download | postgresql-0c9d9e8dd655fff7bcfc401e82838b8c20c16939.tar.gz postgresql-0c9d9e8dd655fff7bcfc401e82838b8c20c16939.zip |
More collations cleanup, from trawling for missed collation assignments.
Mostly cosmetic, though I did find that generateClonedIndexStmt failed
to clone the index's collations.
Diffstat (limited to 'src/backend/parser/parse_utilcmd.c')
-rw-r--r-- | src/backend/parser/parse_utilcmd.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index eafc3b30539..fe8d0c4fac1 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -33,6 +33,7 @@ #include "catalog/heap.h" #include "catalog/index.h" #include "catalog/namespace.h" +#include "catalog/pg_collation.h" #include "catalog/pg_constraint.h" #include "catalog/pg_opclass.h" #include "catalog/pg_operator.h" @@ -111,6 +112,7 @@ static void transformOfType(CreateStmtContext *cxt, static char *chooseIndexName(const RangeVar *relation, IndexStmt *index_stmt); static IndexStmt *generateClonedIndexStmt(CreateStmtContext *cxt, Relation parent_index, AttrNumber *attmap); +static List *get_collation(Oid collation, Oid actual_datatype); static List *get_opclass(Oid opclass, Oid actual_datatype); static void transformIndexConstraints(CreateStmtContext *cxt); static IndexStmt *transformIndexConstraint(Constraint *constraint, @@ -904,6 +906,7 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx, Form_pg_class idxrelrec; Form_pg_index idxrec; Form_pg_am amrec; + oidvector *indcollation; oidvector *indclass; IndexStmt *index; List *indexprs; @@ -931,6 +934,12 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx, /* Fetch pg_am tuple for source index from relcache entry */ amrec = source_idx->rd_am; + /* Extract indcollation from the pg_index tuple */ + datum = SysCacheGetAttr(INDEXRELID, ht_idx, + Anum_pg_index_indcollation, &isnull); + Assert(!isnull); + indcollation = (oidvector *) DatumGetPointer(datum); + /* Extract indclass from the pg_index tuple */ datum = SysCacheGetAttr(INDEXRELID, ht_idx, Anum_pg_index_indclass, &isnull); @@ -1094,6 +1103,9 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx, /* Copy the original index column name */ iparam->indexcolname = pstrdup(NameStr(attrs[keyno]->attname)); + /* Add the collation name, if non-default */ + iparam->collation = get_collation(indcollation->values[keyno], keycoltype); + /* Add the operator class name, if non-default */ iparam->opclass = get_opclass(indclass->values[keyno], keycoltype); @@ -1152,7 +1164,41 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx, } /* - * get_opclass - fetch name of an index operator class + * get_collation - fetch qualified name of a collation + * + * If collation is InvalidOid or is the default for the given actual_datatype, + * then the return value is NIL. + */ +static List * +get_collation(Oid collation, Oid actual_datatype) +{ + List *result; + HeapTuple ht_coll; + Form_pg_collation coll_rec; + char *nsp_name; + char *coll_name; + + if (!OidIsValid(collation)) + return NIL; /* easy case */ + if (collation == get_typcollation(actual_datatype)) + return NIL; /* just let it default */ + + ht_coll = SearchSysCache1(COLLOID, ObjectIdGetDatum(collation)); + if (!HeapTupleIsValid(ht_coll)) + elog(ERROR, "cache lookup failed for collation %u", collation); + coll_rec = (Form_pg_collation) GETSTRUCT(ht_coll); + + /* For simplicity, we always schema-qualify the name */ + nsp_name = get_namespace_name(coll_rec->collnamespace); + coll_name = pstrdup(NameStr(coll_rec->collname)); + result = list_make2(makeString(nsp_name), makeString(coll_name)); + + ReleaseSysCache(ht_coll); + return result; +} + +/* + * get_opclass - fetch qualified name of an index operator class * * If the opclass is the default for the given actual_datatype, then * the return value is NIL. @@ -1160,9 +1206,9 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx, static List * get_opclass(Oid opclass, Oid actual_datatype) { + List *result = NIL; HeapTuple ht_opc; Form_pg_opclass opc_rec; - List *result = NIL; ht_opc = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass)); if (!HeapTupleIsValid(ht_opc)) @@ -1663,6 +1709,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt) iparam->name = pstrdup(key); iparam->expr = NULL; iparam->indexcolname = NULL; + iparam->collation = NIL; iparam->opclass = NIL; iparam->ordering = SORTBY_DEFAULT; iparam->nulls_ordering = SORTBY_NULLS_DEFAULT; |