private XmlQueryType FindFilterType(QilIterator variable, QilNode body) {
XmlQueryType leftType;
QilBinary binary;
if (body.XmlType.TypeCode == XmlTypeCode.None)
return XmlQueryTypeFactory.None;
switch (body.NodeType) {
case QilNodeType.False:
return XmlQueryTypeFactory.Empty;
case QilNodeType.IsType:
// If testing the type of "variable", then filter type can be restricted
if (Ref.Equals(((QilTargetType) body).Source, variable))
return XmlQueryTypeFactory.AtMost(((QilTargetType)body).TargetType, variable.Binding.XmlType.Cardinality);
break;
case QilNodeType.And:
// Both And conditions can be used to restrict filter's type
leftType = FindFilterType(variable, ((QilBinary) body).Left);
if (leftType != null)
return leftType;
return FindFilterType(variable, ((QilBinary) body).Right);
case QilNodeType.Eq:
// Restrict cardinality if position($iterator) = $pos is found
binary = (QilBinary) body;
if (binary.Left.NodeType == QilNodeType.PositionOf) {
if (Ref.Equals(((QilUnary) binary.Left).Child, variable))
return XmlQueryTypeFactory.AtMost(variable.Binding.XmlType, XmlQueryCardinality.ZeroOrOne);
}
break;
}
return null;
}
}