博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PostgreSQL代码分析,查询优化部分,canonicalize_qual
阅读量:7208 次
发布时间:2019-06-29

本文共 3582 字,大约阅读时间需要 11 分钟。

这里把规范谓词表达式的部分就整理完了。阅读的顺序例如以下:

/* * canonicalize_qual *	  Convert a qualification expression to the most useful form. * * The name of this routine is a holdover from a time when it would try to * force the expression into canonical AND-of-ORs or OR-of-ANDs form. * Eventually, we recognized that that had more theoretical purity than * actual usefulness, and so now the transformation doesn't involve any * notion of reaching a canonical form. * * NOTE: we assume the input has already been through eval_const_expressions * and therefore possesses AND/OR flatness.  Formerly this function included * its own flattening logic, but that requires a useless extra pass over the * tree. * * Returns the modified qualification. *//* * 对WHERE语句或ON语句中的条件进行规范化,从集合的角度对AND和OR两个操作做合并分解。

*/ Expr * canonicalize_qual(Expr *qual) { Expr *newqual; /* Quick exit for empty qual */ if (qual == NULL) return NULL; /* * Pull up redundant subclauses in OR-of-AND trees. We do this only * within the top-level AND/OR structure; there's no point in looking * deeper. */ /* * 查找反复的OR操作。即化简条件语句。

* 假设WHERE条件为: * (A=1 AND B=1) OR (A=1 AND C=1) * 能够化简为: * A=1 AND (B=1 OR C=1) * * 另外,这个函数中做了将树状的AND或OR语句平面化(flatten。或拉平)的工作, * 这两个工作主要体如今pull_ands()和pull_ors()两个函数中。 */ newqual = find_duplicate_ors(qual); return newqual; } /* * find_duplicate_ors * Given a qualification tree with the NOTs pushed down, search for * OR clauses to which the inverse OR distributive law might apply. * Only the top-level AND/OR structure is searched. * * Returns the modified qualification. AND/OR flatness is preserved. */ static Expr * find_duplicate_ors(Expr *qual) { /* * “分支一:or_clause” * * 假设WHERE表达式中的主操作是OR,比如是例如以下形式: * A=1 OR B=1 OR (C=1 AND D=1) * 那么參数qual指针实际指向一个BoolExpr结构体。 typedef struct BoolExpr { Expr xpr; = 略 BoolExprType boolop; = OR_EXPR。即对以下的3个进行OR操作 List *args; = 3个,各自是A=1和 B=1和(C=1 AND D=1) } BoolExpr; * * 这里的args是一个list。当中的3个元素的类型分别例如以下: * 第一个是比較操作,类型是OpExpr * 第二个是比較操作。类型是OpExpr * 第三个是AND操作,是一个AND_EXPR类型的BoolExpr,递归调用时会处理 * * 张大明确的blog:http://blog.csdn.net/shujiezhang */ if (or_clause((Node *) qual)) { List *orlist = NIL; ListCell *temp; /* Recurse */ /* * 对BoolExpr中的三个条件分别进行递归处理。

* 在这里须要重点关注上例中的AND_EXPR类型的BoolExpr。由于在递归调用中,他将 * 触发下一个分支(分支二)。 */ foreach(temp, ((BoolExpr *) qual)->args) orlist = lappend(orlist, find_duplicate_ors(lfirst(temp))); /* * Don't need pull_ors() since this routine will never introduce an OR * where there wasn't one before.***这个原因没理解。*** */ /* 详情见《PostgreSQL代码分析,查询优化部分,process_duplicate_ors》博文*/ return process_duplicate_ors(orlist); } /* * “分支二:and_clause” * * 这里主要做了两个操作: * 1) 假设子语句中有OR类型的子语句,则递归调用find_duplicate_ors。由于 子OR语句中 * 也许也能提取公共项。 * 2) 对AND操作进行拉平。

*/ else if (and_clause((Node *) qual)) { List *andlist = NIL; ListCell *temp; /* Recurse */ /* * 子语句中存在一系列OR的情况。 * 比如对于: * A=1 AND ((B=1 AND C=1) OR (B=1 AND D=1)) * 这里的qual指针指向一个AND_EXPR类型的BoolExpr结构体,则 * typedef struct BoolExpr { Expr xpr; = 略 BoolExprType boolop; = AND_EXPR,即对以下的2个进行AND操作 List *args; = 2个,各自是“A=1”和 “((B=1 AND C=1) OR (B=1 AND D=1))” } BoolExpr; * * 对于当中的“((B=1 AND C=1) OR (B=1 AND D=1))”。在递归调用中, * 会进入“分支一:or_clause”,进而转换为: * B=1 AND (C=1 OR D=1) * * 张大明确的blog:http://blog.csdn.net/shujiezhang */ foreach(temp, ((BoolExpr *) qual)->args) andlist = lappend(andlist, find_duplicate_ors(lfirst(temp))); /* Flatten any ANDs introduced just below here */ /* * 拉平。 * * 由于主语句是AND类型。子语句也是AND类型。所以能够直接把子语句拉到父节点。

* */ andlist = pull_ands(andlist); /* The AND list can't get shorter, so result is always an AND */ return make_andclause(andlist); } else return qual; }

PostgreSQL代码分析,查询优化部分。

相关博文:

你可能感兴趣的文章
Python数据可视化的10种技能
查看>>
一地鸡毛 OR 绝地反击,2019年区块链发展指南
查看>>
Kafka团队修改KSQL开源许可,怒怼云厂商
查看>>
今夏发布的Terraform 0.12将提供for循环和第一类表达式
查看>>
GitHub使用Electron重写桌面客户端
查看>>
Microsoft发布Azure Data Factory v2可视化工具的公开预览版
查看>>
周下载量过200万的npm包被注入恶意代码,Vue、Node项目恐受影响
查看>>
九大最热门的IT岗位,机器学习竟然不是第一
查看>>
Stack Overflow技术报告给开发者哪些启示
查看>>
Vue.js 由 1 到 2 的旅程 - (2)
查看>>
麻省理工学院研究人员设计出针对幽灵党和熔毁的DAWG方法
查看>>
Spark Summit EU重头戏:TensorFlow、结构化的流和GPU硬件加速
查看>>
Docker 上开发 nodejs
查看>>
ACM — Rightmost Digit
查看>>
更新:扫码即可实现丨用脚本快速查看自己被多少微信好友删除
查看>>
福利,一张图看懂IT售前工程师修炼之道
查看>>
CSS小技巧收藏
查看>>
SpringBoot应用之分布式会话
查看>>
[LeetCode/LintCode] Happy Number
查看>>
码云近期更新汇总 —— 仓库分支模型+修改仓库地址
查看>>