@@ -8,7 +8,7 @@ internal sealed class Selection
88
99 private Selection ( SimulatedResultSet results ) => this . Results = results ;
1010
11- public static Selection Parse ( Simulation simulation , IEnumerator < Token > tokens , ref Token ? token , Func < string , object ? > getVariableValue )
11+ public static Selection Parse ( Simulation simulation , IEnumerator < Token > tokens , ref Token ? token , Func < string , object ? > getVariableValue , uint depth )
1212 {
1313 token = tokens . RequireNext ( ) ;
1414
@@ -27,6 +27,12 @@ public static Selection Parse(Simulation simulation, IEnumerator<Token> tokens,
2727 case Comma :
2828 continue ;
2929
30+ case CloseParentheses :
31+ if ( depth == 0 )
32+ throw SimulatedSqlException . SyntaxErrorNear ( token ) ;
33+
34+ goto case null ;
35+
3036 case null : // "Select" with no "From".
3137 return new ( new (
3238 columnIndexes ,
@@ -61,7 +67,36 @@ public static Selection Parse(Simulation simulation, IEnumerator<Token> tokens,
6167 table . Rows . Select < object ? [ ] , object ? [ ] > ( row => [ ..expressions . Select ( x => x . Run ( columnName =>
6268 {
6369 var columnIndex = table . Columns . FindIndex ( column => Collation . Default . Equals ( column . Name , columnName . Last ( ) ) ) ;
64- return columnIndex == - 1 ? throw SimulatedSqlException . InvalidColumnName ( columnName ) : row [ columnIndex ] ; } ) ) ] ) ) ) ;
70+ return columnIndex == - 1 ? throw SimulatedSqlException . InvalidColumnName ( columnName ) : row [ columnIndex ] ;
71+ } ) ) ] )
72+ ) ) ;
73+
74+ case OpenParentheses :
75+ if ( ( token = tokens . RequireNext ( ) ) is not UnquotedString maybeSelect || maybeSelect . Parse ( ) != Keyword . Select )
76+ throw SimulatedSqlException . SyntaxErrorNear ( token ) ;
77+
78+ {
79+ var derived = Selection . Parse ( simulation , tokens , ref token , getVariableValue , depth + 1 ) . Results ;
80+
81+ if ( ( token = tokens . RequireNext ( ) ) is UnquotedString maybeAs && maybeAs . Parse ( ) == Keyword . As )
82+ {
83+ if ( token is not UnquotedString )
84+ break ;
85+ }
86+ else
87+ {
88+ break ;
89+ }
90+
91+ return new ( new (
92+ columnIndexes ,
93+ derived . Select < object ? [ ] , object ? [ ] > ( row => [ ..expressions . Select ( x => x . Run ( columnName =>
94+ {
95+ var columnIndex = Array . FindIndex ( derived . columnNames , name => Collation . Default . Equals ( name , columnName . Last ( ) ) ) ;
96+ return columnIndex == - 1 ? throw SimulatedSqlException . InvalidColumnName ( columnName ) : row [ columnIndex ] ;
97+ } ) ) ] )
98+ ) ) ;
99+ }
65100 }
66101
67102 throw new NotSupportedException ( $ "Simulated selection processor expected a source table, found { token } .") ;
0 commit comments