That method is intended if you have a class MyTableScan and a generic rule that can handle any instance of MyTableScan.
If you have (say) five instances of MyTableScan and five rule instances, one for each scan, then you should register each rule instance individually in the planner. There are a couple of pitfalls with your approach. Suppose you have a self join query “select * from t as t1, t as t2”, and t is of type MyTable. There is only one table but two scans, so you will need to register two rule instances. Those rule instances contain state, and therefore hold memory and other resources, you won’t want to keep them for a long time (e.g. in a cache). For these reasons, the recommended policy is to include the state in the table instance (not in the scan, and not in the rule) and therefore you can write generic rules that can be safely cached and reused. This approach makes it possible to write more complex rules - e.g. a rule that matches two scans of MyTable under a Join. In your model, if there are N scans of a MyTable in a query you would have to create and register N^2 rule instances. Julian > On Feb 2, 2024, at 5:45 AM, Austin Richardson > <austin.richard...@teampicnic.com> wrote: > > Hello Calcite devs, > > Our team currently has a setup in which we have a single TableScan > implementation (e.g. MyTableScan) serving multiple Calcite tables. Each > MyTableScan handles the registration of rules tailored to its respective > Calcite table. I've included an example of the code structure at the end of > my email. > > What we’ve run into is the class-based deduplication behaviour here > <https://github.com/apache/calcite/blob/351ddeb47b8dfb5c196c563920290a79575e9864/core/src/main/java/org/apache/calcite/plan/AbstractRelOptPlanner.java#L235>, > meaning only one instance of MyTableScan can successfully register its > rules. > > We’re exploring solutions to split these such that each table has a unique > TableScan implementation, but also wanted to check first: is there any > alternate way we could keep the single class approach, but still have > Calcite register each MyTableScan? > > Best, > Austin > > > --- > > > Example code structure: > > > abstract class MyTable { > abstract RelOptRule getRule(); > > @Override > public RelNode toRel(...) { > return new MyTableScan(getRule()); > } > } > > ... > > class Table1 extends MyTable { > @Override > RelOptRule getRule() { ... } > } > > ... > > class Table2 extends MyTable { > @Override > RelOptRule getRule() { ... } > } > > ... > > class MyTableScan { > RelOptRule rule; > > // ... constructor where rule is injected ... > > @Override > public void register(RelOptPlanner planner) { > planner.addRule(rule); > } > }