继续分析:

    /* 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 源代码分析之十三的更多相关文章

  1. PostgreSQL的 initdb 源代码分析之二十三

    继续分析: vacuum_db(); 展开: cmd是:/home/pgsql/project/bin/postgres" --single -F -O -c search_path=pg_ ...

  2. PostgreSQL的initdb 源代码分析之六

    继续分析 下面的是获取运行此程序的用户名称,主要还是为了防止在linux下用root来运行的情形. effective_user = get_id(); ) username = effective_ ...

  3. PostgreSQL的 initdb 源代码分析之二

    继续分析 下面这一段,当 initdb --version 或者  initdb --help 才有意义. ) { ], || strcmp(argv[], ) { usage(progname); ...

  4. PostgreSQL的 initdb 源代码分析之二十四

    继续分析: make_template0(); 展开: 无需再作解释,就是创建template0数据库 /* * copy template1 to template0 */ static void ...

  5. PostgreSQL的 initdb 源代码分析之十五

    继续分析: if (pwprompt || pwfilename) get_set_pwd(); 由于我启动initdb的时候,没有设置口令相关的选项,故此略过. 接下来: setup_depend( ...

  6. PostgreSQL的 initdb 源代码分析之十二

    继续分析 /* Now create all the text config files */ setup_config(); 将其展开: 实质就是,确定各种参数,分别写入 postgresql.co ...

  7. PostgreSQL的 initdb 源代码分析之十一

    继续分析: /* Top level PG_VERSION is checked by bootstrapper, so make it first */ write_version_file(NUL ...

  8. PostgreSQL的 initdb 源代码分析之七

    继续分析:由于我使用initdb的时候,没有指定 locale,所以会使用OS的缺省locale,这里是 en_US.UTF-8 printf(_("The files belonging ...

  9. PostgreSQL的initdb 源代码分析之五

    接前面,继续分析: putenv("TZ=GMT") 设置了时区信息. find_other_exec(argv[0], "postgres", PG_BACK ...

随机推荐

  1. 自己用C语言写PIC32 serial bootloader

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 从15年12月份以来我 ...

  2. iOS-UIViewController视图控制器跳转界面的几种常用方法

    一.最普通的视图控制器UIViewContoller 一个普通的视图控制器一般只有模态跳转的功能(ipad我不了解除外,这里只说iPhone),这个方法是所有视图控制器对象都可以用的,而实现这种功能, ...

  3. java线程安全总结

    转自:http://blog.csdn.net/haolongabc/article/details/7249098 最近想将java基础的一些东西都整理整理,写下来,这是对知识的总结,也是一种乐趣. ...

  4. hdu 1269 迷宫城堡 强连通分量

    迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  5. OC基础之方法和参数的命名规范

    以前学过C/C++/Java/C#语言的童鞋可能刚开始对于OC的方法和参数的命名规范大为不爽 举例来说,如下一个OC方法: - (void)tableView:(UITableView *)table ...

  6. 《.NET简单企业应用》项目开发环境

    项目开始,开发团队需要构建一套开发环境,主要包含:开发工具.代码管理/版本控制系统.任务和Bug管理系统和持续集成(CI)系统.本文主要列举项目开发中经常使用的开发工具和第三方库. 本文所列工具根据前 ...

  7. FlexBuilder远程调试WEB应用

    Flex使用的开发工具FlexBuiler 3,web server使用apache. 1 第一次安装IE相应flashplayer的debug版本号,下载Flash player 11.8安装,下载 ...

  8. N卡全部历史驱动

    记录一下寻找驱动方法 打开链接 http://www.geforce.cn/drivers/beta-legacy 默认搜索出来是10个,之后打开控制台输入如下内容回车显示全部(100,可以修改数字来 ...

  9. [bzoj3673/3674可持久化并查集加强版]

    n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 0<n,m<=2 ...

  10. 外网访问FTP出错200 Type set to A

    打开IE浏览器,在intenet选项里的高级==> 这里没有勾就对了!