Пример #1
0
 @Override
 public Expr optimize(final QueryContext qc, final VarScope scp) throws QueryException {
   // number of predicates may change in loop
   for (int p = 0; p < preds.length; p++) {
     final Expr pred = preds[p];
     if (pred instanceof CmpG || pred instanceof CmpV) {
       final Cmp cmp = (Cmp) pred;
       if (cmp.exprs[0].isFunction(Function.POSITION)) {
         final Expr e2 = cmp.exprs[1];
         final SeqType st2 = e2.seqType();
         // position() = last() -> last()
         // position() = $n (numeric) -> $n
         if (e2.isFunction(Function.LAST) || st2.one() && st2.type.isNumber()) {
           if (cmp instanceof CmpG && ((CmpG) cmp).op == OpG.EQ
               || cmp instanceof CmpV && ((CmpV) cmp).op == OpV.EQ) {
             qc.compInfo(OPTWRITE, pred);
             preds[p] = e2;
           }
         }
       }
     } else if (pred instanceof And) {
       if (!pred.has(Flag.FCS)) {
         // replace AND expression with predicates (don't swap position tests)
         qc.compInfo(OPTPRED, pred);
         final Expr[] and = ((Arr) pred).exprs;
         final int m = and.length - 1;
         final ExprList el = new ExprList(preds.length + m);
         for (final Expr e : Arrays.asList(preds).subList(0, p)) el.add(e);
         for (final Expr a : and) {
           // wrap test with boolean() if the result is numeric
           el.add(Function.BOOLEAN.get(null, info, a).optimizeEbv(qc, scp));
         }
         for (final Expr e : Arrays.asList(preds).subList(p + 1, preds.length)) el.add(e);
         preds = el.finish();
       }
     } else if (pred instanceof ANum) {
       final ANum it = (ANum) pred;
       final long i = it.itr();
       if (i == it.dbl()) {
         preds[p] = Pos.get(i, info);
       } else {
         qc.compInfo(OPTREMOVE, this, pred);
         return Empty.SEQ;
       }
     } else if (pred.isValue()) {
       if (pred.ebv(qc, info).bool(info)) {
         qc.compInfo(OPTREMOVE, this, pred);
         preds = Array.delete(preds, p--);
       } else {
         // handle statically known predicates
         qc.compInfo(OPTREMOVE, this, pred);
         return Empty.SEQ;
       }
     }
   }
   return this;
 }
Пример #2
0
  @Override
  public Item item(final QueryContext qc, final InputInfo ii) throws QueryException {
    // compute scoring
    if (qc.scoring) {
      double s = 0;
      boolean f = false;
      for (final Expr expr : exprs) {
        final Item it = expr.ebv(qc, info);
        f |= it.bool(ii);
        s += it.score();
      }
      return Bln.get(f, Scoring.avg(s, exprs.length));
    }

    // standard evaluation
    for (final Expr expr : exprs) {
      if (expr.ebv(qc, info).bool(ii)) return Bln.TRUE;
    }
    return Bln.FALSE;
  }