Skip to content

Commit 9d2fa7b

Browse files
committed
Implemented comparison operators.
1 parent 3329339 commit 9d2fa7b

4 files changed

Lines changed: 125 additions & 1 deletion

File tree

SqlServerSimulator.Tests/WhereTests.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,40 @@ public class WhereTests
88
[TestMethod]
99
[DataRow("1 = 0", 0)]
1010
[DataRow("1 = 1", 1)]
11+
[DataRow("1 > 0", 1)]
12+
[DataRow("1 > 1", 0)]
13+
[DataRow("1 >= 0", 1)]
14+
[DataRow("1 >= 1", 1)]
15+
[DataRow("1 >= 2", 0)]
16+
[DataRow("1 > = 0", 1)]
17+
[DataRow("1 > = 1", 1)]
18+
[DataRow("1 > = 2", 0)]
19+
[DataRow("1 <= 0", 0)]
20+
[DataRow("1 <= 1", 1)]
21+
[DataRow("1 <= 2", 1)]
22+
[DataRow("1 < = 0", 0)]
23+
[DataRow("1 < = 1", 1)]
24+
[DataRow("1 < = 2", 1)]
25+
[DataRow("1 <> 0", 1)]
26+
[DataRow("1 <> 1", 0)]
27+
[DataRow("1 < > 0", 1)]
28+
[DataRow("1 < > 1", 0)]
29+
[DataRow("1 != 0", 1)]
30+
[DataRow("1 != 1", 0)]
31+
[DataRow("1 ! = 0", 1)]
32+
[DataRow("1 ! = 1", 0)]
33+
[DataRow("1 !> 0", 0)]
34+
[DataRow("1 !> 1", 1)]
35+
[DataRow("1 !> 2", 1)]
36+
[DataRow("1 ! > 0", 0)]
37+
[DataRow("1 ! > 1", 1)]
38+
[DataRow("1 ! > 2", 1)]
39+
[DataRow("1 !< 0", 1)]
40+
[DataRow("1 !< 1", 1)]
41+
[DataRow("1 !< 2", 0)]
42+
[DataRow("1 ! < 0", 1)]
43+
[DataRow("1 ! < 1", 1)]
44+
[DataRow("1 ! < 2", 0)]
1145
public void PureExpressionFilter(string whereExpression, int expectedCount)
1246
{
1347
AreEqual(expectedCount, new Simulation().ExecuteReader($"select 1 where {whereExpression}").EnumerateRecords().Count());

SqlServerSimulator/DataType.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ private sealed class DbInt32 : BitwiseCompatibleDataType
245245

246246
protected override int Precedence => 17;
247247

248+
public static int ToNative(DataValue value) => Convert.ToInt32(value.Value, CultureInfo.InvariantCulture);
249+
248250
public static int ToNative(object value) => Convert.ToInt32(value, CultureInfo.InvariantCulture);
249251

250252
public override DataValue ConvertFrom(DataValue value) => new(value.Value is null ? null : ToNative(value.Value), this);

SqlServerSimulator/Parser/BooleanExpression.cs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,44 @@ public static BooleanExpression Parse(ParserContext context)
2222
case Operator { Character: '=' }:
2323
context.MoveNextRequired();
2424
return new EqualityExpression(left, Expression.Parse(context));
25+
case Operator { Character: '>' }:
26+
if (context.GetNextRequired() is Operator { Character: '=' })
27+
{
28+
context.MoveNextRequired();
29+
return new GreaterThanOrEqualExpression(left, Expression.Parse(context));
30+
}
31+
return new GreaterThanExpression(left, Expression.Parse(context));
32+
case Operator { Character: '<' }:
33+
switch (context.GetNextRequired())
34+
{
35+
case Operator { Character: '=' }:
36+
context.MoveNextRequired();
37+
return new LessThanOrEqualExpression(left, Expression.Parse(context));
38+
case Operator { Character: '>' }:
39+
context.MoveNextRequired();
40+
return new InequalityExpression(left, Expression.Parse(context));
41+
}
42+
43+
if (context.GetNextRequired() is Operator { Character: '=' })
44+
{
45+
context.MoveNextRequired();
46+
return new LessThanOrEqualExpression(left, Expression.Parse(context));
47+
}
48+
return new LessThanExpression(left, Expression.Parse(context));
49+
case Operator { Character: '!' }:
50+
switch (context.GetNextRequired())
51+
{
52+
case Operator { Character: '=' }:
53+
context.MoveNextRequired();
54+
return new InequalityExpression(left, Expression.Parse(context));
55+
case Operator { Character: '>' }:
56+
context.MoveNextRequired();
57+
return new LessThanOrEqualExpression(left, Expression.Parse(context));
58+
case Operator { Character: '<' }:
59+
context.MoveNextRequired();
60+
return new GreaterThanOrEqualExpression(left, Expression.Parse(context));
61+
}
62+
break;
2563
}
2664

2765
throw SimulatedSqlException.SyntaxErrorNear(context);
@@ -45,6 +83,56 @@ public override bool Run(Func<List<string>, DataValue> getColumnValue) =>
4583

4684
#if DEBUG
4785
public override string ToString() => $"{left} = {right}";
86+
#endif
87+
}
88+
89+
private sealed class InequalityExpression(Expression left, Expression right) : BooleanExpression
90+
{
91+
public override bool Run(Func<List<string>, DataValue> getColumnValue) =>
92+
!(left.Run(getColumnValue).Value?.Equals(right.Run(getColumnValue).Value)).GetValueOrDefault();
93+
94+
#if DEBUG
95+
public override string ToString() => $"{left} <> {right}";
96+
#endif
97+
}
98+
99+
private sealed class GreaterThanExpression(Expression left, Expression right) : BooleanExpression
100+
{
101+
public override bool Run(Func<List<string>, DataValue> getColumnValue) =>
102+
left.Run(getColumnValue).CompareTo(right.Run(getColumnValue)) > 0;
103+
104+
#if DEBUG
105+
public override string ToString() => $"{left} > {right}";
106+
#endif
107+
}
108+
109+
private sealed class GreaterThanOrEqualExpression(Expression left, Expression right) : BooleanExpression
110+
{
111+
public override bool Run(Func<List<string>, DataValue> getColumnValue) =>
112+
left.Run(getColumnValue).CompareTo(right.Run(getColumnValue)) >= 0;
113+
114+
#if DEBUG
115+
public override string ToString() => $"{left} >= {right}";
116+
#endif
117+
}
118+
119+
private sealed class LessThanExpression(Expression left, Expression right) : BooleanExpression
120+
{
121+
public override bool Run(Func<List<string>, DataValue> getColumnValue) =>
122+
left.Run(getColumnValue).CompareTo(right.Run(getColumnValue)) < 0;
123+
124+
#if DEBUG
125+
public override string ToString() => $"{left} < {right}";
126+
#endif
127+
}
128+
129+
private sealed class LessThanOrEqualExpression(Expression left, Expression right) : BooleanExpression
130+
{
131+
public override bool Run(Func<List<string>, DataValue> getColumnValue) =>
132+
left.Run(getColumnValue).CompareTo(right.Run(getColumnValue)) <= 0;
133+
134+
#if DEBUG
135+
public override string ToString() => $"{left} <= {right}";
48136
#endif
49137
}
50138
}

SqlServerSimulator/Parser/Tokenizer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ static class Tokenizer
2525
'-' => ParseMinusOrComment(command, ref index),
2626
'/' => ParseForwardSlashOrComment(command, ref index),
2727
'[' => ParseBracketDelimitedString(command, ref index),
28-
'+' or '*' or '(' or ')' or ',' or '.' or ';' or '=' or '&' or '|' or '^' => new Operator(command, index),
28+
'+' or '*' or '(' or ')' or ',' or '.' or ';' or '=' or '&' or '|' or '^' or '>' or '<' or '!' => new Operator(command, index),
2929
var c => throw SimulatedSqlException.SyntaxErrorNear(c) // Might throw on valid-but-unsupported syntax.
3030
};
3131

0 commit comments

Comments
 (0)