- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在 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/
我是一名优秀的程序员,十分优秀!