I am trying to write my own adapter for some data source. In which,
Statement statement = conn.createStatement();
ResultSet rs = statement.executeQuery("select hostname, ts from
source.table where ts > 1510033561000");
I noticed that the default SqltoRelConverter will try to trim unused
fields, such as:
14:16:52.500 [main] DEBUG org.apache.calcite.sql2rel - Plan after
converting SqlNode to RelNode
LogicalProject(hostname=[$2], ts=[$3])
LogicalFilter(condition=[>($3, 1510033561000)])
BPTableScan(table=[[source, table]])
14:16:52.517 [main] DEBUG org.apache.calcite.sql2rel - Plan after trimming
unused fields
LogicalFilter(condition=[>($1, 1510033561000)])
LogicalProject(hostname=[$2], ts=[$3])
BPTableScan(table=[[source, table]])
But what I really want is to keep LogicalProject always on top of
LogicalFilter. I don't want unused fields get trimmed automatically. I
noticed that in Prepare.java,
final SqlToRelConverter.ConfigBuilder builder =
SqlToRelConverter.configBuilder()
.withTrimUnusedFields(true)
.withExpand(THREAD_EXPAND.get())
.withExplain(sqlQuery.getKind() == SqlKind.EXPLAIN);
So trimming unused fields is a default behavior. Is there a way to use a
customized sql2rel converter when I run statement.executeQuery?
If the answer to the question above is no, the follow-up question is can we
apply some rule to transpose logicalfilter and logicalproject? I did find a
built-in rule, named FilterProjectTransposeRule, which got applied in
the RelOptPlanner. But the final cheapest plan doesn't pick it. What I
understand is that the calculation of cost is simply a sum of all nodes'
cost. So there is no way to transpose filter and project by only tweaking
the cost of filter and project, since the cost doesn't get lesser. Is my
understanding correct? Thank you in advance!
Sincerely,
Junwei Li