Java Code Examples for org.apache.calcite.rex.RexNode#isA()

The following examples show how to use org.apache.calcite.rex.RexNode#isA() . 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: CsvFilterableTable.java    From calcite with Apache License 2.0 6 votes vote down vote up
private boolean addFilter(RexNode filter, Object[] filterValues) {
  if (filter.isA(SqlKind.AND)) {
      // We cannot refine(remove) the operands of AND,
      // it will cause o.a.c.i.TableScanNode.createFilterable filters check failed.
    ((RexCall) filter).getOperands().forEach(subFilter -> addFilter(subFilter, filterValues));
  } else if (filter.isA(SqlKind.EQUALS)) {
    final RexCall call = (RexCall) filter;
    RexNode left = call.getOperands().get(0);
    if (left.isA(SqlKind.CAST)) {
      left = ((RexCall) left).operands.get(0);
    }
    final RexNode right = call.getOperands().get(1);
    if (left instanceof RexInputRef
        && right instanceof RexLiteral) {
      final int index = ((RexInputRef) left).getIndex();
      if (filterValues[index] == null) {
        filterValues[index] = ((RexLiteral) right).getValue2().toString();
        return true;
      }
    }
  }
  return false;
}
 
Example 2
Source File: JoinTranslator.java    From samza with Apache License 2.0 6 votes vote down vote up
/**
 * Traverse the tree of expression and validate. Only allowed predicate is conjunction of exp1 = exp2
 * @param rexPredicate Rex Condition
 * @param conjunctionList result container to pull result form recursion stack.
 */
public static void decomposeAndValidateConjunction(RexNode rexPredicate, List<RexNode> conjunctionList) {
  if (rexPredicate == null || rexPredicate.isAlwaysTrue()) {
    return;
  }

  if (rexPredicate.isA(SqlKind.AND)) {
    for (RexNode operand : ((RexCall) rexPredicate).getOperands()) {
      decomposeAndValidateConjunction(operand, conjunctionList);
    }
  } else if (rexPredicate.isA(SqlKind.EQUALS)) {
    conjunctionList.add(rexPredicate);
  } else {
    throw new SamzaException("Only equi-joins and AND operator is supported in join condition.");
  }
}
 
Example 3
Source File: EnumerableTraitsUtils.java    From calcite with Apache License 2.0 6 votes vote down vote up
/**
 * Determine whether there is mapping between project input and output fields.
 * Bail out if sort relies on non-trivial expressions.
 */
private static boolean isCollationOnTrivialExpr(
    List<RexNode> projects, RelDataTypeFactory typeFactory,
    Mappings.TargetMapping map, RelFieldCollation fc, boolean passDown) {
  final int index = fc.getFieldIndex();
  int target = map.getTargetOpt(index);
  if (target < 0) {
    return false;
  }

  final RexNode node = passDown ? projects.get(index) : projects.get(target);
  if (node.isA(SqlKind.CAST)) {
    // Check whether it is a monotonic preserving cast
    final RexCall cast = (RexCall) node;
    RelFieldCollation newFieldCollation = Objects.requireNonNull(RexUtil.apply(map, fc));
    final RexCallBinding binding =
        RexCallBinding.create(typeFactory, cast,
            ImmutableList.of(RelCollations.of(newFieldCollation)));
    if (cast.getOperator().getMonotonicity(binding)
        == SqlMonotonicity.NOT_MONOTONIC) {
      return false;
    }
  }

  return true;
}
 
Example 4
Source File: RexImplicationChecker.java    From calcite with Apache License 2.0 5 votes vote down vote up
private void updateUnaryOpUsage(RexCall call) {
  final List<RexNode> operands = call.getOperands();
  RexNode first = RexUtil.removeCast(operands.get(0));

  if (first.isA(SqlKind.INPUT_REF)) {
    updateUsage(call.getOperator(), (RexInputRef) first, null);
  }
}
 
Example 5
Source File: RelOptUtil.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Decomposes a predicate into a list of expressions that are OR'ed
 * together.
 *
 * @param rexPredicate predicate to be analyzed
 * @param rexList      list of decomposed RexNodes
 */
public static void decomposeDisjunction(
    RexNode rexPredicate,
    List<RexNode> rexList) {
  if (rexPredicate == null || rexPredicate.isAlwaysFalse()) {
    return;
  }
  if (rexPredicate.isA(SqlKind.OR)) {
    for (RexNode operand : ((RexCall) rexPredicate).getOperands()) {
      decomposeDisjunction(operand, rexList);
    }
  } else {
    rexList.add(rexPredicate);
  }
}
 
Example 6
Source File: OLAPProjectRel.java    From kylin with Apache License 2.0 5 votes vote down vote up
private void rewriteProjectForIntersect(RexNode rex, SqlTypeName sqlTypeName, BasicSqlType eleSqlType,
        ArraySqlType arraySqlType, int idx) {
    if (rex.isA(SqlKind.ARRAY_VALUE_CONSTRUCTOR)) { // somethings like ['2012-01-01', '2012-01-02', '2012-01-03']
        List<RexNode> nodeList = ((RexCall) rex).getOperands();
        RexLiteral newNode = null;
        boolean needChange = true;
        List<RexNode> newerList = new ArrayList<>();
        if (!nodeList.isEmpty()) {
            for (RexNode node : nodeList) {
                if (node instanceof RexLiteral) {
                    RexLiteral literal = (RexLiteral) node;
                    if (literal.getTypeName() == sqlTypeName) {
                        needChange = false;
                        break;
                    } else {
                        newNode = RexLiteral.fromJdbcString(eleSqlType, sqlTypeName,
                                literal.getValue2().toString());
                    }
                }
                if (newNode != null) {
                    newerList.add(newNode);
                }
                newNode = null;
            }
            if (needChange) {
                rewriteProjects.set(idx, ((RexCall) rex).clone(arraySqlType, newerList));
                logger.debug("Rewrite project REL {} for intersect count.", rewriteProjects.get(idx));
            }
        }
    }
}
 
Example 7
Source File: SolrFilter.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
private String translateMatch(RexNode condition) {
  if (condition.getKind().belongsTo(SqlKind.COMPARISON)) {
    return translateComparison(condition);
  } else if (condition.isA(SqlKind.AND)) {
    return translateAnd(condition);
  } else if (condition.isA(SqlKind.OR)) {
    return translateOr(condition);
  } else {
    return null;
  }
}
 
Example 8
Source File: SolrFilter.java    From lucene-solr with Apache License 2.0 5 votes vote down vote up
private String translateMatch(RexNode condition) {
  if (condition.getKind().belongsTo(SqlKind.COMPARISON)) {
    return translateComparison(condition);
  } else if (condition.isA(SqlKind.AND)) {
    return "(" + translateAnd(condition) + ")";
  } else if (condition.isA(SqlKind.OR)) {
    return "(" + translateOr(condition) + ")";
  } else {
    return null;
  }
}
 
Example 9
Source File: OLAPProjectRel.java    From kylin-on-parquet-v2 with Apache License 2.0 5 votes vote down vote up
private void rewriteProjectForIntersect(RexNode rex, SqlTypeName sqlTypeName, BasicSqlType eleSqlType,
        ArraySqlType arraySqlType, int idx) {
    if (rex.isA(SqlKind.ARRAY_VALUE_CONSTRUCTOR)) { // somethings like ['2012-01-01', '2012-01-02', '2012-01-03']
        List<RexNode> nodeList = ((RexCall) rex).getOperands();
        RexLiteral newNode = null;
        boolean needChange = true;
        List<RexNode> newerList = new ArrayList<>();
        if (!nodeList.isEmpty()) {
            for (RexNode node : nodeList) {
                if (node instanceof RexLiteral) {
                    RexLiteral literal = (RexLiteral) node;
                    if (literal.getTypeName() == sqlTypeName) {
                        needChange = false;
                        break;
                    } else {
                        newNode = RexLiteral.fromJdbcString(eleSqlType, sqlTypeName,
                                literal.getValue2().toString());
                    }
                }
                if (newNode != null) {
                    newerList.add(newNode);
                }
                newNode = null;
            }
            if (needChange) {
                rewriteProjects.set(idx, ((RexCall) rex).clone(arraySqlType, newerList));
                logger.debug("Rewrite project REL {} for intersect count.", rewriteProjects.get(idx));
            }
        }
    }
}
 
Example 10
Source File: RelOptUtil.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Decomposes a predicate into a list of expressions that are AND'ed
 * together.
 *
 * @param rexPredicate predicate to be analyzed
 * @param rexList      list of decomposed RexNodes
 */
public static void decomposeConjunction(
    RexNode rexPredicate,
    List<RexNode> rexList) {
  if (rexPredicate == null || rexPredicate.isAlwaysTrue()) {
    return;
  }
  if (rexPredicate.isA(SqlKind.AND)) {
    for (RexNode operand : ((RexCall) rexPredicate).getOperands()) {
      decomposeConjunction(operand, rexList);
    }
  } else {
    rexList.add(rexPredicate);
  }
}
 
Example 11
Source File: RelOptUtil.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * Decomposes a predicate into a list of expressions that are OR'ed
 * together.
 *
 * @param rexPredicate predicate to be analyzed
 * @param rexList      list of decomposed RexNodes
 */
public static void decomposeDisjunction(RexNode rexPredicate, List<RexNode> rexList) {
    if (rexPredicate == null || rexPredicate.isAlwaysFalse()) {
        return;
    }
    if (rexPredicate.isA(SqlKind.OR)) {
        for (RexNode operand : ((RexCall) rexPredicate).getOperands()) {
            decomposeDisjunction(operand, rexList);
        }
    } else {
        rexList.add(rexPredicate);
    }
}
 
Example 12
Source File: RelOptUtil.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * Decomposes a predicate into a list of expressions that are AND'ed
 * together.
 *
 * @param rexPredicate predicate to be analyzed
 * @param rexList      list of decomposed RexNodes
 */
public static void decomposeConjunction(RexNode rexPredicate, List<RexNode> rexList) {
    if (rexPredicate == null || rexPredicate.isAlwaysTrue()) {
        return;
    }
    if (rexPredicate.isA(SqlKind.AND)) {
        for (RexNode operand : ((RexCall) rexPredicate).getOperands()) {
            decomposeConjunction(operand, rexList);
        }
    } else {
        rexList.add(rexPredicate);
    }
}
 
Example 13
Source File: RexImplicationChecker.java    From Bats with Apache License 2.0 5 votes vote down vote up
private void updateBinaryOpUsage(RexCall call) {
  final List<RexNode> operands = call.getOperands();
  RexNode first = removeCast(operands.get(0));
  RexNode second = removeCast(operands.get(1));

  if (first.isA(SqlKind.INPUT_REF)
      && second.isA(SqlKind.LITERAL)) {
    updateUsage(call.getOperator(), (RexInputRef) first, second);
  }

  if (first.isA(SqlKind.LITERAL)
      && second.isA(SqlKind.INPUT_REF)) {
    updateUsage(reverse(call.getOperator()), (RexInputRef) second, first);
  }
}
 
Example 14
Source File: CassandraRules.java    From calcite with Apache License 2.0 5 votes vote down vote up
/** Check if an equality operation is comparing a primary key column with a literal.
 *
 * @param left Left operand of the equality
 * @param right Right operand of the equality
 * @param fieldNames Names of all columns in the table
 * @return The field being compared or null if there is no key equality
 */
private String compareFieldWithLiteral(RexNode left, RexNode right, List<String> fieldNames) {
  // FIXME Ignore casts for new and assume they aren't really necessary
  if (left.isA(SqlKind.CAST)) {
    left = ((RexCall) left).getOperands().get(0);
  }

  if (left.isA(SqlKind.INPUT_REF) && right.isA(SqlKind.LITERAL)) {
    final RexInputRef left1 = (RexInputRef) left;
    String name = fieldNames.get(left1.getIndex());
    return name;
  } else {
    return null;
  }
}
 
Example 15
Source File: RelMdUtil.java    From calcite with Apache License 2.0 5 votes vote down vote up
/**
 * Returns default estimates for selectivities, in the absence of stats.
 *
 * @param predicate      predicate for which selectivity will be computed;
 *                       null means true, so gives selectity of 1.0
 * @param artificialOnly return only the selectivity contribution from
 *                       artificial nodes
 * @return estimated selectivity
 */
public static double guessSelectivity(
    RexNode predicate,
    boolean artificialOnly) {
  double sel = 1.0;
  if ((predicate == null) || predicate.isAlwaysTrue()) {
    return sel;
  }

  double artificialSel = 1.0;

  for (RexNode pred : RelOptUtil.conjunctions(predicate)) {
    if (pred.getKind() == SqlKind.IS_NOT_NULL) {
      sel *= .9;
    } else if (
        (pred instanceof RexCall)
            && (((RexCall) pred).getOperator()
            == RelMdUtil.ARTIFICIAL_SELECTIVITY_FUNC)) {
      artificialSel *= RelMdUtil.getSelectivityValue(pred);
    } else if (pred.isA(SqlKind.EQUALS)) {
      sel *= .15;
    } else if (pred.isA(SqlKind.COMPARISON)) {
      sel *= .5;
    } else {
      sel *= .25;
    }
  }

  if (artificialOnly) {
    return artificialSel;
  } else {
    return sel * artificialSel;
  }
}
 
Example 16
Source File: RelMdUtil.java    From Bats with Apache License 2.0 5 votes vote down vote up
/**
 * Returns default estimates for selectivities, in the absence of stats.
 *
 * @param predicate      predicate for which selectivity will be computed;
 *                       null means true, so gives selectity of 1.0
 * @param artificialOnly return only the selectivity contribution from
 *                       artificial nodes
 * @return estimated selectivity
 */
public static double guessSelectivity(
    RexNode predicate,
    boolean artificialOnly) {
  double sel = 1.0;
  if ((predicate == null) || predicate.isAlwaysTrue()) {
    return sel;
  }

  double artificialSel = 1.0;

  for (RexNode pred : RelOptUtil.conjunctions(predicate)) {
    if (pred.getKind() == SqlKind.IS_NOT_NULL) {
      sel *= .9;
    } else if (
        (pred instanceof RexCall)
            && (((RexCall) pred).getOperator()
            == RelMdUtil.ARTIFICIAL_SELECTIVITY_FUNC)) {
      artificialSel *= RelMdUtil.getSelectivityValue(pred);
    } else if (pred.isA(SqlKind.EQUALS)) {
      sel *= .15;
    } else if (pred.isA(SqlKind.COMPARISON)) {
      sel *= .5;
    } else {
      sel *= .25;
    }
  }

  if (artificialOnly) {
    return artificialSel;
  } else {
    return sel * artificialSel;
  }
}
 
Example 17
Source File: SortProjectTransposeRule.java    From calcite with Apache License 2.0 4 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final Sort sort = call.rel(0);
  final Project project = call.rel(1);
  final RelOptCluster cluster = project.getCluster();

  if (sort.getConvention() != project.getConvention()) {
    return;
  }

  // Determine mapping between project input and output fields. If sort
  // relies on non-trivial expressions, we can't push.
  final Mappings.TargetMapping map =
      RelOptUtil.permutationIgnoreCast(
          project.getProjects(), project.getInput().getRowType());
  for (RelFieldCollation fc : sort.getCollation().getFieldCollations()) {
    if (map.getTargetOpt(fc.getFieldIndex()) < 0) {
      return;
    }
    final RexNode node = project.getProjects().get(fc.getFieldIndex());
    if (node.isA(SqlKind.CAST)) {
      // Check whether it is a monotonic preserving cast, otherwise we cannot push
      final RexCall cast = (RexCall) node;
      RelFieldCollation newFc = Objects.requireNonNull(RexUtil.apply(map, fc));
      final RexCallBinding binding =
          RexCallBinding.create(cluster.getTypeFactory(), cast,
              ImmutableList.of(RelCollations.of(newFc)));
      if (cast.getOperator().getMonotonicity(binding) == SqlMonotonicity.NOT_MONOTONIC) {
        return;
      }
    }
  }
  final RelCollation newCollation =
      cluster.traitSet().canonize(
          RexUtil.apply(map, sort.getCollation()));
  final Sort newSort =
      sort.copy(
          sort.getTraitSet().replace(newCollation),
          project.getInput(),
          newCollation,
          sort.offset,
          sort.fetch);
  RelNode newProject =
      project.copy(
          sort.getTraitSet(),
          ImmutableList.of(newSort));
  // Not only is newProject equivalent to sort;
  // newSort is equivalent to project's input
  // (but only if the sort is not also applying an offset/limit).
  Map<RelNode, RelNode> equiv;
  if (sort.offset == null
      && sort.fetch == null
      && cluster.getPlanner().getRelTraitDefs()
          .contains(RelCollationTraitDef.INSTANCE)) {
    equiv = ImmutableMap.of((RelNode) newSort, project.getInput());
  } else {
    equiv = ImmutableMap.of();
  }
  call.transformTo(newProject, equiv);
}
 
Example 18
Source File: LoptMultiJoin.java    From calcite with Apache License 2.0 4 votes vote down vote up
/**
 * Sets weighting for each combination of factors, depending on which join
 * filters reference which factors. Greater weight is given to equality
 * conditions. Also, sets bitmaps indicating which factors are referenced by
 * each factor within join filters that are comparisons.
 */
public void setFactorWeights() {
  factorWeights = new int[nJoinFactors][nJoinFactors];
  factorsRefByFactor = new ImmutableBitSet[nJoinFactors];
  for (int i = 0; i < nJoinFactors; i++) {
    factorsRefByFactor[i] = ImmutableBitSet.of();
  }

  for (RexNode joinFilter : allJoinFilters) {
    ImmutableBitSet factorRefs = factorsRefByJoinFilter.get(joinFilter);

    // don't give weights to non-comparison expressions
    if (!(joinFilter instanceof RexCall)) {
      continue;
    }
    if (!joinFilter.isA(SqlKind.COMPARISON)) {
      continue;
    }

    // OR the factors referenced in this join filter into the
    // bitmaps corresponding to each of the factors; however,
    // exclude the bit corresponding to the factor itself
    for (int factor : factorRefs) {
      factorsRefByFactor[factor] =
          factorsRefByFactor[factor]
              .rebuild()
              .addAll(factorRefs)
              .clear(factor)
              .build();
    }

    if (factorRefs.cardinality() == 2) {
      int leftFactor = factorRefs.nextSetBit(0);
      int rightFactor = factorRefs.nextSetBit(leftFactor + 1);

      final RexCall call = (RexCall) joinFilter;
      ImmutableBitSet leftFields = fieldBitmap(call.getOperands().get(0));
      ImmutableBitSet leftBitmap = factorBitmap(leftFields);

      // filter contains only two factor references, one on each
      // side of the operator
      int weight;
      if (leftBitmap.cardinality() == 1) {
        // give higher weight to equi-joins
        switch (joinFilter.getKind()) {
        case EQUALS:
          weight = 3;
          break;
        default:
          weight = 2;
        }
      } else {
        // cross product of two tables
        weight = 1;
      }
      setFactorWeight(weight, leftFactor, rightFactor);
    } else {
      // multiple factor references -- set a weight for each
      // combination of factors referenced within the filter
      final List<Integer> list  = ImmutableIntList.copyOf(factorRefs);
      for (int outer : list) {
        for (int inner : list) {
          if (outer != inner) {
            setFactorWeight(1, outer, inner);
          }
        }
      }
    }
  }
}
 
Example 19
Source File: LoptMultiJoin.java    From Bats with Apache License 2.0 4 votes vote down vote up
/**
 * Sets weighting for each combination of factors, depending on which join
 * filters reference which factors. Greater weight is given to equality
 * conditions. Also, sets bitmaps indicating which factors are referenced by
 * each factor within join filters that are comparisons.
 */
public void setFactorWeights() {
  factorWeights = new int[nJoinFactors][nJoinFactors];
  factorsRefByFactor = new ImmutableBitSet[nJoinFactors];
  for (int i = 0; i < nJoinFactors; i++) {
    factorsRefByFactor[i] = ImmutableBitSet.of();
  }

  for (RexNode joinFilter : allJoinFilters) {
    ImmutableBitSet factorRefs = factorsRefByJoinFilter.get(joinFilter);

    // don't give weights to non-comparison expressions
    if (!(joinFilter instanceof RexCall)) {
      continue;
    }
    if (!joinFilter.isA(SqlKind.COMPARISON)) {
      continue;
    }

    // OR the factors referenced in this join filter into the
    // bitmaps corresponding to each of the factors; however,
    // exclude the bit corresponding to the factor itself
    for (int factor : factorRefs) {
      factorsRefByFactor[factor] =
          factorsRefByFactor[factor]
              .rebuild()
              .addAll(factorRefs)
              .clear(factor)
              .build();
    }

    if (factorRefs.cardinality() == 2) {
      int leftFactor = factorRefs.nextSetBit(0);
      int rightFactor = factorRefs.nextSetBit(leftFactor + 1);

      final RexCall call = (RexCall) joinFilter;
      ImmutableBitSet leftFields = fieldBitmap(call.getOperands().get(0));
      ImmutableBitSet leftBitmap = factorBitmap(leftFields);

      // filter contains only two factor references, one on each
      // side of the operator
      int weight;
      if (leftBitmap.cardinality() == 1) {
        // give higher weight to equi-joins
        switch (joinFilter.getKind()) {
        case EQUALS:
          weight = 3;
          break;
        default:
          weight = 2;
        }
      } else {
        // cross product of two tables
        weight = 1;
      }
      setFactorWeight(weight, leftFactor, rightFactor);
    } else {
      // multiple factor references -- set a weight for each
      // combination of factors referenced within the filter
      final List<Integer> list  = ImmutableIntList.copyOf(factorRefs);
      for (int outer : list) {
        for (int inner : list) {
          if (outer != inner) {
            setFactorWeight(1, outer, inner);
          }
        }
      }
    }
  }
}
 
Example 20
Source File: SortProjectTransposeRule.java    From Bats with Apache License 2.0 4 votes vote down vote up
public void onMatch(RelOptRuleCall call) {
  final Sort sort = call.rel(0);
  final Project project = call.rel(1);
  final RelOptCluster cluster = project.getCluster();

  if (sort.getConvention() != project.getConvention()) {
    return;
  }

  // Determine mapping between project input and output fields. If sort
  // relies on non-trivial expressions, we can't push.
  final Mappings.TargetMapping map =
      RelOptUtil.permutationIgnoreCast(
          project.getProjects(), project.getInput().getRowType());
  for (RelFieldCollation fc : sort.getCollation().getFieldCollations()) {
    if (map.getTargetOpt(fc.getFieldIndex()) < 0) {
      return;
    }
    final RexNode node = project.getProjects().get(fc.getFieldIndex());
    if (node.isA(SqlKind.CAST)) {
      // Check whether it is a monotonic preserving cast, otherwise we cannot push
      final RexCall cast = (RexCall) node;
      final RexCallBinding binding =
          RexCallBinding.create(cluster.getTypeFactory(), cast,
              ImmutableList.of(RelCollations.of(RexUtil.apply(map, fc))));
      if (cast.getOperator().getMonotonicity(binding) == SqlMonotonicity.NOT_MONOTONIC) {
        return;
      }
    }
  }
  final RelCollation newCollation =
      cluster.traitSet().canonize(
          RexUtil.apply(map, sort.getCollation()));
  final Sort newSort =
      sort.copy(
          sort.getTraitSet().replace(newCollation),
          project.getInput(),
          newCollation,
          sort.offset,
          sort.fetch);
  RelNode newProject =
      project.copy(
          sort.getTraitSet(),
          ImmutableList.of(newSort));
  // Not only is newProject equivalent to sort;
  // newSort is equivalent to project's input
  // (but only if the sort is not also applying an offset/limit).
  Map<RelNode, RelNode> equiv;
  if (sort.offset == null
      && sort.fetch == null
      && cluster.getPlanner().getRelTraitDefs()
          .contains(RelCollationTraitDef.INSTANCE)) {
    equiv = ImmutableMap.of((RelNode) newSort, project.getInput());
  } else {
    equiv = ImmutableMap.of();
  }
  call.transformTo(newProject, equiv);
}