接前面,继续分析 ChoosePortalStrategy:

/** ChoosePortalStrategy*        Select portal execution strategy given the intended statement list.** The list elements can be Querys, PlannedStmts, or utility statements.* That's more general than portals need, but plancache.c uses this too.** See the comments in portal.h.*/
PortalStrategy
ChoosePortalStrategy(List *stmts)
{int            nSetTag;ListCell   *lc;/** PORTAL_ONE_SELECT and PORTAL_UTIL_SELECT need only consider the* single-statement case, since there are no rewrite rules that can add* auxiliary queries to a SELECT or a utility command. PORTAL_ONE_MOD_WITH* likewise allows only one top-level statement.*/if (list_length(stmts) == 1){Node       *stmt = (Node *) linitial(stmts);if (IsA(stmt, Query)){Query       *query = (Query *) stmt;if (query->canSetTag){if (query->commandType == CMD_SELECT &&query->utilityStmt == NULL){if (query->hasModifyingCTE)return PORTAL_ONE_MOD_WITH;elsereturn PORTAL_ONE_SELECT;}if (query->commandType == CMD_UTILITY &&query->utilityStmt != NULL){if (UtilityReturnsTuples(query->utilityStmt))return PORTAL_UTIL_SELECT;/* it can't be ONE_RETURNING, so give up */return PORTAL_MULTI_QUERY;}}}else if (IsA(stmt, PlannedStmt)){PlannedStmt *pstmt = (PlannedStmt *) stmt;if (pstmt->canSetTag){if (pstmt->commandType == CMD_SELECT &&pstmt->utilityStmt == NULL){if (pstmt->hasModifyingCTE)return PORTAL_ONE_MOD_WITH;elsereturn PORTAL_ONE_SELECT;}}}else{/* must be a utility command; assume it's canSetTag */if (UtilityReturnsTuples(stmt))return PORTAL_UTIL_SELECT;/* it can't be ONE_RETURNING, so give up */return PORTAL_MULTI_QUERY;}}/** PORTAL_ONE_RETURNING has to allow auxiliary queries added by rewrite.* Choose PORTAL_ONE_RETURNING if there is exactly one canSetTag query and* it has a RETURNING list.*/nSetTag = 0;foreach(lc, stmts){Node       *stmt = (Node *) lfirst(lc);if (IsA(stmt, Query)){Query       *query = (Query *) stmt;if (query->canSetTag){if (++nSetTag > 1)return PORTAL_MULTI_QUERY;    /* no need to look further */if (query->returningList == NIL)return PORTAL_MULTI_QUERY;    /* no need to look further */}}else if (IsA(stmt, PlannedStmt)){PlannedStmt *pstmt = (PlannedStmt *) stmt;if (pstmt->canSetTag){if (++nSetTag > 1)return PORTAL_MULTI_QUERY;    /* no need to look further */if (!pstmt->hasReturning)return PORTAL_MULTI_QUERY;    /* no need to look further */}}/* otherwise, utility command, assumed not canSetTag */}if (nSetTag == 1)return PORTAL_ONE_RETURNING;/* Else, it's the general case... */return PORTAL_MULTI_QUERY;
}

先展开第一段的判断:if (list_length(stmts) == 1)

其实是:

static inline int
list_length(const List *l)
{return l ? l->length : 0;
}

这里我作一个查询验证一下,

select * from tst01 where id IN (select sid from tst02) or id IN (select sid from tst03);

list_length(stmts) == 1 的条件满足。

再看:

#define lfirst(lc)                 ((lc)->data.ptr_value)

#define linitial(l)                lfirst(list_head(l))

static inline ListCell *
list_head(const List *l)
{return l ? l->head : NULL;
}

所以呢,这句 :Node *stmt = (Node *) lfirst(lc); 就是拿到了 计划树的头,并且转换为 Node 指针。

PostgreSQL在何处处理 sql查询之二十九相关推荐

  1. PostgreSQL在何处处理 sql查询之二十二

    接前面. 回到程序调用关系上来: estimate_rel_size -> RelationGetNumberOfBlocks->RelationGetNumberOfBlocksINFo ...

  2. PostgreSQL在何处处理 sql查询之二

    在exec_simple_query中,代码如下: 1 /* 2 * exec_simple_query 3 * 4 * Execute a "simple Query" prot ...

  3. PostgreSQL在何处处理 sql查询之二十一

    接前面: 回到mdopen上来,看看是谁调用了 mdopen,又获得了什么. /** mdnblocks() -- Get the number of blocks stored in a relat ...

  4. 零基础带你学习MySQL—单行子查询和多行子查询(二十二)

    零基础带你学习MySQL-多行子查询(二十二) 一.什么是子查询? 子查询是指嵌入在其它 sql 语句中的 select 语句,也叫嵌套查询 二.什么是单行子查询? 单行子查询是指只返回一行数据的子查 ...

  5. Debezium报错处理系列之二十九:Make sure that an instance of SQL Server is running on the host and accepting TCP

    Debezium报错处理系列之二十九:Make sure that an instance of SQL Server is running on the host and accepting TCP ...

  6. FreeSql (二十九)Lambda 表达式

    FreeSql 支持功能丰富的表达式函数解析,方便程序员在不了解数据库函数的情况下编写代码.这是 FreeSql 非常特色的功能之一,深入细化函数解析尽量做到满意,所支持的类型基本都可以使用对应的表达 ...

  7. 【Microsoft Azure 的1024种玩法】二十九.基于Azure VM快速实现网络入侵检测 (IDS) 及网络安全监视 (NSM)

    [简介] 数据包捕获是一个重要组件,可以实施网络入侵检测系统 (IDS) 并执行网络安全监视 (NSM). 我们可以借助开源 IDS 工具来处理数据包捕获,并检查潜在网络入侵和恶意活动的签名. 使用网 ...

  8. 2021年大数据Hadoop(二十九):​​​​​​​关于YARN常用参数设置

    全网最详细的Hadoop文章系列,强烈建议收藏加关注! 后面更新文章都会列出历史文章目录,帮助大家回顾知识重点. 目录 本系列历史文章 前言 关于yarn常用参数设置 设置container分配最小内 ...

  9. 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验二十九:LCD模块

    实验二十九:LCD模块 据说Alinx 301支持 7"TFT,好奇的朋友一定疑惑道,它们3.2"TFT以及7"TFT等两者之间究竟有何区别呢?答案很简单,前者自带控制器 ...

  10. Bootstrap入门(二十九)JS插件6:弹出框

    Bootstrap入门(二十九)JS插件6:弹出框 加入小覆盖的内容,像在iPad上,用于存放非主要信息 弹出框是依赖于工具提示插件的,那它也和工具提示是一样的,是需要初始化才能够使用的 首先我们引入 ...

最新文章

  1. Collections.addAll() 的使用 以及和list.addAll() 的区别
  2. 大尺寸3D打印机:不再是“围城”!工业级3D打印的瞬发时代已来!
  3. linux之wget和curl如何携带cookie进行链接访问
  4. 前端开发-认识前端开发-0226
  5. bootstrap获取选中行的主键_深入分析Mybatis 使用useGeneratedKeys获取自增主键
  6. [笔试面试题] 10-C和C++区别相关
  7. LVS (Linux虚拟服务器)模型及算法
  8. TI TMS570LC43xx 裸机开发快速上手
  9. chown无效的用户mysql_求大神指引,安装MYSQL时执行chown指令出错,已经创建组和用户。local中并没有找到mysql。用find找过路径...
  10. 适合我的前端学习路线(学习前端不迷路)
  11. 计算机DNS怎么配置,dns设置,教您怎么设置dns地址
  12. 零代码与低代码快速开发平台的区别
  13. 【论文笔记】多时相遥感影像变化检测方法综述
  14. 电商后台管理4-商品列表及添加商品(list.vue和add.vue)
  15. “换头术”所引发的“长生不死”
  16. Good Ticket(深搜)
  17. Struggling
  18. SQL查询-查询所有员工的姓名及其直接上级的姓名,没有领导的员工也需要查询
  19. 免费公测 标贝声音理解,检测声音性别和年龄
  20. C++ 计算多边形的面积,计算IOU

热门文章

  1. 你得真心喜欢些什么,才能过好漫长的冬天
  2. 专访Two Sigma CEO Nobel: 当前AI投资有太多的炒作
  3. (转)神秘的比特币地址详解
  4. (转)比特币王国的内战与分裂|《财经》特稿
  5. PolarDB-X 一致性共识协议 (X-Paxos)
  6. 【人脸识别】基于matlab GUI PCA算法人脸识别门禁系统【含Matlab源码 1777期】
  7. 【图像融合】基于matlab对比度和结构提取多模态解剖图像融合【含Matlab源码 1539期】
  8. 【图像加密】基于matlab DNA混沌系统图像加密【含Matlab源码 1190期】
  9. 【语音去噪】基于matlab谱减法去噪【含Matlab源码 429期】
  10. 【股价预测】基于matlab BP神经网络股票价格预测【含Matlab源码 345期】