发信人: Wwashington (Jacky), 信区: NewSoftware
标 题: PostgreSQL 8.0
beta working patch
发信站: BBS 水木清华站 (Fri Aug 13 15:15:04 2004), 站内
Subject: 如何解决中文环境下 PostgreSQL 8.0 beta 的 token 和 timezone 问题
Author
: Wwashington@smth.org
Release:
2004/08/13
[前言] PostgreSQL 是最强大的开放源码数据库,目前的 7.5 dev 突然变成 8.0 beta 了。既然是 beta
版肯定存在不少问题,导致使用不便甚至无法安装。我这篇文档是针对最近的 2004/08/12 版 postgresql-snapshot.tar.gz
制作的,其他版本请大家自行研究,但基本原理不变。
[下载] http://mirrors.isc.org/pub/postgresql/dev/postgresql-snapshot.tar.gz
[注意] 目前已经发现 MinGW 的 gcc 3.4.0 会引起 postgres.exe 在 psql 终端使用 \dp 时报错,建议采用
gcc 3.3.3 或更低版本编译 postgresql 8.0 beta。感谢 ChinaUnix 论坛上 bitbird 的建议。
Part A. 故障描述
1) FATAL: syntax error in file
"E:/Unix/Sys/Pgsql/data/postgresql.conf"
line 261, near token "s"
2) WARNING: could not find a match for Windows timezone
"中国标准时间"
Part B. 故障分析
1) initdb -U postgres -D "E:/Unix/Sys/Pgsql/data" -L
"E:/Unix/Sys/Pgsql/share" --noclean
使用这个脚本初始化,发现 near token "s"
错误,不删除错误配置,发现问题在 Chinese_People's,配置文件里的 'Chinese_People's Republic of
China.936' 应该是 'Chinese_People\'s Republic of China.936',第二个 '
号不是结束符,却过早的结束了整个字串,所以要加上转义符 \ 号。
2) initdb -U postgres -D "E:/Unix/Sys/Pgsql/data" -L
"E:/Unix/Sys/Pgsql/share"
--locale=C
对于第一个问题,可以用上面的办法初始化,但是又出现了第二个问题,也就是 timezone 无法匹配
Part C. 故障解决
1) 经研究,token 问题是因为 src/bin/initdb/initdb.c
里面缺少了语法分析。现在我已完成真正支持多语言的补丁,工作原理是预先扫描
lc_messages、lc_monetary、lc_numeric、lc_time 的 string
里是否含有单引号(即'号),如果有则在前面增加反斜杠(即\号)。这个\号的存在原因是 conf 文件采用的是 Unix
风格的正则表达式(sed、perl 的语法基础)。
------->
/*
* check if given string is a valid locale
detecting
* whether contains a ' symbol by Wwashington @
Smth
* (I will take responsibility for it
:-)
*/
static bool
cfglocale(const char
*locale)
{
bool ret;
char loc_temp[128];
int len,
i, j;
ret = false; j=0;
len =
strlen(locale);
for (i=0;i<len;i++)
{
if (locale[i]=='\'')
{
ret=true;
loc_temp[j++]='\\';
}
loc_temp[j++]=locale[i];
}
/* should we exit here? */
if
(ret)
sprintf(locale,"%s", loc_temp);
return ret;
}
------->
if (cfglocale(lc_messages))
fprintf(stderr,
_("checking\npostgresql.conf: parameter updated -->
lc_messages\n"));
if (cfglocale(lc_monetary))
fprintf(stderr,
_("postgresql.conf: parameter updated -->
lc_monetary\n"));
if
(cfglocale(lc_numeric))
fprintf(stderr,
_("postgresql.conf: parameter updated --> lc_numeric\n"));
if (cfglocale(lc_time))
fprintf(stderr,
_("postgresql.conf: parameter updated --> lc_time\n"));
2) 经研究,timezone 问题是因为 src/timezone/pgtz.c 按英文处理 locale
的名称,但是系统自动检测的是中文信息,所以必须增加一个针对本地语言的扫描,把发生错误的 locale
做一个合适的对应。我已经写好一个完整的函数,但是只包含中文的情况,因为我手头没有其他语种的系统,但是只要能看懂这个补丁,将来在任何语言环境发生
timezone 错误都可以迅速的修正了。
------->
/*
* check if given Windows timezone is a valid
locale
* to meet the English catalog by Wwashington @
Smth
* (I will take responsibility for it
:-)
*/
static bool
scanzone(const char
*locale)
{
bool ret;
ret =
false;
if (strcmp(locale,
"中国标准时间")==0
)
{
ret=true;
sprintf((char *)locale, "China Standard
Time");
}
return ret;
}
------->
memset(tzname, 0, sizeof(tzname));
strftime(tzname,
sizeof(tzname)-1, "%Z", tm);
scanzone(tzname);
Part D. 补丁使用
1) 补丁的制作,把原文件所在目录改名为 src_old,新文件所在目录改名为 src_new
diff -Nur src_old/bin/initdb/initdb.c src_new/bin/initdb/initdb.c >
initdb.dif
diff -Nur src_old/timezone/pgtz.c
src_new/timezone/pgtz.c > pgtz.dif
2) 补丁的应用,首先要把 snapshot 展开到 /src/sql (在 /etc/fstab 里定义
/src),然后把对应的补丁文件拷贝到原文件所在的目录,然后就可以用 patch 命令来打补丁了。
alias cdp='cd /src/sql/postgresql-snapshot'
cdp
cd src/bin/initdb/
patch --verb < initdb.dif
cdp
cd src/timezone/
patch --verb < pgtz.dif
补丁下载:http://www.smth.edu.cn/bbscon.php?bid=99&id=498248&ap=4578
版权声明:CSDN是本Blog托管服务提供商。如本文牵涉版权问题,CSDN不承担相关责任,请版权拥有者直接与文章作者联系解决。[
点击此处收藏本文]