Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4f5cef2

Browse files
committed
Move code for collation version into provider-specific files.
Author: Andreas KarlssonDiscussion:https://postgr.es/m/4548a168-62cd-457b-8d06-9ba7b985c477%40proxel.se
1 parent3c49d46 commit4f5cef2

File tree

4 files changed

+123
-95
lines changed

4 files changed

+123
-95
lines changed

‎src/backend/utils/adt/pg_locale.c

Lines changed: 8 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,6 @@
6969
#include"utils/pg_locale.h"
7070
#include"utils/syscache.h"
7171

72-
#ifdef__GLIBC__
73-
#include<gnu/libc-version.h>
74-
#endif
75-
7672
#ifdefWIN32
7773
#include<shlwapi.h>
7874
#endif
@@ -91,6 +87,7 @@
9187

9288
/* pg_locale_builtin.c */
9389
externpg_locale_tcreate_pg_locale_builtin(Oidcollid,MemoryContextcontext);
90+
externchar*get_collation_actual_version_builtin(constchar*collcollate);
9491

9592
/* pg_locale_icu.c */
9693
#ifdefUSE_ICU
@@ -104,6 +101,7 @@ extern size_t strnxfrm_icu(char *dest, size_t destsize,
104101
externsize_tstrnxfrm_prefix_icu(char*dest,size_tdestsize,
105102
constchar*src,ssize_tsrclen,
106103
pg_locale_tlocale);
104+
externchar*get_collation_actual_version_icu(constchar*collcollate);
107105
#endif
108106
externpg_locale_tcreate_pg_locale_icu(Oidcollid,MemoryContextcontext);
109107

@@ -115,6 +113,7 @@ extern intstrncoll_libc(const char *arg1, ssize_t len1,
115113
externsize_tstrnxfrm_libc(char*dest,size_tdestsize,
116114
constchar*src,ssize_tsrclen,
117115
pg_locale_tlocale);
116+
externchar*get_collation_actual_version_libc(constchar*collcollate);
118117

119118
externsize_tstrlower_builtin(char*dst,size_tdstsize,constchar*src,
120119
ssize_tsrclen,pg_locale_tlocale);
@@ -1391,100 +1390,14 @@ get_collation_actual_version(char collprovider, const char *collcollate)
13911390
{
13921391
char*collversion=NULL;
13931392

1394-
/*
1395-
* The only two supported locales (C and C.UTF-8) are both based on memcmp
1396-
* and are not expected to change, but track the version anyway.
1397-
*
1398-
* Note that the character semantics may change for some locales, but the
1399-
* collation version only tracks changes to sort order.
1400-
*/
14011393
if (collprovider==COLLPROVIDER_BUILTIN)
1402-
{
1403-
if (strcmp(collcollate,"C")==0)
1404-
return"1";
1405-
elseif (strcmp(collcollate,"C.UTF-8")==0)
1406-
return"1";
1407-
else
1408-
ereport(ERROR,
1409-
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
1410-
errmsg("invalid locale name \"%s\" for builtin provider",
1411-
collcollate)));
1412-
}
1413-
1394+
collversion=get_collation_actual_version_builtin(collcollate);
14141395
#ifdefUSE_ICU
1415-
if (collprovider==COLLPROVIDER_ICU)
1416-
{
1417-
UCollator*collator;
1418-
UVersionInfoversioninfo;
1419-
charbuf[U_MAX_VERSION_STRING_LENGTH];
1420-
1421-
collator=pg_ucol_open(collcollate);
1422-
1423-
ucol_getVersion(collator,versioninfo);
1424-
ucol_close(collator);
1425-
1426-
u_versionToString(versioninfo,buf);
1427-
collversion=pstrdup(buf);
1428-
}
1429-
else
1396+
elseif (collprovider==COLLPROVIDER_ICU)
1397+
collversion=get_collation_actual_version_icu(collcollate);
14301398
#endif
1431-
if (collprovider==COLLPROVIDER_LIBC&&
1432-
pg_strcasecmp("C",collcollate)!=0&&
1433-
pg_strncasecmp("C.",collcollate,2)!=0&&
1434-
pg_strcasecmp("POSIX",collcollate)!=0)
1435-
{
1436-
#if defined(__GLIBC__)
1437-
/* Use the glibc version because we don't have anything better. */
1438-
collversion=pstrdup(gnu_get_libc_version());
1439-
#elif defined(LC_VERSION_MASK)
1440-
locale_tloc;
1441-
1442-
/* Look up FreeBSD collation version. */
1443-
loc=newlocale(LC_COLLATE_MASK,collcollate,NULL);
1444-
if (loc)
1445-
{
1446-
collversion=
1447-
pstrdup(querylocale(LC_COLLATE_MASK |LC_VERSION_MASK,loc));
1448-
freelocale(loc);
1449-
}
1450-
else
1451-
ereport(ERROR,
1452-
(errmsg("could not load locale \"%s\"",collcollate)));
1453-
#elif defined(WIN32)
1454-
/*
1455-
* If we are targeting Windows Vista and above, we can ask for a name
1456-
* given a collation name (earlier versions required a location code
1457-
* that we don't have).
1458-
*/
1459-
NLSVERSIONINFOEXversion= {sizeof(NLSVERSIONINFOEX)};
1460-
WCHARwide_collcollate[LOCALE_NAME_MAX_LENGTH];
1461-
1462-
MultiByteToWideChar(CP_ACP,0,collcollate,-1,wide_collcollate,
1463-
LOCALE_NAME_MAX_LENGTH);
1464-
if (!GetNLSVersionEx(COMPARE_STRING,wide_collcollate,&version))
1465-
{
1466-
/*
1467-
* GetNLSVersionEx() wants a language tag such as "en-US", not a
1468-
* locale name like "English_United States.1252". Until those
1469-
* values can be prevented from entering the system, or 100%
1470-
* reliably converted to the more useful tag format, tolerate the
1471-
* resulting error and report that we have no version data.
1472-
*/
1473-
if (GetLastError()==ERROR_INVALID_PARAMETER)
1474-
returnNULL;
1475-
1476-
ereport(ERROR,
1477-
(errmsg("could not get collation version for locale \"%s\": error code %lu",
1478-
collcollate,
1479-
GetLastError())));
1480-
}
1481-
collversion=psprintf("%lu.%lu,%lu.%lu",
1482-
(version.dwNLSVersion >>8)&0xFFFF,
1483-
version.dwNLSVersion&0xFF,
1484-
(version.dwDefinedVersion >>8)&0xFFFF,
1485-
version.dwDefinedVersion&0xFF);
1486-
#endif
1487-
}
1399+
elseif (collprovider==COLLPROVIDER_LIBC)
1400+
collversion=get_collation_actual_version_libc(collcollate);
14881401

14891402
returncollversion;
14901403
}

‎src/backend/utils/adt/pg_locale_builtin.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
externpg_locale_tcreate_pg_locale_builtin(Oidcollid,
2626
MemoryContextcontext);
27+
externchar*get_collation_actual_version_builtin(constchar*collcollate);
2728
externsize_tstrlower_builtin(char*dst,size_tdstsize,constchar*src,
2829
ssize_tsrclen,pg_locale_tlocale);
2930
externsize_tstrtitle_builtin(char*dst,size_tdstsize,constchar*src,
@@ -148,3 +149,26 @@ create_pg_locale_builtin(Oid collid, MemoryContext context)
148149

149150
returnresult;
150151
}
152+
153+
char*
154+
get_collation_actual_version_builtin(constchar*collcollate)
155+
{
156+
/*
157+
* The only two supported locales (C and C.UTF-8) are both based on memcmp
158+
* and are not expected to change, but track the version anyway.
159+
*
160+
* Note that the character semantics may change for some locales, but the
161+
* collation version only tracks changes to sort order.
162+
*/
163+
if (strcmp(collcollate,"C")==0)
164+
return"1";
165+
elseif (strcmp(collcollate,"C.UTF-8")==0)
166+
return"1";
167+
else
168+
ereport(ERROR,
169+
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
170+
errmsg("invalid locale name \"%s\" for builtin provider",
171+
collcollate)));
172+
173+
returnNULL;/* keep compiler quiet */
174+
}

‎src/backend/utils/adt/pg_locale_icu.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ extern size_t strnxfrm_icu(char *dest, size_t destsize,
6767
externsize_tstrnxfrm_prefix_icu(char*dest,size_tdestsize,
6868
constchar*src,ssize_tsrclen,
6969
pg_locale_tlocale);
70+
externchar*get_collation_actual_version_icu(constchar*collcollate);
7071

7172
typedefint32_t (*ICU_Convert_Func) (UChar*dest,int32_tdestCapacity,
7273
constUChar*src,int32_tsrcLength,
@@ -528,6 +529,22 @@ strnxfrm_prefix_icu(char *dest, size_t destsize,
528529
returnresult;
529530
}
530531

532+
char*
533+
get_collation_actual_version_icu(constchar*collcollate)
534+
{
535+
UCollator*collator;
536+
UVersionInfoversioninfo;
537+
charbuf[U_MAX_VERSION_STRING_LENGTH];
538+
539+
collator=pg_ucol_open(collcollate);
540+
541+
ucol_getVersion(collator,versioninfo);
542+
ucol_close(collator);
543+
544+
u_versionToString(versioninfo,buf);
545+
returnpstrdup(buf);
546+
}
547+
531548
/*
532549
* Convert a string in the database encoding into a string of UChars.
533550
*

‎src/backend/utils/adt/pg_locale_libc.c

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@
2525
#include"utils/pg_locale.h"
2626
#include"utils/syscache.h"
2727

28+
#ifdef__GLIBC__
29+
#include<gnu/libc-version.h>
30+
#endif
31+
32+
#ifdefWIN32
33+
#include<shlwapi.h>
34+
#endif
35+
2836
/*
2937
* Size of stack buffer to use for string transformations, used to avoid heap
3038
* allocations in typical cases. This should be large enough that most strings
@@ -48,6 +56,7 @@ extern intstrncoll_libc(const char *arg1, ssize_t len1,
4856
externsize_tstrnxfrm_libc(char*dest,size_tdestsize,
4957
constchar*src,ssize_tsrclen,
5058
pg_locale_tlocale);
59+
externchar*get_collation_actual_version_libc(constchar*collcollate);
5160
staticlocale_tmake_libc_collator(constchar*collate,
5261
constchar*ctype);
5362
staticvoidreport_newlocale_failure(constchar*localename);
@@ -610,6 +619,71 @@ strnxfrm_libc(char *dest, size_t destsize, const char *src, ssize_t srclen,
610619
returnresult;
611620
}
612621

622+
char*
623+
get_collation_actual_version_libc(constchar*collcollate)
624+
{
625+
char*collversion=NULL;
626+
627+
if (pg_strcasecmp("C",collcollate)!=0&&
628+
pg_strncasecmp("C.",collcollate,2)!=0&&
629+
pg_strcasecmp("POSIX",collcollate)!=0)
630+
{
631+
#if defined(__GLIBC__)
632+
/* Use the glibc version because we don't have anything better. */
633+
collversion=pstrdup(gnu_get_libc_version());
634+
#elif defined(LC_VERSION_MASK)
635+
locale_tloc;
636+
637+
/* Look up FreeBSD collation version. */
638+
loc=newlocale(LC_COLLATE_MASK,collcollate,NULL);
639+
if (loc)
640+
{
641+
collversion=
642+
pstrdup(querylocale(LC_COLLATE_MASK |LC_VERSION_MASK,loc));
643+
freelocale(loc);
644+
}
645+
else
646+
ereport(ERROR,
647+
(errmsg("could not load locale \"%s\"",collcollate)));
648+
#elif defined(WIN32)
649+
/*
650+
* If we are targeting Windows Vista and above, we can ask for a name
651+
* given a collation name (earlier versions required a location code
652+
* that we don't have).
653+
*/
654+
NLSVERSIONINFOEXversion= {sizeof(NLSVERSIONINFOEX)};
655+
WCHARwide_collcollate[LOCALE_NAME_MAX_LENGTH];
656+
657+
MultiByteToWideChar(CP_ACP,0,collcollate,-1,wide_collcollate,
658+
LOCALE_NAME_MAX_LENGTH);
659+
if (!GetNLSVersionEx(COMPARE_STRING,wide_collcollate,&version))
660+
{
661+
/*
662+
* GetNLSVersionEx() wants a language tag such as "en-US", not a
663+
* locale name like "English_United States.1252". Until those
664+
* values can be prevented from entering the system, or 100%
665+
* reliably converted to the more useful tag format, tolerate the
666+
* resulting error and report that we have no version data.
667+
*/
668+
if (GetLastError()==ERROR_INVALID_PARAMETER)
669+
returnNULL;
670+
671+
ereport(ERROR,
672+
(errmsg("could not get collation version for locale \"%s\": error code %lu",
673+
collcollate,
674+
GetLastError())));
675+
}
676+
collversion=psprintf("%lu.%lu,%lu.%lu",
677+
(version.dwNLSVersion >>8)&0xFFFF,
678+
version.dwNLSVersion&0xFF,
679+
(version.dwDefinedVersion >>8)&0xFFFF,
680+
version.dwDefinedVersion&0xFF);
681+
#endif
682+
}
683+
684+
returncollversion;
685+
}
686+
613687
/*
614688
* strncoll_libc_win32_utf8
615689
*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp