Java Code Examples for org.apache.calcite.sql.type.SqlTypeName#BOOLEAN

The following examples show how to use org.apache.calcite.sql.type.SqlTypeName#BOOLEAN . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: RexToTestCodeShuttle.java    From calcite with Apache License 2.0 6 votes vote down vote up
@Override public String visitLiteral(RexLiteral literal) {
  RelDataType type = literal.getType();

  if (type.getSqlTypeName() == SqlTypeName.BOOLEAN) {
    if (literal.isNull()) {
      return "nullBool";
    }
    return literal.toString() + "Literal";
  }
  if (type.getSqlTypeName() == SqlTypeName.INTEGER) {
    if (literal.isNull()) {
      return "nullInt";
    }
    return "literal(" + literal.getValue() + ")";
  }
  if (type.getSqlTypeName() == SqlTypeName.VARCHAR) {
    if (literal.isNull()) {
      return "nullVarchar";
    }
  }
  return "/*" + literal.getTypeName().getName() + "*/" + literal.toString();
}
 
Example 2
Source File: JoinRelBase.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
@Override public boolean isValid(Litmus litmus, Context context) {
  if (condition != null) {
    if (condition.getType().getSqlTypeName() != SqlTypeName.BOOLEAN) {
      return litmus.fail("condition must be boolean: {}",
        condition.getType());
    }
    // The input to the condition is a row type consisting of system
    // fields, left fields, and right fields. Very similar to the
    // output row type, except that fields have not yet been made due
    // due to outer joins.
    RexChecker checker =
      new RexChecker(
        getCluster().getTypeFactory().builder()
          .addAll(getSystemFieldList())
          .addAll(getLeft().getRowType().getFieldList())
          .addAll(getRight().getRowType().getFieldList())
          .build(),
        context, litmus);
    condition.accept(checker);
    if (checker.getFailureCount() > 0) {
      return litmus.fail(checker.getFailureCount()
        + " failures in condition " + condition);
    }
  }
  return litmus.succeed();
}
 
Example 3
Source File: JoinRel.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
@Override public boolean isValid(Litmus litmus, Context context) {
  if (condition != null) {
    if (condition.getType().getSqlTypeName() != SqlTypeName.BOOLEAN) {
      return litmus.fail("condition must be boolean: {}",
        condition.getType());
    }

    RexChecker checker =
      new RexChecker(
        getCluster().getTypeFactory().builder()
          .addAll(getSystemFieldList())
          .addAll(getLeft().getRowType().getFieldList())
          .addAll(getRight().getRowType().getFieldList())
          .build(),
        context, litmus);
    condition.accept(checker);
    if (checker.getFailureCount() > 0) {
      return litmus.fail(checker.getFailureCount()
        + " failures in condition " + condition);
    }
  }
  return litmus.succeed();
}
 
Example 4
Source File: Join.java    From Bats with Apache License 2.0 5 votes vote down vote up
@Override public boolean isValid(Litmus litmus, Context context) {
  if (!super.isValid(litmus, context)) {
    return false;
  }
  if (getRowType().getFieldCount()
      != getSystemFieldList().size()
      + left.getRowType().getFieldCount()
      + (this instanceof SemiJoin ? 0 : right.getRowType().getFieldCount())) {
    return litmus.fail("field count mismatch");
  }
  if (condition != null) {
    if (condition.getType().getSqlTypeName() != SqlTypeName.BOOLEAN) {
      return litmus.fail("condition must be boolean: {}",
          condition.getType());
    }
    // The input to the condition is a row type consisting of system
    // fields, left fields, and right fields. Very similar to the
    // output row type, except that fields have not yet been made due
    // due to outer joins.
    RexChecker checker =
        new RexChecker(
            getCluster().getTypeFactory().builder()
                .addAll(getSystemFieldList())
                .addAll(getLeft().getRowType().getFieldList())
                .addAll(getRight().getRowType().getFieldList())
                .build(),
            context, litmus);
    condition.accept(checker);
    if (checker.getFailureCount() > 0) {
      return litmus.fail(checker.getFailureCount()
          + " failures in condition " + condition);
    }
  }
  return litmus.succeed();
}
 
Example 5
Source File: SqlLiteral.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a boolean literal.
 */
public static SqlLiteral createBoolean(
    boolean b,
    SqlParserPos pos) {
  return b ? new SqlLiteral(Boolean.TRUE, SqlTypeName.BOOLEAN, pos)
      : new SqlLiteral(Boolean.FALSE, SqlTypeName.BOOLEAN, pos);
}
 
Example 6
Source File: RexBuilderTest.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Test RexBuilder.ensureType()
 */
@Test void testEnsureTypeWithDifference() {
  final RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
  RexBuilder builder = new RexBuilder(typeFactory);

  RexNode node =  new RexLiteral(
          Boolean.TRUE, typeFactory.createSqlType(SqlTypeName.BOOLEAN), SqlTypeName.BOOLEAN);
  RexNode ensuredNode = builder.ensureType(
          typeFactory.createSqlType(SqlTypeName.INTEGER), node, true);

  assertNotEquals(node, ensuredNode);
  assertEquals(ensuredNode.getType(), typeFactory.createSqlType(SqlTypeName.INTEGER));
}
 
Example 7
Source File: Join.java    From calcite with Apache License 2.0 5 votes vote down vote up
@Override public boolean isValid(Litmus litmus, Context context) {
  if (!super.isValid(litmus, context)) {
    return false;
  }
  if (getRowType().getFieldCount()
      != getSystemFieldList().size()
      + left.getRowType().getFieldCount()
      + (joinType.projectsRight() ? right.getRowType().getFieldCount() : 0)) {
    return litmus.fail("field count mismatch");
  }
  if (condition != null) {
    if (condition.getType().getSqlTypeName() != SqlTypeName.BOOLEAN) {
      return litmus.fail("condition must be boolean: {}",
          condition.getType());
    }
    // The input to the condition is a row type consisting of system
    // fields, left fields, and right fields. Very similar to the
    // output row type, except that fields have not yet been made due
    // due to outer joins.
    RexChecker checker =
        new RexChecker(
            getCluster().getTypeFactory().builder()
                .addAll(getSystemFieldList())
                .addAll(getLeft().getRowType().getFieldList())
                .addAll(getRight().getRowType().getFieldList())
                .build(),
            context, litmus);
    condition.accept(checker);
    if (checker.getFailureCount() > 0) {
      return litmus.fail(checker.getFailureCount()
          + " failures in condition " + condition);
    }
  }
  return litmus.succeed();
}
 
Example 8
Source File: RexLiteralImpl.java    From Bats with Apache License 2.0 5 votes vote down vote up
@Override
public boolean isAlwaysFalse() {
    if (typeName != SqlTypeName.BOOLEAN) {
        return false;
    }
    return !RexLiteral.booleanValue(this);
}
 
Example 9
Source File: JoinPrel.java    From Bats with Apache License 2.0 5 votes vote down vote up
@Override public boolean isValid(Litmus litmus, Context context) {
  if (!this.isSemiJoin && !super.isValid(litmus, context)) {
    return false;
  }
  if (getRowType().getFieldCount()
          != getSystemFieldList().size()
          + left.getRowType().getFieldCount()
          + (this.isSemiJoin ? 0 : right.getRowType().getFieldCount())) {
    return litmus.fail("field count mismatch");
  }
  if (condition != null) {
    if (condition.getType().getSqlTypeName() != SqlTypeName.BOOLEAN) {
      return litmus.fail("condition must be boolean: {}",
              condition.getType());
    }
    // The input to the condition is a row type consisting of system
    // fields, left fields, and right fields. Very similar to the
    // output row type, except that fields have not yet been made due
    // due to outer joins.
    RexChecker checker =
            new RexChecker(
                    getCluster().getTypeFactory().builder()
                            .addAll(getSystemFieldList())
                            .addAll(getLeft().getRowType().getFieldList())
                            .addAll(getRight().getRowType().getFieldList())
                            .build(),
                    context, litmus);
    condition.accept(checker);
    if (checker.getFailureCount() > 0) {
      return litmus.fail(checker.getFailureCount()
              + " failures in condition " + condition);
    }
  }
  return litmus.succeed();
}
 
Example 10
Source File: SqlLiteral.java    From calcite with Apache License 2.0 4 votes vote down vote up
public static SqlLiteral createUnknown(SqlParserPos pos) {
  return new SqlLiteral(null, SqlTypeName.BOOLEAN, pos);
}
 
Example 11
Source File: RexLiteral.java    From calcite with Apache License 2.0 4 votes vote down vote up
/**
 * Computes if data type can be omitted from the digset.
 * <p>For instance, {@code 1:BIGINT} has to keep data type while {@code 1:INT}
 * should be represented as just {@code 1}.
 *
 * <p>Implementation assumption: this method should be fast. In fact might call
 * {@link NlsString#getValue()} which could decode the string, however we rely on the cache there.
 *
 * @see RexLiteral#computeDigest(RexDigestIncludeType)
 * @param value value of the literal
 * @param type type of the literal
 * @return NO_TYPE when type can be omitted, ALWAYS otherwise
 */
private static RexDigestIncludeType shouldIncludeType(Comparable value, RelDataType type) {
  if (type.isNullable()) {
    // This means "null literal", so we require a type for it
    // There might be exceptions like AND(null, true) which are handled by RexCall#computeDigest
    return RexDigestIncludeType.ALWAYS;
  }
  // The variable here simplifies debugging (one can set a breakpoint at return)
  // final ensures we set the value in all the branches, and it ensures the value is set just once
  final RexDigestIncludeType includeType;
  if (type.getSqlTypeName() == SqlTypeName.BOOLEAN
      || type.getSqlTypeName() == SqlTypeName.INTEGER
      || type.getSqlTypeName() == SqlTypeName.SYMBOL) {
    // We don't want false:BOOLEAN NOT NULL, so we don't print type information for
    // non-nullable BOOLEAN and INTEGER
    includeType = RexDigestIncludeType.NO_TYPE;
  } else if (type.getSqlTypeName() == SqlTypeName.CHAR
          && value instanceof NlsString) {
    NlsString nlsString = (NlsString) value;

    // Ignore type information for 'Bar':CHAR(3)
    if ((
        (nlsString.getCharset() != null && type.getCharset().equals(nlsString.getCharset()))
        || (nlsString.getCharset() == null
        && SqlCollation.IMPLICIT.getCharset().equals(type.getCharset())))
        && nlsString.getCollation().equals(type.getCollation())
        && ((NlsString) value).getValue().length() == type.getPrecision()) {
      includeType = RexDigestIncludeType.NO_TYPE;
    } else {
      includeType = RexDigestIncludeType.ALWAYS;
    }
  } else if (type.getPrecision() == 0 && (
             type.getSqlTypeName() == SqlTypeName.TIME
          || type.getSqlTypeName() == SqlTypeName.TIMESTAMP
          || type.getSqlTypeName() == SqlTypeName.DATE)) {
    // Ignore type information for '12:23:20':TIME(0)
    // Note that '12:23:20':TIME WITH LOCAL TIME ZONE
    includeType = RexDigestIncludeType.NO_TYPE;
  } else {
    includeType = RexDigestIncludeType.ALWAYS;
  }
  return includeType;
}
 
Example 12
Source File: TypeInferenceUtils.java    From dremio-oss with Apache License 2.0 4 votes vote down vote up
@Override
public RelDataType inferReturnType(SqlOperatorBinding opBinding) {
  final RelDataTypeFactory factory = opBinding.getTypeFactory();
  SqlTypeName typeToCastTo = null;
  if (opBinding instanceof SqlCallBinding) {
    SqlCallBinding sqlCallBinding = (SqlCallBinding) opBinding;
    if (sqlCallBinding.operand(1).getKind() == SqlKind.LITERAL) {
      String type = null;
      try {
        SqlLiteral sqlLiteral = (SqlLiteral) sqlCallBinding.operand(1);
        type = ((NlsString) sqlLiteral.getValue()).getValue();
        switch(type) {
          case "JSON":
            typeToCastTo = SqlTypeName.ANY;
            break;
          case "UTF8":
          case "UTF16":
            typeToCastTo = SqlTypeName.VARCHAR;
            break;
          case "BOOLEAN_BYTE":
            typeToCastTo = SqlTypeName.BOOLEAN;
            break;
          case "TINYINT_BE":
          case "TINYINT":
            typeToCastTo = SqlTypeName.TINYINT;
            break;
          case "SMALLINT_BE":
          case "SMALLINT":
            typeToCastTo = SqlTypeName.SMALLINT;
            break;
          case "INT_BE":
          case "INT":
          case "INT_HADOOPV":
            typeToCastTo = SqlTypeName.INTEGER;
            break;
          case "BIGINT_BE":
          case "BIGINT":
          case "BIGINT_HADOOPV":
            typeToCastTo = SqlTypeName.BIGINT;
            break;
          case "FLOAT":
            typeToCastTo = SqlTypeName.FLOAT;
            break;
          case "DOUBLE":
            typeToCastTo = SqlTypeName.DOUBLE;
            break;
          case "DATE_EPOCH_BE":
          case "DATE_EPOCH":
            typeToCastTo = SqlTypeName.DATE;
            break;
          case "TIME_EPOCH_BE":
          case "TIME_EPOCH":
            typeToCastTo = SqlTypeName.TIME;
            break;
          case "TIMESTAMP_EPOCH":
          case "TIMESTAMP_IMPALA":
            typeToCastTo = SqlTypeName.TIMESTAMP;
            break;
          default:
            typeToCastTo = SqlTypeName.ANY;
            break;
        }
      } catch (final ClassCastException e) {
        logger.debug("Failed to parse string for convert_from()");
      }
    }
  }

  if (typeToCastTo == null) {
    typeToCastTo = SqlTypeName.ANY;
  }
  return factory.createTypeWithNullability(
      factory.createSqlType(typeToCastTo),
      true);
}
 
Example 13
Source File: EqualityConvertlet.java    From dremio-oss with Apache License 2.0 4 votes vote down vote up
private static RexNode convertEquality(SqlRexContext cx, SqlCall call) {

    final List<SqlNode> operands = call.getOperandList();
    final RexBuilder rexBuilder = cx.getRexBuilder();
    final List<RexNode> exprs =
      convertExpressionList(cx, operands);
    SqlOperator op = call.getOperator();
    RelDataType type = rexBuilder.deriveReturnType(op, exprs);
    RexCall convertedCall = (RexCall) rexBuilder.makeCall(type, op, RexUtil.flatten(exprs, op));

    // The following is copied from Calcite's StdConvertletTable.convertEqualsOrNotEquals()
    final RexNode op0 = convertedCall.getOperands().get(0);
    final RexNode op1 = convertedCall.getOperands().get(1);
    final RexNode booleanOp;
    final RexNode integerOp;

    if (op0.getType().getSqlTypeName() == SqlTypeName.BOOLEAN
      && SqlTypeName.INT_TYPES.contains(op1.getType().getSqlTypeName())) {
      booleanOp = op0;
      integerOp = op1;
    } else if (SqlTypeName.INT_TYPES.contains(op0.getType().getSqlTypeName())
      && op1.getType().getSqlTypeName() == SqlTypeName.BOOLEAN) {
      booleanOp = op1;
      integerOp = op0;
    } else {
      return convertedCall;
    }

    SqlOperator newOp = (op.getKind() == SqlKind.EQUALS || op.getKind() == SqlKind.NOT_EQUALS) ?
      SqlStdOperatorTable.EQUALS :
      SqlStdOperatorTable.IS_NOT_DISTINCT_FROM;

    return rexBuilder.makeCall(call.getOperator(),
      booleanOp,
      rexBuilder.makeCall(
        SqlStdOperatorTable.CASE,
        rexBuilder.makeCall(
          newOp,
          integerOp,
          rexBuilder.makeZeroLiteral(integerOp.getType())),
        rexBuilder.makeLiteral(false),
        rexBuilder.makeLiteral(true)));
  }
 
Example 14
Source File: RexCall.java    From calcite with Apache License 2.0 4 votes vote down vote up
/**
 * Appends call operands without parenthesis.
 * {@link RexLiteral} might omit data type depending on the context.
 * For instance, {@code null:BOOLEAN} vs {@code =(true, null)}.
 * The idea here is to omit "obvious" types for readability purposes while
 * still maintain {@link RelNode#getDigest()} contract.
 *
 * @see RexLiteral#computeDigest(RexDigestIncludeType)
 * @param sb destination
 */
protected final void appendOperands(StringBuilder sb) {
  if (operands.isEmpty()) {
    return;
  }
  List<String> operandDigests = new ArrayList<>(operands.size());
  for (int i = 0; i < operands.size(); i++) {
    RexNode operand = operands.get(i);
    if (!(operand instanceof RexLiteral)) {
      operandDigests.add(operand.toString());
      continue;
    }
    // Type information might be omitted in certain cases to improve readability
    // For instance, AND/OR arguments should be BOOLEAN, so
    // AND(true, null) is better than AND(true, null:BOOLEAN), and we keep the same info.

    // +($0, 2) is better than +($0, 2:BIGINT). Note: if $0 is BIGINT, then 2 is expected to be
    // of BIGINT type as well.
    RexDigestIncludeType includeType = RexDigestIncludeType.OPTIONAL;
    if ((isA(SqlKind.AND) || isA(SqlKind.OR))
        && operand.getType().getSqlTypeName() == SqlTypeName.BOOLEAN) {
      includeType = RexDigestIncludeType.NO_TYPE;
    }
    if (SqlKind.SIMPLE_BINARY_OPS.contains(getKind())) {
      RexNode otherArg = operands.get(1 - i);
      if ((!(otherArg instanceof RexLiteral)
          || ((RexLiteral) otherArg).digestIncludesType() == RexDigestIncludeType.NO_TYPE)
          && equalSansNullability(operand.getType(), otherArg.getType())) {
        includeType = RexDigestIncludeType.NO_TYPE;
      }
    }
    operandDigests.add(((RexLiteral) operand).computeDigest(includeType));
  }
  int totalLength = (operandDigests.size() - 1) * 2; // commas
  for (String s : operandDigests) {
    totalLength += s.length();
  }
  sb.ensureCapacity(sb.length() + totalLength);
  for (int i = 0; i < operandDigests.size(); i++) {
    String op = operandDigests.get(i);
    if (i != 0) {
      sb.append(", ");
    }
    sb.append(op);
  }
}
 
Example 15
Source File: DruidExpressions.java    From calcite with Apache License 2.0 4 votes vote down vote up
/**
 * Translates Calcite rexNode to Druid Expression when possible
 * @param rexNode rexNode to convert to a Druid Expression
 * @param inputRowType input row type of the rexNode to translate
 * @param druidRel Druid query
 *
 * @return Druid Expression or null when can not convert the RexNode
 */
@Nullable
public static String toDruidExpression(
    final RexNode rexNode,
    final RelDataType inputRowType,
    final DruidQuery druidRel) {
  SqlKind kind = rexNode.getKind();
  SqlTypeName sqlTypeName = rexNode.getType().getSqlTypeName();

  if (kind == SqlKind.INPUT_REF) {
    final RexInputRef ref = (RexInputRef) rexNode;
    final String columnName = inputRowType.getFieldNames().get(ref.getIndex());
    if (columnName == null) {
      return null;
    }
    if (druidRel.getDruidTable().timestampFieldName.equals(columnName)) {
      return DruidExpressions.fromColumn(DruidTable.DEFAULT_TIMESTAMP_COLUMN);
    }
    return DruidExpressions.fromColumn(columnName);
  }

  if (rexNode instanceof RexCall) {
    final SqlOperator operator = ((RexCall) rexNode).getOperator();
    final DruidSqlOperatorConverter conversion = druidRel.getOperatorConversionMap()
        .get(operator);
    if (conversion == null) {
      //unknown operator can not translate
      return null;
    } else {
      return conversion.toDruidExpression(rexNode, inputRowType, druidRel);
    }
  }
  if (kind == SqlKind.LITERAL) {
    // Translate literal.
    if (RexLiteral.isNullLiteral(rexNode)) {
      //case the filter/project might yield to unknown let Calcite deal with this for now
      return null;
    } else if (SqlTypeName.NUMERIC_TYPES.contains(sqlTypeName)) {
      return DruidExpressions.numberLiteral((Number) RexLiteral
          .value(rexNode));
    } else if (SqlTypeFamily.INTERVAL_DAY_TIME == sqlTypeName.getFamily()) {
      // Calcite represents DAY-TIME intervals in milliseconds.
      final long milliseconds = ((Number) RexLiteral.value(rexNode)).longValue();
      return DruidExpressions.numberLiteral(milliseconds);
    } else if (SqlTypeFamily.INTERVAL_YEAR_MONTH == sqlTypeName.getFamily()) {
      // Calcite represents YEAR-MONTH intervals in months.
      final long months = ((Number) RexLiteral.value(rexNode)).longValue();
      return DruidExpressions.numberLiteral(months);
    } else if (SqlTypeName.STRING_TYPES.contains(sqlTypeName)) {
      return
          DruidExpressions.stringLiteral(RexLiteral.stringValue(rexNode));
    } else if (SqlTypeName.DATE == sqlTypeName
        || SqlTypeName.TIMESTAMP == sqlTypeName
        || SqlTypeName.TIME_WITH_LOCAL_TIME_ZONE == sqlTypeName) {
      return DruidExpressions.numberLiteral(
          DruidDateTimeUtils.literalValue(rexNode));
    } else if (SqlTypeName.BOOLEAN == sqlTypeName) {
      return DruidExpressions.numberLiteral(RexLiteral.booleanValue(rexNode) ? 1 : 0);
    }
  }
  // Not Literal/InputRef/RexCall or unknown type?
  return null;
}
 
Example 16
Source File: RexSimplify.java    From calcite with Apache License 2.0 4 votes vote down vote up
private void verify(RexNode before, RexNode simplified, RexUnknownAs unknownAs) {
  if (simplified.isAlwaysFalse()
      && before.isAlwaysTrue()) {
    throw new AssertionError("always true [" + before
        + "] simplified to always false [" + simplified  + "]");
  }
  if (simplified.isAlwaysTrue()
      && before.isAlwaysFalse()) {
    throw new AssertionError("always false [" + before
        + "] simplified to always true [" + simplified  + "]");
  }
  final RexAnalyzer foo0 = new RexAnalyzer(before, predicates);
  final RexAnalyzer foo1 = new RexAnalyzer(simplified, predicates);
  if (foo0.unsupportedCount > 0 || foo1.unsupportedCount > 0) {
    // Analyzer cannot handle this expression currently
    return;
  }
  if (!foo0.variables.containsAll(foo1.variables)) {
    throw new AssertionError("variable mismatch: "
        + before + " has " + foo0.variables + ", "
        + simplified + " has " + foo1.variables);
  }
  assignment_loop:
  for (Map<RexNode, Comparable> map : foo0.assignments()) {
    for (RexNode predicate : predicates.pulledUpPredicates) {
      final Comparable v = RexInterpreter.evaluate(predicate, map);
      if (!v.equals(true)) {
        continue assignment_loop;
      }
    }
    Comparable v0 = RexInterpreter.evaluate(foo0.e, map);
    if (v0 == null) {
      throw new AssertionError("interpreter returned null for " + foo0.e);
    }
    Comparable v1 = RexInterpreter.evaluate(foo1.e, map);
    if (v1 == null) {
      throw new AssertionError("interpreter returned null for " + foo1.e);
    }
    if (before.getType().getSqlTypeName() == SqlTypeName.BOOLEAN) {
      switch (unknownAs) {
      case FALSE:
      case TRUE:
        if (v0 == NullSentinel.INSTANCE) {
          v0 = unknownAs.toBoolean();
        }
        if (v1 == NullSentinel.INSTANCE) {
          v1 = unknownAs.toBoolean();
        }
      }
    }
    if (!v0.equals(v1)) {
      throw new AssertionError("result mismatch: when applied to " + map
          + ", " + before + " yielded " + v0
          + ", and " + simplified + " yielded " + v1);
    }
  }
}
 
Example 17
Source File: Aggregate.java    From calcite with Apache License 2.0 4 votes vote down vote up
private boolean isPredicate(RelNode input, int index) {
  final RelDataType type =
      input.getRowType().getFieldList().get(index).getType();
  return type.getSqlTypeName() == SqlTypeName.BOOLEAN
      && !type.isNullable();
}
 
Example 18
Source File: RexSimplify.java    From Bats with Apache License 2.0 4 votes vote down vote up
private void verify(RexNode before, RexNode simplified, RexUnknownAs unknownAs) {
    if (simplified.isAlwaysFalse() && before.isAlwaysTrue()) {
        throw new AssertionError("always true [" + before + "] simplified to always false [" + simplified + "]");
    }
    if (simplified.isAlwaysTrue() && before.isAlwaysFalse()) {
        throw new AssertionError("always false [" + before + "] simplified to always true [" + simplified + "]");
    }
    final RexAnalyzer foo0 = new RexAnalyzer(before, predicates);
    final RexAnalyzer foo1 = new RexAnalyzer(simplified, predicates);
    if (foo0.unsupportedCount > 0 || foo1.unsupportedCount > 0) {
        // Analyzer cannot handle this expression currently
        return;
    }
    if (!foo0.variables.containsAll(foo1.variables)) {
        throw new AssertionError("variable mismatch: " + before + " has " + foo0.variables + ", " + simplified
                + " has " + foo1.variables);
    }
    assignment_loop: for (Map<RexNode, Comparable> map : foo0.assignments()) {
        for (RexNode predicate : predicates.pulledUpPredicates) {
            final Comparable v = RexInterpreter.evaluate(predicate, map);
            if (!v.equals(true)) {
                continue assignment_loop;
            }
        }
        Comparable v0 = RexInterpreter.evaluate(foo0.e, map);
        if (v0 == null) {
            throw new AssertionError("interpreter returned null for " + foo0.e);
        }
        Comparable v1 = RexInterpreter.evaluate(foo1.e, map);
        if (v1 == null) {
            throw new AssertionError("interpreter returned null for " + foo1.e);
        }
        if (before.getType().getSqlTypeName() == SqlTypeName.BOOLEAN) {
            switch (unknownAs) {
            case FALSE:
            case TRUE:
                if (v0 == NullSentinel.INSTANCE) {
                    v0 = unknownAs.toBoolean();
                }
                if (v1 == NullSentinel.INSTANCE) {
                    v1 = unknownAs.toBoolean();
                }
            }
        }
        if (!v0.equals(v1)) {
            throw new AssertionError("result mismatch: when applied to " + map + ", " + before + " yielded " + v0
                    + ", and " + simplified + " yielded " + v1);
        }
    }
}
 
Example 19
Source File: ReduceExpressionsRule.java    From calcite with Apache License 2.0 4 votes vote down vote up
/** Pushes predicates into a CASE.
 *
 * <p>We have a loose definition of 'predicate': any boolean expression will
 * do, except CASE. For example '(CASE ...) = 5' or '(CASE ...) IS NULL'.
 */
public static RexCall pushPredicateIntoCase(RexCall call) {
  if (call.getType().getSqlTypeName() != SqlTypeName.BOOLEAN) {
    return call;
  }
  switch (call.getKind()) {
  case CASE:
  case AND:
  case OR:
    return call; // don't push CASE into CASE!
  case EQUALS: {
    // checks that the EQUALS operands may be splitted and
    // doesn't push EQUALS into CASE
    List<RexNode> equalsOperands = call.getOperands();
    ImmutableBitSet left = RelOptUtil.InputFinder.bits(equalsOperands.get(0));
    ImmutableBitSet right = RelOptUtil.InputFinder.bits(equalsOperands.get(1));
    if (!left.isEmpty() && !right.isEmpty() && left.intersect(right).isEmpty()) {
      return call;
    }
  }
  }
  int caseOrdinal = -1;
  final List<RexNode> operands = call.getOperands();
  for (int i = 0; i < operands.size(); i++) {
    RexNode operand = operands.get(i);
    if (operand.getKind() == SqlKind.CASE) {
      caseOrdinal = i;
    }
  }
  if (caseOrdinal < 0) {
    return call;
  }
  // Convert
  //   f(CASE WHEN p1 THEN v1 ... END, arg)
  // to
  //   CASE WHEN p1 THEN f(v1, arg) ... END
  final RexCall case_ = (RexCall) operands.get(caseOrdinal);
  final List<RexNode> nodes = new ArrayList<>();
  for (int i = 0; i < case_.getOperands().size(); i++) {
    RexNode node = case_.getOperands().get(i);
    if (!RexUtil.isCasePredicate(case_, i)) {
      node = substitute(call, caseOrdinal, node);
    }
    nodes.add(node);
  }
  return case_.clone(call.getType(), nodes);
}
 
Example 20
Source File: Aggregate.java    From Bats with Apache License 2.0 4 votes vote down vote up
private boolean isPredicate(RelNode input, int index) {
  final RelDataType type =
      input.getRowType().getFieldList().get(index).getType();
  return type.getSqlTypeName() == SqlTypeName.BOOLEAN
      && !type.isNullable();
}