I think it's reasonable for a system to not want these transformations. A
given execution engine could choose to implement  an EQUALS function
between the two different types, rather than using implicit cast. Also, for
use cases like Matthew's, it seems reasonable that we could configure
SqlValidator and SqlToRel to not do any type coercion.

On Sat, Mar 8, 2025 at 10:18 AM Mihai Budiu <mbu...@gmail.com> wrote:

> Yes, these transformations are essential for compiling programs, because
> they make the program's meaning unambiguous. Consider your example where
> you check equality between two columns of different types A and B.  The
> meaning of the program is very different depending on what casts are
> inserted:
>
> a = b
>
> Can be interpreted as
>
> (B)a = b
>
> or as
>
> a = (A)b
>
> These will give different results in some cases. The Validator makes it
> clear what the choice of the compiler is.
>
> Mihai
>
> ________________________________
> From: Matthew McMillian <matthewgmcmill...@gmail.com>
> Sent: Friday, March 7, 2025 10:34 PM
> To: dev@calcite.apache.org <dev@calcite.apache.org>
> Subject: Questions Regarding Type Coercion and CAST Transformations in
> SqlValidator and RexBuilder
>
> Hi Calcite community,
>
> I'm using Calcite to analyze SQL queries and have encountered some issues
> with transformations that interfere with my use case. I hope the community
> can provide guidance.
>
> My current workflow:
>
>    1. Parse the query into a SqlNode.
>    2. Validate the SqlNode using SqlValidator (callRewrite=false), applying
>    type coercion and other transformations.
>    3. Walk the validated SqlNode to perform custom validation, using
>    SqlValidator and SqlValidatorScope for column resolution.
>    4. Convert the SqlNode to a RelNode.
>    5. Walk the RelNode for further custom validation.
>
> For my use case, I care deeply about the original syntax of the query. I
> need to preserve the original query structure rather than an equivalent
> transformation. Steps #2 and #4 introduce changes that create challenges.
> For example, a comparison between two columns of different types.
>
>    - <bool_column> = <int_column> is rewritten in step #2 as
> CAST(<bool_column>
>    AS INT) = <int_column> (AbstractTypeCoercion
>    <
> https://github.com/apache/calcite/blob/main/core/src/main/java/org/apache/calcite/sql/validate/implicit/AbstractTypeCoercion.java#L157
> >
>    ).
>    - In step #4, it further transforms into CASE(IS NOT
>    NULL(<bool_column>), CASE(<bool_column>, 1, 0), null) (RexBuilder
>    <
> https://github.com/apache/calcite/blob/main/core/src/main/java/org/apache/calcite/rex/RexBuilder.java#L940
> >
>    ).
>
> I have two questions:
>
>    1. Are the aforementioned types of transformations essential for
>    Calcite to compile queries? Is there a way to disable them while still
>    compiling queries?
>    2. Is my current approach reasonable, or is there a better way to
>    achieve my goal within Calcite?
>
>
> Any insights would be greatly appreciated.
>
> Thanks,
> Matthew McMillian
>

Reply via email to