PostgreSQL Source Code git master
Loading...
Searching...
No Matches
collationcmds.h File Reference
Include dependency graph for collationcmds.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

ObjectAddress DefineCollation (ParseState *pstate, List *names, List *parameters, bool if_not_exists)
 
void IsThereCollationInNamespace (const char *collname, Oid nspOid)
 
ObjectAddress AlterCollation (AlterCollationStmt *stmt)
 

Function Documentation

◆ AlterCollation()

ObjectAddress AlterCollation ( AlterCollationStmt stmt)
extern

Definition at line 429 of file collationcmds.c.

430{
431 Relation rel;
432 Oid collOid;
435 Datum datum;
436 bool isnull;
437 char *oldversion;
438 char *newversion;
439 ObjectAddress address;
440
442 collOid = get_collation_oid(stmt->collname, false);
443
444 if (collOid == DEFAULT_COLLATION_OID)
446 (errmsg("cannot refresh version of default collation"),
447 /* translator: %s is an SQL command */
448 errhint("Use %s instead.",
449 "ALTER DATABASE ... REFRESH COLLATION VERSION")));
450
453 NameListToString(stmt->collname));
454
456 if (!HeapTupleIsValid(tup))
457 elog(ERROR, "cache lookup failed for collation %u", collOid);
458
461 oldversion = isnull ? NULL : TextDatumGetCString(datum);
462
463 if (collForm->collprovider == COLLPROVIDER_LIBC)
465 else
467
469 TextDatumGetCString(datum));
470
471 /* cannot change from NULL to non-NULL or vice versa */
472 if ((!oldversion && newversion) || (oldversion && !newversion))
473 elog(ERROR, "invalid collation version change");
474 else if (oldversion && newversion && strcmp(newversion, oldversion) != 0)
475 {
476 bool nulls[Natts_pg_collation];
479
481 (errmsg("changing version from %s to %s",
483
484 memset(values, 0, sizeof(values));
485 memset(nulls, false, sizeof(nulls));
486 memset(replaces, false, sizeof(replaces));
487
490
492 values, nulls, replaces);
493 }
494 else
496 (errmsg("version has not changed")));
497
498 CatalogTupleUpdate(rel, &tup->t_self, tup);
499
501
502 ObjectAddressSet(address, CollationRelationId, collOid);
503
505 table_close(rel, NoLock);
506
507 return address;
508}
@ ACLCHECK_NOT_OWNER
Definition acl.h:185
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition aclchk.c:2654
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
Definition aclchk.c:4090
static Datum values[MAXATTR]
Definition bootstrap.c:155
#define CStringGetTextDatum(s)
Definition builtins.h:97
#define TextDatumGetCString(d)
Definition builtins.h:98
int errhint(const char *fmt,...)
Definition elog.c:1330
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define NOTICE
Definition elog.h:35
#define ereport(elevel,...)
Definition elog.h:150
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition heaptuple.c:1210
void heap_freetuple(HeapTuple htup)
Definition heaptuple.c:1435
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
#define stmt
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
Definition indexing.c:313
#define NoLock
Definition lockdefs.h:34
#define RowExclusiveLock
Definition lockdefs.h:38
Oid GetUserId(void)
Definition miscinit.c:469
char * NameListToString(const List *names)
Definition namespace.c:3664
Oid get_collation_oid(List *collname, bool missing_ok)
Definition namespace.c:4041
#define InvokeObjectPostAlterHook(classId, objectId, subId)
#define ObjectAddressSet(addr, class_id, object_id)
@ OBJECT_COLLATION
FormData_pg_collation * Form_pg_collation
char * get_collation_actual_version(char collprovider, const char *collcollate)
Definition pg_locale.c:1247
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:262
uint64_t Datum
Definition postgres.h:70
unsigned int Oid
static int fb(int x)
#define RelationGetDescr(relation)
Definition rel.h:540
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:595
Datum SysCacheGetAttrNotNull(int cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition syscache.c:625
#define SearchSysCacheCopy1(cacheId, key1)
Definition syscache.h:91
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40

References aclcheck_error(), ACLCHECK_NOT_OWNER, CatalogTupleUpdate(), CStringGetTextDatum, elog, ereport, errhint(), errmsg(), ERROR, fb(), get_collation_actual_version(), get_collation_oid(), GETSTRUCT(), GetUserId(), heap_freetuple(), heap_modify_tuple(), HeapTupleIsValid, InvokeObjectPostAlterHook, NameListToString(), NoLock, NOTICE, OBJECT_COLLATION, object_ownercheck(), ObjectAddressSet, ObjectIdGetDatum(), RelationGetDescr, RowExclusiveLock, SearchSysCacheCopy1, stmt, SysCacheGetAttr(), SysCacheGetAttrNotNull(), table_close(), table_open(), TextDatumGetCString, and values.

Referenced by ProcessUtilitySlow().

◆ DefineCollation()

ObjectAddress DefineCollation ( ParseState pstate,
List names,
List parameters,
bool  if_not_exists 
)
extern

Definition at line 58 of file collationcmds.c.

59{
60 char *collName;
63 ListCell *pl;
72 char *collcollate;
73 char *collctype;
74 const char *colllocale;
75 char *collicurules;
77 int collencoding;
78 char collprovider;
79 char *collversion = NULL;
80 Oid newoid;
81 ObjectAddress address;
82
84
89
90 foreach(pl, parameters)
91 {
94
95 if (strcmp(defel->defname, "from") == 0)
96 defelp = &fromEl;
97 else if (strcmp(defel->defname, "locale") == 0)
99 else if (strcmp(defel->defname, "lc_collate") == 0)
101 else if (strcmp(defel->defname, "lc_ctype") == 0)
102 defelp = &lcctypeEl;
103 else if (strcmp(defel->defname, "provider") == 0)
105 else if (strcmp(defel->defname, "deterministic") == 0)
107 else if (strcmp(defel->defname, "rules") == 0)
108 defelp = &rulesEl;
109 else if (strcmp(defel->defname, "version") == 0)
110 defelp = &versionEl;
111 else
112 {
115 errmsg("collation attribute \"%s\" not recognized",
116 defel->defname),
117 parser_errposition(pstate, defel->location)));
118 break;
119 }
120 if (*defelp != NULL)
122 *defelp = defel;
123 }
124
125 if (localeEl && (lccollateEl || lcctypeEl))
128 errmsg("conflicting or redundant options"),
129 errdetail("LOCALE cannot be specified together with LC_COLLATE or LC_CTYPE."));
130
131 if (fromEl && list_length(parameters) != 1)
134 errmsg("conflicting or redundant options"),
135 errdetail("FROM cannot be specified together with any other options."));
136
137 if (fromEl)
138 {
139 Oid collid;
140 HeapTuple tp;
141 Datum datum;
142 bool isnull;
143
146 if (!HeapTupleIsValid(tp))
147 elog(ERROR, "cache lookup failed for collation %u", collid);
148
151 collencoding = ((Form_pg_collation) GETSTRUCT(tp))->collencoding;
152
154 if (!isnull)
156 else
158
160 if (!isnull)
162 else
163 collctype = NULL;
164
166 if (!isnull)
168 else
170
171 /*
172 * When the ICU locale comes from an existing collation, do not
173 * canonicalize to a language tag.
174 */
175
177 if (!isnull)
179 else
181
182 ReleaseSysCache(tp);
183
184 /*
185 * Copying the "default" collation is not allowed because most code
186 * checks for DEFAULT_COLLATION_OID instead of COLLPROVIDER_DEFAULT,
187 * and so having a second collation with COLLPROVIDER_DEFAULT would
188 * not work and potentially confuse or crash some code. This could be
189 * fixed with some legwork.
190 */
194 errmsg("collation \"default\" cannot be copied")));
195 }
196 else
197 {
198 char *collproviderstr = NULL;
199
201 collctype = NULL;
204
205 if (providerEl)
207
208 if (deterministicEl)
210 else
211 collisdeterministic = true;
212
213 if (rulesEl)
215
216 if (versionEl)
218
219 if (collproviderstr)
220 {
221 if (pg_strcasecmp(collproviderstr, "builtin") == 0)
223 else if (pg_strcasecmp(collproviderstr, "icu") == 0)
225 else if (pg_strcasecmp(collproviderstr, "libc") == 0)
227 else
230 errmsg("unrecognized collation provider: %s",
232 }
233 else
235
236 if (localeEl)
237 {
239 {
242 }
243 else
245 }
246
247 if (lccollateEl)
249
250 if (lcctypeEl)
252
254 {
255 if (!colllocale)
258 errmsg("parameter \"%s\" must be specified",
259 "locale")));
260
262 colllocale);
263 }
265 {
266 if (!collcollate)
269 errmsg("parameter \"%s\" must be specified",
270 "lc_collate")));
271
272 if (!collctype)
275 errmsg("parameter \"%s\" must be specified",
276 "lc_ctype")));
277 }
278 else if (collprovider == COLLPROVIDER_ICU)
279 {
280 if (!colllocale)
283 errmsg("parameter \"%s\" must be specified",
284 "locale")));
285
286 /*
287 * During binary upgrade, preserve the locale string. Otherwise,
288 * canonicalize to a language tag.
289 */
290 if (!IsBinaryUpgrade)
291 {
294
295 if (langtag && strcmp(colllocale, langtag) != 0)
296 {
298 (errmsg("using standard form \"%s\" for ICU locale \"%s\"",
300
302 }
303 }
304
306 }
307
308 /*
309 * Nondeterministic collations are currently only supported with ICU
310 * because that's the only case where it can actually make a
311 * difference. So we can save writing the code for the other
312 * providers.
313 */
317 errmsg("nondeterministic collations not supported with this provider")));
318
322 errmsg("ICU rules cannot be specified unless locale provider is ICU")));
323
325 {
326 collencoding = builtin_locale_encoding(colllocale);
327 }
328 else if (collprovider == COLLPROVIDER_ICU)
329 {
330#ifdef USE_ICU
331 /*
332 * We could create ICU collations with collencoding == database
333 * encoding, but it seems better to use -1 so that it matches the
334 * way initdb would create ICU collations. However, only allow
335 * one to be created when the current database's encoding is
336 * supported. Otherwise the collation is useless, plus we get
337 * surprising behaviors like not being able to drop the collation.
338 *
339 * Skip this test when !USE_ICU, because the error we want to
340 * throw for that isn't thrown till later.
341 */
345 errmsg("current database's encoding is not supported with this provider")));
346#endif
347 collencoding = -1;
348 }
349 else
350 {
351 collencoding = GetDatabaseEncoding();
353 }
354 }
355
356 if (!collversion)
357 {
358 const char *locale;
359
361 locale = collcollate;
362 else
363 locale = colllocale;
364
366 }
367
370 GetUserId(),
373 collencoding,
375 collctype,
379 if_not_exists,
380 false); /* not quiet */
381
382 if (!OidIsValid(newoid))
384
385 /* Check that the locales can be loaded. */
388
390
391 return address;
392}
AclResult
Definition acl.h:182
@ ACLCHECK_OK
Definition acl.h:183
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition aclchk.c:3836
#define OidIsValid(objectId)
Definition c.h:788
Oid collid
void check_encoding_locale_matches(int encoding, const char *collate, const char *ctype)
char * defGetString(DefElem *def)
Definition define.c:34
bool defGetBoolean(DefElem *def)
Definition define.c:93
List * defGetQualifiedName(DefElem *def)
Definition define.c:238
void errorConflictingDefElem(DefElem *defel, ParseState *pstate)
Definition define.c:370
int errdetail(const char *fmt,...)
Definition elog.c:1216
int errcode(int sqlerrcode)
Definition elog.c:863
bool is_encoding_supported_by_icu(int encoding)
Definition encnames.c:461
bool IsBinaryUpgrade
Definition globals.c:121
char * get_namespace_name(Oid nspid)
Definition lsyscache.c:3516
int GetDatabaseEncoding(void)
Definition mbutils.c:1264
Oid QualifiedNameGetCreationNamespace(const List *names, char **objname_p)
Definition namespace.c:3557
const ObjectAddress InvalidObjectAddress
int parser_errposition(ParseState *pstate, int location)
Definition parse_node.c:106
@ OBJECT_SCHEMA
#define ACL_CREATE
Definition parsenodes.h:85
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)
Definition pg_list.h:176
static int list_length(const List *l)
Definition pg_list.h:152
int icu_validation_level
Definition pg_locale.c:92
void icu_validate_locale(const char *loc_str)
Definition pg_locale.c:1789
pg_locale_t pg_newlocale_from_collation(Oid collid)
Definition pg_locale.c:1189
int builtin_locale_encoding(const char *locale)
Definition pg_locale.c:1667
char * icu_language_tag(const char *loc_str, int elevel)
Definition pg_locale.c:1731
const char * builtin_validate_locale(int encoding, const char *locale)
Definition pg_locale.c:1691
int pg_strcasecmp(const char *s1, const char *s2)
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition syscache.c:220
void CommandCounterIncrement(void)
Definition xact.c:1101

References ACL_CREATE, aclcheck_error(), ACLCHECK_OK, builtin_locale_encoding(), builtin_validate_locale(), check_encoding_locale_matches(), CollationCreate(), collid, CommandCounterIncrement(), defGetBoolean(), defGetQualifiedName(), defGetString(), elog, ereport, errcode(), errdetail(), errmsg(), ERROR, errorConflictingDefElem(), fb(), get_collation_actual_version(), get_collation_oid(), get_namespace_name(), GetDatabaseEncoding(), GETSTRUCT(), GetUserId(), HeapTupleIsValid, icu_language_tag(), icu_validate_locale(), icu_validation_level, InvalidObjectAddress, is_encoding_supported_by_icu(), IsBinaryUpgrade, lfirst_node, list_length(), NOTICE, object_aclcheck(), OBJECT_SCHEMA, ObjectAddressSet, ObjectIdGetDatum(), OidIsValid, parser_errposition(), pg_newlocale_from_collation(), pg_strcasecmp(), QualifiedNameGetCreationNamespace(), ReleaseSysCache(), SearchSysCache1(), SysCacheGetAttr(), and TextDatumGetCString.

Referenced by ProcessUtilitySlow().

◆ IsThereCollationInNamespace()

void IsThereCollationInNamespace ( const char collname,
Oid  nspOid 
)
extern

Definition at line 401 of file collationcmds.c.

402{
403 /* make sure the name doesn't already exist in new schema */
405 CStringGetDatum(collname),
410 errmsg("collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"",
411 collname, GetDatabaseEncodingName(),
413
414 /* mustn't match an any-encoding entry, either */
416 CStringGetDatum(collname),
417 Int32GetDatum(-1),
421 errmsg("collation \"%s\" already exists in schema \"%s\"",
422 collname, get_namespace_name(nspOid))));
423}
const char * GetDatabaseEncodingName(void)
Definition mbutils.c:1270
static Datum CStringGetDatum(const char *X)
Definition postgres.h:380
static Datum Int32GetDatum(int32 X)
Definition postgres.h:222
#define ERRCODE_DUPLICATE_OBJECT
Definition streamutil.c:30
#define SearchSysCacheExists3(cacheId, key1, key2, key3)
Definition syscache.h:104

References CStringGetDatum(), ereport, errcode(), ERRCODE_DUPLICATE_OBJECT, errmsg(), ERROR, fb(), get_namespace_name(), GetDatabaseEncoding(), GetDatabaseEncodingName(), Int32GetDatum(), ObjectIdGetDatum(), and SearchSysCacheExists3.

Referenced by AlterObjectNamespace_internal(), and AlterObjectRename_internal().