Open roji opened 3 months ago
Am I correct in the assumption that VisitChildren
and Update
do not need to recompute the type mapping?
@ranma42 they certainly don't today. The moment some visitor needs to do something fancy and do a custom change to any node type (e.g. change the type mapping), it's their responsibility to handle that node type themselves; VisitChildren is only the generic visitation logic for visitors that don't have such custom logic.
But I might be missing your meaning... What scenario do you have in mind, or possible concern?
If that assumption holds true, it should be fairly straightforward to split the "simple optimizations" (constant folding & similar) out of the SqlExpressionFactory
and still get useable expressions. Basically my idea is to move those optimizations into static methods (either in SqlExpressionFactory
or maybe a SqlExpressionSimplifier
, ...) and instead leave the ApplyTypeMapping
part as responsibility of SqlExpressionFactory
(whose instance methods can rely on the dependencies which are specific to the provider).
Yep, sounds right. I'd consider just putting the static methods on each expression type (SqlBinaryExpression would hold the method that knows how to simplify itself).
BTW just noting that we can't do this until efficient deep comparison is implemented (#34149), since this means that all visitors will start doing comparisons for all binary expressions (and other) once they're changed by any visitor anywhere.
We have been starting to apply certain optimizations early, at creation in SqlExpressionFactory; for example, if someone calls
SqlExpressionFactory.MakeBinary
withx AND true
,x
is returned.We should do the same optimizations in e.g. SqlBinaryExpression.VisitChildren(), and possibly even in SqlBinaryExpression.Update(). This will ensure that arbitrary visitors that happen to simplify an operand of a binary expression would transparently get the whole binary expression optimized away.
Ideally, we'd factor things in a way that the same simplification code is used from both SqlExpressionFactory and from SqlBinaryExpression itself (probably have the code on SqlBinaryExpression and call it from SqlExpressionFactory).
(note that this applies to other expression types, not just SqlBinaryExpression)
/cc @ranma42