Alima777 commented on a change in pull request #825: [IOTDB-499] Add query
engine decument
URL: https://github.com/apache/incubator-iotdb/pull/825#discussion_r381268957
##########
File path: docs/Documentation-CHN/SystemDesign/2-QueryEngine/2-Planner.md
##########
@@ -50,14 +68,193 @@ mvn clean compile
之后生成代码位置:server/target/generated-sources/ant
谓词去非优化器,将谓词逻辑中的非操作符去掉。
* org.apache.iotdb.db.qp.strategy.optimizer.DnfFilterOptimizer
-
+
将谓词转化为析取范式。
-
+
* org.apache.iotdb.db.qp.strategy.optimizer.MergeSingleFilterOptimizer
将相同路径的谓词逻辑合并。
-
+
+### ConcatPathOptimizer
+
+ConcatPathOptimizer 使用其中的 transform() 方法将给定查询中 SELECT 子句、FROM 子句和 WHERE
子句中的路径进行合并。该方法的申明如下:
+
+ Operator transform(Operator operator)
+ 输入:待转化的 SFWOperator
+ 输出:路径经过连接处理后的 SFWOperator
+
+
+该方法的主要步骤如下:
+
+1. 取出 FROM 子句和 SELECT 子句中的路径,前者称为前缀路径,后者称为后缀路径。进入步骤2.
+2. 判断该查询是否包含 ALIGN BY DEVICE 子句。如果不包含,则可进入步骤3;否则,进入步骤4.
+3. 则调用 concatSelect() 方法将前缀路径和后缀路径合并补全(包括带 * 的路径),形成全路径。如果查询中包含 SLIMIT 子句,则对
SELECT 子句中的路径做相应的筛选。进入步骤5.
+4. 对每一条 FROM 子句中的路径分析其设备名,如果不为空则抛出异常。进入步骤5.
+5. 对 WHERE 子句中过滤条件里包含的路径做补全。此时,SELECT 子句和 WHERE 子句中的路径都是完整的路径。
+
+### RemoveNotOptimizer
+
+RemoveNotOptimizer 类中的 removeNot() 和 reverseFilter()
方法共同实现了删去NOT关键字的功能。removeNot() 方法的申明如下:
+
+ FilterOperator removeNot(FilterOperator filter)
+ 输入:待优化的可能含有 NOT 关键字的谓词
+ 输出:优化后,不包含 NOT 关键字的谓词
+
+该方法的输入为待优化的谓词,并且递归地优化该谓词中的每个子部分。将输入的谓词看作一棵二叉树,其中叶子节点是 BasicFunctionOperator (如
s0 > 10),非叶子节点是“与”、“或”、“非”操作符。 方法的逻辑如下:
+
+1. 判断该节点是否为叶子节点。如果是叶子节点则返回该节点。如果不是叶子节点则进入步骤2.
+2. 判断关系类型。如果是“与”、“或”关系,则进入步骤3;如果是“非”关系,则进入步骤4;如果不是“与”、“或”、“非”关系,则抛出异常。
+3. 此时的“与”、“或”关系一定包含2个孩子节点。对左右孩子递归调用 removeNot() 方法,去除左右子树中的 NOT 关键词,再将该节点返回。
+4. 对该节点调用 reverseFilter() 方法,取反,并且去除 NOT 关键字。
+
+reverseFilter() 方法的申明如下:
+
+ FilterOperator reverseFilter(FilterOperator filter)
+ 输入:待取反的节点
+ 输出:该节点取反后的结果
+
+reverseFilter() 方法的逻辑如下:
+
+1. 判断节点是否为叶子节点,如果是,则调用该节点自身的 reverseFunc() 方法取反。其中,reverseFunc()
方法只用设定的Map来对关键字取反,如将 < 映射为 >= ,将 AND 映射为 OR。如果不是叶子节点,则进入步骤2.
+2.
如果不是叶子节点,分两种情况。如果是“与”、“或”关系,则进入步骤3;如果是“非”关系则进入步骤4;如果既不是“与”、“或”关系,也不是“非”关系,则抛出异常。
+3. 对该节点的左右子树递归调用 reverseFilter() 方法,得到两个取反后的子树,并将该节点返回。
+4. 对孩子节点调用 removeNot() 方法,并将去除NOT关键字的孩子节点返回。
+
+removeNot() 和 reverseFilter() 之间存在一定的耦合关系。removeNot() 访问非 NOT 关系的节点,确保不含有 NOT
关键字;reverseFilter() 访问 NOT 关系节点以及子节点,并进行取反转换,删去 NOT 关键字。
+
+### DnfFilterOptimizer
+
+DNF 是 Disjuctive Normal Form 的缩写,即析取范式。DnfFilterOptimizer 中的 optimize() 方法来依靠
getDnf() 来实现,对过滤条件进行优化,将过滤条件转化为析取范式的形式。该方法的申明如下:
+
+ FilterOperator getDnf(FilterOperator filter)
+ 输入:待优化的 FilterOperator
+ 输出:优化后的 FilterOperator,以析取范式为形式
+
+该方法的步骤如下:
+
+- 1. 如果当前节点是叶子节点,则返回该节点
+- 2. 如果当前节点表示关系“或”,则
+ - (2.1) 获取当前节点所有的子节点(子节点数目为2),并对左右子节点分别递归地调用 getDnf() 方法,使得左右字节点都为析取范式。
+ - (2.2)
对该节点的左子节点和右子节点分别分析。如果子节点是叶子节点或表示关系“与”,则保持不变;否则,说明该子节点的关系为“或”,则将子节点的所有子节点也添加到当前节点的子节点中。即
(OR (OR A, B), C) 转换为 (OR A, B, C)。
+ - (2.3) 返回当前节点。
+- 3. 如果当前节点表示关系“与”,则
+ - (3.1) 获取当前节点所有的子节点(子节点数目为2),并对左右子节点分别递归地调用 getDnf() 方法,使得左右字节点都为析取范式。
+ - (3.2) 对该节点的左子节点和右子节点分别分析。
+ - (3.2.1)
如果左右子节点都不是“或”关系,则说明左右子节点要么是叶子节点,要么是关系“与”,如果是叶子节点,则保持不变,如果是关系“与”,则将该子节点的子节点添加到当前节点的孩子节点中,如
(AND A, (AND B, C)) 就转化为 (AND A, B, C)。
+ - (3.2.2) 如果左右子节点包含为两个“或”关系,将其中一个子节点的两个子节点标记为 A 和 B ,另一子节点的两个子节点标记为 C
和 D,则将 {A, B} 与 {C, D} 两个集合中的元素两两组合,(A, C), (A, D), (B, C), (B, D), 对每一组组合调用
mergeToConjunction() 方法生成合取式作为当前节点的子节点,并将当前节点设为关系“或”,即,把 (AND (OR A, B), (OR C,
D)) 转换为 (OR (AND A, C), (AND A, D), (AND B, C), (AND B, D))。
+ - (3.2.3) 如果左右子节点包含一个“或”关系,一个“与”关系或叶子节点。将“或”子节点的两个子节点标记为 X,
Y,将另一子节点标记为 Z,则只要将 {X, Y} 与 {Z} 集合种的元素两两组合,对 (X, Z), (Y,Z) 调用
mergeToConjunctive() 方法生成合取式作为当前节点的子节点,并将当前节点设为关系“或”,即,把 (AND (OR X, Y), Z) 转换为
(OR (AND X, Z), (AND Y, Z))。
+ - (3.3) 返回当前节点。
+
+
+对于以上提到的 mergeToConjunctive() 方法,申明如下:
+
+ FilterOperator mergeToConjunction(FilterOperator operator1, FilterOperator
operator2)
+ 输入:两个子 FilterOperator
+ 输出:合并后的合取式
+
+该方法生成关系“与”,并将输入的两个 FilterOperator 作为其两个子节点。
Review comment:
```suggestion
该方法将输入的两个子合取式 Operator 合并为一个合取式,例如:(a and b) merge (c) -> (a and b and c)
```
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services