package org.basex.query.expr;
import static org.basex.query.QueryText.*;
import org.basex.query.QueryContext;
import org.basex.query.QueryException;
import org.basex.query.item.Bln;
import org.basex.query.item.Item;
import org.basex.query.util.IndexContext;
import org.basex.util.Array;
import org.basex.util.InputInfo;
import org.basex.util.ft.Scoring;
/**
* Or expression.
*
* @author BaseX Team 2005-12, BSD License
* @author Christian Gruen
*/
public final class Or extends Logical {
/**
* Constructor.
* @param ii input info
* @param e expression list
*/
public Or(final InputInfo ii, final Expr... e) {
super(ii, e);
}
@Override
public Expr comp(final QueryContext ctx) throws QueryException {
// remove atomic values
final Expr c = super.comp(ctx);
if(c != this) return c;
// merge predicates if possible
CmpG cmpg = null;
Expr[] ex = {};
for(final Expr e : expr) {
Expr tmp = null;
if(e instanceof CmpG) {
// merge general comparisons
final CmpG g = (CmpG) e;
if(cmpg == null) cmpg = g;
else if(cmpg.union(g, ctx)) tmp = g;
}
// no optimization found; add original expression
if(tmp == null) ex = Array.add(ex, e);
}
if(ex.length != expr.length) ctx.compInfo(OPTWRITE, this);
expr = ex;
compFlatten(ctx);
// return single expression if it yields a boolean
return expr.length == 1 ? compBln(expr[0]) : this;
}
@Override
public Item item(final QueryContext ctx, final InputInfo ii)
throws QueryException {
double d = 0;
boolean f = false;
for(final Expr e : expr) {
final Item it = e.ebv(ctx, input);
if(it.bool(input)) {
final double s = it.score();
if(s == 0) return Bln.TRUE;
d = Scoring.or(d, s);
f = true;
}
}
return d == 0 ? Bln.get(f) : Bln.get(d);
}
@Override
public boolean indexAccessible(final IndexContext ic) throws QueryException {
int is = 0;
Expr[] exprs = {};
boolean ia = true;
for(final Expr e : expr) {
if(e.indexAccessible(ic) && !ic.seq) {
// skip expressions without results
if(ic.costs() == 0) continue;
is += ic.costs();
} else {
ia = false;
}
exprs = Array.add(exprs, e);
}
ic.costs(is);
expr = exprs;
return ia;
}
@Override
public Expr indexEquivalent(final IndexContext ic) throws QueryException {
super.indexEquivalent(ic);
return new Union(input, expr);
}
@Override
public String toString() {
return toString(' ' + OR + ' ');
}
}