postgres源码学习之sql查询
- sql查询的主流程
- 读取sql
- 解析sql
- 重写sql
- 获得执行计划
- 执行查询操作
- 结果返回
sql查询的主流程
参考postgres的处理流程
由上一节,我们可以看到,当有新的连接通过权限认证之后,将进入等待接收sql语句,并执行sql语句的过程。
读取sql
建立连接后,服务端postgres就等待接收命令
解析sql
解析sql语句函数为pg_parse_query,其调用栈如下:
重写sql
重写sql语句函数为parse_analyze_fixedparams,其调用栈如下:
获得执行计划
获得执行计划函数为pg_plan_queries,调用栈如下:
执行查询操作
查询操作调用顺序为PortalRun–>PortRunSelect–>ExecutorRun–>standard_ExecutorRun–>ExecutePlan
结果返回
在ExecutePlan中,会将结果集返回给客户端,调用栈如下:
涉及到查询结果返回的,会调用到printtup函数。
其函数主要内容如下:
/** send the attributes of this tuple*/for (i = 0; i < natts; ++i){PrinttupAttrInfo *thisState = myState->myinfo + i;Datum attr = slot->tts_values[i];if (slot->tts_isnull[i]){pq_sendint32(buf, -1);continue;}if (thisState->typisvarlena)VALGRIND_CHECK_MEM_IS_DEFINED(DatumGetPointer(attr),VARSIZE_ANY(attr));if (thisState->format == 0){/* Text output */char *outputstr;outputstr = OutputFunctionCall(&thisState->finfo, attr);pq_sendcountedtext(buf, outputstr, strlen(outputstr));}else{/* Binary output */bytea *outputbytes;outputbytes = SendFunctionCall(&thisState->finfo, attr);pq_sendint32(buf, VARSIZE(outputbytes) - VARHDRSZ);pq_sendbytes(buf, VARDATA(outputbytes),VARSIZE(outputbytes) - VARHDRSZ);}}
其输出形式和之前介绍的Mysql Resultset 解析记录中介绍的结果集存储有着相似的地方。