Uploaded image for project: 'Calcite'
  1. Calcite
  2. CALCITE-5489

When creating a RexCall to TIMESTAMP_DIFF function, cannot convert a TIMESTAMP literal to a org.apache.calcite.avatica.util.TimeUnit

    XMLWordPrintableJSON

Details

    Description

      It seems it stops working after

      [CALCITE-5360] Add TIMESTAMP_ADD function (enabled in BigQuery library)

      for RexCallBinding

      e.g. this test starts failing

        @Test void testTimestampDiffCall() {
          final RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
          RexBuilder rexBuilder = new RexBuilder(typeFactory);
          final RexImplicationCheckerFixtures.Fixture f = new RexImplicationCheckerFixtures.Fixture();
          final TimestampString ts =
              TimestampString.fromCalendarFields(Util.calendar());
      
          rexBuilder.makeCall(SqlStdOperatorTable.TIMESTAMP_DIFF,
              ImmutableList.of(rexBuilder.makeFlag(TimeUnit.QUARTER),
                  f.timestampLiteral(ts), f.timestampLiteral(ts)));
        }
      

      like

      cannot convert TIMESTAMP literal to class org.apache.calcite.avatica.util.TimeUnit
      java.lang.AssertionError: cannot convert TIMESTAMP literal to class org.apache.calcite.avatica.util.TimeUnit
      	at org.apache.calcite.rex.RexLiteral.getValueAs(RexLiteral.java:1143)
      	at org.apache.calcite.rex.RexCallBinding.getOperandLiteralValue(RexCallBinding.java:100)
      	at org.apache.calcite.sql.fun.SqlTimestampDiffFunction.inferReturnType2(SqlTimestampDiffFunction.java:69)
      	at org.apache.calcite.sql.SqlOperator.inferReturnType(SqlOperator.java:537)
      	at org.apache.calcite.rex.RexBuilder.deriveReturnType(RexBuilder.java:292)
      	at org.apache.calcite.rex.RexBuilder.makeCall(RexBuilder.java:266)
      	at org.apache.calcite.rex.RexBuilderTest.testTimestampDiffCall(RexBuilderTest.java:863)
      ...
      

      It seems it recognise FLAG(QUARTER) as a literal...
      at org.apache.calcite.sql.fun.SqlTimestampDiffFunction#inferReturnType2

          if (opBinding.isOperandLiteral(0, true)) {
            type1 = opBinding.getOperandType(0);
            type2 = opBinding.getOperandType(1);
            timeUnit = opBinding.getOperandLiteralValue(2, TimeUnit.class);
          } else {
            timeUnit = opBinding.getOperandLiteralValue(0, TimeUnit.class);
            type1 = opBinding.getOperandType(1);
            type2 = opBinding.getOperandType(2);
          }
      

      Attachments

        Issue Links

          Activity

            People

              tanclary Tanner Clary
              Sergey Nuyanzin Sergey Nuyanzin
              Votes:
              0 Vote for this issue
              Watchers:
              7 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Time Tracking

                  Estimated:
                  Original Estimate - Not Specified
                  Not Specified
                  Remaining:
                  Remaining Estimate - 0h
                  0h
                  Logged:
                  Time Spent - 1h 40m
                  1h 40m