如何修改 RelNode 树?

How to modify a RelNode tree?

我正在使用 Apache Calcite 根据对这些 SQL 查询施加某些限制的策略来验证和重写 SQL。我正在尝试修改 RelNode 树以重写查询以强制执行这些限制。我希望能够从查询中删除某些部分(在验证之后)。例如,我希望能够删除投影字段(我设法使用 RelBuilder.projectExcept 完成)并从查询中删除 table 扫描及其相应的列引用。

简单示例:

SELECT a.foo, b.bar, c.baz
FROM a, b, c
WHERE a.index = b.index AND b.index = c.index

假设我们要从查询中删除 table c,以获得以下结果:

SELECT a.foo, b.bar
FROM a, b
WHERE a.index = b.index

我试过使用 RelBuilder 但这不支持从树中删除节点。我也考虑过使用 RelVisitor 的方法,但这似乎很复杂。我认为这基本上需要构建一个新的 RelNode 树。最后,使用 RelRule 实施规则似乎是一个 suitable 选项,但我无法从 Calcite 文档中弄清楚如何删除特定的 RelNode 以及如何对其进行参数化(例如如果 table 名称是 c).

,则有条件地应用规则

谁能告诉我一个好的方法?或者,仅修改 SqlNode 解析树会更容易吗?

规则将(在本例中为 TransformationRuleRelNode 转换为 等价物 RelNode 即两者应具有同一行。假设你想使用 HepPlanner 和你注册的自定义规则,如果规则匹配,它最终会使用 RelOptUtil#verifyTypeEquivalence 检查原始 rel 和转换后的 rel 是否有相同的行。我认为通过 RelVisitor 改变 relNode 或通过 SqlVisitor 改变 sqlNode 是你最好的选择。