54{
55 char *collName;
64 DefElem *deterministicEl = NULL;
67 char *collcollate;
68 char *collctype;
69 const char *colllocale;
70 char *collicurules;
71 bool collisdeterministic;
72 int collencoding;
73 char collprovider;
74 char *collversion = NULL;
77
79
84
85 foreach(pl, parameters)
86 {
89
90 if (strcmp(defel->
defname,
"from") == 0)
91 defelp = &fromEl;
92 else if (strcmp(defel->
defname,
"locale") == 0)
93 defelp = &localeEl;
94 else if (strcmp(defel->
defname,
"lc_collate") == 0)
95 defelp = &lccollateEl;
96 else if (strcmp(defel->
defname,
"lc_ctype") == 0)
97 defelp = &lcctypeEl;
98 else if (strcmp(defel->
defname,
"provider") == 0)
99 defelp = &providerEl;
100 else if (strcmp(defel->
defname,
"deterministic") == 0)
101 defelp = &deterministicEl;
102 else if (strcmp(defel->
defname,
"rules") == 0)
103 defelp = &rulesEl;
104 else if (strcmp(defel->
defname,
"version") == 0)
105 defelp = &versionEl;
106 else
107 {
109 (
errcode(ERRCODE_SYNTAX_ERROR),
110 errmsg(
"collation attribute \"%s\" not recognized",
113 break;
114 }
115 if (*defelp != NULL)
117 *defelp = defel;
118 }
119
120 if (localeEl && (lccollateEl || lcctypeEl))
123 errmsg(
"conflicting or redundant options"),
124 errdetail(
"LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE."));
125
129 errmsg(
"conflicting or redundant options"),
130 errdetail(
"FROM cannot be specified together with any other options."));
131
132 if (fromEl)
133 {
137 bool isnull;
138
143
147
148 datum =
SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collcollate, &isnull);
149 if (!isnull)
151 else
152 collcollate = NULL;
153
154 datum =
SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collctype, &isnull);
155 if (!isnull)
157 else
158 collctype = NULL;
159
160 datum =
SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_colllocale, &isnull);
161 if (!isnull)
163 else
164 colllocale = NULL;
165
166
167
168
169
170
171 datum =
SysCacheGetAttr(COLLOID, tp, Anum_pg_collation_collicurules, &isnull);
172 if (!isnull)
174 else
175 collicurules = NULL;
176
178
179
180
181
182
183
184
185
186 if (collprovider == COLLPROVIDER_DEFAULT)
188 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
189 errmsg(
"collation \"default\" cannot be copied")));
190 }
191 else
192 {
193 char *collproviderstr = NULL;
194
195 collcollate = NULL;
196 collctype = NULL;
197 colllocale = NULL;
198 collicurules = NULL;
199
200 if (providerEl)
202
203 if (deterministicEl)
205 else
206 collisdeterministic = true;
207
208 if (rulesEl)
210
211 if (versionEl)
213
214 if (collproviderstr)
215 {
217 collprovider = COLLPROVIDER_BUILTIN;
219 collprovider = COLLPROVIDER_ICU;
221 collprovider = COLLPROVIDER_LIBC;
222 else
224 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
225 errmsg(
"unrecognized collation provider: %s",
226 collproviderstr)));
227 }
228 else
229 collprovider = COLLPROVIDER_LIBC;
230
231 if (localeEl)
232 {
233 if (collprovider == COLLPROVIDER_LIBC)
234 {
237 }
238 else
240 }
241
242 if (lccollateEl)
244
245 if (lcctypeEl)
247
248 if (collprovider == COLLPROVIDER_BUILTIN)
249 {
250 if (!colllocale)
252 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
253 errmsg(
"parameter \"%s\" must be specified",
254 "locale")));
255
257 colllocale);
258 }
259 else if (collprovider == COLLPROVIDER_LIBC)
260 {
261 if (!collcollate)
263 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
264 errmsg(
"parameter \"%s\" must be specified",
265 "lc_collate")));
266
267 if (!collctype)
269 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
270 errmsg(
"parameter \"%s\" must be specified",
271 "lc_ctype")));
272 }
273 else if (collprovider == COLLPROVIDER_ICU)
274 {
275 if (!colllocale)
277 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
278 errmsg(
"parameter \"%s\" must be specified",
279 "locale")));
280
281
282
283
284
286 {
289
290 if (langtag && strcmp(colllocale, langtag) != 0)
291 {
293 (
errmsg(
"using standard form \"%s\" for ICU locale \"%s\"",
294 langtag, colllocale)));
295
296 colllocale = langtag;
297 }
298 }
299
301 }
302
303
304
305
306
307
308
309 if (!collisdeterministic && collprovider != COLLPROVIDER_ICU)
311 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
312 errmsg(
"nondeterministic collations not supported with this provider")));
313
314 if (collicurules && collprovider != COLLPROVIDER_ICU)
316 (
errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
317 errmsg(
"ICU rules cannot be specified unless locale provider is ICU")));
318
319 if (collprovider == COLLPROVIDER_BUILTIN)
320 {
322 }
323 else if (collprovider == COLLPROVIDER_ICU)
324 {
325#ifdef USE_ICU
326
327
328
329
330
331
332
333
334
335
336
339 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
340 errmsg(
"current database's encoding is not supported with this provider")));
341#endif
342 collencoding = -1;
343 }
344 else
345 {
348 }
349 }
350
351 if (!collversion)
352 {
354
355 if (collprovider == COLLPROVIDER_LIBC)
357 else
359
361 }
362
364 collNamespace,
366 collprovider,
367 collisdeterministic,
368 collencoding,
369 collcollate,
370 collctype,
371 colllocale,
372 collicurules,
373 collversion,
374 if_not_exists,
375 false);
376
379
380
383
385
386 return address;
387}
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)