Example #1
0
    // implement CallConvertlet
    public void convert(RexCall call) {
      // REVIEW jvs 18-Mar-2006:  The test for variableSeen
      // here and elsewhere precludes predicates like where
      // (boolean_col AND (int_col > 10)).  Should probably
      // support bare boolean columns as predicates with
      // coordinate TRUE.

      if (variableSeen || (coordinate != null)) {
        failed = true;
      }

      if (failed) {
        return;
      }

      int nOperands = call.getOperands().size();
      assert (exprStack.size() >= nOperands);

      SargSetExpr expr = factory.newSetExpr(boundInputRef.getType(), setOp);

      // Pop the correct number of operands off the stack
      // and transfer them to the new set expression.
      ListIterator<SargExpr> iter = exprStack.listIterator(exprStack.size() - nOperands);
      while (iter.hasNext()) {
        expr.addChild(iter.next());
        iter.remove();
      }

      exprStack.add(expr);
    }
Example #2
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);
    }
  }
Example #3
0
  private void intersectSequences(SargIntervalSequence targetSeq, SargIntervalSequence sourceSeq) {
    ListIterator<SargInterval> targetIter = targetSeq.list.listIterator();
    if (!targetIter.hasNext()) {
      // No target intervals at all, so quit.
      return;
    }

    ListIterator<SargInterval> sourceIter = sourceSeq.list.listIterator();
    if (!sourceIter.hasNext()) {
      // No source intervals at all, so result is empty
      targetSeq.list.clear();
      return;
    }

    // Start working on first source and target intervals
    SargInterval target = targetIter.next();
    SargInterval source = sourceIter.next();

    // loop invariant:  both source and target are non-null on entry
    for (; ; ) {
      if (source.getUpperBound().compareTo(target.getLowerBound()) < 0) {
        // Source is completely below target; discard it and
        // move on to next one.
        if (!sourceIter.hasNext()) {
          // No more sources.
          break;
        }
        source = sourceIter.next();
        continue;
      }

      if (target.getUpperBound().compareTo(source.getLowerBound()) < 0) {
        // Target is completely below source; discard it and
        // move on to next one.
        targetIter.remove();
        if (!targetIter.hasNext()) {
          // All done.
          return;
        }
        target = targetIter.next();
        continue;
      }

      // Overlap case:  perform intersection of the two intervals.

      if (source.getLowerBound().compareTo(target.getLowerBound()) > 0) {
        // Source starts after target starts, so trim the target.
        target.setLower(
            source.getLowerBound().getCoordinate(), source.getLowerBound().getStrictness());
      }

      int c = source.getUpperBound().compareTo(target.getUpperBound());
      if (c < 0) {
        // The source ends before the target ends, so split the target
        // into two parts.  The first part will be kept for sure; the
        // second part will be compared against further source ranges.
        SargInterval newTarget = new SargInterval(factory, dataType);
        newTarget.setLower(
            source.getUpperBound().getCoordinate(),
            source.getUpperBound().getStrictnessComplement());

        if (target.getUpperBound().isFinite()) {
          newTarget.setUpper(
              target.getUpperBound().getCoordinate(), target.getUpperBound().getStrictness());
        }

        // Trim current target to exclude the part of the range
        // which will move to newTarget.
        target.setUpper(
            source.getUpperBound().getCoordinate(), source.getUpperBound().getStrictness());

        // Insert newTarget after target.  This makes newTarget
        // into previous().
        targetIter.add(newTarget);

        // Next time through, work on newTarget.
        // targetIter.previous() is pointing at the newTarget.
        target = targetIter.previous();

        // Now targetIter.next() is also pointing at the newTarget;
        // need to do this redundant step to get targetIter in sync
        // with target.
        target = targetIter.next();

        // Advance source.
        if (!sourceIter.hasNext()) {
          break;
        }
        source = sourceIter.next();
      } else if (c == 0) {
        // Source and target ends coincide, so advance both source and
        // target.
        if (!targetIter.hasNext()) {
          return;
        }
        target = targetIter.next();
        if (!sourceIter.hasNext()) {
          break;
        }
        source = sourceIter.next();
      } else {
        // Source ends after target ends, so advance target.
        assert (c > 0);
        if (!targetIter.hasNext()) {
          return;
        }
        target = targetIter.next();
      }
    }

    // Discard any remaining targets since they didn't have corresponding
    // sources.
    for (; ; ) {
      targetIter.remove();
      if (!targetIter.hasNext()) {
        break;
      }
      targetIter.next();
    }
  }