|
24 | 24 | #include"access/htup_details.h"
|
25 | 25 | #include"catalog/namespace.h"
|
26 | 26 | #include"catalog/pg_class.h"
|
| 27 | +#include"catalog/pg_collation.h" |
27 | 28 | #include"catalog/pg_operator.h"
|
28 | 29 | #include"catalog/pg_proc.h"
|
29 | 30 | #include"catalog/pg_ts_config.h"
|
@@ -1043,6 +1044,157 @@ regclasssend(PG_FUNCTION_ARGS)
|
1043 | 1044 | }
|
1044 | 1045 |
|
1045 | 1046 |
|
| 1047 | +/* |
| 1048 | + * regcollationin- converts "collationname" to collation OID |
| 1049 | + * |
| 1050 | + * We also accept a numeric OID, for symmetry with the output routine. |
| 1051 | + * |
| 1052 | + * '-' signifies unknown (OID 0). In all other cases, the input must |
| 1053 | + * match an existing pg_collation entry. |
| 1054 | + */ |
| 1055 | +Datum |
| 1056 | +regcollationin(PG_FUNCTION_ARGS) |
| 1057 | +{ |
| 1058 | +char*collation_name_or_oid=PG_GETARG_CSTRING(0); |
| 1059 | +Oidresult=InvalidOid; |
| 1060 | +List*names; |
| 1061 | + |
| 1062 | +/* '-' ? */ |
| 1063 | +if (strcmp(collation_name_or_oid,"-")==0) |
| 1064 | +PG_RETURN_OID(InvalidOid); |
| 1065 | + |
| 1066 | +/* Numeric OID? */ |
| 1067 | +if (collation_name_or_oid[0] >='0'&& |
| 1068 | +collation_name_or_oid[0] <='9'&& |
| 1069 | +strspn(collation_name_or_oid,"0123456789")==strlen(collation_name_or_oid)) |
| 1070 | +{ |
| 1071 | +result=DatumGetObjectId(DirectFunctionCall1(oidin, |
| 1072 | +CStringGetDatum(collation_name_or_oid))); |
| 1073 | +PG_RETURN_OID(result); |
| 1074 | +} |
| 1075 | + |
| 1076 | +/* Else it's a name, possibly schema-qualified */ |
| 1077 | + |
| 1078 | +/* The rest of this wouldn't work in bootstrap mode */ |
| 1079 | +if (IsBootstrapProcessingMode()) |
| 1080 | +elog(ERROR,"regcollation values must be OIDs in bootstrap mode"); |
| 1081 | + |
| 1082 | +/* |
| 1083 | + * Normal case: parse the name into components and see if it matches any |
| 1084 | + * pg_collation entries in the current search path. |
| 1085 | + */ |
| 1086 | +names=stringToQualifiedNameList(collation_name_or_oid); |
| 1087 | + |
| 1088 | +result=get_collation_oid(names, false); |
| 1089 | + |
| 1090 | +PG_RETURN_OID(result); |
| 1091 | +} |
| 1092 | + |
| 1093 | +/* |
| 1094 | + * to_regcollation- converts "collationname" to collation OID |
| 1095 | + * |
| 1096 | + * If the name is not found, we return NULL. |
| 1097 | + */ |
| 1098 | +Datum |
| 1099 | +to_regcollation(PG_FUNCTION_ARGS) |
| 1100 | +{ |
| 1101 | +char*collation_name=text_to_cstring(PG_GETARG_TEXT_PP(0)); |
| 1102 | +Oidresult; |
| 1103 | +List*names; |
| 1104 | + |
| 1105 | +/* |
| 1106 | + * Parse the name into components and see if it matches any pg_collation |
| 1107 | + * entries in the current search path. |
| 1108 | + */ |
| 1109 | +names=stringToQualifiedNameList(collation_name); |
| 1110 | + |
| 1111 | +/* We might not even have permissions on this relation; don't lock it. */ |
| 1112 | +result=get_collation_oid(names, true); |
| 1113 | + |
| 1114 | +if (OidIsValid(result)) |
| 1115 | +PG_RETURN_OID(result); |
| 1116 | +else |
| 1117 | +PG_RETURN_NULL(); |
| 1118 | +} |
| 1119 | + |
| 1120 | +/* |
| 1121 | + * regcollationout- converts collation OID to "collation_name" |
| 1122 | + */ |
| 1123 | +Datum |
| 1124 | +regcollationout(PG_FUNCTION_ARGS) |
| 1125 | +{ |
| 1126 | +Oidcollationid=PG_GETARG_OID(0); |
| 1127 | +char*result; |
| 1128 | +HeapTuplecollationtup; |
| 1129 | + |
| 1130 | +if (collationid==InvalidOid) |
| 1131 | +{ |
| 1132 | +result=pstrdup("-"); |
| 1133 | +PG_RETURN_CSTRING(result); |
| 1134 | +} |
| 1135 | + |
| 1136 | +collationtup=SearchSysCache1(COLLOID,ObjectIdGetDatum(collationid)); |
| 1137 | + |
| 1138 | +if (HeapTupleIsValid(collationtup)) |
| 1139 | +{ |
| 1140 | +Form_pg_collationcollationform= (Form_pg_collation)GETSTRUCT(collationtup); |
| 1141 | +char*collationname=NameStr(collationform->collname); |
| 1142 | + |
| 1143 | +/* |
| 1144 | + * In bootstrap mode, skip the fancy namespace stuff and just return |
| 1145 | + * the collation name. (This path is only needed for debugging output |
| 1146 | + * anyway.) |
| 1147 | + */ |
| 1148 | +if (IsBootstrapProcessingMode()) |
| 1149 | +result=pstrdup(collationname); |
| 1150 | +else |
| 1151 | +{ |
| 1152 | +char*nspname; |
| 1153 | + |
| 1154 | +/* |
| 1155 | + * Would this collation be found by regcollationin? If not, qualify it. |
| 1156 | + */ |
| 1157 | +if (CollationIsVisible(collationid)) |
| 1158 | +nspname=NULL; |
| 1159 | +else |
| 1160 | +nspname=get_namespace_name(collationform->collnamespace); |
| 1161 | + |
| 1162 | +result=quote_qualified_identifier(nspname,collationname); |
| 1163 | +} |
| 1164 | + |
| 1165 | +ReleaseSysCache(collationtup); |
| 1166 | +} |
| 1167 | +else |
| 1168 | +{ |
| 1169 | +/* If OID doesn't match any pg_collation entry, return it numerically */ |
| 1170 | +result= (char*)palloc(NAMEDATALEN); |
| 1171 | +snprintf(result,NAMEDATALEN,"%u",collationid); |
| 1172 | +} |
| 1173 | + |
| 1174 | +PG_RETURN_CSTRING(result); |
| 1175 | +} |
| 1176 | + |
| 1177 | +/* |
| 1178 | + *regcollationrecv- converts external binary format to regcollation |
| 1179 | + */ |
| 1180 | +Datum |
| 1181 | +regcollationrecv(PG_FUNCTION_ARGS) |
| 1182 | +{ |
| 1183 | +/* Exactly the same as oidrecv, so share code */ |
| 1184 | +returnoidrecv(fcinfo); |
| 1185 | +} |
| 1186 | + |
| 1187 | +/* |
| 1188 | + *regcollationsend- converts regcollation to binary format |
| 1189 | + */ |
| 1190 | +Datum |
| 1191 | +regcollationsend(PG_FUNCTION_ARGS) |
| 1192 | +{ |
| 1193 | +/* Exactly the same as oidsend, so share code */ |
| 1194 | +returnoidsend(fcinfo); |
| 1195 | +} |
| 1196 | + |
| 1197 | + |
1046 | 1198 | /*
|
1047 | 1199 | * regtypein- converts "typename" to type OID
|
1048 | 1200 | *
|
|