Java Code Examples for org.apache.calcite.rex.RexCall#clone()

The following examples show how to use org.apache.calcite.rex.RexCall#clone() . 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: JoinCommuteRule.java    From Bats with Apache License 2.0 6 votes vote down vote up
public RexNode go(RexNode rex) {
    if (rex instanceof RexCall) {
        ImmutableList.Builder<RexNode> builder = ImmutableList.builder();
        final RexCall call = (RexCall) rex;
        for (RexNode operand : call.getOperands()) {
            builder.add(go(operand));
        }
        return call.clone(call.getType(), builder.build());
    } else if (rex instanceof RexInputRef) {
        RexInputRef var = (RexInputRef) rex;
        int index = var.getIndex();
        if (index < leftFields.size()) {
            // Field came from left side of join. Move it to the right.
            return rexBuilder.makeInputRef(leftFields.get(index).getType(), rightFields.size() + index);
        }
        index -= leftFields.size();
        if (index < rightFields.size()) {
            // Field came from right side of join. Move it to the left.
            return rexBuilder.makeInputRef(rightFields.get(index).getType(), index);
        }
        throw new AssertionError("Bad field offset: index=" + var.getIndex() + ", leftFieldCount="
                + leftFields.size() + ", rightFieldCount=" + rightFields.size());
    } else {
        return rex;
    }
}
 
Example 2
Source File: RexVisitorComplexExprSplitter.java    From Bats with Apache License 2.0 6 votes vote down vote up
@Override
public RexNode visitCall(RexCall call) {

    String functionName = call.getOperator().getName();

    List<RexNode> newOps = new ArrayList<>();
    for (RexNode operand : call.getOperands()) {
        newOps.add(operand.accept(this));
    }
    if (funcReg.isFunctionComplexOutput(functionName)) {
        RexBuilder builder = new RexBuilder(factory);
        RexNode ret = builder.makeInputRef(new RelDataTypeDrillImpl(new RelDataTypeHolder(), factory),
                lastUsedIndex);
        lastUsedIndex++;
        complexExprs.add(call.clone(new RelDataTypeDrillImpl(new RelDataTypeHolder(), factory), newOps));
        return ret;
    }
    return call.clone(call.getType(), newOps);
}
 
Example 3
Source File: DrillRelOptUtil.java    From Bats with Apache License 2.0 6 votes vote down vote up
public RexNode go(RexNode rex) {
    if (rex instanceof RexCall) {
        ImmutableList.Builder<RexNode> builder = ImmutableList.builder();
        final RexCall call = (RexCall) rex;
        for (RexNode operand : call.getOperands()) {
            builder.add(go(operand));
        }
        return call.clone(call.getType(), builder.build());
    } else if (rex instanceof RexInputRef) {
        RexInputRef var = (RexInputRef) rex;
        int index = var.getIndex();
        return rexBuilder.makeInputRef(var.getType(), inputRefMap.get(index));
    } else {
        return rex;
    }
}
 
Example 4
Source File: RexVisitorComplexExprSplitter.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
@Override
public RexNode visitCall(RexCall call) {

  String functionName = call.getOperator().getName();

  List<RexNode> newOps = new ArrayList<>();
  for (RexNode operand : call.operands) {
    newOps.add(operand.accept(this));
  }
  if (funcReg.isFunctionComplexOutput(functionName)) {
    RexNode ret = builder.makeInputRef( factory.createTypeWithNullability(factory.createSqlType(SqlTypeName.ANY), true), lastUsedIndex);
    lastUsedIndex++;
    complexExprs.add(call.clone(factory.createTypeWithNullability(factory.createSqlType(SqlTypeName.ANY), true), newOps));
    return ret;
  }
  return call.clone(call.getType(), newOps);
}
 
Example 5
Source File: PythonCorrelateSplitRule.java    From flink with Apache License 2.0 6 votes vote down vote up
private FlinkLogicalTableFunctionScan createNewScan(
	FlinkLogicalTableFunctionScan scan,
	ScalarFunctionSplitter splitter) {
	RexCall rightRexCall = (RexCall) scan.getCall();
	// extract Java funcs from Python TableFunction or Python funcs from Java TableFunction.
	List<RexNode> rightCalcProjects = rightRexCall
		.getOperands()
		.stream()
		.map(x -> x.accept(splitter))
		.collect(Collectors.toList());

	RexCall newRightRexCall = rightRexCall.clone(rightRexCall.getType(), rightCalcProjects);
	return new FlinkLogicalTableFunctionScan(
		scan.getCluster(),
		scan.getTraitSet(),
		scan.getInputs(),
		newRightRexCall,
		scan.getElementType(),
		scan.getRowType(),
		scan.getColumnMappings());
}
 
Example 6
Source File: PythonCorrelateSplitRule.java    From flink with Apache License 2.0 6 votes vote down vote up
private FlinkLogicalTableFunctionScan createNewScan(
	FlinkLogicalTableFunctionScan scan,
	ScalarFunctionSplitter splitter) {
	RexCall rightRexCall = (RexCall) scan.getCall();
	// extract Java funcs from Python TableFunction or Python funcs from Java TableFunction.
	List<RexNode> rightCalcProjects = rightRexCall
		.getOperands()
		.stream()
		.map(x -> x.accept(splitter))
		.collect(Collectors.toList());

	RexCall newRightRexCall = rightRexCall.clone(rightRexCall.getType(), rightCalcProjects);
	return new FlinkLogicalTableFunctionScan(
		scan.getCluster(),
		scan.getTraitSet(),
		scan.getInputs(),
		newRightRexCall,
		scan.getElementType(),
		scan.getRowType(),
		scan.getColumnMappings());
}
 
Example 7
Source File: SqlImplementor.java    From Bats with Apache License 2.0 5 votes vote down vote up
/** Removes cast from string.
 *
 * <p>For example, {@code x > CAST('2015-01-07' AS DATE)}
 * becomes {@code x > '2015-01-07'}.
 */
private static RexNode stripCastFromString(RexNode node) {
    switch (node.getKind()) {
    case EQUALS:
    case IS_NOT_DISTINCT_FROM:
    case NOT_EQUALS:
    case GREATER_THAN:
    case GREATER_THAN_OR_EQUAL:
    case LESS_THAN:
    case LESS_THAN_OR_EQUAL:
        final RexCall call = (RexCall) node;
        final RexNode o0 = call.getOperands().get(0);
        final RexNode o1 = call.getOperands().get(1);
        if (o0.getKind() == SqlKind.CAST && o1.getKind() != SqlKind.CAST) {
            final RexNode o0b = ((RexCall) o0).getOperands().get(0);
            switch (o0b.getType().getSqlTypeName()) {
            case CHAR:
            case VARCHAR:
                return call.clone(call.getType(), ImmutableList.of(o0b, o1));
            }
        }
        if (o1.getKind() == SqlKind.CAST && o0.getKind() != SqlKind.CAST) {
            final RexNode o1b = ((RexCall) o1).getOperands().get(0);
            switch (o1b.getType().getSqlTypeName()) {
            case CHAR:
            case VARCHAR:
                return call.clone(call.getType(), ImmutableList.of(o0, o1b));
            }
        }
    }
    return node;
}
 
Example 8
Source File: SqlImplementor.java    From dremio-oss with Apache License 2.0 5 votes vote down vote up
/**
 * Removes cast from string.
 *
 * <p>For example, {@code x > CAST('2015-01-07' AS DATE)}
 * becomes {@code x > '2015-01-07'}.
 */
private static RexNode stripCastFromString(RexNode node) {
  switch (node.getKind()) {
    case EQUALS:
    case IS_NOT_DISTINCT_FROM:
    case NOT_EQUALS:
    case GREATER_THAN:
    case GREATER_THAN_OR_EQUAL:
    case LESS_THAN:
    case LESS_THAN_OR_EQUAL:
      final RexCall call = (RexCall) node;
      final RexNode o0 = call.operands.get(0);
      final RexNode o1 = call.operands.get(1);
      if (o0.getKind() == SqlKind.CAST
        && o1.getKind() != SqlKind.CAST) {
        final RexNode o0b = ((RexCall) o0).getOperands().get(0);
        switch (o0b.getType().getSqlTypeName()) {
          case CHAR:
          case VARCHAR:
            return call.clone(call.getType(), ImmutableList.of(o0b, o1));
        }
      }
      if (o1.getKind() == SqlKind.CAST
        && o0.getKind() != SqlKind.CAST) {
        final RexNode o1b = ((RexCall) o1).getOperands().get(0);
        switch (o1b.getType().getSqlTypeName()) {
          case CHAR:
          case VARCHAR:
            return call.clone(call.getType(), ImmutableList.of(o0, o1b));
        }
      }
  }
  return node;
}
 
Example 9
Source File: SqlImplementor.java    From calcite with Apache License 2.0 5 votes vote down vote up
/** Removes cast from string.
 *
 * <p>For example, {@code x > CAST('2015-01-07' AS DATE)}
 * becomes {@code x > '2015-01-07'}.
 */
private static RexNode stripCastFromString(RexNode node, SqlDialect dialect) {
  switch (node.getKind()) {
  case EQUALS:
  case IS_NOT_DISTINCT_FROM:
  case NOT_EQUALS:
  case GREATER_THAN:
  case GREATER_THAN_OR_EQUAL:
  case LESS_THAN:
  case LESS_THAN_OR_EQUAL:
    final RexCall call = (RexCall) node;
    final RexNode o0 = call.operands.get(0);
    final RexNode o1 = call.operands.get(1);
    if (o0.getKind() == SqlKind.CAST
        && o1.getKind() != SqlKind.CAST) {
      if (!dialect.supportsImplicitTypeCoercion((RexCall) o0)) {
        // If the dialect does not support implicit type coercion,
        // we definitely can not strip the cast.
        return node;
      }
      final RexNode o0b = ((RexCall) o0).getOperands().get(0);
      return call.clone(call.getType(), ImmutableList.of(o0b, o1));
    }
    if (o1.getKind() == SqlKind.CAST
        && o0.getKind() != SqlKind.CAST) {
      if (!dialect.supportsImplicitTypeCoercion((RexCall) o1)) {
        return node;
      }
      final RexNode o1b = ((RexCall) o1).getOperands().get(0);
      return call.clone(call.getType(), ImmutableList.of(o0, o1b));
    }
  }
  return node;
}
 
Example 10
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 11
Source File: ReduceExpressionsRule.java    From Bats with Apache License 2.0 4 votes vote down vote up
/** Converts op(arg0, ..., argOrdinal, ..., argN) to op(arg0,..., node, ..., argN). */
protected static RexNode substitute(RexCall call, int ordinal, RexNode node) {
  final List<RexNode> newOperands = Lists.newArrayList(call.getOperands());
  newOperands.set(ordinal, node);
  return call.clone(call.getType(), newOperands);
}
 
Example 12
Source File: RelOptUtil.java    From Bats with Apache License 2.0 4 votes vote down vote up
/**
 * Pushes down parts of a join condition.
 *
 * <p>For example, given
 * "emp JOIN dept ON emp.deptno + 1 = dept.deptno", adds a project above
 * "emp" that computes the expression
 * "emp.deptno + 1". The resulting join condition is a simple combination
 * of AND, equals, and input fields.
 */
private static RexNode pushDownEqualJoinConditions(RexNode node, int leftCount, int rightCount,
        List<RexNode> extraLeftExprs, List<RexNode> extraRightExprs) {
    switch (node.getKind()) {
    case AND:
    case EQUALS:
        final RexCall call = (RexCall) node;
        final List<RexNode> list = new ArrayList<>();
        List<RexNode> operands = Lists.newArrayList(call.getOperands());
        for (int i = 0; i < operands.size(); i++) {
            RexNode operand = operands.get(i);
            final int left2 = leftCount + extraLeftExprs.size();
            final int right2 = rightCount + extraRightExprs.size();
            final RexNode e = pushDownEqualJoinConditions(operand, leftCount, rightCount, extraLeftExprs,
                    extraRightExprs);
            final List<RexNode> remainingOperands = Util.skip(operands, i + 1);
            final int left3 = leftCount + extraLeftExprs.size();
            fix(remainingOperands, left2, left3);
            fix(list, left2, left3);
            list.add(e);
        }
        if (!list.equals(call.getOperands())) {
            return call.clone(call.getType(), list);
        }
        return call;
    case OR:
    case INPUT_REF:
    case LITERAL:
    case NOT:
        return node;
    default:
        final ImmutableBitSet bits = RelOptUtil.InputFinder.bits(node);
        final int mid = leftCount + extraLeftExprs.size();
        switch (Side.of(bits, mid)) {
        case LEFT:
            fix(extraRightExprs, mid, mid + 1);
            extraLeftExprs.add(node);
            return RexBuilder.getRexFactory().makeInputRef(mid, node.getType());
        case RIGHT:
            final int index2 = mid + rightCount + extraRightExprs.size();
            extraRightExprs.add(node);
            return RexBuilder.getRexFactory().makeInputRef(index2, node.getType());
        case BOTH:
        case EMPTY:
        default:
            return node;
        }
    }
}
 
Example 13
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 14
Source File: ReduceExpressionsRule.java    From calcite with Apache License 2.0 4 votes vote down vote up
/** Converts op(arg0, ..., argOrdinal, ..., argN) to op(arg0,..., node, ..., argN). */
protected static RexNode substitute(RexCall call, int ordinal, RexNode node) {
  final List<RexNode> newOperands = Lists.newArrayList(call.getOperands());
  newOperands.set(ordinal, node);
  return call.clone(call.getType(), newOperands);
}