PostgreSQL的 initdb 源代码分析之十三
继续分析:
/* Bootstrap template1 */
bootstrap_template1();
展开:
我这里读入的文件是:/home/pgsql/project/share/postgres.bki
/*
* run the BKI script in bootstrap mode to create template1
*/
static void
bootstrap_template1(void)
{
PG_CMD_DECL;
char **line;
char *talkargs = "";
char **bki_lines;
char headerline[MAXPGPATH];
char buf[]; printf(_("creating template1 database in %s/base/1 ... "), pg_data);
fflush(stdout); if (debug)
talkargs = "-d 5"; bki_lines = readfile(bki_file); /* Check that bki file appears to be of the right version */ snprintf(headerline, sizeof(headerline), "# PostgreSQL %s\n",
PG_MAJORVERSION); if (strcmp(headerline, *bki_lines) != )
{
fprintf(stderr,
_("%s: input file \"%s\" does not belong to PostgreSQL %s\n"
"Check your installation or specify the correct path "
"using the option -L.\n"),
progname, bki_file, PG_VERSION);
exit_nicely();
} /* Substitute for various symbols used in the BKI file */ sprintf(buf, "%d", NAMEDATALEN);
bki_lines = replace_token(bki_lines, "NAMEDATALEN", buf); sprintf(buf, "%d", (int) sizeof(Pointer));
bki_lines = replace_token(bki_lines, "SIZEOF_POINTER", buf); bki_lines = replace_token(bki_lines, "ALIGNOF_POINTER",
(sizeof(Pointer) == ) ? "i" : "d"); bki_lines = replace_token(bki_lines, "FLOAT4PASSBYVAL",
FLOAT4PASSBYVAL ? "true" : "false"); bki_lines = replace_token(bki_lines, "FLOAT8PASSBYVAL",
FLOAT8PASSBYVAL ? "true" : "false"); bki_lines = replace_token(bki_lines, "POSTGRES", username); bki_lines = replace_token(bki_lines, "ENCODING", encodingid); bki_lines = replace_token(bki_lines, "LC_COLLATE", escape_quotes(lc_collate)); bki_lines = replace_token(bki_lines, "LC_CTYPE", escape_quotes(lc_ctype)); /*
* Pass correct LC_xxx environment to bootstrap.
*
* The shell script arranged to restore the LC settings afterwards, but
* there doesn't seem to be any compelling reason to do that.
*/
snprintf(cmd, sizeof(cmd), "LC_COLLATE=%s", lc_collate);
putenv(xstrdup(cmd)); snprintf(cmd, sizeof(cmd), "LC_CTYPE=%s", lc_ctype);
putenv(xstrdup(cmd)); unsetenv("LC_ALL"); /* Also ensure backend isn't confused by this environment var: */
unsetenv("PGCLIENTENCODING"); snprintf(cmd, sizeof(cmd),
"\"%s\" --boot -x1 %s %s",
backend_exec, boot_options, talkargs); PG_CMD_OPEN; for (line = bki_lines; *line != NULL; line++)
{
PG_CMD_PUTS(*line);
free(*line);
} PG_CMD_CLOSE; free(bki_lines); check_ok();
}
其中, bki_lines = readfile(bki_file) ,是得到了要读取的文件的每一行。
再展开看 replace_token 函数:
这个函数就是用 replacement指向的字符串,替换在 lines所代表的文件内容行数组中所有token值。
比如:
sprintf(buf, "%d", NAMEDATALEN);
bki_lines = replace_token(bki_lines, "NAMEDATALEN", buf);
把 postgres.bki 文件中 类似于
insert OID = 19 ( name 11 10 NAMEDATALEN f b S f t \054 0 18 1003 namein nameout namerecv namesend - - - c p f 0 -1 0 0 _null_ _null_ )
这样的句子,在内存中替换为(根据宏定义、NAMEDATALEN为64):
insert OID = 19 ( name 11 10 64 f b S f t \054 0 18 1003 namein nameout namerecv namesend - - - c p f 0 -1 0 0 _null_ _null_ )
/*
* make a copy of the array of lines, with token replaced by replacement
* the first time it occurs on each line.
*
* This does most of what sed was used for in the shell script, but
* doesn't need any regexp stuff.
*/
static char **
replace_token(char **lines, const char *token, const char *replacement)
{
int numlines = ;
int i;
char **result;
int toklen,
replen,
diff; for (i = ; lines[i]; i++)
numlines++; result = (char **) pg_malloc(numlines * sizeof(char *)); toklen = strlen(token);
replen = strlen(replacement);
diff = replen - toklen; for (i = ; i < numlines; i++)
{
char *where;
char *newline;
int pre; /* just copy pointer if NULL or no change needed */
if (lines[i] == NULL || (where = strstr(lines[i], token)) == NULL)
{
result[i] = lines[i];
continue;
} /* if we get here a change is needed - set up new line */ newline = (char *) pg_malloc(strlen(lines[i]) + diff + ); pre = where - lines[i]; strncpy(newline, lines[i], pre); strcpy(newline + pre, replacement); strcpy(newline + pre + replen, lines[i] + pre + toklen); result[i] = newline;
} return result;
}
综合上述两段,加入调试信息后,可以看到:
---------------replace for NAMEDATALEN ------start
===============lines[] OLD is : insert OID = ( name NAMEDATALEN f b S f t \ namein nameout namerecv namesend - - - c p f - _null_ _null_ ) ===============result[] NEW is : insert OID = ( name f b S f t \ namein nameout namerecv namesend - - - c p f - _null_ _null_ ) ===============lines[] OLD is : insert ( proname - NAMEDATALEN - - f p c t f f t _null_ _null_) ===============result[] NEW is : insert ( proname - - - f p c t f f t _null_ _null_) ===============lines[] OLD is : insert ( typname - NAMEDATALEN - - f p c t f f t _null_ _null_) ===============result[] NEW is : insert ( typname - - - f p c t f f t _null_ _null_) ===============lines[] OLD is : insert ( attname - NAMEDATALEN - - f p c t f f t _null_ _null_) ===============result[] NEW is : insert ( attname - - - f p c t f f t _null_ _null_) ===============lines[] OLD is : insert ( relname - NAMEDATALEN - - f p c t f f t _null_ _null_) ===============result[] NEW is : insert ( relname - - - f p c t f f t _null_ _null_) ---------------replace for NAMEDATALEN ------end ---------------replace for SIZEOF_POINTER ------start
===============lines[] OLD is : insert OID = ( internal SIZEOF_POINTER t p P f t \ internal_in internal_out - - - - - ALIGNOF_POINTER p f - _null_ _null_ ) ===============result[] NEW is : insert OID = ( internal t p P f t \ internal_in internal_out - - - - - ALIGNOF_POINTER p f - _null_ _null_ ) ---------------replace for SIZEOF_POINTER ------end ---------------replace for ALIGNOF_POINTER ------start
===============lines[] OLD is : insert OID = ( internal t p P f t \ internal_in internal_out - - - - - ALIGNOF_POINTER p f - _null_ _null_ ) ===============result[] NEW is : insert OID = ( internal t p P f t \ internal_in internal_out - - - - - d p f - _null_ _null_ ) ---------------replace for ALIGNOF_POINTER ------end ---------------replace for FLOAT4PASSBYVAL ------start
===============lines[] OLD is : insert OID = ( float4 FLOAT4PASSBYVAL b N f t \ float4in float4out float4recv float4send - - - i p f - _null_ _null_ ) ===============result[] NEW is : insert OID = ( float4 true b N f t \ float4in float4out float4recv float4send - - - i p f - _null_ _null_ ) ===============lines[] OLD is : insert ( procost - - - FLOAT4PASSBYVAL p i t f f t _null_ _null_) ===============result[] NEW is : insert ( procost - - - true p i t f f t _null_ _null_) ===============lines[] OLD is : insert ( prorows - - - FLOAT4PASSBYVAL p i t f f t _null_ _null_) ===============result[] NEW is : insert ( prorows - - - true p i t f f t _null_ _null_) ===============lines[] OLD is : insert ( reltuples - - - FLOAT4PASSBYVAL p i t f f t _null_ _null_) ===============result[] NEW is : insert ( reltuples - - - true p i t f f t _null_ _null_) ---------------replace for FLOAT4PASSBYVAL ------end ---------------replace for FLOAT8PASSBYVAL ------start
===============lines[] OLD is : insert OID = ( int8 FLOAT8PASSBYVAL b N f t \ int8in int8out int8recv int8send - - - d p f - _null_ _null_ ) ===============result[] NEW is : insert OID = ( int8 true b N f t \ int8in int8out int8recv int8send - - - d p f - _null_ _null_ ) ===============lines[] OLD is : insert OID = ( float8 FLOAT8PASSBYVAL b N t t \ float8in float8out float8recv float8send - - - d p f - _null_ _null_ ) ===============result[] NEW is : insert OID = ( float8 true b N t t \ float8in float8out float8recv float8send - - - d p f - _null_ _null_ ) ===============lines[] OLD is : insert OID = ( money FLOAT8PASSBYVAL b N f t \ cash_in cash_out cash_recv cash_send - - - d p f - _null_ _null_ ) ===============result[] NEW is : insert OID = ( money true b N f t \ cash_in cash_out cash_recv cash_send - - - d p f - _null_ _null_ ) ===============lines[] OLD is : insert OID = ( time FLOAT8PASSBYVAL b D f t \ time_in time_out time_recv time_send timetypmodin timetypmodout - d p f - _null_ _null_ ) ===============result[] NEW is : insert OID = ( time true b D f t \ time_in time_out time_recv time_send timetypmodin timetypmodout - d p f - _null_ _null_ ) ===============lines[] OLD is : insert OID = ( timestamp FLOAT8PASSBYVAL b D f t \ timestamp_in timestamp_out timestamp_recv timestamp_send timestamptypmodin timestamptypmodout - d p f - _null_ _null_ ) ===============result[] NEW is : insert OID = ( timestamp true b D f t \ timestamp_in timestamp_out timestamp_recv timestamp_send timestamptypmodin timestamptypmodout - d p f - _null_ _null_ ) ===============lines[] OLD is : insert OID = ( timestamptz FLOAT8PASSBYVAL b D t t \ timestamptz_in timestamptz_out timestamptz_recv timestamptz_send timestamptztypmodin timestamptztypmodout - d p f - _null_ _null_ ) ===============result[] NEW is : insert OID = ( timestamptz true b D t t \ timestamptz_in timestamptz_out timestamptz_recv timestamptz_send timestamptztypmodin timestamptztypmodout - d p f - _null_ _null_ ) ---------------replace for FLOAT4PASSBYVAL ------end ---------------replace for POSTGRES ------start
===============lines[] OLD is : insert OID = ( "POSTGRES" t t t t t t t - _null_ _null_ ) ===============result[] NEW is : insert OID = ( "pgsql" t t t t t t t - _null_ _null_ ) ---------------replace for POSTGRES ------end ---------------replace for ENCODING ------start
===============lines[] OLD is : insert OID = ( template1 ENCODING "LC_COLLATE" "LC_CTYPE" t t - _null_) ===============result[] NEW is : insert OID = ( template1 "LC_COLLATE" "LC_CTYPE" t t - _null_) ---------------replace for ENCODING ------end ---------------replace for LC_COLLATE ------start
===============lines[] OLD is : insert OID = ( template1 "LC_COLLATE" "LC_CTYPE" t t - _null_) ===============result[] NEW is : insert OID = ( template1 "en_US.UTF-8" "LC_CTYPE" t t - _null_) ---------------replace for LC_COLLATE ------end ---------------replace for LC_CTYPE ------start
===============lines[] OLD is : insert OID = ( template1 "en_US.UTF-8" "LC_CTYPE" t t - _null_) ===============result[] NEW is : insert OID = ( template1 "en_US.UTF-8" "en_US.UTF-8" t t - _null_) ---------------replace for LC_CTYPE ------end
这些被替换以后的信息,如何被使用呢? 看前面的 bootstrap_template1 函数中的这一段:
/*
* Pass correct LC_xxx environment to bootstrap.
*
* The shell script arranged to restore the LC settings afterwards, but
* there doesn't seem to be any compelling reason to do that.
*/
snprintf(cmd, sizeof(cmd), "LC_COLLATE=%s", lc_collate);
putenv(xstrdup(cmd)); snprintf(cmd, sizeof(cmd), "LC_CTYPE=%s", lc_ctype);
putenv(xstrdup(cmd)); unsetenv("LC_ALL"); /* Also ensure backend isn't confused by this environment var: */
unsetenv("PGCLIENTENCODING"); snprintf(cmd, sizeof(cmd),
"\"%s\" --boot -x1 %s %s",
backend_exec, boot_options, talkargs);
我可以得到 cmd是: "/home/pgsql/project/bin/postgres" --boot -x1 -F
而后面的一段:
则是一次一次的逐行带参数执行 Postgresql.bki中所有行(包括被替换的和没有被替换的行)
可以理解为特殊的模式下,向postgresql 的template 数据库中逐条写入数据。
PG_CMD_OPEN;
for (line = bki_lines; *line != NULL; line++)
{
PG_CMD_PUTS(*line);
free(*line);
}
PG_CMD_CLOSE;
需要注意的是,对各个系统表的建立,都是在此处,通过执行 postgres.bki文件中的各行脚本来完成的。
PostgreSQL的 initdb 源代码分析之十三的更多相关文章
- PostgreSQL的 initdb 源代码分析之二十三
继续分析: vacuum_db(); 展开: cmd是:/home/pgsql/project/bin/postgres" --single -F -O -c search_path=pg_ ...
- PostgreSQL的initdb 源代码分析之六
继续分析 下面的是获取运行此程序的用户名称,主要还是为了防止在linux下用root来运行的情形. effective_user = get_id(); ) username = effective_ ...
- PostgreSQL的 initdb 源代码分析之二
继续分析 下面这一段,当 initdb --version 或者 initdb --help 才有意义. ) { ], || strcmp(argv[], ) { usage(progname); ...
- PostgreSQL的 initdb 源代码分析之二十四
继续分析: make_template0(); 展开: 无需再作解释,就是创建template0数据库 /* * copy template1 to template0 */ static void ...
- PostgreSQL的 initdb 源代码分析之十五
继续分析: if (pwprompt || pwfilename) get_set_pwd(); 由于我启动initdb的时候,没有设置口令相关的选项,故此略过. 接下来: setup_depend( ...
- PostgreSQL的 initdb 源代码分析之十二
继续分析 /* Now create all the text config files */ setup_config(); 将其展开: 实质就是,确定各种参数,分别写入 postgresql.co ...
- PostgreSQL的 initdb 源代码分析之十一
继续分析: /* Top level PG_VERSION is checked by bootstrapper, so make it first */ write_version_file(NUL ...
- PostgreSQL的 initdb 源代码分析之七
继续分析:由于我使用initdb的时候,没有指定 locale,所以会使用OS的缺省locale,这里是 en_US.UTF-8 printf(_("The files belonging ...
- PostgreSQL的initdb 源代码分析之五
接前面,继续分析: putenv("TZ=GMT") 设置了时区信息. find_other_exec(argv[0], "postgres", PG_BACK ...
随机推荐
- 01day1
最大音量 动态规划 题意:给出一个初始值和一个变化序列 c,在第 i 步可以加上或减去 c[i],求 n 步之后能达到的最大值.有一个限定值 maxlevel,在变化过程中值不能超过 maxlevel ...
- MySQL基础之第7章 索引
第7章 索引 MySQL中,所有的数据类型都可以被索引,包括普通索引,唯一性索引,全文索引,单列索引,多列索引和空间索引等. 7.1.索引简介 7.1.1.索引的含义和特点 BTREE索引,HASH索 ...
- 用ioctl获取无线网络信息 /usr//include/linux/wireless.h
1.UNIX Network Programming环境搭建 Unix NetWork Programming――环境搭建(解决unp.h等源码编译问题) http://blog.csdn.net/a ...
- 【转】http-equiv的含义
http-equiv顾名思义,相当于http的文件头作用,它可以向浏览器传回一些有用的信息,以帮助正确和精确地显示网页内容,与之对应的属性值为content,content中的内容其实就是各个参数的变 ...
- 2.Linq实用性技巧篇
在论坛上经常会看到别人问,linq怎么实现递归,如何求笛卡尔积等问题..都可以用linq快速方便的解决..下面我就来个总的归纳 1.)递归 我们经常会遇到一个情况,就是想获取当前节点下的所有子节点.比 ...
- 完美完全卸载Oracle 11g数据库
Oracle 11g可在开始菜单中卸载,然后同时需要删除注册表中相关内容. 操作系统:windows10专业版. 卸载步骤: 1.停用oracle服务:进入计算机管理,在服务中,找到oracle开头的 ...
- A Spy in the Metro
题意: n个车站,已知到达相邻车站的时间,有m1辆车从1站出发已知发车时间,有m2辆车从n站出发已知发车时间,求从1到达n所需等车的总时间最小. 分析: 有三种情况,在原地等,乘左到右的车,乘右到左的 ...
- codeforces 680E Bear and Square Grid 巧妙暴力
这个题是个想法题 先预处理连通块,然后需要用到一种巧妙暴力,即0变1,1变0,一列列添加删除 复杂度O(n^3) #include <cstdio> #include <iostre ...
- hdu 4720 计算几何简单题
昨天用vim练了一道大水题,今天特地找了道稍难一点的题.不过也不是很难,简单的计算几何而已.练习用vim编码,用gdb调试,结果居然1A了,没调试...囧... 做法很简单,无非就是两种情况:①三个巫 ...
- 看仪表盘——validation
先试想一下,对于一个简单的二分类问题,我们如何选择合适的算法? 我们有许许多多的H,如何选择出最为合适的算法? 最合理的方法是:对于每一个H,我们选择出Eout最小的g,然后对于各个g,再选择Eout ...