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

前端之家收集整理的这篇文章主要介绍了PostgreSQL代码分析,查询优化部分,canonicalize_qual前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。


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

@H_404_15@一、PostgreSQL代码分析,查询优化部分,canonicalize_qual

二、PostgreSQL代码分析,查询优化部分,pull_ands()和pull_ors()

三、PostgreSQL代码分析,查询优化部分,process_duplicate_ors



  1. /*
  2. * canonicalize_qual
  3. * Convert a qualification expression to the most useful form.
  4. *
  5. * The name of this routine is a holdover from a time when it would try to
  6. * force the expression into canonical AND-of-ORs or OR-of-ANDs form.
  7. * Eventually,we recognized that that had more theoretical purity than
  8. * actual usefulness,and so now the transformation doesn't involve any
  9. * notion of reaching a canonical form.
  10. *
  11. * NOTE: we assume the input has already been through eval_const_expressions
  12. * and therefore possesses AND/OR flatness. Formerly this function included
  13. * its own flattening logic,but that requires a useless extra pass over the
  14. * tree.
  15. *
  16. * Returns the modified qualification.
  17. */
  18. /*
  19. * 对WHERE语句或ON语句中的条件进行规范化,从集合的角度对AND和OR两个操作做合并分解。
  20. */
  21. Expr *
  22. canonicalize_qual(Expr *qual)
  23. {
  24. Expr *newqual;
  25.  
  26. /* Quick exit for empty qual */
  27. if (qual == NULL)
  28. return NULL;
  29.  
  30. /*
  31. * Pull up redundant subclauses in OR-of-AND trees. We do this only
  32. * within the top-level AND/OR structure; there's no point in looking
  33. * deeper.
  34. */
  35. /*
  36. * 查找重复的OR操作,即化简条件语句。
  37. * 假设WHERE条件为:
  38. * (A=1 AND B=1) OR (A=1 AND C=1)
  39. * 可以化简为:
  40. * A=1 AND (B=1 OR C=1)
  41. *
  42. * 另外,这个函数中做了将树状的AND或OR语句平面化(flatten,或拉平)的工作,
  43. * 这两个工作主要体现在pull_ands()和pull_ors()两个函数中。
  44. */
  45. newqual = find_duplicate_ors(qual);
  46.  
  47. return newqual;
  48. }
  49.  
  50.  
  51. /*
  52. * find_duplicate_ors
  53. * Given a qualification tree with the NOTs pushed down,search for
  54. * OR clauses to which the inverse OR distributive law might apply.
  55. * Only the top-level AND/OR structure is searched.
  56. *
  57. * Returns the modified qualification. AND/OR flatness is preserved.
  58. */
  59. static Expr *
  60. find_duplicate_ors(Expr *qual)
  61. {
  62. /*
  63. * “分支一:or_clause”
  64. *
  65. * 如果WHERE表达式中的主操作是OR,例如是如下形式:
  66. * A=1 OR B=1 OR (C=1 AND D=1)
  67. * 那么参数qual指针实际指向一个BoolExpr结构体。
  68. typedef struct BoolExpr
  69. {
  70. Expr xpr; = 略
  71. BoolExprType boolop; = OR_EXPR,即对下面的3个进行OR操作
  72. List *args; = 3个,分别是A=1和 B=1和(C=1 AND D=1)
  73. } BoolExpr;
  74. *
  75. * 这里的args是一个list,其中的3个元素的类型分别如下:
  76. * 第一个是比较操作,类型是OpExpr
  77. * 第二个是比较操作,类型是OpExpr
  78. * 第三个是AND操作,是一个AND_EXPR类型的BoolExpr,递归调用时会处理
  79. *
  80. * 张大明白的blog:http://blog.csdn.net/shujiezhang
  81. */
  82. if (or_clause((Node *) qual))
  83. {
  84. List *orlist = NIL;
  85. ListCell *temp;
  86.  
  87. /* Recurse */
  88. /*
  89. * 对BoolExpr中的三个条件分别进行递归处理。
  90. * 在这里需要重点关注上例中的AND_EXPR类型的BoolExpr,因为在递归调用中,他将
  91. * 触发下一个分支(分支二)。
  92. */
  93. foreach(temp,((BoolExpr *) qual)->args)
  94. orlist = lappend(orlist,find_duplicate_ors(lfirst(temp)));
  95.  
  96. /*
  97. * Don't need pull_ors() since this routine will never introduce an OR
  98. * where there wasn't one before.***这个原因没理解。***
  99. */
  100. /* 详情见《Postgresql代码分析,查询优化部分,process_duplicate_ors》博文*/
  101. return process_duplicate_ors(orlist);
  102. }
  103. /*
  104. * “分支二:and_clause”
  105. *
  106. * 这里主要做了两个操作:
  107. * 1) 如果子语句中有OR类型的子语句,则递归调用find_duplicate_ors,因为 子OR语句中
  108. * 或许也能提取公共项。
  109. * 2) 对AND操作进行拉平。
  110. */
  111. else if (and_clause((Node *) qual))
  112. {
  113. List *andlist = NIL;
  114. ListCell *temp;
  115.  
  116. /* Recurse */
  117. /*
  118. * 子语句中存在一系列OR的情况。
  119. * 例如对于:
  120. * A=1 AND ((B=1 AND C=1) OR (B=1 AND D=1))
  121. * 这里的qual指针指向一个AND_EXPR类型的BoolExpr结构体,则
  122. *
  123. typedef struct BoolExpr
  124. {
  125. Expr xpr; = 略
  126. BoolExprType boolop; = AND_EXPR,即对下面的2个进行AND操作
  127. List *args; = 2个,分别是“A=1”和 “((B=1 AND C=1) OR (B=1 AND D=1))”
  128. } BoolExpr;
  129. *
  130. * 对于其中的“((B=1 AND C=1) OR (B=1 AND D=1))”,在递归调用中,
  131. * 会进入“分支一:or_clause”,进而转换为:
  132. * B=1 AND (C=1 OR D=1)
  133. *
  134. * 张大明白的blog:http://blog.csdn.net/shujiezhang
  135. */
  136. foreach(temp,((BoolExpr *) qual)->args)
  137. andlist = lappend(andlist,find_duplicate_ors(lfirst(temp)));
  138.  
  139. /* Flatten any ANDs introduced just below here */
  140. /*
  141. * 拉平。
  142. *
  143. * 因为主语句是AND类型,子语句也是AND类型,所以可以直接把子语句拉到父节点。
  144. *
  145. */
  146. andlist = pull_ands(andlist);
  147. /* The AND list can't get shorter,so result is always an AND */
  148. return make_andclause(andlist);
  149. }
  150. else
  151. return qual;
  152. }

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

张大明白的blog:http://blog.csdn.net/shujiezhang

相关博文:PostgreSQL代码分析,查询优化部分,process_duplicate_ors

猜你在找的Postgre SQL相关文章