/**
   * Determines if a filter condition is a simple one and returns the parameters corresponding to
   * the simple filters.
   *
   * @param calcRel original CalcRel
   * @param filterExprs filter expression being analyzed
   * @param filterList returns the list of filter ordinals in the simple expression
   * @param literals returns the list of literals to be used in the simple comparisons
   * @param op returns the operator to be used in the simple comparison
   * @return true if the filter condition is simple
   */
  private boolean isConditionSimple(
      CalcRel calcRel,
      RexNode filterExprs,
      List<Integer> filterList,
      List<RexLiteral> literals,
      List<CompOperatorEnum> op) {
    SargFactory sargFactory = new SargFactory(calcRel.getCluster().getRexBuilder());
    SargRexAnalyzer rexAnalyzer = sargFactory.newRexAnalyzer(true);
    List<SargBinding> sargBindingList = rexAnalyzer.analyzeAll(filterExprs);

    // Currently, it's all or nothing.  So, if there are filters rejected
    // by the analyzer, we can't process a subset using the reshape
    // exec stream
    if (rexAnalyzer.getNonSargFilterRexNode() != null) {
      return false;
    }

    List<RexInputRef> filterCols = new ArrayList<RexInputRef>();
    List<RexNode> filterOperands = new ArrayList<RexNode>();
    if (FennelRelUtil.extractSimplePredicates(sargBindingList, filterCols, filterOperands, op)) {
      for (RexInputRef filterCol : filterCols) {
        filterList.add(filterCol.getIndex());
      }
      for (RexNode operand : filterOperands) {
        literals.add((RexLiteral) operand);
      }
      return true;
    } else {
      return false;
    }
  }
Example #2
0
  /**
   * Reconstructs a rex predicate from a list of SargBindings which are AND'ed together.
   *
   * @param sargBindingList list of SargBindings to be converted.
   * @return the rex predicate reconstructed from the list of SargBindings.
   */
  public RexNode getSargBindingListToRexNode(List<SargBinding> sargBindingList) {
    if (sargBindingList.isEmpty()) {
      return null;
    }

    RexNode newAndNode = sarg2RexMap.get(sargBindingList.get(0).getExpr());

    for (int i = 1; i < sargBindingList.size(); i++) {
      RexNode nextNode = sarg2RexMap.get(sargBindingList.get(i).getExpr());
      newAndNode =
          factory.getRexBuilder().makeCall(SqlStdOperatorTable.andOperator, newAndNode, nextNode);
    }
    return newAndNode;
  }
Example #3
0
  /**
   * Reconstructs a rex predicate from the non-sargable filter predicates which are AND'ed together.
   *
   * @return the rex predicate reconstructed from the non-sargable predicates.
   */
  public RexNode getNonSargFilterRexNode() {
    if (nonSargFilterList.isEmpty()) {
      return null;
    }

    RexNode newAndNode = nonSargFilterList.get(0);

    for (int i = 1; i < nonSargFilterList.size(); i++) {
      newAndNode =
          factory
              .getRexBuilder()
              .makeCall(SqlStdOperatorTable.andOperator, newAndNode, nonSargFilterList.get(i));
    }

    return newAndNode;
  }
Example #4
0
  /** Reconstructs a rex predicate from a list of SargExprs which will be AND'ed together. */
  private void recomposeConjunction() {
    for (int i = 0; i < sargBindingList.size(); i++) {
      final SargBinding currBinding = sargBindingList.get(i);
      final RexInputRef currRef = currBinding.getInputRef();
      SargExpr currSargExpr = currBinding.getExpr();
      RexNode currAndNode = sarg2RexMap.get(currSargExpr);

      // don't need this anymore
      // will be have new mapping put back if currSargExpr remain
      // unchanged.
      sarg2RexMap.remove(currSargExpr);
      boolean recomp = false;

      // search the rest of the list to find SargExpr on the same col.
      ListIterator<SargBinding> iter = sargBindingList.listIterator(i + 1);

      while (iter.hasNext()) {
        final SargBinding nextBinding = iter.next();
        final RexInputRef nextRef = nextBinding.getInputRef();
        final SargExpr nextSargExpr = nextBinding.getExpr();

        if (nextRef.getIndex() == currRef.getIndex()) {
          // build new SargExpr
          SargSetExpr expr =
              factory.newSetExpr(currSargExpr.getDataType(), SargSetOperator.INTERSECTION);
          expr.addChild(currSargExpr);
          expr.addChild(nextSargExpr);

          // build new RexNode
          currAndNode =
              factory
                  .getRexBuilder()
                  .makeCall(
                      SqlStdOperatorTable.andOperator, currAndNode, sarg2RexMap.get(nextSargExpr));

          currSargExpr = expr;

          sarg2RexMap.remove(nextSargExpr);
          iter.remove();

          recomp = true;
        }
      }

      if (recomp) {
        assert !simpleMode;
        if (!testDynamicParamSupport(currSargExpr)) {
          // Oops, we can't actually support the conjunction we
          // recomposed.  Toss it.  (We could do a better job by at
          // least using part of it, but the effort might be better
          // spent on implementing deferred expression evaluation.)
          nonSargFilterList.add(currAndNode);
          sargBindingList.remove(i);
          continue;
        }
      }

      if (recomp) {
        SargBinding newBinding = new SargBinding(currSargExpr, currRef);
        sargBindingList.remove(i);
        sargBindingList.add(i, newBinding);
      }

      sarg2RexMap.put(currSargExpr, currAndNode);
    }
  }