gpt4 book ai didi

c - 为 'A' < 'a' 调试 postgresql

转载 作者:太空狗 更新时间:2023-10-29 11:46:42 24 4
gpt4 key购买 nike

在 postgres 9.1 和 8.4 中的简单比较测试中得到以下奇怪的结果。

postgres=# select 1 one where 'A' < 'a';
one
-----
(0 rows) // ..... I would have expected 1 row

postgres=# select 1 one where 'A' < 'b';
one
-----
1
(1 row) // ...... this looks OK

postgres=# select 1 one where 'A' = 'a';
one
-----
(0 rows) // ...... This also looks OK

postgres=# select 1 one where 'A' > 'a';
one
-----
1
(1 row) // ...... This is inconsistent with the above results

'A' 的 ascii 值是 0x41 而 'a' 是 0x61 所以直接比较 ascii 值应该意味着 'A' 小于 'a',或者如果某些不区分大小写的魔法那么至少 A>b和 Alocale 问题,但话又说回来——但是我的本地设置为标准 us_EN.utf8 设置,使用标准 Centos5 和 Fedora16 安装,结果相同。

将调试器附加到 postgres 进程,我已经能够追踪到问题来自于此;

strcoll("A","a") returns 6;

在哪里

strcoll("A","b") returns -1;

然而,这只能从 postgres 进程内部进行演示(例如附加 gdb 时),并且像下面这样的外部程序会给出完全合理的结果。

main()
{
char *a="a";
char *b="b";
char *A="A";

printf("%s\n",setlocale(2,"us_ENG.utf8"));

printf("%d\n",strcoll(A,a));
printf("%d\n",strcoll(A,b));
printf("%d\n",strcoll(a,a));
printf("%d\n",strcoll(b,b));

printf("%d\n",strcoll(a,A));
printf("%d\n",strcoll(b,A));
printf("%d\n",strcoll(b,a));
printf("%d\n",strcoll(A,A));
}

问题是:有没有人知道什么会导致 strcoll 返回错误的值,以及关于如何修复它以使我的示例 SQL 正常工作的任何建议。

更新:我尝试将数据库重新创建为 initdb --locale=C,'A'<'a' 给出了预期的结果 - 然而没有解释为什么这在创建为 UTF-8 的数据库中失败。

最佳答案

排序取决于您的数据库 locale ,不是系统语言环境。 (虽然应该注意 PostgreSQL 依赖于操作系统来提供细节。More in the Postgres Wiki.)
ASCII 值仅与非语言环境 “C” 相关。

查看您当前的设置:

SELECT * FROM pg_settings WHERE name ~~ 'lc%';

特别是 LC_COLLATE 的设置是相关的。您还可以:

SHOW lc_collate;

在 PostgreSQL 9.1 中,您可以更改每个语句的适用排序规则。尝试:

SELECT 1 AS one WHERE 'A' < 'a' COLLATE "C";

在旧版本中,您(大部分)坚持使用在创建数据库集群时选择的 LC_COLLATE 的值。

关于c - 为 'A' < 'a' 调试 postgresql,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9424033/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com