Skip to content

Commit 451e876

Browse files
committed
Added ABS function support, reorganized built-in function tests.
1 parent bd0bba2 commit 451e876

2 files changed

Lines changed: 36 additions & 8 deletions

File tree

SqlServerSimulator.Tests/BuiltInFunctionTests.cs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ namespace SqlServerSimulator;
77
[TestClass]
88
public sealed class BuiltInFunctionTests
99
{
10-
1110
[TestMethod]
1211
public void UnrecognizedBuiltInFunction()
1312
{
@@ -16,12 +15,24 @@ public void UnrecognizedBuiltInFunction()
1615
}
1716

1817
[TestMethod]
19-
public void DataLengthOfNull() => IsInstanceOfType<DBNull>(ExecuteScalar("select datalength(null)"));
20-
21-
[TestMethod]
22-
[DataRow("1", 4)]
23-
public void DataLength(string input, object? output) => AreEqual(output, ExecuteScalar($"select datalength({input})"));
18+
[DataRow("abs")]
19+
[DataRow("datalength")]
20+
public void NullPassThrough(string function)
21+
{
22+
AreEqual(function.ToLowerInvariant(), function);
23+
_ = IsInstanceOfType<DBNull>(ExecuteScalar($"select {function}(null)"));
24+
_ = IsInstanceOfType<DBNull>(ExecuteScalar($"select {function.ToUpperInvariant()}(null)"));
25+
}
2426

2527
[TestMethod]
26-
public void DataLengthAllCaps() => AreEqual(4, ExecuteScalar<int>("select DATALENGTH(1)"));
28+
[DataRow("datalength", "1", 4)]
29+
[DataRow("abs", "1", 1)]
30+
[DataRow("abs", "0", 0)]
31+
[DataRow("abs", "-1", 1)]
32+
public void BuiltInFunction(string function, string input, object output)
33+
{
34+
AreEqual(function.ToLowerInvariant(), function);
35+
AreEqual(output, ExecuteScalar($"select {function}({input})"));
36+
AreEqual(output, ExecuteScalar($"select {function.ToUpperInvariant()}({input})"));
37+
}
2738
}

SqlServerSimulator/Parser/Expression.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,8 @@ public static Expression Parse(Simulation simulation, IEnumerator<Token> tokens,
141141
private delegate Expression FunctionResolver(Simulation simulation, IEnumerator<Token> tokens, ref Token? token, Func<string, object?> getVariableValue);
142142

143143
private static readonly FrozenDictionary<string, FunctionResolver> BuiltInFunctions = FrozenDictionary.Create<string, FunctionResolver>(Collation.Default, [
144-
new("datalength", (simulation, tokens, ref token, getVariableValue) => new DataLength(Expression.Parse(simulation, tokens, ref token, getVariableValue)))
144+
new("datalength", (simulation, tokens, ref token, getVariableValue) => new DataLength(Expression.Parse(simulation, tokens, ref token, getVariableValue))),
145+
new("abs", (simulation, tokens, ref token, getVariableValue) => new AbsoluteValue(Expression.Parse(simulation, tokens, ref token, getVariableValue))),
145146
]);
146147

147148
private sealed class NamedExpression(Expression expression, string name) : Expression
@@ -281,6 +282,22 @@ public sealed class DataLength(Expression source) : Expression
281282

282283
#if DEBUG
283284
public override string ToString() => $"DATALENGTH({source})";
285+
#endif
286+
}
287+
288+
public sealed class AbsoluteValue(Expression source) : Expression
289+
{
290+
private readonly Expression source = source;
291+
292+
public override object? Run(Func<List<string>, object?> getColumnValue) => source.Run(getColumnValue) switch
293+
{
294+
null => null,
295+
int value => Math.Abs(value),
296+
_ => throw new NotSupportedException($"Simulation unable to to run DATALENGTH function on the provided expression."),
297+
};
298+
299+
#if DEBUG
300+
public override string ToString() => $"ABS({source})";
284301
#endif
285302
}
286303
}

0 commit comments

Comments
 (0)