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