58{
59 char *collName;
68 DefElem *deterministicEl = NULL;
71 char *collcollate;
72 char *collctype;
73 const char *colllocale;
74 char *collicurules;
75 bool collisdeterministic;
76 int collencoding;
77 char collprovider;
78 char *collversion = NULL;
81
83
88
89 foreach(pl, parameters)
90 {
93
94 if (strcmp(defel->
defname,
"from") == 0)
95 defelp = &fromEl;
96 else if (strcmp(defel->
defname,
"locale") == 0)
97 defelp = &localeEl;
98 else if (strcmp(defel->
defname,
"lc_collate") == 0)
99 defelp = &lccollateEl;
100 else if (strcmp(defel->
defname,
"lc_ctype") == 0)
101 defelp = &lcctypeEl;
102 else if (strcmp(defel->
defname,
"provider") == 0)
103 defelp = &providerEl;
104 else if (strcmp(defel->
defname,
"deterministic") == 0)
105 defelp = &deterministicEl;
106 else if (strcmp(defel->
defname,
"rules") == 0)
107 defelp = &rulesEl;
108 else if (strcmp(defel->
defname,
"version") == 0)
109 defelp = &versionEl;
110 else
111 {
113 (
errcode(ERRCODE_SYNTAX_ERROR),
114 errmsg(
"collation attribute \"%s\" not recognized",
117 break;
118 }
119 if (*defelp != NULL)
121 *defelp = defel;
122 }
123
124 if (localeEl && (lccollateEl || lcctypeEl))
127 errmsg(
"conflicting or redundant options"),
128 errdetail(
"LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE."));
129
133 errmsg(
"conflicting or redundant options"),
134 errdetail(
"FROM cannot be specified together with any other options."));
135
136 if (fromEl)
137 {
141 bool isnull;
142
147
151
152 datum =
SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collcollate, &isnull);
153 if (!isnull)
155 else
156 collcollate = NULL;
157
158 datum =
SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collctype, &isnull);
159 if (!isnull)
161 else
162 collctype = NULL;
163
164 datum =
SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_colllocale, &isnull);
165 if (!isnull)
167 else
168 colllocale = NULL;
169
170
171
172
173
174
175 datum =
SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collicurules, &isnull);
176 if (!isnull)
178 else
179 collicurules = NULL;
180
182
183
184
185
186
187
188
189
190 if (collprovider == COLLPROVIDER_DEFAULT)
192 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
193 errmsg(
"collation \"default\" cannot be copied")));
194 }
195 else
196 {
197 char *collproviderstr = NULL;
198
199 collcollate = NULL;
200 collctype = NULL;
201 colllocale = NULL;
202 collicurules = NULL;
203
204 if (providerEl)
206
207 if (deterministicEl)
209 else
210 collisdeterministic = true;
211
212 if (rulesEl)
214
215 if (versionEl)
217
218 if (collproviderstr)
219 {
221 collprovider = COLLPROVIDER_BUILTIN;
223 collprovider = COLLPROVIDER_ICU;
225 collprovider = COLLPROVIDER_LIBC;
226 else
228 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
229 errmsg(
"unrecognized collation provider: %s",
230 collproviderstr)));
231 }
232 else
233 collprovider = COLLPROVIDER_LIBC;
234
235 if (localeEl)
236 {
237 if (collprovider == COLLPROVIDER_LIBC)
238 {
241 }
242 else
244 }
245
246 if (lccollateEl)
248
249 if (lcctypeEl)
251
252 if (collprovider == COLLPROVIDER_BUILTIN)
253 {
254 if (!colllocale)
256 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
257 errmsg(
"parameter \"%s\" must be specified",
258 "locale")));
259
261 colllocale);
262 }
263 else if (collprovider == COLLPROVIDER_LIBC)
264 {
265 if (!collcollate)
267 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
268 errmsg(
"parameter \"%s\" must be specified",
269 "lc_collate")));
270
271 if (!collctype)
273 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
274 errmsg(
"parameter \"%s\" must be specified",
275 "lc_ctype")));
276 }
277 else if (collprovider == COLLPROVIDER_ICU)
278 {
279 if (!colllocale)
281 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
282 errmsg(
"parameter \"%s\" must be specified",
283 "locale")));
284
285
286
287
288
290 {
293
294 if (langtag && strcmp(colllocale, langtag) != 0)
295 {
297 (
errmsg(
"using standard form \"%s\" for ICU locale \"%s\"",
298 langtag, colllocale)));
299
300 colllocale = langtag;
301 }
302 }
303
305 }
306
307
308
309
310
311
312
313 if (!collisdeterministic && collprovider != COLLPROVIDER_ICU)
315 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
316 errmsg(
"nondeterministic collations not supported with this provider")));
317
318 if (collicurules && collprovider != COLLPROVIDER_ICU)
320 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
321 errmsg(
"ICU rules cannot be specified unless locale provider is ICU")));
322
323 if (collprovider == COLLPROVIDER_BUILTIN)
324 {
326 }
327 else if (collprovider == COLLPROVIDER_ICU)
328 {
329#ifdef USE_ICU
330
331
332
333
334
335
336
337
338
339
340
343 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
344 errmsg(
"current database's encoding is not supported with this provider")));
345#endif
346 collencoding = -1;
347 }
348 else
349 {
352 }
353 }
354
355 if (!collversion)
356 {
358
359 if (collprovider == COLLPROVIDER_LIBC)
361 else
363
365 }
366
368 collNamespace,
370 collprovider,
371 collisdeterministic,
372 collencoding,
373 collcollate,
374 collctype,
375 colllocale,
376 collicurules,
377 collversion,
378 if_not_exists,
379 false);
380
383
384
387
389
390 return address;
391}
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
#define OidIsValid(objectId)
void check_encoding_locale_matches(int encoding, const char *collate, const char *ctype)
char * defGetString(DefElem *def)
bool defGetBoolean(DefElem *def)
List * defGetQualifiedName(DefElem *def)
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
int errdetail(const char *fmt,...)
int errcode(int sqlerrcode)
bool is_encoding_supported_by_icu(int encoding)
char * get_namespace_name(Oid nspid)
int GetDatabaseEncoding(void)
Oid QualifiedNameGetCreationNamespace(const List *names, char **objname_p)
const ObjectAddress InvalidObjectAddress
int parser_errposition(ParseState *pstate, int location)
Oid CollationCreate(const char *collname, Oid collnamespace, Oid collowner, char collprovider, bool collisdeterministic, int32 collencoding, const char *collcollate, const char *collctype, const char *colllocale, const char *collicurules, const char *collversion, bool if_not_exists, bool quiet)
#define lfirst_node(type, lc)
static int list_length(const List *l)
void icu_validate_locale(const char *loc_str)
pg_locale_t pg_newlocale_from_collation(Oid collid)
int builtin_locale_encoding(const char *locale)
char * icu_language_tag(const char *loc_str, int elevel)
const char * builtin_validate_locale(int encoding, const char *locale)
int pg_strcasecmp(const char *s1, const char *s2)
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
void CommandCounterIncrement(void)