private static IndexRange IntersectOn(IndexRange range, SqlExpressionType op, Field value, bool nullCheck)
{
var start = range.StartValue;
var startPosition = range.StartOffset;
var end = range.EndValue;
var endPosition = range.EndOffset;
bool inclusive = op == SqlExpressionType.Is ||
op == SqlExpressionType.Equal ||
op == SqlExpressionType.GreaterOrEqualThan ||
op == SqlExpressionType.SmallerOrEqualThan;
if (op == SqlExpressionType.Is ||
op == SqlExpressionType.Equal ||
op == SqlExpressionType.GreaterThan ||
op == SqlExpressionType.GreaterOrEqualThan) {
// With this operator, NULL values must return null.
if (nullCheck && value.IsNull) {
return IndexRange.Null;
}
if (start.Equals(IndexRange.FirstInSet)) {
start = value;
startPosition = inclusive ? RangeFieldOffset.FirstValue : RangeFieldOffset.AfterLastValue;
} else {
int c = value.CompareTo(start);
if ((c == 0 && startPosition == RangeFieldOffset.FirstValue) || c > 0) {
start = value;
startPosition = inclusive ? RangeFieldOffset.FirstValue : RangeFieldOffset.AfterLastValue;
}
}
}
if (op == SqlExpressionType.Is ||
op == SqlExpressionType.Equal ||
op == SqlExpressionType.SmallerThan ||
op == SqlExpressionType.SmallerOrEqualThan) {
// With this operator, NULL values must return null.
if (nullCheck && value.IsNull) {
return IndexRange.Null;
}
// If start is first in set, then we have to change it to after NULL
if (nullCheck && start.Equals(IndexRange.FirstInSet)) {
start = Field.Null();
startPosition = RangeFieldOffset.AfterLastValue;
}
if (end.Equals(IndexRange.LastInSet)) {
end = value;
endPosition = inclusive ? RangeFieldOffset.LastValue : RangeFieldOffset.BeforeFirstValue;
} else {
int c = value.CompareTo(end);
if ((c == 0 && endPosition == RangeFieldOffset.LastValue) || c < 0) {
end = value;
endPosition = inclusive ? RangeFieldOffset.LastValue : RangeFieldOffset.BeforeFirstValue;
}
}
}
// If start and end are not null types (if either are, then it means it
// is a placeholder value meaning start or end of set).
if (!start.Equals(IndexRange.FirstInSet) &&
!end.Equals(IndexRange.LastInSet)) {
// If start is higher than end, return null
int c = start.CompareTo(end);
if ((c == 0 && (startPosition == RangeFieldOffset.AfterLastValue ||
endPosition == RangeFieldOffset.BeforeFirstValue)) ||
c > 0) {
return IndexRange.Null;
}
}
// The new intersected range
return new IndexRange(startPosition, start, endPosition, end);
}