听蓝小筑

不愤不启·不悱不发

原创 PostgreSQL 8.0 beta working patch::转载文章::收藏

新一篇: 中国现状地缘政治分析::转载::他站的高度不错:: | 旧一篇:  22首柔美至级的音乐::转载::

发信人: 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

发表于 @ 2004年08月13日 15:44:00|评论(loading...)|编辑

新一篇: 中国现状地缘政治分析::转载::他站的高度不错:: | 旧一篇:  22首柔美至级的音乐::转载::

评论:没有评论。

发表评论  


当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
Csdn Blog version 3.1a
Copyright © chaoyuebetter@gmail.com