Java Code Examples for org.apache.calcite.rex.RexBuilder#makeLiteral()

The following examples show how to use org.apache.calcite.rex.RexBuilder#makeLiteral() . 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: RelMetadataTest.java    From calcite with Apache License 2.0 6 votes vote down vote up
private void addRow(ImmutableList.Builder<ImmutableList<RexLiteral>> builder,
    RexBuilder rexBuilder, Object... values) {
  ImmutableList.Builder<RexLiteral> b = ImmutableList.builder();
  final RelDataType varcharType =
      rexBuilder.getTypeFactory().createSqlType(SqlTypeName.VARCHAR);
  for (Object value : values) {
    final RexLiteral literal;
    if (value == null) {
      literal = rexBuilder.makeNullLiteral(varcharType);
    } else if (value instanceof Integer) {
      literal = rexBuilder.makeExactLiteral(
          BigDecimal.valueOf((Integer) value));
    } else {
      literal = rexBuilder.makeLiteral((String) value);
    }
    b.add(literal);
  }
  builder.add(b.build());
}
 
Example 2
Source File: RexTransformerTest.java    From calcite with Apache License 2.0 6 votes vote down vote up
@BeforeEach public void setUp() {
  typeFactory = new JavaTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
  rexBuilder = new RexBuilder(typeFactory);
  boolRelDataType = typeFactory.createSqlType(SqlTypeName.BOOLEAN);

  x = new RexInputRef(
      0,
      typeFactory.createTypeWithNullability(boolRelDataType, true));
  y = new RexInputRef(
      1,
      typeFactory.createTypeWithNullability(boolRelDataType, true));
  z = new RexInputRef(
      2,
      typeFactory.createTypeWithNullability(boolRelDataType, true));
  trueRex = rexBuilder.makeLiteral(true);
  falseRex = rexBuilder.makeLiteral(false);
}
 
Example 3
Source File: EmpInitializerExpressionFactory.java    From calcite with Apache License 2.0 6 votes vote down vote up
@Override public RexNode newColumnDefaultValue(RelOptTable table,
    int iColumn, InitializerContext context) {
  final RexBuilder rexBuilder = context.getRexBuilder();
  final RelDataTypeFactory typeFactory = rexBuilder.getTypeFactory();
  switch (iColumn) {
  case 0:
    return rexBuilder.makeExactLiteral(new BigDecimal(123),
        typeFactory.createSqlType(SqlTypeName.INTEGER));
  case 1:
    return rexBuilder.makeLiteral("Bob");
  case 5:
    return rexBuilder.makeExactLiteral(new BigDecimal(555),
        typeFactory.createSqlType(SqlTypeName.INTEGER));
  default:
    return super.newColumnDefaultValue(table, iColumn, context);
  }
}
 
Example 4
Source File: RelBuilder.java    From Bats with Apache License 2.0 6 votes vote down vote up
/** Creates a literal (constant expression). */
public RexNode literal(Object value) {
    final RexBuilder rexBuilder = cluster.getRexBuilder();
    if (value == null) {
        return rexBuilder.constantNull();
    } else if (value instanceof Boolean) {
        return rexBuilder.makeLiteral((Boolean) value);
    } else if (value instanceof BigDecimal) {
        return rexBuilder.makeExactLiteral((BigDecimal) value);
    } else if (value instanceof Float || value instanceof Double) {
        return rexBuilder.makeApproxLiteral(BigDecimal.valueOf(((Number) value).doubleValue()));
    } else if (value instanceof Number) {
        return rexBuilder.makeExactLiteral(BigDecimal.valueOf(((Number) value).longValue()));
    } else if (value instanceof String) {
        return rexBuilder.makeLiteral((String) value);
    } else {
        throw new IllegalArgumentException("cannot convert " + value + " (" + value.getClass() + ") to a constant");
    }
}
 
Example 5
Source File: RelOptUtil.java    From Bats with Apache License 2.0 6 votes vote down vote up
/**
 * Ands two sets of join filters together, either of which can be null.
 *
 * @param rexBuilder rexBuilder to create AND expression
 * @param left       filter on the left that the right will be AND'd to
 * @param right      filter on the right
 * @return AND'd filter
 *
 * @see org.apache.calcite.rex.RexUtil#composeConjunction
 */
public static RexNode andJoinFilters(RexBuilder rexBuilder, RexNode left, RexNode right) {
    // don't bother AND'ing in expressions that always evaluate to
    // true
    if ((left != null) && !left.isAlwaysTrue()) {
        if ((right != null) && !right.isAlwaysTrue()) {
            left = rexBuilder.makeCall(SqlStdOperatorTable.AND, left, right);
        }
    } else {
        left = right;
    }

    // Joins must have some filter
    if (left == null) {
        left = rexBuilder.makeLiteral(true);
    }
    return left;
}
 
Example 6
Source File: SubstitutionVisitor.java    From calcite with Apache License 2.0 6 votes vote down vote up
private static RexNode splitOr(
    final RexBuilder rexBuilder, RexNode condition, RexNode target) {
  List<RexNode> conditions = RelOptUtil.disjunctions(condition);
  int conditionsLength = conditions.size();
  int targetsLength = 0;
  for (RexNode e : RelOptUtil.disjunctions(target)) {
    removeAll(conditions, e);
    targetsLength++;
  }
  if (conditions.isEmpty() && conditionsLength == targetsLength) {
    return rexBuilder.makeLiteral(true);
  } else if (conditions.isEmpty()) {
    return condition;
  }
  return null;
}
 
Example 7
Source File: Handler.java    From calcite with Apache License 2.0 6 votes vote down vote up
private RexLiteral item(Ast.Node node, RelDataType type) {
  final RexBuilder rexBuilder = builder.getRexBuilder();
  switch (node.op) {
  case LITERAL:
    final Ast.Literal literal = (Ast.Literal) node;
    return (RexLiteral) rexBuilder.makeLiteral(literal.value, type, false);
  case TUPLE:
    final Ast.Call tuple = (Ast.Call) node;
    final ImmutableList<RexLiteral> list = tuple(tuple.operands, type);
    return (RexLiteral) rexBuilder.makeLiteral(list, type, false);
  case BAG:
    final Ast.Call bag = (Ast.Call) node;
    final ImmutableList<RexLiteral> list2 = bag(bag.operands, type);
    return (RexLiteral) rexBuilder.makeLiteral(list2, type, false);
  default:
    throw new IllegalArgumentException("not a literal: " + node);
  }
}
 
Example 8
Source File: RelOptUtil.java    From calcite with Apache License 2.0 6 votes vote down vote up
/**
 * Ands two sets of join filters together, either of which can be null.
 *
 * @param rexBuilder rexBuilder to create AND expression
 * @param left       filter on the left that the right will be AND'd to
 * @param right      filter on the right
 * @return AND'd filter
 *
 * @see org.apache.calcite.rex.RexUtil#composeConjunction
 */
public static RexNode andJoinFilters(
    RexBuilder rexBuilder,
    RexNode left,
    RexNode right) {
  // don't bother AND'ing in expressions that always evaluate to
  // true
  if ((left != null) && !left.isAlwaysTrue()) {
    if ((right != null) && !right.isAlwaysTrue()) {
      left =
          rexBuilder.makeCall(
              SqlStdOperatorTable.AND,
              left,
              right);
    }
  } else {
    left = right;
  }

  // Joins must have some filter
  if (left == null) {
    left = rexBuilder.makeLiteral(true);
  }
  return left;
}
 
Example 9
Source File: RelBuilder.java    From calcite with Apache License 2.0 6 votes vote down vote up
/** Creates a literal (constant expression). */
public RexNode literal(Object value) {
  final RexBuilder rexBuilder = cluster.getRexBuilder();
  if (value == null) {
    final RelDataType type = getTypeFactory().createSqlType(SqlTypeName.NULL);
    return rexBuilder.makeNullLiteral(type);
  } else if (value instanceof Boolean) {
    return rexBuilder.makeLiteral((Boolean) value);
  } else if (value instanceof BigDecimal) {
    return rexBuilder.makeExactLiteral((BigDecimal) value);
  } else if (value instanceof Float || value instanceof Double) {
    return rexBuilder.makeApproxLiteral(
        BigDecimal.valueOf(((Number) value).doubleValue()));
  } else if (value instanceof Number) {
    return rexBuilder.makeExactLiteral(
        BigDecimal.valueOf(((Number) value).longValue()));
  } else if (value instanceof String) {
    return rexBuilder.makeLiteral((String) value);
  } else if (value instanceof Enum) {
    return rexBuilder.makeLiteral(value,
        getTypeFactory().createSqlType(SqlTypeName.SYMBOL), false);
  } else {
    throw new IllegalArgumentException("cannot convert " + value
        + " (" + value.getClass() + ") to a constant");
  }
}
 
Example 10
Source File: SubstitutionVisitor.java    From Bats with Apache License 2.0 5 votes vote down vote up
private static RexNode splitOr(final RexBuilder rexBuilder, RexNode condition, RexNode target) {
    List<RexNode> conditions = RelOptUtil.disjunctions(condition);
    int conditionsLength = conditions.size();
    int targetsLength = 0;
    for (RexNode e : RelOptUtil.disjunctions(target)) {
        removeAll(conditions, e);
        targetsLength++;
    }
    if (conditions.isEmpty() && conditionsLength == targetsLength) {
        return rexBuilder.makeLiteral(true);
    } else if (conditions.isEmpty()) {
        return condition;
    }
    return null;
}
 
Example 11
Source File: RelMdPredicates.java    From calcite with Apache License 2.0 4 votes vote down vote up
/** Converts a predicate on a particular set of columns into a predicate on
 * a subset of those columns, weakening if necessary.
 *
 * <p>If not possible to simplify, returns {@code true}, which is the weakest
 * possible predicate.
 *
 * <p>Examples:<ol>
 * <li>The predicate {@code $7 = $9} on columns [7]
 *     becomes {@code $7 is not null}
 * <li>The predicate {@code $7 = $9 + $11} on columns [7, 9]
 *     becomes {@code $7 is not null or $9 is not null}
 * <li>The predicate {@code $7 = $9 and $9 = 5} on columns [7] becomes
 *   {@code $7 = 5}
 * <li>The predicate
 *   {@code $7 = $9 and ($9 = $1 or $9 = $2) and $1 > 3 and $2 > 10}
 *   on columns [7] becomes {@code $7 > 3}
 * </ol>
 *
 * <p>We currently only handle examples 1 and 2.
 *
 * @param rexBuilder Rex builder
 * @param input Input relational expression
 * @param r Predicate expression
 * @param columnsMapped Columns which the final predicate can reference
 * @return Predicate expression narrowed to reference only certain columns
 */
private RexNode projectPredicate(final RexBuilder rexBuilder, RelNode input,
    RexNode r, ImmutableBitSet columnsMapped) {
  ImmutableBitSet rCols = RelOptUtil.InputFinder.bits(r);
  if (columnsMapped.contains(rCols)) {
    // All required columns are present. No need to weaken.
    return r;
  }
  if (columnsMapped.intersects(rCols)) {
    final List<RexNode> list = new ArrayList<>();
    for (int c : columnsMapped.intersect(rCols)) {
      if (input.getRowType().getFieldList().get(c).getType().isNullable()
          && Strong.isNull(r, ImmutableBitSet.of(c))) {
        list.add(
            rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL,
                rexBuilder.makeInputRef(input, c)));
      }
    }
    if (!list.isEmpty()) {
      return RexUtil.composeDisjunction(rexBuilder, list);
    }
  }
  // Cannot weaken to anything non-trivial
  return rexBuilder.makeLiteral(true);
}
 
Example 12
Source File: SqlNodeToRexConverterImpl.java    From calcite with Apache License 2.0 4 votes vote down vote up
public RexNode convertLiteral(
    SqlRexContext cx,
    SqlLiteral literal) {
  RexBuilder rexBuilder = cx.getRexBuilder();
  RelDataTypeFactory typeFactory = cx.getTypeFactory();
  SqlValidator validator = cx.getValidator();
  if (literal.getValue() == null) {
    // Since there is no eq. RexLiteral of SqlLiteral.Unknown we
    // treat it as a cast(null as boolean)
    RelDataType type;
    if (literal.getTypeName() == SqlTypeName.BOOLEAN) {
      type = typeFactory.createSqlType(SqlTypeName.BOOLEAN);
      type = typeFactory.createTypeWithNullability(type, true);
    } else {
      type = validator.getValidatedNodeType(literal);
    }
    return rexBuilder.makeNullLiteral(type);
  }

  BitString bitString;
  SqlIntervalLiteral.IntervalValue intervalValue;
  long l;

  switch (literal.getTypeName()) {
  case DECIMAL:
    // exact number
    BigDecimal bd = literal.getValueAs(BigDecimal.class);
    return rexBuilder.makeExactLiteral(
        bd,
        literal.createSqlType(typeFactory));

  case DOUBLE:
    // approximate type
    // TODO:  preserve fixed-point precision and large integers
    return rexBuilder.makeApproxLiteral(literal.getValueAs(BigDecimal.class));

  case CHAR:
    return rexBuilder.makeCharLiteral(literal.getValueAs(NlsString.class));
  case BOOLEAN:
    return rexBuilder.makeLiteral(literal.getValueAs(Boolean.class));
  case BINARY:
    bitString = literal.getValueAs(BitString.class);
    Preconditions.checkArgument((bitString.getBitCount() % 8) == 0,
        "incomplete octet");

    // An even number of hexits (e.g. X'ABCD') makes whole number
    // of bytes.
    ByteString byteString = new ByteString(bitString.getAsByteArray());
    return rexBuilder.makeBinaryLiteral(byteString);
  case SYMBOL:
    return rexBuilder.makeFlag(literal.getValueAs(Enum.class));
  case TIMESTAMP:
    return rexBuilder.makeTimestampLiteral(
        literal.getValueAs(TimestampString.class),
        ((SqlTimestampLiteral) literal).getPrec());
  case TIME:
    return rexBuilder.makeTimeLiteral(
        literal.getValueAs(TimeString.class),
        ((SqlTimeLiteral) literal).getPrec());
  case DATE:
    return rexBuilder.makeDateLiteral(literal.getValueAs(DateString.class));

  case INTERVAL_YEAR:
  case INTERVAL_YEAR_MONTH:
  case INTERVAL_MONTH:
  case INTERVAL_DAY:
  case INTERVAL_DAY_HOUR:
  case INTERVAL_DAY_MINUTE:
  case INTERVAL_DAY_SECOND:
  case INTERVAL_HOUR:
  case INTERVAL_HOUR_MINUTE:
  case INTERVAL_HOUR_SECOND:
  case INTERVAL_MINUTE:
  case INTERVAL_MINUTE_SECOND:
  case INTERVAL_SECOND:
    SqlIntervalQualifier sqlIntervalQualifier =
        literal.getValueAs(SqlIntervalLiteral.IntervalValue.class)
            .getIntervalQualifier();
    return rexBuilder.makeIntervalLiteral(
        literal.getValueAs(BigDecimal.class),
        sqlIntervalQualifier);
  default:
    throw Util.unexpected(literal.getTypeName());
  }
}
 
Example 13
Source File: LoptOptimizeJoinRule.java    From calcite with Apache License 2.0 4 votes vote down vote up
/**
 * Determines which join filters can be added to the current join tree. Note
 * that the join filter still reflects the original join ordering. It will
 * only be adjusted to reflect the new join ordering if the "adjust"
 * parameter is set to true.
 *
 * @param multiJoin join factors being optimized
 * @param leftTree left subtree of the join tree
 * @param leftIdx if &ge; 0, only consider filters that reference leftIdx in
 * leftTree; otherwise, consider all filters that reference any factor in
 * leftTree
 * @param rightTree right subtree of the join tree
 * @param filtersToAdd remaining join filters that need to be added; those
 * that are added are removed from the list
 * @param adjust if true, adjust filter to reflect new join ordering
 *
 * @return AND'd expression of the join filters that can be added to the
 * current join tree
 */
private RexNode addFilters(
    LoptMultiJoin multiJoin,
    LoptJoinTree leftTree,
    int leftIdx,
    LoptJoinTree rightTree,
    List<RexNode> filtersToAdd,
    boolean adjust) {
  // loop through the remaining filters to be added and pick out the
  // ones that reference only the factors in the new join tree
  final RexBuilder rexBuilder =
      multiJoin.getMultiJoinRel().getCluster().getRexBuilder();
  final ImmutableBitSet.Builder childFactorBuilder =
      ImmutableBitSet.builder();
  childFactorBuilder.addAll(rightTree.getTreeOrder());
  if (leftIdx >= 0) {
    childFactorBuilder.set(leftIdx);
  } else {
    childFactorBuilder.addAll(leftTree.getTreeOrder());
  }
  for (int child : rightTree.getTreeOrder()) {
    childFactorBuilder.set(child);
  }

  final ImmutableBitSet childFactor = childFactorBuilder.build();
  RexNode condition = null;
  final ListIterator<RexNode> filterIter = filtersToAdd.listIterator();
  while (filterIter.hasNext()) {
    RexNode joinFilter = filterIter.next();
    ImmutableBitSet filterBitmap =
        multiJoin.getFactorsRefByJoinFilter(joinFilter);

    // if all factors in the join filter are in the join tree,
    // AND the filter to the current join condition
    if (childFactor.contains(filterBitmap)) {
      if (condition == null) {
        condition = joinFilter;
      } else {
        condition =
            rexBuilder.makeCall(
                SqlStdOperatorTable.AND,
                condition,
                joinFilter);
      }
      filterIter.remove();
    }
  }

  if (adjust && (condition != null)) {
    int [] adjustments = new int[multiJoin.getNumTotalFields()];
    if (needsAdjustment(
        multiJoin,
        adjustments,
        leftTree,
        rightTree,
        false)) {
      condition =
          condition.accept(
              new RelOptUtil.RexInputConverter(
                  rexBuilder,
                  multiJoin.getMultiJoinFields(),
                  leftTree.getJoinTree().getRowType().getFieldList(),
                  rightTree.getJoinTree().getRowType().getFieldList(),
                  adjustments));
    }
  }

  if (condition == null) {
    condition = rexBuilder.makeLiteral(true);
  }

  return condition;
}
 
Example 14
Source File: RelMdPredicates.java    From Bats with Apache License 2.0 4 votes vote down vote up
/** Converts a predicate on a particular set of columns into a predicate on
 * a subset of those columns, weakening if necessary.
 *
 * <p>If not possible to simplify, returns {@code true}, which is the weakest
 * possible predicate.
 *
 * <p>Examples:<ol>
 * <li>The predicate {@code $7 = $9} on columns [7]
 *     becomes {@code $7 is not null}
 * <li>The predicate {@code $7 = $9 + $11} on columns [7, 9]
 *     becomes {@code $7 is not null or $9 is not null}
 * <li>The predicate {@code $7 = $9 and $9 = 5} on columns [7] becomes
 *   {@code $7 = 5}
 * <li>The predicate
 *   {@code $7 = $9 and ($9 = $1 or $9 = $2) and $1 > 3 and $2 > 10}
 *   on columns [7] becomes {@code $7 > 3}
 * </ol>
 *
 * <p>We currently only handle examples 1 and 2.
 *
 * @param rexBuilder Rex builder
 * @param input Input relational expression
 * @param r Predicate expression
 * @param columnsMapped Columns which the final predicate can reference
 * @return Predicate expression narrowed to reference only certain columns
 */
private RexNode projectPredicate(final RexBuilder rexBuilder, RelNode input,
    RexNode r, ImmutableBitSet columnsMapped) {
  ImmutableBitSet rCols = RelOptUtil.InputFinder.bits(r);
  if (columnsMapped.contains(rCols)) {
    // All required columns are present. No need to weaken.
    return r;
  }
  if (columnsMapped.intersects(rCols)) {
    final List<RexNode> list = new ArrayList<>();
    for (int c : columnsMapped.intersect(rCols)) {
      if (input.getRowType().getFieldList().get(c).getType().isNullable()
          && Strong.isNull(r, ImmutableBitSet.of(c))) {
        list.add(
            rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL,
                rexBuilder.makeInputRef(input, c)));
      }
    }
    if (!list.isEmpty()) {
      return RexUtil.composeDisjunction(rexBuilder, list);
    }
  }
  // Cannot weaken to anything non-trivial
  return rexBuilder.makeLiteral(true);
}
 
Example 15
Source File: SqlNodeToRexConverterImpl.java    From Bats with Apache License 2.0 4 votes vote down vote up
public RexNode convertLiteral(
    SqlRexContext cx,
    SqlLiteral literal) {
  RexBuilder rexBuilder = cx.getRexBuilder();
  RelDataTypeFactory typeFactory = cx.getTypeFactory();
  SqlValidator validator = cx.getValidator();
  if (literal.getValue() == null) {
    // Since there is no eq. RexLiteral of SqlLiteral.Unknown we
    // treat it as a cast(null as boolean)
    RelDataType type;
    if (literal.getTypeName() == SqlTypeName.BOOLEAN) {
      type = typeFactory.createSqlType(SqlTypeName.BOOLEAN);
      type = typeFactory.createTypeWithNullability(type, true);
    } else {
      type = validator.getValidatedNodeType(literal);
    }
    return rexBuilder.makeCast(
        type,
        rexBuilder.constantNull());
  }

  BitString bitString;
  SqlIntervalLiteral.IntervalValue intervalValue;
  long l;

  switch (literal.getTypeName()) {
  case DECIMAL:
    // exact number
    BigDecimal bd = literal.getValueAs(BigDecimal.class);
    return rexBuilder.makeExactLiteral(
        bd,
        literal.createSqlType(typeFactory));

  case DOUBLE:
    // approximate type
    // TODO:  preserve fixed-point precision and large integers
    return rexBuilder.makeApproxLiteral(literal.getValueAs(BigDecimal.class));

  case CHAR:
    return rexBuilder.makeCharLiteral(literal.getValueAs(NlsString.class));
  case BOOLEAN:
    return rexBuilder.makeLiteral(literal.getValueAs(Boolean.class));
  case BINARY:
    bitString = literal.getValueAs(BitString.class);
    Preconditions.checkArgument((bitString.getBitCount() % 8) == 0,
        "incomplete octet");

    // An even number of hexits (e.g. X'ABCD') makes whole number
    // of bytes.
    ByteString byteString = new ByteString(bitString.getAsByteArray());
    return rexBuilder.makeBinaryLiteral(byteString);
  case SYMBOL:
    return rexBuilder.makeFlag(literal.getValueAs(Enum.class));
  case TIMESTAMP:
    return rexBuilder.makeTimestampLiteral(
        literal.getValueAs(TimestampString.class),
        ((SqlTimestampLiteral) literal).getPrec());
  case TIME:
    return rexBuilder.makeTimeLiteral(
        literal.getValueAs(TimeString.class),
        ((SqlTimeLiteral) literal).getPrec());
  case DATE:
    return rexBuilder.makeDateLiteral(literal.getValueAs(DateString.class));

  case INTERVAL_YEAR:
  case INTERVAL_YEAR_MONTH:
  case INTERVAL_MONTH:
  case INTERVAL_DAY:
  case INTERVAL_DAY_HOUR:
  case INTERVAL_DAY_MINUTE:
  case INTERVAL_DAY_SECOND:
  case INTERVAL_HOUR:
  case INTERVAL_HOUR_MINUTE:
  case INTERVAL_HOUR_SECOND:
  case INTERVAL_MINUTE:
  case INTERVAL_MINUTE_SECOND:
  case INTERVAL_SECOND:
    SqlIntervalQualifier sqlIntervalQualifier =
        literal.getValueAs(SqlIntervalLiteral.IntervalValue.class)
            .getIntervalQualifier();
    return rexBuilder.makeIntervalLiteral(
        literal.getValueAs(BigDecimal.class),
        sqlIntervalQualifier);
  default:
    throw Util.unexpected(literal.getTypeName());
  }
}
 
Example 16
Source File: JoinInfo.java    From Bats with Apache License 2.0 4 votes vote down vote up
@Override public RexNode getRemaining(RexBuilder rexBuilder) {
  return rexBuilder.makeLiteral(true);
}
 
Example 17
Source File: LoptOptimizeJoinRule.java    From Bats with Apache License 2.0 4 votes vote down vote up
/**
 * Determines which join filters can be added to the current join tree. Note
 * that the join filter still reflects the original join ordering. It will
 * only be adjusted to reflect the new join ordering if the "adjust"
 * parameter is set to true.
 *
 * @param multiJoin join factors being optimized
 * @param leftTree left subtree of the join tree
 * @param leftIdx if &ge; 0, only consider filters that reference leftIdx in
 * leftTree; otherwise, consider all filters that reference any factor in
 * leftTree
 * @param rightTree right subtree of the join tree
 * @param filtersToAdd remaining join filters that need to be added; those
 * that are added are removed from the list
 * @param adjust if true, adjust filter to reflect new join ordering
 *
 * @return AND'd expression of the join filters that can be added to the
 * current join tree
 */
private RexNode addFilters(
    LoptMultiJoin multiJoin,
    LoptJoinTree leftTree,
    int leftIdx,
    LoptJoinTree rightTree,
    List<RexNode> filtersToAdd,
    boolean adjust) {
  // loop through the remaining filters to be added and pick out the
  // ones that reference only the factors in the new join tree
  final RexBuilder rexBuilder =
      multiJoin.getMultiJoinRel().getCluster().getRexBuilder();
  final ImmutableBitSet.Builder childFactorBuilder =
      ImmutableBitSet.builder();
  childFactorBuilder.addAll(rightTree.getTreeOrder());
  if (leftIdx >= 0) {
    childFactorBuilder.set(leftIdx);
  } else {
    childFactorBuilder.addAll(leftTree.getTreeOrder());
  }
  for (int child : rightTree.getTreeOrder()) {
    childFactorBuilder.set(child);
  }

  final ImmutableBitSet childFactor = childFactorBuilder.build();
  RexNode condition = null;
  final ListIterator<RexNode> filterIter = filtersToAdd.listIterator();
  while (filterIter.hasNext()) {
    RexNode joinFilter = filterIter.next();
    ImmutableBitSet filterBitmap =
        multiJoin.getFactorsRefByJoinFilter(joinFilter);

    // if all factors in the join filter are in the join tree,
    // AND the filter to the current join condition
    if (childFactor.contains(filterBitmap)) {
      if (condition == null) {
        condition = joinFilter;
      } else {
        condition =
            rexBuilder.makeCall(
                SqlStdOperatorTable.AND,
                condition,
                joinFilter);
      }
      filterIter.remove();
    }
  }

  if (adjust && (condition != null)) {
    int [] adjustments = new int[multiJoin.getNumTotalFields()];
    if (needsAdjustment(
        multiJoin,
        adjustments,
        leftTree,
        rightTree,
        false)) {
      condition =
          condition.accept(
              new RelOptUtil.RexInputConverter(
                  rexBuilder,
                  multiJoin.getMultiJoinFields(),
                  leftTree.getJoinTree().getRowType().getFieldList(),
                  rightTree.getJoinTree().getRowType().getFieldList(),
                  adjustments));
    }
  }

  if (condition == null) {
    condition = rexBuilder.makeLiteral(true);
  }

  return condition;
}
 
Example 18
Source File: SubstitutionVisitor.java    From calcite with Apache License 2.0 3 votes vote down vote up
/**
 * Maps a condition onto a target.
 *
 * <p>If condition is stronger than target, returns the residue.
 * If it is equal to target, returns the expression that evaluates to
 * the constant {@code true}. If it is weaker than target, returns
 * {@code null}.</p>
 *
 * <p>The terms satisfy the relation</p>
 *
 * <blockquote>
 * <pre>{@code condition = target AND residue}</pre>
 * </blockquote>
 *
 * <p>and {@code residue} must be as weak as possible.</p>
 *
 * <p>Example #1: condition stronger than target</p>
 * <ul>
 * <li>condition: x = 1 AND y = 2</li>
 * <li>target: x = 1</li>
 * <li>residue: y = 2</li>
 * </ul>
 *
 * <p>Note that residue {@code x &gt; 0 AND y = 2} would also satisfy the
 * relation {@code condition = target AND residue} but is stronger than
 * necessary, so we prefer {@code y = 2}.</p>
 *
 * <p>Example #2: target weaker than condition (valid, but not currently
 * implemented)</p>
 * <ul>
 * <li>condition: x = 1</li>
 * <li>target: x = 1 OR z = 3</li>
 * <li>residue: x = 1</li>
 * </ul>
 *
 * <p>Example #3: condition and target are equivalent</p>
 * <ul>
 * <li>condition: x = 1 AND y = 2</li>
 * <li>target: y = 2 AND x = 1</li>
 * <li>residue: TRUE</li>
 * </ul>
 *
 * <p>Example #4: condition weaker than target</p>
 * <ul>
 * <li>condition: x = 1</li>
 * <li>target: x = 1 AND y = 2</li>
 * <li>residue: null (i.e. no match)</li>
 * </ul>
 *
 * <p>There are many other possible examples. It amounts to solving
 * whether {@code condition AND NOT target} can ever evaluate to
 * true, and therefore is a form of the NP-complete
 * <a href="http://en.wikipedia.org/wiki/Satisfiability">Satisfiability</a>
 * problem.</p>
 */
@VisibleForTesting
public static RexNode splitFilter(final RexSimplify simplify,
    RexNode condition, RexNode target) {
  final RexBuilder rexBuilder = simplify.rexBuilder;
  RexNode condition2 = canonizeNode(rexBuilder, condition);
  RexNode target2 = canonizeNode(rexBuilder, target);

  // First, try splitting into ORs.
  // Given target    c1 OR c2 OR c3 OR c4
  // and condition   c2 OR c4
  // residue is      c2 OR c4
  // Also deals with case target [x] condition [x] yields residue [true].
  RexNode z = splitOr(rexBuilder, condition2, target2);
  if (z != null) {
    return z;
  }

  if (isEquivalent(rexBuilder, condition2, target2)) {
    return rexBuilder.makeLiteral(true);
  }

  RexNode x = andNot(rexBuilder, target2, condition2);
  if (mayBeSatisfiable(x)) {
    RexNode x2 = RexUtil.composeConjunction(rexBuilder,
        ImmutableList.of(condition2, target2));
    RexNode r = canonizeNode(rexBuilder,
        simplify.simplifyUnknownAsFalse(x2));
    if (!r.isAlwaysFalse() && isEquivalent(rexBuilder, condition2, r)) {
      List<RexNode> conjs = RelOptUtil.conjunctions(r);
      for (RexNode e : RelOptUtil.conjunctions(target2)) {
        removeAll(conjs, e);
      }
      return RexUtil.composeConjunction(rexBuilder, conjs);
    }
  }
  return null;
}
 
Example 19
Source File: SubstitutionVisitor.java    From Bats with Apache License 2.0 3 votes vote down vote up
/**
 * Maps a condition onto a target.
 *
 * <p>If condition is stronger than target, returns the residue.
 * If it is equal to target, returns the expression that evaluates to
 * the constant {@code true}. If it is weaker than target, returns
 * {@code null}.</p>
 *
 * <p>The terms satisfy the relation</p>
 *
 * <blockquote>
 * <pre>{@code condition = target AND residue}</pre>
 * </blockquote>
 *
 * <p>and {@code residue} must be as weak as possible.</p>
 *
 * <p>Example #1: condition stronger than target</p>
 * <ul>
 * <li>condition: x = 1 AND y = 2</li>
 * <li>target: x = 1</li>
 * <li>residue: y = 2</li>
 * </ul>
 *
 * <p>Note that residue {@code x &gt; 0 AND y = 2} would also satisfy the
 * relation {@code condition = target AND residue} but is stronger than
 * necessary, so we prefer {@code y = 2}.</p>
 *
 * <p>Example #2: target weaker than condition (valid, but not currently
 * implemented)</p>
 * <ul>
 * <li>condition: x = 1</li>
 * <li>target: x = 1 OR z = 3</li>
 * <li>residue: x = 1</li>
 * </ul>
 *
 * <p>Example #3: condition and target are equivalent</p>
 * <ul>
 * <li>condition: x = 1 AND y = 2</li>
 * <li>target: y = 2 AND x = 1</li>
 * <li>residue: TRUE</li>
 * </ul>
 *
 * <p>Example #4: condition weaker than target</p>
 * <ul>
 * <li>condition: x = 1</li>
 * <li>target: x = 1 AND y = 2</li>
 * <li>residue: null (i.e. no match)</li>
 * </ul>
 *
 * <p>There are many other possible examples. It amounts to solving
 * whether {@code condition AND NOT target} can ever evaluate to
 * true, and therefore is a form of the NP-complete
 * <a href="http://en.wikipedia.org/wiki/Satisfiability">Satisfiability</a>
 * problem.</p>
 */
@VisibleForTesting
public static RexNode splitFilter(final RexSimplify simplify, RexNode condition, RexNode target) {
    final RexBuilder rexBuilder = simplify.rexBuilder;
    RexNode condition2 = canonizeNode(rexBuilder, condition);
    RexNode target2 = canonizeNode(rexBuilder, target);

    // First, try splitting into ORs.
    // Given target c1 OR c2 OR c3 OR c4
    // and condition c2 OR c4
    // residue is c2 OR c4
    // Also deals with case target [x] condition [x] yields residue [true].
    RexNode z = splitOr(rexBuilder, condition2, target2);
    if (z != null) {
        return z;
    }

    if (isEquivalent(rexBuilder, condition2, target2)) {
        return rexBuilder.makeLiteral(true);
    }

    RexNode x = andNot(rexBuilder, target2, condition2);
    if (mayBeSatisfiable(x)) {
        RexNode x2 = RexUtil.composeConjunction(rexBuilder, ImmutableList.of(condition2, target2));
        RexNode r = canonizeNode(rexBuilder, simplify.simplifyUnknownAsFalse(x2));
        if (!r.isAlwaysFalse() && isEquivalent(rexBuilder, condition2, r)) {
            List<RexNode> conjs = RelOptUtil.conjunctions(r);
            for (RexNode e : RelOptUtil.conjunctions(target2)) {
                removeAll(conjs, e);
            }
            return RexUtil.composeConjunction(rexBuilder, conjs);
        }
    }
    return null;
}