private void AnalyzeExpression(BinaryNode expr)
{
if (_linearExpression == _expression)
return;
if (expr._op == Operators.Or)
{
_linearExpression = _expression;
return;
}
else
if (expr._op == Operators.And)
{
bool isLeft = false, isRight = false;
if (expr._left is BinaryNode)
{
AnalyzeExpression((BinaryNode)expr._left);
if (_linearExpression == _expression)
return;
isLeft = true;
}
else
{
UnaryNode unaryNode = expr._left as UnaryNode;
if (unaryNode != null)
{
while (unaryNode._op == Operators.Noop && unaryNode._right is UnaryNode && ((UnaryNode)unaryNode._right)._op == Operators.Noop)
{
unaryNode = (UnaryNode)unaryNode._right;
}
if (unaryNode._op == Operators.Noop && unaryNode._right is BinaryNode)
{
AnalyzeExpression((BinaryNode)(unaryNode._right));
if (_linearExpression == _expression)
{
return;
}
isLeft = true;
}
}
}
if (expr._right is BinaryNode)
{
AnalyzeExpression((BinaryNode)expr._right);
if (_linearExpression == _expression)
return;
isRight = true;
}
else
{
UnaryNode unaryNode = expr._right as UnaryNode;
if (unaryNode != null)
{
while (unaryNode._op == Operators.Noop && unaryNode._right is UnaryNode && ((UnaryNode)unaryNode._right)._op == Operators.Noop)
{
unaryNode = (UnaryNode)unaryNode._right;
}
if (unaryNode._op == Operators.Noop && unaryNode._right is BinaryNode)
{
AnalyzeExpression((BinaryNode)(unaryNode._right));
if (_linearExpression == _expression)
{
return;
}
isRight = true;
}
}
}
if (isLeft && isRight)
return;
ExpressionNode e = isLeft ? expr._right : expr._left;
_linearExpression = (_linearExpression == null ? e : new BinaryNode(_table, Operators.And, e, _linearExpression));
return;
}
else
if (IsSupportedOperator(expr._op))
{
if (expr._left is NameNode && expr._right is ConstNode)
{
ColumnInfo canColumn = _candidateColumns[((NameNode)(expr._left))._column.Ordinal];
canColumn.expr = (canColumn.expr == null ? expr : new BinaryNode(_table, Operators.And, expr, canColumn.expr));
if (expr._op == Operators.EqualTo)
{
canColumn.equalsOperator = true;
}
_candidatesForBinarySearch = true;
return;
}
else
if (expr._right is NameNode && expr._left is ConstNode)
{
ExpressionNode temp = expr._left;
expr._left = expr._right;
expr._right = temp;
switch (expr._op)
{
case Operators.GreaterThen: expr._op = Operators.LessThen; break;
case Operators.LessThen: expr._op = Operators.GreaterThen; break;
case Operators.GreaterOrEqual: expr._op = Operators.LessOrEqual; break;
case Operators.LessOrEqual: expr._op = Operators.GreaterOrEqual; break;
default: break;
}
ColumnInfo canColumn = _candidateColumns[((NameNode)(expr._left))._column.Ordinal];
canColumn.expr = (canColumn.expr == null ? expr : new BinaryNode(_table, Operators.And, expr, canColumn.expr));
if (expr._op == Operators.EqualTo)
{
canColumn.equalsOperator = true;
}
_candidatesForBinarySearch = true;
return;
}
}
_linearExpression = (_linearExpression == null ? expr : new BinaryNode(_table, Operators.And, expr, _linearExpression));
return;
}