aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/pg_locale_libc.c
diff options
context:
space:
mode:
authorJeff Davis <jdavis@postgresql.org>2024-12-02 23:20:32 -0800
committerJeff Davis <jdavis@postgresql.org>2024-12-02 23:24:35 -0800
commit1ba0782ce90cb4261098de59b49ae5cb2326566b (patch)
treeaf0b1a9d72bb582f0871a1171428a0635b434636 /src/backend/utils/adt/pg_locale_libc.c
parent8817e8d3a4e5f00a5583e56a17f5d49a4e21dafd (diff)
downloadpostgresql-1ba0782ce90cb4261098de59b49ae5cb2326566b.tar.gz
postgresql-1ba0782ce90cb4261098de59b49ae5cb2326566b.zip
Perform provider-specific initialization in new functions.
Reviewed-by: Andreas Karlsson Discussion: https://postgr.es/m/4548a168-62cd-457b-8d06-9ba7b985c477@proxel.se
Diffstat (limited to 'src/backend/utils/adt/pg_locale_libc.c')
-rw-r--r--src/backend/utils/adt/pg_locale_libc.c74
1 files changed, 70 insertions, 4 deletions
diff --git a/src/backend/utils/adt/pg_locale_libc.c b/src/backend/utils/adt/pg_locale_libc.c
index 83f310fc71c..374ac37ba0a 100644
--- a/src/backend/utils/adt/pg_locale_libc.c
+++ b/src/backend/utils/adt/pg_locale_libc.c
@@ -11,10 +11,16 @@
#include "postgres.h"
+#include "access/htup_details.h"
+#include "catalog/pg_database.h"
#include "catalog/pg_collation.h"
#include "mb/pg_wchar.h"
+#include "miscadmin.h"
+#include "utils/builtins.h"
#include "utils/formatting.h"
+#include "utils/memutils.h"
#include "utils/pg_locale.h"
+#include "utils/syscache.h"
/*
* Size of stack buffer to use for string transformations, used to avoid heap
@@ -24,15 +30,16 @@
*/
#define TEXTBUFLEN 1024
-extern locale_t make_libc_collator(const char *collate,
- const char *ctype);
+extern pg_locale_t create_pg_locale_libc(Oid collid, MemoryContext context);
+
extern int strncoll_libc(const char *arg1, ssize_t len1,
const char *arg2, ssize_t len2,
pg_locale_t locale);
extern size_t strnxfrm_libc(char *dest, size_t destsize,
const char *src, ssize_t srclen,
pg_locale_t locale);
-
+static locale_t make_libc_collator(const char *collate,
+ const char *ctype);
static void report_newlocale_failure(const char *localename);
#ifdef WIN32
@@ -41,6 +48,65 @@ static int strncoll_libc_win32_utf8(const char *arg1, ssize_t len1,
pg_locale_t locale);
#endif
+pg_locale_t
+create_pg_locale_libc(Oid collid, MemoryContext context)
+{
+ const char *collate;
+ const char *ctype;
+ locale_t loc;
+ pg_locale_t result;
+
+ if (collid == DEFAULT_COLLATION_OID)
+ {
+ HeapTuple tp;
+ Datum datum;
+
+ tp = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId));
+ if (!HeapTupleIsValid(tp))
+ elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tp,
+ Anum_pg_database_datcollate);
+ collate = TextDatumGetCString(datum);
+ datum = SysCacheGetAttrNotNull(DATABASEOID, tp,
+ Anum_pg_database_datctype);
+ ctype = TextDatumGetCString(datum);
+
+ ReleaseSysCache(tp);
+ }
+ else
+ {
+ HeapTuple tp;
+ Datum datum;
+
+ tp = SearchSysCache1(COLLOID, ObjectIdGetDatum(collid));
+ if (!HeapTupleIsValid(tp))
+ elog(ERROR, "cache lookup failed for collation %u", collid);
+
+ datum = SysCacheGetAttrNotNull(COLLOID, tp,
+ Anum_pg_collation_collcollate);
+ collate = TextDatumGetCString(datum);
+ datum = SysCacheGetAttrNotNull(COLLOID, tp,
+ Anum_pg_collation_collctype);
+ ctype = TextDatumGetCString(datum);
+
+ ReleaseSysCache(tp);
+ }
+
+
+ loc = make_libc_collator(collate, ctype);
+
+ result = MemoryContextAllocZero(context, sizeof(struct pg_locale_struct));
+ result->provider = COLLPROVIDER_LIBC;
+ result->deterministic = true;
+ result->collate_is_c = (strcmp(collate, "C") == 0) ||
+ (strcmp(collate, "POSIX") == 0);
+ result->ctype_is_c = (strcmp(ctype, "C") == 0) ||
+ (strcmp(ctype, "POSIX") == 0);
+ result->info.lt = loc;
+
+ return result;
+}
+
/*
* Create a locale_t with the given collation and ctype.
*
@@ -49,7 +115,7 @@ static int strncoll_libc_win32_utf8(const char *arg1, ssize_t len1,
*
* Ensure that no path leaks a locale_t.
*/
-locale_t
+static locale_t
make_libc_collator(const char *collate, const char *ctype)
{
locale_t loc = 0;