美文网首页PostgreSQL Internals
PostgreSQL Executor(2): 不可优化语句的执

PostgreSQL Executor(2): 不可优化语句的执

作者: DavidLi2010 | 来源:发表于2019-05-19 12:55 被阅读0次

    不可优化语句包括DDL、DCL等。与DML语句不同,它们的处理方式是为每一个类型的语句提供相应的处理函数。

    PostgreSQL在SQL语法解析时,对于所有的SQL语句都会生成相应的Statement数据结构。例如,SELECT语句有对应的SelectStmt数据结构,CREATE TABLE语句有对应的CreateStmt语句。解析的结果就是一个ParseTree的链表,链上的每一个节点都是一个Statement的数据结构。

    在语义分析阶段,会对Statement进行分析转换。具体的转换过程在函数transformStmt中,这里不展开叙述。分析的结果是将ParseTree转换成便于优化器工作的QueryTree。而对于不可优化语句,在分析阶段只是简单的创建一个Query对象,并将具体的Statement挂载到Query::utilityStmt字段上,并将Query::commandType字段设置为CMD_UTILITY

    在查询重写阶段,不可优化语句被直接跳过,不需要重写。

    在查询优化阶段,不可优化语句不需要规划路径,被直接挂载到生成的PlannedStmt上。

    因此,对于不可优化语句,执行器得到的计划树中只有SQL语法解析后的Statement数据结构。该计划树在函数PortalDefineQuery中被设置到Portal上。

    PortalStart中选择执行策略时,对于不可优化语句,只有返回元组时(参见函数UtilityReturnsTuples)才会选择PORTAL_UTIL_SELECT,否则选择PORTAL_MULTI_QUERY

    PortalRun阶段,执行流程最终会进入到函数ProcessUtility中,对不同的Statement执行特定的处理逻辑。

    针对各种不同的査询树,査询编译器在执行处理前会做一些额外的处理对査询树进行分析、处理与转换。例如,创建表的语句会用函数transformCreateStmt进行査询树的处理。这些处理过程可能会在当前操作之前和之后增加一些新的操作(例如在创建表的操作之前增加创建serial序列表操作、之后增加创建触发器用于外键约束操作等),也可能会执行对数据结构的处理操作(例如将CreateStmt节点tableElts字段中CONST_CHECK类型的Constraint节点转存到CreateStmt的ccmstraints链表中等)。由于这些处理过程会产生一些新的操作,因此最终会生成一个由多个操作构成的链表。因此,执行过程需要依次扫描该链表,为每一个原子操作调用相应的处理函数。

    下面是创建表进入到执行阶段时的函数栈调用:

    transformCreateStmt parse_utilcmd.c:171
    ProcessUtilitySlow utility.c:996
    standard_ProcessUtility utility.c:923
    ProcessUtility utility.c:360
    PortalRunUtility pquery.c:1178
    PortalRunMulti pquery.c:1324
    PortalRun pquery.c:799
    exec_simple_query postgres.c:1145
    PostgresMain postgres.c:4182
    BackendRun postmaster.c:4358
    BackendStartup postmaster.c:4030
    ServerLoop postmaster.c:1707
    PostmasterMain postmaster.c:1380
    main main.c:228
    start 0x00007fff709083d5
    

    从实现上看,ProcessUtility只作为入口选择函数,它会根据输人的节点类型调用相应的处理过程。

    相关文章

      网友评论

        本文标题:PostgreSQL Executor(2): 不可优化语句的执

        本文链接:https://www.haomeiwen.com/subject/vkafzqtx.html