Java Code Examples for org.apache.calcite.rex.RexUtil#isCasePredicate()

The following examples show how to use org.apache.calcite.rex.RexUtil#isCasePredicate() . 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: Strong.java    From Bats with Apache License 2.0 5 votes vote down vote up
/** Returns whether an expression is definitely null.
 *
 * <p>The answer is based on calls to {@link #isNull} for its constituent
 * expressions, and you may override methods to test hypotheses such as
 * "if {@code x} is null, is {@code x + y} null? */
public boolean isNull(RexNode node) {
  final Policy policy = policy(node.getKind());
  switch (policy) {
  case NOT_NULL:
    return false;
  case ANY:
    return anyNull(((RexCall) node).getOperands());
  default:
    break;
  }

  switch (node.getKind()) {
  case LITERAL:
    return ((RexLiteral) node).isNull();
  // We can only guarantee AND to return NULL if both inputs are NULL  (similar for OR)
  // AND(NULL, FALSE) = FALSE
  case AND:
  case OR:
  case COALESCE:
    return allNull(((RexCall) node).getOperands());
  case NULLIF:
    // NULLIF(null, X) where X can be NULL, returns NULL
    // NULLIF(X, Y) where X is not NULL, then this may return NULL if X = Y, otherwise X.
    return allNull(ImmutableList.of(((RexCall) node).getOperands().get(0)));
  case INPUT_REF:
    return isNull((RexInputRef) node);
  case CASE:
    final RexCall caseCall = (RexCall) node;
    final List<RexNode> caseValues = new ArrayList<>();
    for (int i = 0; i < caseCall.getOperands().size(); i++) {
      if (!RexUtil.isCasePredicate(caseCall, i)) {
        caseValues.add(caseCall.getOperands().get(i));
      }
    }
    return allNull(caseValues);
  default:
    return false;
  }
}
 
Example 2
Source File: Strong.java    From calcite with Apache License 2.0 5 votes vote down vote up
/** Returns whether an expression is definitely null.
 *
 * <p>The answer is based on calls to {@link #isNull} for its constituent
 * expressions, and you may override methods to test hypotheses such as
 * "if {@code x} is null, is {@code x + y} null? */
public boolean isNull(RexNode node) {
  final Policy policy = policy(node.getKind());
  switch (policy) {
  case NOT_NULL:
    return false;
  case ANY:
    return anyNull(((RexCall) node).getOperands());
  default:
    break;
  }

  switch (node.getKind()) {
  case LITERAL:
    return ((RexLiteral) node).isNull();
  // We can only guarantee AND to return NULL if both inputs are NULL  (similar for OR)
  // AND(NULL, FALSE) = FALSE
  case AND:
  case OR:
  case COALESCE:
    return allNull(((RexCall) node).getOperands());
  case NULLIF:
    // NULLIF(null, X) where X can be NULL, returns NULL
    // NULLIF(X, Y) where X is not NULL, then this may return NULL if X = Y, otherwise X.
    return allNull(ImmutableList.of(((RexCall) node).getOperands().get(0)));
  case INPUT_REF:
    return isNull((RexInputRef) node);
  case CASE:
    final RexCall caseCall = (RexCall) node;
    final List<RexNode> caseValues = new ArrayList<>();
    for (int i = 0; i < caseCall.getOperands().size(); i++) {
      if (!RexUtil.isCasePredicate(caseCall, i)) {
        caseValues.add(caseCall.getOperands().get(i));
      }
    }
    return allNull(caseValues);
  default:
    return false;
  }
}
 
Example 3
Source File: ReduceExpressionsRule.java    From Bats 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);
    switch (operand.getKind()) {
    case 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 4
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);
}