Dmitry Sysolyatin created CALCITE-7288:
------------------------------------------

             Summary: Redesign RelShuttle
                 Key: CALCITE-7288
                 URL: https://issues.apache.org/jira/browse/CALCITE-7288
             Project: Calcite
          Issue Type: Improvement
          Components: core
            Reporter: Dmitry Sysolyatin


This task is mainly for discussion and comes from [1]. We have an interface 
called {{RelShuttle}} that tries to do two things at once. It tries to follow 
the proper visitor pattern, ** but at the same time it also has a common method:

{code:java}
RelNode visit(RelNode other);{code}

It would be better to remove this method from the interface and correctly use 
the visitor pattern (as for example RexVisitor does). That means, if we have a 
class {{A}} that extends {{{}RelNode{}}}, then {{RelShuttle}} should have a 
method like:

{code:java}
RelShuttle.visit(A rel) {code}

Main concern:

When we add a new method to `RelShuttle` for example 
`visit({{{}LogicalSnapshot{}}})`, all LogicalSnapshot related code will start 
calling {{RelShuttle.visit(LogicalSnapshot)}} instead of 
{{{}RelShuttle.visit(RelNode other){}}}. But users might already handle 
snapshots in their {{RelShuttle.visit(RelNode other)}} method (as it happens 
with {{{}HintCollector{}}}/{{{}RelHomogeneousShuttle{}}}). It can silently 
break their code. Even if they have tests, they might think everything is fine 
while some issues still go unnoticed.

With a proper visitor pattern, this would result in a compile-time error rather 
than silent behavior that could take a long time to debug

Another option is to have only a single {{visit(RelNode other)}} method (like 
{{RelHomogeneousShuttle}} does, though in a specific way) and use pattern 
matching inside it. 

*But both approaches should not be used together in the same interface.*

 

[1] [https://github.com/apache/calcite/pull/4620] 



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to