概述
一,前言
源码分析的过程是以vscode调试的形式进行的源码阅读,所以我们要先启动pgsql然后attatch 到对应的进程,并在postgres.c的for (;;)语句位置设置断点,并执行查询SQL。
二,接收和返回
在for(;;)死循环中,pgsql一直接受当前回话用户的请求并把执行结果返回给用户。
变量send_ready_for_query是个bool值,判断发送回用户的数据是否已经准备好,首次执行时为假。
if (send_ready_for_query)
{
......
}
之后阻塞在这里,等待用户输入请求。返回值firstchar为对应请求的命令类型。常见的取值为:Q(增删改查入口都在这)。
/*
* (3) read a command (loop blocks here)
*/
firstchar = ReadCommand(&input_message);
判断命令,如果是Q(增删改查),则读取转码后的用户输入,并调用主函数exec_simple_query()。
如果在整个exec_simple_query中发生异常。则PortalRun函数会调用elog.c:pg_re_throw,之后会直接跳回 postgres.c 中 if (sigsetjmp(local_sigjmp_buf, 1) != 0),然后 再次开始for(; ; )。
如果执行过程成功则设置send_ready_for_query 为真,并退出switch。
switch (firstchar)
{
case 'Q': /* simple query */
{
const char *query_string;
/* Set statement_timestamp() */
SetCurrentStatementStartTimestamp();
/* 获取转码后的用户输入 */
query_string = pq_getmsgstring(&input_message);
pq_getmsgend(&input_message);
if (am_walsender)
{
if (!exec_replication_command(query_string))
exec_simple_query(query_string);
}
else
exec_simple_query(query_string);
send_ready_for_query = true;
}
break;
进入for(; ; )的下一个循环,再次判断if (send_ready_for_query),并进入到if语句中,将结果返回给用户,同时设置send_ready_for_query为假。之后再次阻塞在ReadCommand函数中,等待用户的再次请求。
if (send_ready_for_query)
{
......
ReadyForQuery(whereToSendOutput);
send_ready_for_query = false;
}
最后
以上就是无辜溪流为你收集整理的postgresql查询编译源码分析——接收和返回的全部内容,希望文章能够帮你解决postgresql查询编译源码分析——接收和返回所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复