PostgreSQL Source Code git master
Loading...
Searching...
No Matches
collationcmds.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * collationcmds.c
4 * collation-related commands support code
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/commands/collationcmds.c
12 *
13 *-------------------------------------------------------------------------
14 */
15#include "postgres.h"
16
17#ifdef USE_ICU
18#include <unicode/uloc.h>
19#endif
20
21#include "access/htup_details.h"
22#include "access/table.h"
23#include "access/xact.h"
24#include "catalog/indexing.h"
25#include "catalog/namespace.h"
28#include "catalog/pg_database.h"
31#include "commands/comment.h"
32#include "commands/dbcommands.h"
33#include "commands/defrem.h"
34#include "common/string.h"
35#include "mb/pg_wchar.h"
36#include "miscadmin.h"
37#include "storage/fd.h"
38#include "utils/acl.h"
39#include "utils/builtins.h"
40#include "utils/lsyscache.h"
41#include "utils/pg_locale.h"
42#include "utils/rel.h"
43#include "utils/syscache.h"
44
45
46typedef struct
47{
48 char *localename; /* name of locale, as per "locale -a" */
49 char *alias; /* shortened alias for same */
50 int enc; /* encoding */
52
53
54/*
55 * CREATE COLLATION
56 */
58DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_exists)
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}
393
394/*
395 * Subroutine for ALTER COLLATION SET SCHEMA and RENAME
396 *
397 * Is there a collation with the same name of the given collation already in
398 * the given namespace? If so, raise an appropriate error message.
399 */
400void
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}
424
425/*
426 * ALTER COLLATION
427 */
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}
509
510
511Datum
513{
515 char provider;
516 char *locale;
517 char *version;
518 Datum datum;
519
521 {
522 /* retrieve from pg_database */
523
525
529 errmsg("database with OID %u does not exist", MyDatabaseId)));
530
532
534 {
536 locale = TextDatumGetCString(datum);
537 }
538 else
539 {
541 locale = TextDatumGetCString(datum);
542 }
543
545 }
546 else
547 {
548 /* retrieve from pg_collation */
549
551
555 errmsg("collation with OID %u does not exist", collid)));
556
559
561 {
563 locale = TextDatumGetCString(datum);
564 }
565 else
566 {
568 locale = TextDatumGetCString(datum);
569 }
570
572 }
573
574 version = get_collation_actual_version(provider, locale);
575 if (version)
577 else
579}
580
581
582/* will we use "locale -a" in pg_import_system_collations? */
583#if !defined(WIN32)
584#define READ_LOCALE_A_OUTPUT
585#endif
586
587/* will we use EnumSystemLocalesEx in pg_import_system_collations? */
588#ifdef WIN32
589#define ENUM_SYSTEM_LOCALE
590#endif
591
592
593#ifdef READ_LOCALE_A_OUTPUT
594/*
595 * "Normalize" a libc locale name, stripping off encoding tags such as
596 * ".utf8" (e.g., "en_US.utf8" -> "en_US", but "br_FR.iso885915@euro"
597 * -> "br_FR@euro"). Return true if a new, different name was
598 * generated.
599 */
600static bool
601normalize_libc_locale_name(char *new, const char *old)
602{
603 char *n = new;
604 const char *o = old;
605 bool changed = false;
606
607 while (*o)
608 {
609 if (*o == '.')
610 {
611 /* skip over encoding tag such as ".utf8" or ".UTF-8" */
612 o++;
613 while ((*o >= 'A' && *o <= 'Z')
614 || (*o >= 'a' && *o <= 'z')
615 || (*o >= '0' && *o <= '9')
616 || (*o == '-'))
617 o++;
618 changed = true;
619 }
620 else
621 *n++ = *o++;
622 }
623 *n = '\0';
624
625 return changed;
626}
627
628/*
629 * qsort comparator for CollAliasData items
630 */
631static int
632cmpaliases(const void *a, const void *b)
633{
634 const CollAliasData *ca = (const CollAliasData *) a;
635 const CollAliasData *cb = (const CollAliasData *) b;
636
637 /* comparing localename is enough because other fields are derived */
638 return strcmp(ca->localename, cb->localename);
639}
640#endif /* READ_LOCALE_A_OUTPUT */
641
642
643#ifdef USE_ICU
644/*
645 * Get a comment (specifically, the display name) for an ICU locale.
646 * The result is a palloc'd string, or NULL if we can't get a comment
647 * or find that it's not all ASCII. (We can *not* accept non-ASCII
648 * comments, because the contents of template0 must be encoding-agnostic.)
649 */
650static char *
651get_icu_locale_comment(const char *localename)
652{
653 UErrorCode status;
654 UChar displayname[128];
656 int32 i;
657 char *result;
658
659 status = U_ZERO_ERROR;
660 len_uchar = uloc_getDisplayName(localename, "en",
662 &status);
663 if (U_FAILURE(status))
664 return NULL; /* no good reason to raise an error */
665
666 /* Check for non-ASCII comment (can't use pg_is_ascii for this) */
667 for (i = 0; i < len_uchar; i++)
668 {
669 if (displayname[i] > 127)
670 return NULL;
671 }
672
673 /* OK, transcribe */
674 result = palloc(len_uchar + 1);
675 for (i = 0; i < len_uchar; i++)
676 result[i] = displayname[i];
677 result[len_uchar] = '\0';
678
679 return result;
680}
681#endif /* USE_ICU */
682
683
684/*
685 * Create a new collation using the input locale 'locale'. (subroutine for
686 * pg_import_system_collations())
687 *
688 * 'nspid' is the namespace id where the collation will be created.
689 *
690 * 'nvalidp' is incremented if the locale has a valid encoding.
691 *
692 * 'ncreatedp' is incremented if the collation is actually created. If the
693 * collation already exists it will quietly do nothing.
694 *
695 * The returned value is the encoding of the locale, -1 if the locale is not
696 * valid for creating a collation.
697 *
698 */
700static int
702 int *nvalidp, int *ncreatedp)
703{
704 int enc;
706
707 /*
708 * Some systems have locale names that don't consist entirely of ASCII
709 * letters (such as "bokm&aring;l" or "fran&ccedil;ais"). This is pretty
710 * silly, since we need the locale itself to interpret the non-ASCII
711 * characters. We can't do much with those, so we filter them out.
712 */
713 if (!pg_is_ascii(locale))
714 {
715 elog(DEBUG1, "skipping locale with non-ASCII name: \"%s\"", locale);
716 return -1;
717 }
718
720 if (enc < 0)
721 {
722 elog(DEBUG1, "skipping locale with unrecognized encoding: \"%s\"", locale);
723 return -1;
724 }
726 {
727 elog(DEBUG1, "skipping locale with client-only encoding: \"%s\"", locale);
728 return -1;
729 }
731 return -1; /* C/POSIX are already in the catalog */
732
733 /* count valid locales found in operating system */
734 (*nvalidp)++;
735
736 /*
737 * Create a collation named the same as the locale, but quietly doing
738 * nothing if it already exists. This is the behavior we need even at
739 * initdb time, because some versions of "locale -a" can report the same
740 * locale name more than once. And it's convenient for later import runs,
741 * too, since you just about always want to add on new locales without a
742 * lot of chatter about existing ones.
743 */
745 COLLPROVIDER_LIBC, true, enc,
746 locale, locale, NULL, NULL,
748 true, true);
749 if (OidIsValid(collid))
750 {
751 (*ncreatedp)++;
752
753 /* Must do CCI between inserts to handle duplicates correctly */
755 }
756
757 return enc;
758}
759
760
761#ifdef ENUM_SYSTEM_LOCALE
762/* parameter to be passed to the callback function win32_read_locale() */
763typedef struct
764{
765 Oid nspid;
766 int *ncreatedp;
767 int *nvalidp;
768} CollParam;
769
770/*
771 * Callback function for EnumSystemLocalesEx() in
772 * pg_import_system_collations(). Creates a collation for every valid locale
773 * and a POSIX alias collation.
774 *
775 * The callback contract is to return TRUE to continue enumerating and FALSE
776 * to stop enumerating. We always want to continue.
777 */
778static BOOL CALLBACK
780{
781 CollParam *param = (CollParam *) lparam;
783 int result;
784 int enc;
785
786 (void) dwFlags;
787
789 NULL, NULL);
790
791 if (result == 0)
792 {
794 elog(DEBUG1, "skipping locale with too-long name: \"%s\"", localebuf);
795 return TRUE;
796 }
797 if (localebuf[0] == '\0')
798 return TRUE;
799
801 param->nvalidp, param->ncreatedp);
802 if (enc < 0)
803 return TRUE;
804
805 /*
806 * Windows will use hyphens between language and territory, where POSIX
807 * uses an underscore. Simply create a POSIX alias.
808 */
809 if (strchr(localebuf, '-'))
810 {
811 char alias[NAMEDATALEN];
812 Oid collid;
813
814 strcpy(alias, localebuf);
815 for (char *p = alias; *p; p++)
816 if (*p == '-')
817 *p = '_';
818
819 collid = CollationCreate(alias, param->nspid, GetUserId(),
820 COLLPROVIDER_LIBC, true, enc,
823 true, true);
824 if (OidIsValid(collid))
825 {
826 (*param->ncreatedp)++;
827
829 }
830 }
831
832 return TRUE;
833}
834#endif /* ENUM_SYSTEM_LOCALE */
835
836
837/*
838 * pg_import_system_collations: add known system collations to pg_collation
839 */
840Datum
842{
844 int ncreated = 0;
845
846 if (!superuser())
849 errmsg("must be superuser to import system collations")));
850
854 errmsg("schema with OID %u does not exist", nspid)));
855
856 /* Load collations known to libc, using "locale -a" to enumerate them */
857#ifdef READ_LOCALE_A_OUTPUT
858 {
861 int nvalid = 0;
862 Oid collid;
863 CollAliasData *aliases;
864 int naliases,
866 i;
867
868 /* expansible array of aliases */
869 maxaliases = 100;
870 aliases = (CollAliasData *) palloc(maxaliases * sizeof(CollAliasData));
871 naliases = 0;
872
873 locale_a_handle = OpenPipeStream("locale -a", "r");
874 if (locale_a_handle == NULL)
877 errmsg("could not execute command \"%s\": %m",
878 "locale -a")));
879
880 while (fgets(localebuf, sizeof(localebuf), locale_a_handle))
881 {
882 size_t len;
883 int enc;
884 char alias[LOCALE_NAME_BUFLEN];
885
887
888 if (len == 0 || localebuf[len - 1] != '\n')
889 {
890 elog(DEBUG1, "skipping locale with too-long name: \"%s\"", localebuf);
891 continue;
892 }
893 localebuf[len - 1] = '\0';
894
896 if (enc < 0)
897 continue;
898
899 /*
900 * Generate aliases such as "en_US" in addition to "en_US.utf8"
901 * for ease of use. Note that collation names are unique per
902 * encoding only, so this doesn't clash with "en_US" for LATIN1,
903 * say.
904 *
905 * However, it might conflict with a name we'll see later in the
906 * "locale -a" output. So save up the aliases and try to add them
907 * after we've read all the output.
908 */
910 {
911 if (naliases >= maxaliases)
912 {
913 maxaliases *= 2;
914 aliases = (CollAliasData *)
915 repalloc(aliases, maxaliases * sizeof(CollAliasData));
916 }
918 aliases[naliases].alias = pstrdup(alias);
919 aliases[naliases].enc = enc;
920 naliases++;
921 }
922 }
923
924 /*
925 * We don't check the return value of this, because we want to support
926 * the case where there "locale" command does not exist. (This is
927 * unusual but can happen on minimalized Linux distributions, for
928 * example.) We will warn below if no locales could be found.
929 */
931
932 /*
933 * Before processing the aliases, sort them by locale name. The point
934 * here is that if "locale -a" gives us multiple locale names with the
935 * same encoding and base name, say "en_US.utf8" and "en_US.utf-8", we
936 * want to pick a deterministic one of them. First in ASCII sort
937 * order is a good enough rule. (Before PG 10, the code corresponding
938 * to this logic in initdb.c had an additional ordering rule, to
939 * prefer the locale name exactly matching the alias, if any. We
940 * don't need to consider that here, because we would have already
941 * created such a pg_collation entry above, and that one will win.)
942 */
943 if (naliases > 1)
944 qsort(aliases, naliases, sizeof(CollAliasData), cmpaliases);
945
946 /* Now add aliases, ignoring any that match pre-existing entries */
947 for (i = 0; i < naliases; i++)
948 {
949 char *locale = aliases[i].localename;
950 char *alias = aliases[i].alias;
951 int enc = aliases[i].enc;
952
954 COLLPROVIDER_LIBC, true, enc,
955 locale, locale, NULL, NULL,
957 true, true);
958 if (OidIsValid(collid))
959 {
960 ncreated++;
961
963 }
964 }
965
966 /* Give a warning if "locale -a" seems to be malfunctioning */
967 if (nvalid == 0)
969 (errmsg("no usable system locales were found")));
970 }
971#endif /* READ_LOCALE_A_OUTPUT */
972
973 /*
974 * Load collations known to ICU
975 *
976 * We use uloc_countAvailable()/uloc_getAvailable() rather than
977 * ucol_countAvailable()/ucol_getAvailable(). The former returns a full
978 * set of language+region combinations, whereas the latter only returns
979 * language+region combinations if they are distinct from the language's
980 * base collation. So there might not be a de-DE or en-GB, which would be
981 * confusing.
982 */
983#ifdef USE_ICU
984 {
985 int i;
986
987 /*
988 * Start the loop at -1 to sneak in the root locale without too much
989 * code duplication.
990 */
991 for (i = -1; i < uloc_countAvailable(); i++)
992 {
993 const char *name;
994 char *langtag;
995 char *icucomment;
996 Oid collid;
997
998 if (i == -1)
999 name = ""; /* ICU root locale */
1000 else
1002
1004
1005 /*
1006 * Be paranoid about not allowing any non-ASCII strings into
1007 * pg_collation
1008 */
1009 if (!pg_is_ascii(langtag))
1010 continue;
1011
1012 collid = CollationCreate(psprintf("%s-x-icu", langtag),
1013 nspid, GetUserId(),
1014 COLLPROVIDER_ICU, true, -1,
1015 NULL, NULL, langtag, NULL,
1017 true, true);
1018 if (OidIsValid(collid))
1019 {
1020 ncreated++;
1021
1023
1025 if (icucomment)
1027 icucomment);
1028 }
1029 }
1030 }
1031#endif /* USE_ICU */
1032
1033 /* Load collations known to WIN32 */
1034#ifdef ENUM_SYSTEM_LOCALE
1035 {
1036 int nvalid = 0;
1037 CollParam param;
1038
1039 param.nspid = nspid;
1040 param.ncreatedp = &ncreated;
1041 param.nvalidp = &nvalid;
1042
1043 /*
1044 * Enumerate the locales that are either installed on or supported by
1045 * the OS.
1046 */
1048 (LPARAM) &param, NULL))
1050
1051 /* Give a warning if EnumSystemLocalesEx seems to be malfunctioning */
1052 if (nvalid == 0)
1054 (errmsg("no usable system locales were found")));
1055 }
1056#endif /* ENUM_SYSTEM_LOCALE */
1057
1059}
AclResult
Definition acl.h:182
@ ACLCHECK_OK
Definition acl.h:183
@ ACLCHECK_NOT_OWNER
Definition acl.h:185
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
Definition aclchk.c:2654
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition aclchk.c:3836
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
#define Assert(condition)
Definition c.h:873
int32_t int32
Definition c.h:542
#define lengthof(array)
Definition c.h:803
#define OidIsValid(objectId)
Definition c.h:788
Datum pg_collation_actual_version(PG_FUNCTION_ARGS)
static bool normalize_libc_locale_name(char *new, const char *old)
int nspid
int int * nvalidp
static int cmpaliases(const void *a, const void *b)
pg_attribute_unused() static int create_collation_from_locale(const char *locale
ObjectAddress AlterCollation(AlterCollationStmt *stmt)
void IsThereCollationInNamespace(const char *collname, Oid nspOid)
Datum pg_import_system_collations(PG_FUNCTION_ARGS)
int int int * ncreatedp
Oid collid
ObjectAddress DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_exists)
void CreateComments(Oid oid, Oid classoid, int32 subid, const char *comment)
Definition comment.c:143
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 errcode_for_file_access(void)
Definition elog.c:886
int errdetail(const char *fmt,...)
Definition elog.c:1216
int errhint(const char *fmt,...)
Definition elog.c:1330
int errcode(int sqlerrcode)
Definition elog.c:863
int errmsg(const char *fmt,...)
Definition elog.c:1080
#define WARNING
Definition elog.h:36
#define DEBUG1
Definition elog.h:30
#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
bool is_encoding_supported_by_icu(int encoding)
Definition encnames.c:461
FILE * OpenPipeStream(const char *command, const char *mode)
Definition fd.c:2727
int ClosePipeStream(FILE *file)
Definition fd.c:3035
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define PG_RETURN_NULL()
Definition fmgr.h:346
#define PG_RETURN_TEXT_P(x)
Definition fmgr.h:374
#define PG_RETURN_INT32(x)
Definition fmgr.h:355
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
bool IsBinaryUpgrade
Definition globals.c:121
Oid MyDatabaseId
Definition globals.c:94
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
int b
Definition isn.c:74
int a
Definition isn.c:73
int i
Definition isn.c:77
#define NoLock
Definition lockdefs.h:34
#define RowExclusiveLock
Definition lockdefs.h:38
char * get_namespace_name(Oid nspid)
Definition lsyscache.c:3516
int GetDatabaseEncoding(void)
Definition mbutils.c:1264
const char * GetDatabaseEncodingName(void)
Definition mbutils.c:1270
char * pstrdup(const char *in)
Definition mcxt.c:1781
void * repalloc(void *pointer, Size size)
Definition mcxt.c:1632
void * palloc(Size size)
Definition mcxt.c:1387
Oid GetUserId(void)
Definition miscinit.c:469
char * NameListToString(const List *names)
Definition namespace.c:3664
Oid QualifiedNameGetCreationNamespace(const List *names, char **objname_p)
Definition namespace.c:3557
Oid get_collation_oid(List *collname, bool missing_ok)
Definition namespace.c:4041
#define InvokeObjectPostAlterHook(classId, objectId, subId)
const ObjectAddress InvalidObjectAddress
#define ObjectAddressSet(addr, class_id, object_id)
int parser_errposition(ParseState *pstate, int location)
Definition parse_node.c:106
@ OBJECT_COLLATION
@ 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)
FormData_pg_collation * Form_pg_collation
#define NAMEDATALEN
const void size_t len
char datlocprovider
Definition pg_database.h:44
FormData_pg_database * Form_pg_database
Definition pg_database.h:96
#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
char * get_collation_actual_version(char collprovider, const char *collcollate)
Definition pg_locale.c:1247
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
#define LOCALE_NAME_BUFLEN
Definition pg_locale.h:18
@ PG_SQL_ASCII
Definition pg_wchar.h:226
#define PG_VALID_BE_ENCODING(_enc)
Definition pg_wchar.h:281
int pg_strcasecmp(const char *s1, const char *s2)
int pg_get_encoding_from_locale(const char *ctype, bool write_message)
Definition chklocale.c:301
#define qsort(a, b, c, d)
Definition port.h:495
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:262
uint64_t Datum
Definition postgres.h:70
static Datum CStringGetDatum(const char *X)
Definition postgres.h:380
static Datum Int32GetDatum(int32 X)
Definition postgres.h:222
unsigned int Oid
static int fb(int x)
char * psprintf(const char *fmt,...)
Definition psprintf.c:43
#define RelationGetDescr(relation)
Definition rel.h:540
#define ERRCODE_DUPLICATE_OBJECT
Definition streamutil.c:30
bool pg_is_ascii(const char *str)
Definition string.c:132
Definition pg_list.h:54
bool superuser(void)
Definition superuser.c:46
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition syscache.c:220
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
#define SearchSysCacheExists1(cacheId, key1)
Definition syscache.h:100
#define SearchSysCacheExists3(cacheId, key1, key2, key3)
Definition syscache.h:104
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40
text * cstring_to_text(const char *s)
Definition varlena.c:181
const char * name
void _dosmaperr(unsigned long)
Definition win32error.c:177
void CommandCounterIncrement(void)
Definition xact.c:1101