Exemple #1
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;
  }
Exemple #2
0
 protected RexNode register(RexNode expr) {
   final String key = expr.toString();
   final RexNode previous = mapDigestToExpr.put(key, expr);
   if (!allowDups && (previous != null)) {
     throw new SubExprExistsException(expr);
   }
   return expr;
 }
Exemple #3
0
  /**
   * Analyzes a rex predicate.
   *
   * @param rexPredicate predicate to be analyzed
   * @return a list of SargBindings contained in the input rex predicate
   */
  public List<SargBinding> analyzeAll(RexNode rexPredicate) {
    sargBindingList = new ArrayList<SargBinding>();
    sarg2RexMap = new HashMap<SargExpr, RexNode>();
    nonSargFilterList = new ArrayList<RexNode>();

    // Flatten out the RexNode tree into a list of terms that
    // are AND'ed together
    final List<RexNode> rexCFList = RelOptUtil.conjunctions(rexPredicate);

    // In simple mode, each input ref can only be referenced once, so
    // keep a list of them.  We also only allow one non-point expression.
    List<Integer> boundRefList = new ArrayList<Integer>();
    boolean rangeFound = false;

    for (RexNode rexPred : rexCFList) {
      final SargBinding sargBinding = analyze(rexPred);
      if (sargBinding != null) {
        if (simpleMode) {
          RexInputRef inputRef = sargBinding.getInputRef();
          if (boundRefList.contains(inputRef.getIndex())) {
            nonSargFilterList.add(rexPred);
            continue;
          } else {
            boundRefList.add(inputRef.getIndex());
          }
          SargIntervalSequence sargSeq = sargBinding.getExpr().evaluate();
          if (sargSeq.isRange()) {
            if (rangeFound) {
              nonSargFilterList.add(rexPred);
              continue;
            } else {
              rangeFound = true;
            }
          }
        }
        sargBindingList.add(sargBinding);
        sarg2RexMap.put(sargBinding.getExpr(), rexPred);
      } else {
        nonSargFilterList.add(rexPred);
      }
    }

    // Reset the state variables used during analyze, just for sanity sake.
    failed = false;
    boundInputRef = null;
    clearLeaf();

    // Combine the AND terms back together.
    recomposeConjunction();

    return sargBindingList;
  }
 private List<AggregateCall> transformAggCalls(
     RelDataTypeFactory typeFactory, int nGroupCols, List<AggregateCall> origCalls) {
   List<AggregateCall> newCalls = new ArrayList<AggregateCall>();
   int iInput = nGroupCols;
   for (AggregateCall origCall : origCalls) {
     if (origCall.isDistinct()
         || !SUPPORTED_AGGREGATES.containsKey(origCall.getAggregation().getClass())) {
       return null;
     }
     Aggregation aggFun;
     RelDataType aggType;
     if (origCall.getAggregation().getName().equals("COUNT")) {
       aggFun = new SqlSumEmptyIsZeroAggFunction(origCall.getType());
       SqlAggFunction af = (SqlAggFunction) aggFun;
       final AggregateRelBase.AggCallBinding binding =
           new AggregateRelBase.AggCallBinding(
               typeFactory, af, Collections.singletonList(origCall.getType()), nGroupCols);
       // count(any) is always not null, however nullability of sum might
       // depend on the number of columns in GROUP BY.
       // Here we use SUM0 since we are sure we will not face nullable
       // inputs nor we'll face empty set.
       aggType = af.inferReturnType(binding);
     } else {
       aggFun = origCall.getAggregation();
       aggType = origCall.getType();
     }
     AggregateCall newCall =
         new AggregateCall(
             aggFun,
             origCall.isDistinct(),
             Collections.singletonList(iInput),
             aggType,
             origCall.getName());
     newCalls.add(newCall);
     ++iInput;
   }
   return newCalls;
 }
 static {
   SUPPORTED_AGGREGATES.put(SqlMinMaxAggFunction.class, true);
   SUPPORTED_AGGREGATES.put(SqlCountAggFunction.class, true);
   SUPPORTED_AGGREGATES.put(SqlSumAggFunction.class, true);
   SUPPORTED_AGGREGATES.put(SqlSumEmptyIsZeroAggFunction.class, true);
 }
Exemple #6
0
 protected RexNode lookup(RexNode expr) {
   return mapDigestToExpr.get(expr.toString());
 }
Exemple #7
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);
    }
  }
Exemple #8
0
 private void registerConvertlet(SqlOperator op, CallConvertlet convertlet) {
   convertletMap.put(op, convertlet);
 }