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

CompositeOperandTypeChecker should check operands without type coercion first

    XMLWordPrintableJSON

Details

    Description

      If define an operator with the following type checker:

      SqlSingleOperandTypeChecker operandTypeChecker = OperandTypes.or(
              OperandTypes.family(SqlTypeFamily.STRING, SqlTypeFamily.STRING)
                  .and(OperandTypes.SAME_SAME),
              OperandTypes.family(SqlTypeFamily.INTEGER, SqlTypeFamily.INTEGER)
                  .and(OperandTypes.SAME_SAME));
      

      and pass two operands with INTEGER type to this type checker. Then they will be wrapped into CAST operator which will cast them to VARCHAR. But they shouldn't be casted to VARCHAR.

      Testcase:

      @Test void testCompositeOperandTypeWithoutCast() {
          SqlValidator validator = SqlTestFactory.INSTANCE.createValidator();
      
          SqlSingleOperandTypeChecker operandTypeChecker = OperandTypes.or(
              OperandTypes.family(SqlTypeFamily.STRING, SqlTypeFamily.STRING)
                  .and(OperandTypes.SAME_SAME),
              OperandTypes.family(SqlTypeFamily.INTEGER, SqlTypeFamily.INTEGER)
                  .and(OperandTypes.SAME_SAME));
      
          SqlBinaryOperator op = new SqlBinaryOperator(
              "~",
              SqlKind.OTHER,
              60,
              true,
              null,
              null,
              null);
      
          List<SqlLiteral> args = ImmutableList.of(
              SqlLiteral.createExactNumeric("20", SqlParserPos.ZERO),
              SqlLiteral.createExactNumeric("30", SqlParserPos.ZERO));
      
          SqlCallBinding binding = new SqlCallBinding(
              validator,
              new EmptyScope((SqlValidatorImpl) validator),
              new SqlBasicCall(op, args, SqlParserPos.ZERO));
          List<RelDataType> typesBeforeChecking =
              ImmutableList.of(binding.getOperandType(0), binding.getOperandType(1));
      
          operandTypeChecker.checkOperandTypes(binding, false);
      
          # It fails
          assertEquals(typesBeforeChecking.get(0), binding.getOperandType(0));
          assertEquals(typesBeforeChecking.get(1), binding.getOperandType(1));
        }
      

       

      Attachments

        Issue Links

          Activity

            People

              dmsysolyatin Dmitry Sysolyatin
              dmsysolyatin Dmitry Sysolyatin
              Votes:
              0 Vote for this issue
              Watchers:
              5 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 - 10m
                  10m