|
33 | 33 | #include"catalog/heap.h"
|
34 | 34 | #include"catalog/index.h"
|
35 | 35 | #include"catalog/namespace.h"
|
| 36 | +#include"catalog/pg_collation.h" |
36 | 37 | #include"catalog/pg_constraint.h"
|
37 | 38 | #include"catalog/pg_opclass.h"
|
38 | 39 | #include"catalog/pg_operator.h"
|
@@ -111,6 +112,7 @@ static void transformOfType(CreateStmtContext *cxt,
|
111 | 112 | staticchar*chooseIndexName(constRangeVar*relation,IndexStmt*index_stmt);
|
112 | 113 | staticIndexStmt*generateClonedIndexStmt(CreateStmtContext*cxt,
|
113 | 114 | Relationparent_index,AttrNumber*attmap);
|
| 115 | +staticList*get_collation(Oidcollation,Oidactual_datatype); |
114 | 116 | staticList*get_opclass(Oidopclass,Oidactual_datatype);
|
115 | 117 | staticvoidtransformIndexConstraints(CreateStmtContext*cxt);
|
116 | 118 | staticIndexStmt*transformIndexConstraint(Constraint*constraint,
|
@@ -904,6 +906,7 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
|
904 | 906 | Form_pg_classidxrelrec;
|
905 | 907 | Form_pg_indexidxrec;
|
906 | 908 | Form_pg_amamrec;
|
| 909 | +oidvector*indcollation; |
907 | 910 | oidvector*indclass;
|
908 | 911 | IndexStmt*index;
|
909 | 912 | List*indexprs;
|
@@ -931,6 +934,12 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
|
931 | 934 | /* Fetch pg_am tuple for source index from relcache entry */
|
932 | 935 | amrec=source_idx->rd_am;
|
933 | 936 |
|
| 937 | +/* Extract indcollation from the pg_index tuple */ |
| 938 | +datum=SysCacheGetAttr(INDEXRELID,ht_idx, |
| 939 | +Anum_pg_index_indcollation,&isnull); |
| 940 | +Assert(!isnull); |
| 941 | +indcollation= (oidvector*)DatumGetPointer(datum); |
| 942 | + |
934 | 943 | /* Extract indclass from the pg_index tuple */
|
935 | 944 | datum=SysCacheGetAttr(INDEXRELID,ht_idx,
|
936 | 945 | Anum_pg_index_indclass,&isnull);
|
@@ -1094,6 +1103,9 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
|
1094 | 1103 | /* Copy the original index column name */
|
1095 | 1104 | iparam->indexcolname=pstrdup(NameStr(attrs[keyno]->attname));
|
1096 | 1105 |
|
| 1106 | +/* Add the collation name, if non-default */ |
| 1107 | +iparam->collation=get_collation(indcollation->values[keyno],keycoltype); |
| 1108 | + |
1097 | 1109 | /* Add the operator class name, if non-default */
|
1098 | 1110 | iparam->opclass=get_opclass(indclass->values[keyno],keycoltype);
|
1099 | 1111 |
|
@@ -1152,17 +1164,51 @@ generateClonedIndexStmt(CreateStmtContext *cxt, Relation source_idx,
|
1152 | 1164 | }
|
1153 | 1165 |
|
1154 | 1166 | /*
|
1155 |
| - * get_opclass- fetch name of an index operator class |
| 1167 | + * get_collation- fetch qualified name of a collation |
| 1168 | + * |
| 1169 | + * If collation is InvalidOid or is the default for the given actual_datatype, |
| 1170 | + * then the return value is NIL. |
| 1171 | + */ |
| 1172 | +staticList* |
| 1173 | +get_collation(Oidcollation,Oidactual_datatype) |
| 1174 | +{ |
| 1175 | +List*result; |
| 1176 | +HeapTupleht_coll; |
| 1177 | +Form_pg_collationcoll_rec; |
| 1178 | +char*nsp_name; |
| 1179 | +char*coll_name; |
| 1180 | + |
| 1181 | +if (!OidIsValid(collation)) |
| 1182 | +returnNIL;/* easy case */ |
| 1183 | +if (collation==get_typcollation(actual_datatype)) |
| 1184 | +returnNIL;/* just let it default */ |
| 1185 | + |
| 1186 | +ht_coll=SearchSysCache1(COLLOID,ObjectIdGetDatum(collation)); |
| 1187 | +if (!HeapTupleIsValid(ht_coll)) |
| 1188 | +elog(ERROR,"cache lookup failed for collation %u",collation); |
| 1189 | +coll_rec= (Form_pg_collation)GETSTRUCT(ht_coll); |
| 1190 | + |
| 1191 | +/* For simplicity, we always schema-qualify the name */ |
| 1192 | +nsp_name=get_namespace_name(coll_rec->collnamespace); |
| 1193 | +coll_name=pstrdup(NameStr(coll_rec->collname)); |
| 1194 | +result=list_make2(makeString(nsp_name),makeString(coll_name)); |
| 1195 | + |
| 1196 | +ReleaseSysCache(ht_coll); |
| 1197 | +returnresult; |
| 1198 | +} |
| 1199 | + |
| 1200 | +/* |
| 1201 | + * get_opclass- fetch qualified name of an index operator class |
1156 | 1202 | *
|
1157 | 1203 | * If the opclass is the default for the given actual_datatype, then
|
1158 | 1204 | * the return value is NIL.
|
1159 | 1205 | */
|
1160 | 1206 | staticList*
|
1161 | 1207 | get_opclass(Oidopclass,Oidactual_datatype)
|
1162 | 1208 | {
|
| 1209 | +List*result=NIL; |
1163 | 1210 | HeapTupleht_opc;
|
1164 | 1211 | Form_pg_opclassopc_rec;
|
1165 |
| -List*result=NIL; |
1166 | 1212 |
|
1167 | 1213 | ht_opc=SearchSysCache1(CLAOID,ObjectIdGetDatum(opclass));
|
1168 | 1214 | if (!HeapTupleIsValid(ht_opc))
|
@@ -1663,6 +1709,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
|
1663 | 1709 | iparam->name=pstrdup(key);
|
1664 | 1710 | iparam->expr=NULL;
|
1665 | 1711 | iparam->indexcolname=NULL;
|
| 1712 | +iparam->collation=NIL; |
1666 | 1713 | iparam->opclass=NIL;
|
1667 | 1714 | iparam->ordering=SORTBY_DEFAULT;
|
1668 | 1715 | iparam->nulls_ordering=SORTBY_NULLS_DEFAULT;
|
|