int nWhereSize = whereExprs.size();
for(int oi = 0; oi < nWhereSize; oi++) {
final XQExpression eachExpr = whereExprs.get(oi);
boolean innerModified = false;
if(eachExpr instanceof ComparisonOp) {
final ComparisonOp cmpOpr = (ComparisonOp) eachExpr;
XQExpression replaceVarRef = null;
inner: for(int ii = 0; ii < 2; ii++) {
final XQExpression left = cmpOpr.getLeftOperand();
final XQExpression right = cmpOpr.getRightOperand();
if(left instanceof VarRef) {
final Variable referent = ((VarRef) left).getValue();
if(firstBindingExpr instanceof PathExpr) {
final PathExpr bindingPathExpr = (PathExpr) firstBindingExpr;
if(firstBindingVar == referent) {
cmpOpr.setLeftOperand(new ContextItemExpr(bindingPathExpr.getType()));
bindingPathExpr.addPredicate(cmpOpr);
innerModified = true;
replaceVarRef = firstBindingVar;
break inner;
} else if((firstBindingType == Binding.FOR_CLAUSE)
&& (cmpOpr instanceof GeneralComp)) {
final PositionalVariable posVar = ((ForClause) firstBinding).getPositionVariable();
if(posVar == referent) {
bindingPathExpr.addPredicate(right);
innerModified = true;
replaceVarRef = posVar;
break inner;
}
}
}
} else if(left instanceof RelativePath) {
final RelativePath leftPathExpr = ((RelativePath) left);
final List<XQExpression> steps = leftPathExpr.getSteps();
final XQExpression firstStep = steps.get(0);
if(firstStep instanceof VarRef) {
final Variable referent = ((VarRef) firstStep).getValue();
if(firstBindingVar == referent) {
if(firstBindingExpr instanceof VarRef) {
final Variable ref = ((VarRef) firstBindingExpr).getValue();
final XQExpression refval = ref.getValue();
if(refval instanceof PathExpr) {
firstBindingExpr = refval;
}
}
if(firstBindingExpr instanceof PathExpr) {
final PathExpr bindingPathExpr = (PathExpr) firstBindingExpr;
steps.remove(0);
assert (!steps.isEmpty());
bindingPathExpr.addPredicate(cmpOpr);
innerModified = true;
replaceVarRef = firstBindingVar;
break inner;
}
} else if(ii == 1) {// delete an unnessesary where clause
innerModified = true;
break inner;
}
}
} else if(left instanceof DirectFunctionCall) {
final Function func = ((DirectFunctionCall) left).getFunction();
if(func instanceof Position) {
if(firstBindingExpr instanceof PathExpr) {
final PathExpr bindingPathExpr = (PathExpr) firstBindingExpr;
if(TypeUtil.subtypeOf(right.getType(), NumericType.getInstance())) {
bindingPathExpr.addPredicate(right);
} else {
TypePromotedExpr typePromoted = new TypePromotedExpr(right, IntegerType.INTEGER);
bindingPathExpr.addPredicate(typePromoted);
}
innerModified = true;
break inner;
}
}
} else {
if(firstBindingExpr instanceof PathExpr) {
final PathExpr bindingPathExpr = (PathExpr) firstBindingExpr;
final VarRefDetector detector1 = new VarRefDetector(firstBindingVar, true);
detector1.visit(left, null);
if(detector1.isDetected()) {
final VarRefDetector detector2 = new VarRefDetector(firstBindingVar, false);
detector2.visit(right, null);
if(detector2.isJoinDisabled() || detector2.isDetected()) {
break inner;
} else {
bindingPathExpr.addPredicate(cmpOpr);
innerModified = true;
break inner;
}
}
}
}
cmpOpr.switchOperand();
}//inner
if(replaceVarRef != null) {
final PredicateReplacer replacer = new PredicateReplacer(replaceVarRef);
replacer.visit(cmpOpr, null);
}