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 /*
41  * CREATE COLLATION
42  */
44 DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_exists)
45 {
46  char *collName;
47  Oid collNamespace;
48  AclResult aclresult;
49  ListCell *pl;
50  DefElem *fromEl = NULL;
51  DefElem *localeEl = NULL;
52  DefElem *lccollateEl = NULL;
53  DefElem *lcctypeEl = NULL;
54  DefElem *providerEl = NULL;
55  DefElem *versionEl = NULL;
56  char *collcollate = NULL;
57  char *collctype = NULL;
58  char *collproviderstr = NULL;
59  int collencoding;
60  char collprovider = 0;
61  char *collversion = NULL;
62  Oid newoid;
63  ObjectAddress address;
64 
65  collNamespace = QualifiedNameGetCreationNamespace(names, &collName);
66 
67  aclresult = pg_namespace_aclcheck(collNamespace, GetUserId(), ACL_CREATE);
68  if (aclresult != ACLCHECK_OK)
70  get_namespace_name(collNamespace));
71 
72  foreach(pl, parameters)
73  {
74  DefElem *defel = castNode(DefElem, lfirst(pl));
75  DefElem **defelp;
76 
77  if (pg_strcasecmp(defel->defname, "from") == 0)
78  defelp = &fromEl;
79  else if (pg_strcasecmp(defel->defname, "locale") == 0)
80  defelp = &localeEl;
81  else if (pg_strcasecmp(defel->defname, "lc_collate") == 0)
82  defelp = &lccollateEl;
83  else if (pg_strcasecmp(defel->defname, "lc_ctype") == 0)
84  defelp = &lcctypeEl;
85  else if (pg_strcasecmp(defel->defname, "provider") == 0)
86  defelp = &providerEl;
87  else if (pg_strcasecmp(defel->defname, "version") == 0)
88  defelp = &versionEl;
89  else
90  {
91  ereport(ERROR,
92  (errcode(ERRCODE_SYNTAX_ERROR),
93  errmsg("collation attribute \"%s\" not recognized",
94  defel->defname),
95  parser_errposition(pstate, defel->location)));
96  break;
97  }
98 
99  *defelp = defel;
100  }
101 
102  if ((localeEl && (lccollateEl || lcctypeEl))
103  || (fromEl && list_length(parameters) != 1))
104  ereport(ERROR,
105  (errcode(ERRCODE_SYNTAX_ERROR),
106  errmsg("conflicting or redundant options")));
107 
108  if (fromEl)
109  {
110  Oid collid;
111  HeapTuple tp;
112 
113  collid = get_collation_oid(defGetQualifiedName(fromEl), false);
115  if (!HeapTupleIsValid(tp))
116  elog(ERROR, "cache lookup failed for collation %u", collid);
117 
118  collcollate = pstrdup(NameStr(((Form_pg_collation) GETSTRUCT(tp))->collcollate));
119  collctype = pstrdup(NameStr(((Form_pg_collation) GETSTRUCT(tp))->collctype));
120  collprovider = ((Form_pg_collation) GETSTRUCT(tp))->collprovider;
121 
122  ReleaseSysCache(tp);
123  }
124 
125  if (localeEl)
126  {
127  collcollate = defGetString(localeEl);
128  collctype = defGetString(localeEl);
129  }
130 
131  if (lccollateEl)
132  collcollate = defGetString(lccollateEl);
133 
134  if (lcctypeEl)
135  collctype = defGetString(lcctypeEl);
136 
137  if (providerEl)
138  collproviderstr = defGetString(providerEl);
139 
140  if (versionEl)
141  collversion = defGetString(versionEl);
142 
143  if (collproviderstr)
144  {
145  if (pg_strcasecmp(collproviderstr, "icu") == 0)
146  collprovider = COLLPROVIDER_ICU;
147  else if (pg_strcasecmp(collproviderstr, "libc") == 0)
148  collprovider = COLLPROVIDER_LIBC;
149  else
150  ereport(ERROR,
151  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
152  errmsg("unrecognized collation provider: %s",
153  collproviderstr)));
154  }
155  else if (!fromEl)
156  collprovider = COLLPROVIDER_LIBC;
157 
158  if (!collcollate)
159  ereport(ERROR,
160  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
161  errmsg("parameter \"lc_collate\" must be specified")));
162 
163  if (!collctype)
164  ereport(ERROR,
165  (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
166  errmsg("parameter \"lc_ctype\" must be specified")));
167 
168  if (collprovider == COLLPROVIDER_ICU)
169  collencoding = -1;
170  else
171  {
172  collencoding = GetDatabaseEncoding();
173  check_encoding_locale_matches(collencoding, collcollate, collctype);
174  }
175 
176  if (!collversion)
177  collversion = get_collation_actual_version(collprovider, collcollate);
178 
179  newoid = CollationCreate(collName,
180  collNamespace,
181  GetUserId(),
182  collprovider,
183  collencoding,
184  collcollate,
185  collctype,
186  collversion,
187  if_not_exists);
188 
189  if (!OidIsValid(newoid))
190  return InvalidObjectAddress;
191 
192  ObjectAddressSet(address, CollationRelationId, newoid);
193 
194  /* check that the locales can be loaded */
196  (void) pg_newlocale_from_collation(newoid);
197 
198  return address;
199 }
200 
201 /*
202  * Subroutine for ALTER COLLATION SET SCHEMA and RENAME
203  *
204  * Is there a collation with the same name of the given collation already in
205  * the given namespace? If so, raise an appropriate error message.
206  */
207 void
208 IsThereCollationInNamespace(const char *collname, Oid nspOid)
209 {
210  /* make sure the name doesn't already exist in new schema */
212  CStringGetDatum(collname),
214  ObjectIdGetDatum(nspOid)))
215  ereport(ERROR,
217  errmsg("collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"",
218  collname, GetDatabaseEncodingName(),
219  get_namespace_name(nspOid))));
220 
221  /* mustn't match an any-encoding entry, either */
223  CStringGetDatum(collname),
224  Int32GetDatum(-1),
225  ObjectIdGetDatum(nspOid)))
226  ereport(ERROR,
228  errmsg("collation \"%s\" already exists in schema \"%s\"",
229  collname, get_namespace_name(nspOid))));
230 }
231 
232 /*
233  * ALTER COLLATION
234  */
237 {
238  Relation rel;
239  Oid collOid;
240  HeapTuple tup;
241  Form_pg_collation collForm;
242  Datum collversion;
243  bool isnull;
244  char *oldversion;
245  char *newversion;
246  ObjectAddress address;
247 
249  collOid = get_collation_oid(stmt->collname, false);
250 
251  if (!pg_collation_ownercheck(collOid, GetUserId()))
253  NameListToString(stmt->collname));
254 
256  if (!HeapTupleIsValid(tup))
257  elog(ERROR, "cache lookup failed for collation %u", collOid);
258 
259  collForm = (Form_pg_collation) GETSTRUCT(tup);
261  &isnull);
262  oldversion = isnull ? NULL : TextDatumGetCString(collversion);
263 
264  newversion = get_collation_actual_version(collForm->collprovider, NameStr(collForm->collcollate));
265 
266  /* cannot change from NULL to non-NULL or vice versa */
267  if ((!oldversion && newversion) || (oldversion && !newversion))
268  elog(ERROR, "invalid collation version change");
269  else if (oldversion && newversion && strcmp(newversion, oldversion) != 0)
270  {
271  bool nulls[Natts_pg_collation];
272  bool replaces[Natts_pg_collation];
274 
275  ereport(NOTICE,
276  (errmsg("changing version from %s to %s",
277  oldversion, newversion)));
278 
279  memset(values, 0, sizeof(values));
280  memset(nulls, false, sizeof(nulls));
281  memset(replaces, false, sizeof(replaces));
282 
283  values[Anum_pg_collation_collversion - 1] = CStringGetTextDatum(newversion);
284  replaces[Anum_pg_collation_collversion - 1] = true;
285 
286  tup = heap_modify_tuple(tup, RelationGetDescr(rel),
287  values, nulls, replaces);
288  }
289  else
290  ereport(NOTICE,
291  (errmsg("version has not changed")));
292 
293  CatalogTupleUpdate(rel, &tup->t_self, tup);
294 
296 
297  ObjectAddressSet(address, CollationRelationId, collOid);
298 
299  heap_freetuple(tup);
300  heap_close(rel, NoLock);
301 
302  return address;
303 }
304 
305 
306 Datum
308 {
309  Oid collid = PG_GETARG_OID(0);
310  HeapTuple tp;
311  char *collcollate;
312  char collprovider;
313  char *version;
314 
316  if (!HeapTupleIsValid(tp))
317  ereport(ERROR,
318  (errcode(ERRCODE_UNDEFINED_OBJECT),
319  errmsg("collation with OID %u does not exist", collid)));
320 
321  collcollate = pstrdup(NameStr(((Form_pg_collation) GETSTRUCT(tp))->collcollate));
322  collprovider = ((Form_pg_collation) GETSTRUCT(tp))->collprovider;
323 
324  ReleaseSysCache(tp);
325 
326  version = get_collation_actual_version(collprovider, collcollate);
327 
328  if (version)
330  else
331  PG_RETURN_NULL();
332 }
333 
334 
335 /*
336  * "Normalize" a libc locale name, stripping off encoding tags such as
337  * ".utf8" (e.g., "en_US.utf8" -> "en_US", but "br_FR.iso885915@euro"
338  * -> "br_FR@euro"). Return true if a new, different name was
339  * generated.
340  */
342 static bool
343 normalize_libc_locale_name(char *new, const char *old)
344 {
345  char *n = new;
346  const char *o = old;
347  bool changed = false;
348 
349  while (*o)
350  {
351  if (*o == '.')
352  {
353  /* skip over encoding tag such as ".utf8" or ".UTF-8" */
354  o++;
355  while ((*o >= 'A' && *o <= 'Z')
356  || (*o >= 'a' && *o <= 'z')
357  || (*o >= '0' && *o <= '9')
358  || (*o == '-'))
359  o++;
360  changed = true;
361  }
362  else
363  *n++ = *o++;
364  }
365  *n = '\0';
366 
367  return changed;
368 }
369 
370 
371 #ifdef USE_ICU
372 static char *
373 get_icu_language_tag(const char *localename)
374 {
375  char buf[ULOC_FULLNAME_CAPACITY];
376  UErrorCode status;
377 
378  status = U_ZERO_ERROR;
379  uloc_toLanguageTag(localename, buf, sizeof(buf), TRUE, &status);
380  if (U_FAILURE(status))
381  ereport(ERROR,
382  (errmsg("could not convert locale name \"%s\" to language tag: %s",
383  localename, u_errorName(status))));
384 
385  return pstrdup(buf);
386 }
387 
388 
389 static char *
390 get_icu_locale_comment(const char *localename)
391 {
392  UErrorCode status;
393  UChar displayname[128];
394  int32 len_uchar;
395  char *result;
396 
397  status = U_ZERO_ERROR;
398  len_uchar = uloc_getDisplayName(localename, "en", &displayname[0], sizeof(displayname), &status);
399  if (U_FAILURE(status))
400  ereport(ERROR,
401  (errmsg("could get display name for locale \"%s\": %s",
402  localename, u_errorName(status))));
403 
404  icu_from_uchar(&result, displayname, len_uchar);
405 
406  return result;
407 }
408 #endif /* USE_ICU */
409 
410 
411 Datum
413 {
414 #if defined(HAVE_LOCALE_T) && !defined(WIN32)
415  bool if_not_exists = PG_GETARG_BOOL(0);
416  Oid nspid = PG_GETARG_OID(1);
417 
418  FILE *locale_a_handle;
419  char localebuf[NAMEDATALEN]; /* we assume ASCII so this is fine */
420  int count = 0;
421  List *aliaslist = NIL;
422  List *localelist = NIL;
423  List *enclist = NIL;
424  ListCell *lca,
425  *lcl,
426  *lce;
427 #endif
428 
429  if (!superuser())
430  ereport(ERROR,
431  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
432  (errmsg("must be superuser to import system collations"))));
433 
434 #if defined(HAVE_LOCALE_T) && !defined(WIN32)
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  int i;
445  size_t len;
446  int enc;
447  bool skip;
448  char alias[NAMEDATALEN];
449 
450  len = strlen(localebuf);
451 
452  if (len == 0 || localebuf[len - 1] != '\n')
453  {
454  elog(DEBUG1, "locale name too long, skipped: \"%s\"", localebuf);
455  continue;
456  }
457  localebuf[len - 1] = '\0';
458 
459  /*
460  * Some systems have locale names that don't consist entirely of ASCII
461  * letters (such as "bokm&aring;l" or "fran&ccedil;ais"). This is
462  * pretty silly, since we need the locale itself to interpret the
463  * non-ASCII characters. We can't do much with those, so we filter
464  * them out.
465  */
466  skip = false;
467  for (i = 0; i < len; i++)
468  {
469  if (IS_HIGHBIT_SET(localebuf[i]))
470  {
471  skip = true;
472  break;
473  }
474  }
475  if (skip)
476  {
477  elog(DEBUG1, "locale name has non-ASCII characters, skipped: \"%s\"", localebuf);
478  continue;
479  }
480 
481  enc = pg_get_encoding_from_locale(localebuf, false);
482  if (enc < 0)
483  {
484  /* error message printed by pg_get_encoding_from_locale() */
485  continue;
486  }
487  if (!PG_VALID_BE_ENCODING(enc))
488  continue; /* ignore locales for client-only encodings */
489  if (enc == PG_SQL_ASCII)
490  continue; /* C/POSIX are already in the catalog */
491 
492  count++;
493 
494  CollationCreate(localebuf, nspid, GetUserId(), COLLPROVIDER_LIBC, enc,
495  localebuf, localebuf,
497  if_not_exists);
498 
500 
501  /*
502  * Generate aliases such as "en_US" in addition to "en_US.utf8" for
503  * ease of use. Note that collation names are unique per encoding
504  * only, so this doesn't clash with "en_US" for LATIN1, say.
505  *
506  * However, it might conflict with a name we'll see later in the
507  * "locale -a" output. So save up the aliases and try to add them
508  * after we've read all the output.
509  */
510  if (normalize_libc_locale_name(alias, localebuf))
511  {
512  aliaslist = lappend(aliaslist, pstrdup(alias));
513  localelist = lappend(localelist, pstrdup(localebuf));
514  enclist = lappend_int(enclist, enc);
515  }
516  }
517 
518  ClosePipeStream(locale_a_handle);
519 
520  /* Now try to add any aliases we created */
521  forthree(lca, aliaslist, lcl, localelist, lce, enclist)
522  {
523  char *alias = (char *) lfirst(lca);
524  char *locale = (char *) lfirst(lcl);
525  int enc = lfirst_int(lce);
526 
527  CollationCreate(alias, nspid, GetUserId(), COLLPROVIDER_LIBC, enc,
528  locale, locale,
530  true);
532  }
533 
534  if (count == 0)
536  (errmsg("no usable system locales were found")));
537 #endif /* not HAVE_LOCALE_T && not WIN32 */
538 
539 #ifdef USE_ICU
541  {
542  ereport(NOTICE,
543  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
544  errmsg("encoding \"%s\" not supported by ICU",
546  }
547  else
548  {
549  int i;
550 
551  /*
552  * Start the loop at -1 to sneak in the root locale without too much
553  * code duplication.
554  */
555  for (i = -1; i < ucol_countAvailable(); i++)
556  {
557  const char *name;
558  char *langtag;
559  const char *collcollate;
560  UEnumeration *en;
561  UErrorCode status;
562  const char *val;
563  Oid collid;
564 
565  if (i == -1)
566  name = ""; /* ICU root locale */
567  else
568  name = ucol_getAvailable(i);
569 
570  langtag = get_icu_language_tag(name);
571  collcollate = U_ICU_VERSION_MAJOR_NUM >= 54 ? langtag : name;
572  collid = CollationCreate(psprintf("%s-x-icu", langtag),
573  nspid, GetUserId(), COLLPROVIDER_ICU, -1,
574  collcollate, collcollate,
576  if_not_exists);
577 
579  get_icu_locale_comment(name));
580 
581  /*
582  * Add keyword variants
583  */
584  status = U_ZERO_ERROR;
585  en = ucol_getKeywordValuesForLocale("collation", name, TRUE, &status);
586  if (U_FAILURE(status))
587  ereport(ERROR,
588  (errmsg("could not get keyword values for locale \"%s\": %s",
589  name, u_errorName(status))));
590 
591  status = U_ZERO_ERROR;
592  uenum_reset(en, &status);
593  while ((val = uenum_next(en, NULL, &status)))
594  {
595  char *localeid = psprintf("%s@collation=%s", name, val);
596 
597  langtag = get_icu_language_tag(localeid);
598  collcollate = U_ICU_VERSION_MAJOR_NUM >= 54 ? langtag : localeid;
599  collid = CollationCreate(psprintf("%s-x-icu", langtag),
600  nspid, GetUserId(), COLLPROVIDER_ICU, -1,
601  collcollate, collcollate,
603  if_not_exists);
605  get_icu_locale_comment(localeid));
606  }
607  if (U_FAILURE(status))
608  ereport(ERROR,
609  (errmsg("could not get keyword values for locale \"%s\": %s",
610  name, u_errorName(status))));
611  uenum_close(en);
612  }
613  }
614 #endif
615 
616  PG_RETURN_VOID();
617 }
bool pg_collation_ownercheck(Oid coll_oid, Oid roleid)
Definition: aclchk.c:4973
#define COLLPROVIDER_ICU
Definition: pg_collation.h:84
#define NIL
Definition: pg_list.h:69
static void skip(struct vars *v)
Definition: regc_lex.c:1109
#define Anum_pg_collation_collversion
Definition: pg_collation.h:65
#define DEBUG1
Definition: elog.h:25
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
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)
Definition: pg_collation.c:42
void check_encoding_locale_matches(int encoding, const char *collate, const char *ctype)
Definition: dbcommands.c:722
static const struct @27 enclist[]
#define RelationGetDescr(relation)
Definition: rel.h:429
Oid GetUserId(void)
Definition: miscinit.c:283
#define castNode(_type_, nodeptr)
Definition: nodes.h:575
Oid QualifiedNameGetCreationNamespace(List *names, char **objname_p)
Definition: namespace.c:2846
#define Natts_pg_collation
Definition: pg_collation.h:57
#define forthree(cell1, list1, cell2, list2, cell3, list3)
Definition: pg_list.h:183
char * pstrdup(const char *in)
Definition: mcxt.c:1077
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
bool is_encoding_supported_by_icu(int encoding)
Definition: encnames.c:455
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:141
return result
Definition: formatting.c:1618
#define heap_close(r, l)
Definition: heapam.h:97
#define PG_GETARG_BOOL(n)
Definition: fmgr.h:239
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
void heap_freetuple(HeapTuple htup)
Definition: heaptuple.c:1374
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:4467
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:152
signed int int32
Definition: c.h:256
int ClosePipeStream(FILE *file)
Definition: fd.c:2470
#define NAMEDATALEN
pg_attribute_unused()
#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:75
#define SearchSysCacheExists3(cacheId, key1, key2, key3)
Definition: syscache.h:174
struct pg_encoding enc
Definition: encode.c:522
#define lfirst_int(lc)
Definition: pg_list.h:107
char * defGetString(DefElem *def)
Definition: define.c:49
ItemPointerData t_self
Definition: htup.h:65
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3006
#define NoLock
Definition: lockdefs.h:34
static char * buf
Definition: pg_test_fsync.c:65
#define PG_GETARG_OID(n)
Definition: fmgr.h:240
void aclcheck_error(AclResult aclerr, AclObjectKind objectkind, const char *objectname)
Definition: aclchk.c:3382
int location
Definition: parsenodes.h:711
#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
List * lappend_int(List *list, int datum)
Definition: list.c:146
List * lappend(List *list, void *datum)
Definition: list.c:128
#define WARNING
Definition: elog.h:40
char * NameListToString(List *names)
Definition: namespace.c:2953
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:1116
int GetDatabaseEncoding(void)
Definition: mbutils.c:1015
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition: syscache.c:1278
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1287
#define CollationRelationId
Definition: pg_collation.h:30
ObjectAddress DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_exists)
Definition: collationcmds.c:44
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_VOID()
Definition: fmgr.h:309
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:330
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:607
text * cstring_to_text(const char *s)
Definition: varlena.c:149
#define PG_VALID_BE_ENCODING(_enc)
Definition: pg_wchar.h:293
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1021
Datum lca(PG_FUNCTION_ARGS)
Definition: ltree_op.c:471
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:109
const char * name
Definition: encode.c:521
FormData_pg_collation * Form_pg_collation
Definition: pg_collation.h:51
#define ObjectAddressSet(addr, class_id, object_id)
Definition: objectaddress.h:40
static Datum values[MAXATTR]
Definition: bootstrap.c:162
#define SearchSysCacheCopy1(cacheId, key1)
Definition: syscache.h:161
#define Int32GetDatum(X)
Definition: postgres.h:485
const ObjectAddress InvalidObjectAddress
Datum pg_import_system_collations(PG_FUNCTION_ARGS)
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:708
#define TRUE
Definition: c.h:217
#define elog
Definition: elog.h:219
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:793
#define ERRCODE_DUPLICATE_OBJECT
Definition: streamutil.c:31
Oid get_collation_oid(List *name, bool missing_ok)
Definition: namespace.c:3380
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:85
char * get_collation_actual_version(char collprovider, const char *collcollate)
Definition: pg_locale.c:1423