11using SqlServerSimulator . Parser . Tokens ;
2- using System . Collections . Frozen ;
32
43namespace SqlServerSimulator . Parser ;
54
@@ -132,11 +131,8 @@ public static Expression Parse(Simulation simulation, IEnumerator<Token> tokens,
132131 {
133132 if ( expression is not Reference reference )
134133 throw SimulatedSqlException . SyntaxErrorNear ( token ) ;
135- if ( ! BuiltInFunctions . TryGetValue ( reference . Name , out var builtInFunction ) )
136- throw SimulatedSqlException . UnrecognizedBuiltInFunction ( reference . Name ) ;
137-
138134 token = tokens . RequireNext ( ) ; // Move past (
139- expression = builtInFunction ( simulation , tokens , ref token , getVariableValue ) ;
135+ expression = ResolveBuiltIn ( reference . Name , simulation , tokens , ref token , getVariableValue ) ;
140136 _ = tokens . TryMoveNext ( out token ) ; // Move past )
141137 return expression ;
142138 }
@@ -159,12 +155,24 @@ public static Expression Parse(Simulation simulation, IEnumerator<Token> tokens,
159155 public abstract override string ToString ( ) ;
160156#endif
161157
162- private delegate Expression FunctionResolver ( Simulation simulation , IEnumerator < Token > tokens , ref Token ? token , Func < string , object ? > getVariableValue ) ;
163-
164- private static readonly FrozenDictionary < string , FunctionResolver > BuiltInFunctions = FrozenDictionary . Create < string , FunctionResolver > ( Collation . Default , [
165- new ( "datalength" , ( simulation , tokens , ref token , getVariableValue ) => new DataLength( Expression . Parse ( simulation , tokens , ref token , getVariableValue ) ) ) ,
166- new ( "abs" , ( simulation , tokens , ref token , getVariableValue ) => new AbsoluteValue( Expression . Parse ( simulation , tokens , ref token , getVariableValue ) ) ) ,
167- ] ) ;
158+ private static Expression ResolveBuiltIn ( string name , Simulation simulation , IEnumerator < Token > tokens , ref Token ? token , Func < string , object ? > getVariableValue )
159+ {
160+ Span < char > uppercaseName = stackalloc char [ name . Length ] ;
161+ return name . ToUpperInvariant ( uppercaseName ) switch
162+ {
163+ 3 => uppercaseName switch
164+ {
165+ "ABS" => new AbsoluteValue ( simulation , tokens , ref token , getVariableValue ) ,
166+ _ => null
167+ } ,
168+ 10 => uppercaseName switch
169+ {
170+ "DATALENGTH" => new DataLength ( simulation , tokens , ref token , getVariableValue ) ,
171+ _ => null
172+ } ,
173+ _ => ( Expression ? ) null
174+ } ?? throw SimulatedSqlException . UnrecognizedBuiltInFunction ( name ) ;
175+ }
168176
169177 /// <summary>
170178 /// An expression that has been given a name, such as with `as`.
@@ -296,10 +304,12 @@ public sealed class Reference(Name name) : Expression
296304 /// <summary>
297305 /// Encapsulates the SQL DATALENGTH command: https://learn.microsoft.com/en-us/sql/t-sql/functions/datalength-transact-sql
298306 /// </summary>
299- /// <param name="source">Provides the value to be processed.</param>
300- public sealed class DataLength ( Expression source ) : Expression
307+ public sealed class DataLength : Expression
301308 {
302- private readonly Expression source = source ;
309+ private readonly Expression source ;
310+
311+ public DataLength ( Simulation simulation , IEnumerator < Token > tokens , ref Token ? token , Func < string , object ? > getVariableValue )
312+ => this . source = Expression . Parse ( simulation , tokens , ref token , getVariableValue ) ;
303313
304314 public override object ? Run ( Func < List < string > , object ? > getColumnValue ) => source . Run ( getColumnValue ) switch
305315 {
@@ -316,10 +326,12 @@ public sealed class DataLength(Expression source) : Expression
316326 /// <summary>
317327 /// Encapsulates the SQL ABS command: https://learn.microsoft.com/en-us/sql/t-sql/functions/abs-transact-sql
318328 /// </summary>
319- /// <param name="source">Provides the value to be processed.</param>
320- public sealed class AbsoluteValue ( Expression source ) : Expression
329+ public sealed class AbsoluteValue : Expression
321330 {
322- private readonly Expression source = source ;
331+ private readonly Expression source ;
332+
333+ public AbsoluteValue ( Simulation simulation , IEnumerator < Token > tokens , ref Token ? token , Func < string , object ? > getVariableValue )
334+ => this . source = Expression . Parse ( simulation , tokens , ref token , getVariableValue ) ;
323335
324336 public override object ? Run ( Func < List < string > , object ? > getColumnValue ) => source . Run ( getColumnValue ) switch
325337 {
0 commit comments