PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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-2017, 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 #include "access/heapam.h"
18 #include "access/htup_details.h"
19 #include "access/xact.h"
20 #include "catalog/dependency.h"
21 #include "catalog/indexing.h"
22 #include "catalog/namespace.h"
23 #include "catalog/objectaccess.h"
24 #include "catalog/pg_collation.h"
26 #include "commands/alter.h"
27 #include "commands/collationcmds.h"
28 #include "commands/comment.h"
29 #include "commands/dbcommands.h"
30 #include "commands/defrem.h"
31 #include "mb/pg_wchar.h"
32 #include "miscadmin.h"
33 #include "utils/builtins.h"
34 #include "utils/lsyscache.h"
35 #include "utils/pg_locale.h"
36 #include "utils/rel.h"
37 #include "utils/syscache.h"
38 
39 
40 typedef struct
41 {
42  char *localename; /* name of locale, as per "locale -a" */
43  char *alias; /* shortened alias for same */
44  int enc; /* encoding */
46 
47 
48 /*
49  * CREATE COLLATION
50  */
52 DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_exists)
53 {
54  char *collName;
55  Oid collNamespace;
56  AclResult aclresult;
57  ListCell *pl;
58  DefElem *fromEl = NULL;
59  DefElem *localeEl = NULL;
60  DefElem *lccollateEl = NULL;
61  DefElem *lcctypeEl = NULL;
62  DefElem *providerEl = NULL;
63  DefElem *versionEl = NULL;
64  char *collcollate = NULL;
65  char *collctype = NULL;
66  char *collproviderstr = NULL;
67  int collencoding = 0;
68  char collprovider = 0;
69  char *collversion = NULL;
70  Oid newoid;
71  ObjectAddress address;
72 
73  collNamespace = QualifiedNameGetCreationNamespace(names, &collName);
74 
75  aclresult = pg_namespace_aclcheck(collNamespace, GetUserId(), ACL_CREATE);
76  if (aclresult != ACLCHECK_OK)
78  get_namespace_name(collNamespace));
79 
80  foreach(pl, parameters)
81  {
82  DefElem *defel = lfirst_node(DefElem, pl);
83  DefElem **defelp;
84 
85  if (pg_strcasecmp(defel->defname, "from") == 0)
86  defelp = &fromEl;
87  else if (pg_strcasecmp(defel->defname, "locale") == 0)
88  defelp = &localeEl;
89  else if (pg_strcasecmp(defel->defname, "lc_collate") == 0)
90  defelp = &lccollateEl;
91  else if (pg_strcasecmp(defel->defname, "lc_ctype") == 0)
92  defelp = &lcctypeEl;
93  else if (pg_strcasecmp(defel->defname, "provider") == 0)
94  defelp = &providerEl;
95  else if (pg_strcasecmp(defel->defname, "version") == 0)
96  defelp = &versionEl;
97  else
98  {
99  ereport(ERROR,
100  (errcode(ERRCODE_SYNTAX_ERROR),
101  errmsg("collation attribute \"%s\" not recognized",
102  defel->defname),
103  parser_errposition(pstate, defel->location)));
104  break;
105  }
106 
107  *defelp = defel;
108  }
109 
110  if ((localeEl && (lccollateEl || lcctypeEl))
111  || (fromEl && list_length(parameters) != 1))
112  ereport(ERROR,
113  (errcode(ERRCODE_SYNTAX_ERROR),
114  errmsg("conflicting or redundant options")));
115 
116  if (fromEl)
117  {
118  Oid collid;
119  HeapTuple tp;
120 
121  collid = get_collation_oid(defGetQualifiedName(fromEl), false);
123  if (!HeapTupleIsValid(tp))
124  elog(ERROR, "cache lookup failed for collation %u", collid);
125 
126  collcollate = pstrdup(NameStr(((Form_pg_collation) GETSTRUCT(tp))->collcollate));
127  collctype = pstrdup(NameStr(((Form_pg_collation) GETSTRUCT(tp))->collctype));
128  collprovider = ((Form_pg_collation) GETSTRUCT(tp))->collprovider;
129  collencoding = ((Form_pg_collation) GETSTRUCT(tp))->collencoding;
130 
131  ReleaseSysCache(tp);
132 
133  /*
134  * Copying the "default" collation is not allowed because most code
135  * checks for DEFAULT_COLLATION_OID instead of COLLPROVIDER_DEFAULT,
136  * and so having a second collation with COLLPROVIDER_DEFAULT would
137  * not work and potentially confuse or crash some code. This could be
138  * fixed with some legwork.
139  */
140  if (collprovider == COLLPROVIDER_DEFAULT)
141  ereport(ERROR,
142  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
143  errmsg("collation \"default\" cannot be copied")));
144  }
145 
146  if (localeEl)
147  {
148  collcollate = defGetString(localeEl);
149  collctype = defGetString(localeEl);
150  }
151 
152  if (lccollateEl)
153  collcollate = defGetString(lccollateEl);
154 
155  if (lcctypeEl)
156  collctype = defGetString(lcctypeEl);
157 
158  if (providerEl)
159  collproviderstr = defGetString(providerEl);
160 
161  if (versionEl)
162  collversion = defGetString(versionEl);
163 
164  if (collproviderstr)
165  {
166  if (pg_strcasecmp(collproviderstr, "icu") == 0)
167  collprovider = COLLPROVIDER_ICU;
168  else if (pg_strcasecmp(collproviderstr, "libc") == 0)
169  collprovider = COLLPROVIDER_LIBC;
170  else
171  ereport(ERROR,
172  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
173  errmsg("unrecognized collation provider: %s",
174  collproviderstr)));
175  }
176  else if (!fromEl)
177  collprovider = COLLPROVIDER_LIBC;
178 
179  if (!collcollate)
180  ereport(ERROR,
181  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
182  errmsg("parameter \"lc_collate\" must be specified")));
183 
184  if (!collctype)
185  ereport(ERROR,
186  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
187  errmsg("parameter \"lc_ctype\" must be specified")));
188 
189  if (!fromEl)
190  {
191  if (collprovider == COLLPROVIDER_ICU)
192  collencoding = -1;
193  else
194  {
195  collencoding = GetDatabaseEncoding();
196  check_encoding_locale_matches(collencoding, collcollate, collctype);
197  }
198  }
199 
200  if (!collversion)
201  collversion = get_collation_actual_version(collprovider, collcollate);
202 
203  newoid = CollationCreate(collName,
204  collNamespace,
205  GetUserId(),
206  collprovider,
207  collencoding,
208  collcollate,
209  collctype,
210  collversion,
211  if_not_exists,
212  false); /* not quiet */
213 
214  if (!OidIsValid(newoid))
215  return InvalidObjectAddress;
216 
217  ObjectAddressSet(address, CollationRelationId, newoid);
218 
219  /* check that the locales can be loaded */
221  (void) pg_newlocale_from_collation(newoid);
222 
223  return address;
224 }
225 
226 /*
227  * Subroutine for ALTER COLLATION SET SCHEMA and RENAME
228  *
229  * Is there a collation with the same name of the given collation already in
230  * the given namespace? If so, raise an appropriate error message.
231  */
232 void
233 IsThereCollationInNamespace(const char *collname, Oid nspOid)
234 {
235  /* make sure the name doesn't already exist in new schema */
237  CStringGetDatum(collname),
239  ObjectIdGetDatum(nspOid)))
240  ereport(ERROR,
242  errmsg("collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"",
243  collname, GetDatabaseEncodingName(),
244  get_namespace_name(nspOid))));
245 
246  /* mustn't match an any-encoding entry, either */
248  CStringGetDatum(collname),
249  Int32GetDatum(-1),
250  ObjectIdGetDatum(nspOid)))
251  ereport(ERROR,
253  errmsg("collation \"%s\" already exists in schema \"%s\"",
254  collname, get_namespace_name(nspOid))));
255 }
256 
257 /*
258  * ALTER COLLATION
259  */
262 {
263  Relation rel;
264  Oid collOid;
265  HeapTuple tup;
266  Form_pg_collation collForm;
267  Datum collversion;
268  bool isnull;
269  char *oldversion;
270  char *newversion;
271  ObjectAddress address;
272 
274  collOid = get_collation_oid(stmt->collname, false);
275 
276  if (!pg_collation_ownercheck(collOid, GetUserId()))
278  NameListToString(stmt->collname));
279 
281  if (!HeapTupleIsValid(tup))
282  elog(ERROR, "cache lookup failed for collation %u", collOid);
283 
284  collForm = (Form_pg_collation) GETSTRUCT(tup);
286  &isnull);
287  oldversion = isnull ? NULL : TextDatumGetCString(collversion);
288 
289  newversion = get_collation_actual_version(collForm->collprovider, NameStr(collForm->collcollate));
290 
291  /* cannot change from NULL to non-NULL or vice versa */
292  if ((!oldversion && newversion) || (oldversion && !newversion))
293  elog(ERROR, "invalid collation version change");
294  else if (oldversion && newversion && strcmp(newversion, oldversion) != 0)
295  {
296  bool nulls[Natts_pg_collation];
297  bool replaces[Natts_pg_collation];
299 
300  ereport(NOTICE,
301  (errmsg("changing version from %s to %s",
302  oldversion, newversion)));
303 
304  memset(values, 0, sizeof(values));
305  memset(nulls, false, sizeof(nulls));
306  memset(replaces, false, sizeof(replaces));
307 
308  values[Anum_pg_collation_collversion - 1] = CStringGetTextDatum(newversion);
309  replaces[Anum_pg_collation_collversion - 1] = true;
310 
311  tup = heap_modify_tuple(tup, RelationGetDescr(rel),
312  values, nulls, replaces);
313  }
314  else
315  ereport(NOTICE,
316  (errmsg("version has not changed")));
317 
318  CatalogTupleUpdate(rel, &tup->t_self, tup);
319 
321 
322  ObjectAddressSet(address, CollationRelationId, collOid);
323 
324  heap_freetuple(tup);
325  heap_close(rel, NoLock);
326 
327  return address;
328 }
329 
330 
331 Datum
333 {
334  Oid collid = PG_GETARG_OID(0);
335  HeapTuple tp;
336  char *collcollate;
337  char collprovider;
338  char *version;
339 
341  if (!HeapTupleIsValid(tp))
342  ereport(ERROR,
343  (errcode(ERRCODE_UNDEFINED_OBJECT),
344  errmsg("collation with OID %u does not exist", collid)));
345 
346  collcollate = pstrdup(NameStr(((Form_pg_collation) GETSTRUCT(tp))->collcollate));
347  collprovider = ((Form_pg_collation) GETSTRUCT(tp))->collprovider;
348 
349  ReleaseSysCache(tp);
350 
351  version = get_collation_actual_version(collprovider, collcollate);
352 
353  if (version)
355  else
356  PG_RETURN_NULL();
357 }
358 
359 
360 /* will we use "locale -a" in pg_import_system_collations? */
361 #if defined(HAVE_LOCALE_T) && !defined(WIN32)
362 #define READ_LOCALE_A_OUTPUT
363 #endif
364 
365 #if defined(READ_LOCALE_A_OUTPUT) || defined(USE_ICU)
366 /*
367  * Check a string to see if it is pure ASCII
368  */
369 static bool
370 is_all_ascii(const char *str)
371 {
372  while (*str)
373  {
374  if (IS_HIGHBIT_SET(*str))
375  return false;
376  str++;
377  }
378  return true;
379 }
380 #endif /* READ_LOCALE_A_OUTPUT || USE_ICU */
381 
382 #ifdef READ_LOCALE_A_OUTPUT
383 /*
384  * "Normalize" a libc locale name, stripping off encoding tags such as
385  * ".utf8" (e.g., "en_US.utf8" -> "en_US", but "br_FR.iso885915@euro"
386  * -> "br_FR@euro"). Return true if a new, different name was
387  * generated.
388  */
389 static bool
390 normalize_libc_locale_name(char *new, const char *old)
391 {
392  char *n = new;
393  const char *o = old;
394  bool changed = false;
395 
396  while (*o)
397  {
398  if (*o == '.')
399  {
400  /* skip over encoding tag such as ".utf8" or ".UTF-8" */
401  o++;
402  while ((*o >= 'A' && *o <= 'Z')
403  || (*o >= 'a' && *o <= 'z')
404  || (*o >= '0' && *o <= '9')
405  || (*o == '-'))
406  o++;
407  changed = true;
408  }
409  else
410  *n++ = *o++;
411  }
412  *n = '\0';
413 
414  return changed;
415 }
416 
417 /*
418  * qsort comparator for CollAliasData items
419  */
420 static int
421 cmpaliases(const void *a, const void *b)
422 {
423  const CollAliasData *ca = (const CollAliasData *) a;
424  const CollAliasData *cb = (const CollAliasData *) b;
425 
426  /* comparing localename is enough because other fields are derived */
427  return strcmp(ca->localename, cb->localename);
428 }
429 #endif /* READ_LOCALE_A_OUTPUT */
430 
431 
432 #ifdef USE_ICU
433 /*
434  * Get the ICU language tag for a locale name.
435  * The result is a palloc'd string.
436  */
437 static char *
438 get_icu_language_tag(const char *localename)
439 {
440  char buf[ULOC_FULLNAME_CAPACITY];
441  UErrorCode status;
442 
443  status = U_ZERO_ERROR;
444  uloc_toLanguageTag(localename, buf, sizeof(buf), TRUE, &status);
445  if (U_FAILURE(status))
446  ereport(ERROR,
447  (errmsg("could not convert locale name \"%s\" to language tag: %s",
448  localename, u_errorName(status))));
449 
450  return pstrdup(buf);
451 }
452 
453 /*
454  * Get a comment (specifically, the display name) for an ICU locale.
455  * The result is a palloc'd string, or NULL if we can't get a comment
456  * or find that it's not all ASCII. (We can *not* accept non-ASCII
457  * comments, because the contents of template0 must be encoding-agnostic.)
458  */
459 static char *
460 get_icu_locale_comment(const char *localename)
461 {
462  UErrorCode status;
463  UChar displayname[128];
464  int32 len_uchar;
465  int32 i;
466  char *result;
467 
468  status = U_ZERO_ERROR;
469  len_uchar = uloc_getDisplayName(localename, "en",
470  displayname, lengthof(displayname),
471  &status);
472  if (U_FAILURE(status))
473  return NULL; /* no good reason to raise an error */
474 
475  /* Check for non-ASCII comment (can't use is_all_ascii for this) */
476  for (i = 0; i < len_uchar; i++)
477  {
478  if (displayname[i] > 127)
479  return NULL;
480  }
481 
482  /* OK, transcribe */
483  result = palloc(len_uchar + 1);
484  for (i = 0; i < len_uchar; i++)
485  result[i] = displayname[i];
486  result[len_uchar] = '\0';
487 
488  return result;
489 }
490 #endif /* USE_ICU */
491 
492 
493 /*
494  * pg_import_system_collations: add known system collations to pg_collation
495  */
496 Datum
498 {
499  Oid nspid = PG_GETARG_OID(0);
500  int ncreated = 0;
501 
502  /* silence compiler warning if we have no locale implementation at all */
503  (void) nspid;
504 
505  if (!superuser())
506  ereport(ERROR,
507  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
508  (errmsg("must be superuser to import system collations"))));
509 
510  /* Load collations known to libc, using "locale -a" to enumerate them */
511 #ifdef READ_LOCALE_A_OUTPUT
512  {
513  FILE *locale_a_handle;
514  char localebuf[NAMEDATALEN]; /* we assume ASCII so this is fine */
515  int nvalid = 0;
516  Oid collid;
517  CollAliasData *aliases;
518  int naliases,
519  maxaliases,
520  i;
521 
522  /* expansible array of aliases */
523  maxaliases = 100;
524  aliases = (CollAliasData *) palloc(maxaliases * sizeof(CollAliasData));
525  naliases = 0;
526 
527  locale_a_handle = OpenPipeStream("locale -a", "r");
528  if (locale_a_handle == NULL)
529  ereport(ERROR,
531  errmsg("could not execute command \"%s\": %m",
532  "locale -a")));
533 
534  while (fgets(localebuf, sizeof(localebuf), locale_a_handle))
535  {
536  size_t len;
537  int enc;
538  char alias[NAMEDATALEN];
539 
540  len = strlen(localebuf);
541 
542  if (len == 0 || localebuf[len - 1] != '\n')
543  {
544  elog(DEBUG1, "locale name too long, skipped: \"%s\"", localebuf);
545  continue;
546  }
547  localebuf[len - 1] = '\0';
548 
549  /*
550  * Some systems have locale names that don't consist entirely of
551  * ASCII letters (such as "bokm&aring;l" or "fran&ccedil;ais").
552  * This is pretty silly, since we need the locale itself to
553  * interpret the non-ASCII characters. We can't do much with
554  * those, so we filter them out.
555  */
556  if (!is_all_ascii(localebuf))
557  {
558  elog(DEBUG1, "locale name has non-ASCII characters, skipped: \"%s\"", localebuf);
559  continue;
560  }
561 
562  enc = pg_get_encoding_from_locale(localebuf, false);
563  if (enc < 0)
564  {
565  /* error message printed by pg_get_encoding_from_locale() */
566  continue;
567  }
568  if (!PG_VALID_BE_ENCODING(enc))
569  continue; /* ignore locales for client-only encodings */
570  if (enc == PG_SQL_ASCII)
571  continue; /* C/POSIX are already in the catalog */
572 
573  /* count valid locales found in operating system */
574  nvalid++;
575 
576  /*
577  * Create a collation named the same as the locale, but quietly
578  * doing nothing if it already exists. This is the behavior we
579  * need even at initdb time, because some versions of "locale -a"
580  * can report the same locale name more than once. And it's
581  * convenient for later import runs, too, since you just about
582  * always want to add on new locales without a lot of chatter
583  * about existing ones.
584  */
585  collid = CollationCreate(localebuf, nspid, GetUserId(),
586  COLLPROVIDER_LIBC, enc,
587  localebuf, localebuf,
589  true, true);
590  if (OidIsValid(collid))
591  {
592  ncreated++;
593 
594  /* Must do CCI between inserts to handle duplicates correctly */
596  }
597 
598  /*
599  * Generate aliases such as "en_US" in addition to "en_US.utf8"
600  * for ease of use. Note that collation names are unique per
601  * encoding only, so this doesn't clash with "en_US" for LATIN1,
602  * say.
603  *
604  * However, it might conflict with a name we'll see later in the
605  * "locale -a" output. So save up the aliases and try to add them
606  * after we've read all the output.
607  */
608  if (normalize_libc_locale_name(alias, localebuf))
609  {
610  if (naliases >= maxaliases)
611  {
612  maxaliases *= 2;
613  aliases = (CollAliasData *)
614  repalloc(aliases, maxaliases * sizeof(CollAliasData));
615  }
616  aliases[naliases].localename = pstrdup(localebuf);
617  aliases[naliases].alias = pstrdup(alias);
618  aliases[naliases].enc = enc;
619  naliases++;
620  }
621  }
622 
623  ClosePipeStream(locale_a_handle);
624 
625  /*
626  * Before processing the aliases, sort them by locale name. The point
627  * here is that if "locale -a" gives us multiple locale names with the
628  * same encoding and base name, say "en_US.utf8" and "en_US.utf-8", we
629  * want to pick a deterministic one of them. First in ASCII sort
630  * order is a good enough rule. (Before PG 10, the code corresponding
631  * to this logic in initdb.c had an additional ordering rule, to
632  * prefer the locale name exactly matching the alias, if any. We
633  * don't need to consider that here, because we would have already
634  * created such a pg_collation entry above, and that one will win.)
635  */
636  if (naliases > 1)
637  qsort((void *) aliases, naliases, sizeof(CollAliasData), cmpaliases);
638 
639  /* Now add aliases, ignoring any that match pre-existing entries */
640  for (i = 0; i < naliases; i++)
641  {
642  char *locale = aliases[i].localename;
643  char *alias = aliases[i].alias;
644  int enc = aliases[i].enc;
645 
646  collid = CollationCreate(alias, nspid, GetUserId(),
647  COLLPROVIDER_LIBC, enc,
648  locale, locale,
650  true, true);
651  if (OidIsValid(collid))
652  {
653  ncreated++;
654 
656  }
657  }
658 
659  /* Give a warning if "locale -a" seems to be malfunctioning */
660  if (nvalid == 0)
662  (errmsg("no usable system locales were found")));
663  }
664 #endif /* READ_LOCALE_A_OUTPUT */
665 
666  /* Load collations known to ICU */
667 #ifdef USE_ICU
668  {
669  int i;
670 
671  /*
672  * Start the loop at -1 to sneak in the root locale without too much
673  * code duplication.
674  */
675  for (i = -1; i < ucol_countAvailable(); i++)
676  {
677  const char *name;
678  char *langtag;
679  char *icucomment;
680  const char *collcollate;
681  UEnumeration *en;
682  UErrorCode status;
683  const char *val;
684  Oid collid;
685 
686  if (i == -1)
687  name = ""; /* ICU root locale */
688  else
689  name = ucol_getAvailable(i);
690 
691  langtag = get_icu_language_tag(name);
692  collcollate = U_ICU_VERSION_MAJOR_NUM >= 54 ? langtag : name;
693 
694  /*
695  * Be paranoid about not allowing any non-ASCII strings into
696  * pg_collation
697  */
698  if (!is_all_ascii(langtag) || !is_all_ascii(collcollate))
699  continue;
700 
701  collid = CollationCreate(psprintf("%s-x-icu", langtag),
702  nspid, GetUserId(),
703  COLLPROVIDER_ICU, -1,
704  collcollate, collcollate,
706  true, true);
707  if (OidIsValid(collid))
708  {
709  ncreated++;
710 
712 
713  icucomment = get_icu_locale_comment(name);
714  if (icucomment)
716  icucomment);
717  }
718 
719  /*
720  * Add keyword variants
721  */
722  status = U_ZERO_ERROR;
723  en = ucol_getKeywordValuesForLocale("collation", name, TRUE, &status);
724  if (U_FAILURE(status))
725  ereport(ERROR,
726  (errmsg("could not get keyword values for locale \"%s\": %s",
727  name, u_errorName(status))));
728 
729  status = U_ZERO_ERROR;
730  uenum_reset(en, &status);
731  while ((val = uenum_next(en, NULL, &status)))
732  {
733  char *localeid = psprintf("%s@collation=%s", name, val);
734 
735  langtag = get_icu_language_tag(localeid);
736  collcollate = U_ICU_VERSION_MAJOR_NUM >= 54 ? langtag : localeid;
737 
738  /*
739  * Be paranoid about not allowing any non-ASCII strings into
740  * pg_collation
741  */
742  if (!is_all_ascii(langtag) || !is_all_ascii(collcollate))
743  continue;
744 
745  collid = CollationCreate(psprintf("%s-x-icu", langtag),
746  nspid, GetUserId(),
747  COLLPROVIDER_ICU, -1,
748  collcollate, collcollate,
750  true, true);
751  if (OidIsValid(collid))
752  {
753  ncreated++;
754 
756 
757  icucomment = get_icu_locale_comment(name);
758  if (icucomment)
760  icucomment);
761  }
762  }
763  if (U_FAILURE(status))
764  ereport(ERROR,
765  (errmsg("could not get keyword values for locale \"%s\": %s",
766  name, u_errorName(status))));
767  uenum_close(en);
768  }
769  }
770 #endif /* USE_ICU */
771 
772  PG_RETURN_INT32(ncreated);
773 }
bool pg_collation_ownercheck(Oid coll_oid, Oid roleid)
Definition: aclchk.c:4990
#define COLLPROVIDER_ICU
Definition: pg_collation.h:85
#define Anum_pg_collation_collversion
Definition: pg_collation.h:66
#define COLLPROVIDER_DEFAULT
Definition: pg_collation.h:84
#define DEBUG1
Definition: elog.h:25
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
void check_encoding_locale_matches(int encoding, const char *collate, const char *ctype)
Definition: dbcommands.c:722
#define RelationGetDescr(relation)
Definition: rel.h:428
Oid GetUserId(void)
Definition: miscinit.c:284
char * localename
Definition: collationcmds.c:42
Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p)
Definition: namespace.c:2956
#define Natts_pg_collation
Definition: pg_collation.h:58
char * pstrdup(const char *in)
Definition: mcxt.c:1077
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
#define PG_RETURN_INT32(x)
Definition: fmgr.h:314
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
void CreateComments(Oid oid, Oid classoid, int32 subid, char *comment)
Definition: comment.c:142
return result
Definition: formatting.c:1633
#define heap_close(r, l)
Definition: heapam.h:97
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
#define lengthof(array)
Definition: c.h:562
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1372
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
AclResult pg_namespace_aclcheck(Oid nsp_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4484
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:156
signed int int32
Definition: c.h:256
int ClosePipeStream(FILE *file)
Definition: fd.c:2470
#define NAMEDATALEN
#define IS_HIGHBIT_SET(ch)
Definition: c.h:973
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define ACL_CREATE
Definition: parsenodes.h:82
#define SearchSysCacheExists3(cacheId, key1, key2, key3)
Definition: syscache.h:178
struct pg_encoding enc
Definition: encode.c:522
char * defGetString(DefElem *def)
Definition: define.c:49
ItemPointerData t_self
Definition: htup.h:65
#define lfirst_node(type, lc)
Definition: pg_list.h:109
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3033
#define NoLock
Definition: lockdefs.h:34
static char * buf
Definition: pg_test_fsync.c:66
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3399
int location
Definition: parsenodes.h:722
#define RowExclusiveLock
Definition: lockdefs.h:38
int errcode_for_file_access(void)
Definition: elog.c:598
#define CStringGetDatum(X)
Definition: postgres.h:584
void IsThereCollationInNamespace(const char *collname, Oid nspOid)
FILE * OpenPipeStream(const char *command, const char *mode)
Definition: fd.c:2184
Datum pg_collation_actual_version(PG_FUNCTION_ARGS)
#define ereport(elevel, rest)
Definition: elog.h:122
#define InvokeObjectPostAlterHook(classId, objectId, subId)
Definition: objectaccess.h:163
Oid CollationCreate(const char *collname, Oid collnamespace, Oid collowner, char collprovider, int32 collencoding, const char *collcollate, const char *collctype, const char *collversion, bool if_not_exists, bool quiet)
Definition: pg_collation.c:47
#define WARNING
Definition: elog.h:40
char * NameListToString(List *names)
Definition: namespace.c:3063
pg_locale_t pg_newlocale_from_collation(Oid collid)
Definition: pg_locale.c:1265
#define TextDatumGetCString(d)
Definition: builtins.h:92
AclResult
Definition: acl.h:170
uintptr_t Datum
Definition: postgres.h:372
void CommandCounterIncrement(void)
Definition: xact.c:922
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
int GetDatabaseEncoding(void)
Definition: mbutils.c:1015
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1279
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define CollationRelationId
Definition: pg_collation.h:30
ObjectAddress DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_exists)
Definition: collationcmds.c:52
int pg_get_encoding_from_locale(const char *ctype, bool write_message)
Definition: chklocale.c:433
#define NOTICE
Definition: elog.h:37
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:330
text * cstring_to_text(const char *s)
Definition: varlena.c:149
#define PG_VALID_BE_ENCODING(_enc)
Definition: pg_wchar.h:295
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1021
List * defGetQualifiedName(DefElem *def)
Definition: define.c:223
void CatalogTupleUpdate(Relation heapRel, ItemPointer otid, HeapTuple tup)
Definition: indexing.c:210
static int list_length(const List *l)
Definition: pg_list.h:89
int parser_errposition(ParseState *pstate, int location)
Definition: parse_node.c:111
void * repalloc(void *pointer, Size size)
Definition: mcxt.c:963
const char * name
Definition: encode.c:521
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:52
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
static Datum values[MAXATTR]
Definition: bootstrap.c:163
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:165
#define Int32GetDatum(X)
Definition: postgres.h:485
const ObjectAddress InvalidObjectAddress
Datum pg_import_system_collations(PG_FUNCTION_ARGS)
void * palloc(Size size)
Definition: mcxt.c:849
int errmsg(const char *fmt,...)
Definition: elog.c:797
ObjectAddress AlterCollation(AlterCollationStmt *stmt)
int i
#define NameStr(name)
Definition: c.h:499
static char * locale
Definition: initdb.c:123
#define CStringGetTextDatum(s)
Definition: builtins.h:91
#define PG_FUNCTION_ARGS
Definition: fmgr.h:158
char * defname
Definition: parsenodes.h:719
#define TRUE
Definition: c.h:217
#define elog
Definition: elog.h:219
#define qsort(a, b, c, d)
Definition: port.h:443
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:224
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *replValues, bool *replIsnull, bool *doReplace)
Definition: heaptuple.c:791
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:32
Oid get_collation_oid(List *name, bool missing_ok)
Definition: namespace.c:3493
Definition: pg_list.h:45
long val
Definition: informix.c:689
#define PG_RETURN_NULL()
Definition: fmgr.h:305
#define COLLPROVIDER_LIBC
Definition: pg_collation.h:86
char * get_collation_actual_version(char collprovider, const char *collcollate)
Definition: pg_locale.c:1432