I am using Apache Calcite to validate and rewrite SQL based on policies that put certain restrictions on these SQL queries. I am trying to modify a RelNode
tree in order to rewrite the query to enforce these restrictions. I want to be able to remove certain parts from a query (after it has been validated). For example, I want to be able to remove projection fields (which I managed to do using RelBuilder.projectExcept
) and to remove a table scan and its corresponding column references from a query.
Simple example:
SELECT a.foo, b.bar, c.baz
FROM a, b, c
WHERE a.index = b.index AND b.index = c.index
Let's say we want to remove table c
from the query, to get to the following:
SELECT a.foo, b.bar
FROM a, b
WHERE a.index = b.index
I have tried using RelBuilder
but this does not support removing nodes from the tree. I have also thought about an approach using RelVisitor
but this seems quite complicated for this purpose. I think it would essentially require building a new RelNode
tree. Lastly, implementing rules using RelRule
seems like it would be a suitable option, but I cannot figure out from the Calcite documentation how to remove a particular RelNode
and how to parameterize this (e.g. conditionally apply the rule if the table name is c
).
Can anyone point me to a good approach? Alternatively, would it be easier to just modify the SqlNode
parse tree?
A rule transforms (in this case TransformationRule
) a RelNode
to an equivalent RelNode
i.e both should have the same row. Assumming you want to use HepPlanner
with your custom rule registered and if the rule matches, it will eventually check whether the original rel and the transformed rel have the same row using RelOptUtil#verifyTypeEquivalence
. I think mutating the relNode
via RelVisitor
or mutating the sqlNode
via SqlVisitor
is your best bet.