[ 
https://issues.apache.org/jira/browse/CALCITE-7151?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Dmitry Sysolyatin updated CALCITE-7151:
---------------------------------------
    Description: 
The current test case fails with this error:
{code:java}
java.lang.UnsupportedOperationException: class 
org.apache.calcite.sql.SqlBasicCall: TIMESTAMP '1970-01-01 01:23:45' - INTERVAL 
'7' DAY
{code}
{code:java}
  @Test void testAggWithIdentifierExpansionDisabled() {
    String sql = "select MAX(TIMESTAMP '1970-01-01 01:23:45' - INTERVAL '7' 
DAY) from emp";
    sql(sql)
        .withFactory(f ->
            f.withValidator((opTab, catalogReader, typeFactory, config)
                -> SqlValidatorUtil.newValidator(opTab, catalogReader,
                typeFactory, config.withIdentifierExpansion(false))))
        .withTrim(false)
        .ok();

    String sql2 = "select MAX(CURRENT_TIMESTAMP - INTERVAL '7' DAY) from emp";
    sql(sql2)
        .withFactory(f ->
            f.withValidator((opTab, catalogReader, typeFactory, config)
                -> SqlValidatorUtil.newValidator(opTab, catalogReader,
                typeFactory, config.withIdentifierExpansion(false))))
        .withTrim(false)
        .ok();
  }
{code}
*Reason*

1. `SqlValidatorImpl` expands `SqlUnknownLiteral` ({{{}TIMESTAMP '1970-01-01 
01:23:45'{}}}) into `SqlTimestampLiteral`.
2. `SqlValidatorImpl` adds the `SqlBasicCall` for {{TIMESTAMP '1970-01-01 
01:23:45' - INTERVAL '7' DAY}} to nodeToTypeMap. The operands of this 
`SqlBasicCall` are already expanded (i.e, they contain `SqlTimestampLiteral`).
3. If the identifierExpansion flag is true, then the result of 
SqlValidatorImpl.validate will have expanded `SqlUnknownLiteral` (e.g 
SqlTimestampLiteral). If false, the result SqlNode will not contain expanded 
node (i.e, SqlUnknownLiteral will stay as SqlUnknownLiteral).
4. `SqlToRelConverter` tries to convert `SqlBasicCall` {{TIMESTAMP '1970-01-01 
01:23:45' - INTERVAL '7' DAY}} to `RexNode` and uses 
ValidatorImpl.nodeToTypeMap to get the type of the expression. But 
nodeToTypeMap contains expanded nodes, while the SqlNode passed to 
`SqlToRelConverter` is not expanded. So the SqlNodes are different and this 
causes the exception.

The same behaviour happens for CURRENT_TIMESTAMP as it expands to 
{{ExpandedBasicCall}}

*Solutions*

1. One way to fix the problem is similar to CALCITE-6853 (use 
{{{}bb.getValidator().deriveType(bb.scope, call){}}}), but this only fixes the 
symptom, not the root cause.
2. A better solution might be to add both expanded and not expanded nodes into 
nodeToTypeMap in SqlValidatorImpl.
3. There might be an even better solution.

There is also a question of whether identifierExpansion should be false by 
default. PlannerImpl overrides it to true, and almost all test classes, like 
SqlToRelConverterTest, also set it to true. And as a library user, I would 
expect the default configuration to be the most tested one, but it isn't.

  was:
The current test case fails with this error:
{code}
java.lang.UnsupportedOperationException: class 
org.apache.calcite.sql.SqlBasicCall: TIMESTAMP '1970-01-01 01:23:45' - INTERVAL 
'7' DAY
{code}

{code}
  @Test void testAggWithIdentifierExpansionDisabled() {
    String sql = "select MAX(TIMESTAMP '1970-01-01 01:23:45' - INTERVAL '7' 
DAY) from emp";
    sql(sql)
        .withFactory(f ->
            f.withValidator((opTab, catalogReader, typeFactory, config)
                -> SqlValidatorUtil.newValidator(opTab, catalogReader,
                typeFactory, config.withIdentifierExpansion(false))))
        .withTrim(false)
        .ok();

    String sql2 = "select MAX(CURRENT_TIMESTAMP - INTERVAL '7' DAY) from emp";
    sql(sql2)
        .withFactory(f ->
            f.withValidator((opTab, catalogReader, typeFactory, config)
                -> SqlValidatorUtil.newValidator(opTab, catalogReader,
                typeFactory, config.withIdentifierExpansion(false))))
        .withTrim(false)
        .ok();
  }
{code}

*Reason*

1. `SqlValidatorImpl` expands `SqlUnknownLiteral` ({{TIMESTAMP '1970-01-01 
01:23:45'}}) into `SqlTimestampLiteral`.
2. `SqlValidatorImpl` adds the `SqlBasicCall` for {{TIMESTAMP '1970-01-01 
01:23:45' - INTERVAL '7' DAY}} to nodeToTypeMap. The operands of this 
`SqlBasicCall` are already expanded (i.e, they contain `SqlTimestampLiteral`).
3.  If the identifierExpansion flag is true, then the result of 
SqlValidatorImpl.validate will have expanded `SqlUnknownLiteral` (e.g 
SqlTimestampLiteral). If false, the result SqlNode will not contain expanded 
node (i.e, SqlUnknownLiteral will stay as SqlUnknownLiteral).
4. `SqlToRelConverter` tries to convert `SqlBasicCall` {{TIMESTAMP '1970-01-01 
01:23:45' - INTERVAL '7' DAY}} to `RexNode` and uses 
ValidatorImpl.nodeToTypeMap to get the type of the expression. But 
nodeToTypeMap contains expanded nodes, while the SqlNode passed to 
`SqlToRelConverter` is not expanded. So the SqlNodes are different and this 
causes the exception.

*Solutions*

1. One way to fix the problem is similar to CALCITE-6853 (use 
{{bb.getValidator().deriveType(bb.scope, call)}}), but this only fixes the 
symptom, not the root cause.
2. A better solution might be to add both expanded and not expanded nodes into 
nodeToTypeMap in SqlValidatorImpl.
3. There might be an even better solution.


There is also a question of whether identifierExpansion should be false by 
default. PlannerImpl overrides it to true, and almost all test classes, like 
SqlToRelConverterTest, also set it to true. And as a library user, I would 
expect the default configuration to be the most tested one, but it isn't.



> Aggregate throws UnsupportedOperationException with the default 
> ValidatorConfig
> -------------------------------------------------------------------------------
>
>                 Key: CALCITE-7151
>                 URL: https://issues.apache.org/jira/browse/CALCITE-7151
>             Project: Calcite
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 1.40.0
>            Reporter: Dmitry Sysolyatin
>            Priority: Major
>
> The current test case fails with this error:
> {code:java}
> java.lang.UnsupportedOperationException: class 
> org.apache.calcite.sql.SqlBasicCall: TIMESTAMP '1970-01-01 01:23:45' - 
> INTERVAL '7' DAY
> {code}
> {code:java}
>   @Test void testAggWithIdentifierExpansionDisabled() {
>     String sql = "select MAX(TIMESTAMP '1970-01-01 01:23:45' - INTERVAL '7' 
> DAY) from emp";
>     sql(sql)
>         .withFactory(f ->
>             f.withValidator((opTab, catalogReader, typeFactory, config)
>                 -> SqlValidatorUtil.newValidator(opTab, catalogReader,
>                 typeFactory, config.withIdentifierExpansion(false))))
>         .withTrim(false)
>         .ok();
>     String sql2 = "select MAX(CURRENT_TIMESTAMP - INTERVAL '7' DAY) from emp";
>     sql(sql2)
>         .withFactory(f ->
>             f.withValidator((opTab, catalogReader, typeFactory, config)
>                 -> SqlValidatorUtil.newValidator(opTab, catalogReader,
>                 typeFactory, config.withIdentifierExpansion(false))))
>         .withTrim(false)
>         .ok();
>   }
> {code}
> *Reason*
> 1. `SqlValidatorImpl` expands `SqlUnknownLiteral` ({{{}TIMESTAMP '1970-01-01 
> 01:23:45'{}}}) into `SqlTimestampLiteral`.
> 2. `SqlValidatorImpl` adds the `SqlBasicCall` for {{TIMESTAMP '1970-01-01 
> 01:23:45' - INTERVAL '7' DAY}} to nodeToTypeMap. The operands of this 
> `SqlBasicCall` are already expanded (i.e, they contain `SqlTimestampLiteral`).
> 3. If the identifierExpansion flag is true, then the result of 
> SqlValidatorImpl.validate will have expanded `SqlUnknownLiteral` (e.g 
> SqlTimestampLiteral). If false, the result SqlNode will not contain expanded 
> node (i.e, SqlUnknownLiteral will stay as SqlUnknownLiteral).
> 4. `SqlToRelConverter` tries to convert `SqlBasicCall` {{TIMESTAMP 
> '1970-01-01 01:23:45' - INTERVAL '7' DAY}} to `RexNode` and uses 
> ValidatorImpl.nodeToTypeMap to get the type of the expression. But 
> nodeToTypeMap contains expanded nodes, while the SqlNode passed to 
> `SqlToRelConverter` is not expanded. So the SqlNodes are different and this 
> causes the exception.
> The same behaviour happens for CURRENT_TIMESTAMP as it expands to 
> {{ExpandedBasicCall}}
> *Solutions*
> 1. One way to fix the problem is similar to CALCITE-6853 (use 
> {{{}bb.getValidator().deriveType(bb.scope, call){}}}), but this only fixes 
> the symptom, not the root cause.
> 2. A better solution might be to add both expanded and not expanded nodes 
> into nodeToTypeMap in SqlValidatorImpl.
> 3. There might be an even better solution.
> There is also a question of whether identifierExpansion should be false by 
> default. PlannerImpl overrides it to true, and almost all test classes, like 
> SqlToRelConverterTest, also set it to true. And as a library user, I would 
> expect the default configuration to be the most tested one, but it isn't.



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

Reply via email to