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