@@ -2,6 +2,11 @@ import type {
22 ASTNode ,
33 Alias ,
44 ArithOp ,
5+ Assignment ,
6+ InsertStatement ,
7+ Statement ,
8+ UpdateStatement ,
9+ ValuesRow ,
510 CaseExpr ,
611 CaseWhen ,
712 CastExpr ,
@@ -55,8 +60,58 @@ import grammar, { type SQLSemantics } from "./sql.ohm-bundle";
5560const semantics : SQLSemantics = grammar . createSemantics ( ) ;
5661
5762semantics . addOperation < ASTNode > ( "toAST()" , {
58- Statement ( select , _semi ) {
59- return select . toAST ( ) ;
63+ Statement ( stmt , _semi ) {
64+ return stmt . toAST ( ) ;
65+ } ,
66+
67+ InsertStatement_withCols ( _insert , _into , tableName , _open , colList , _close , _values , rows ) {
68+ const tn = tableName . toAST ( ) as TableName ;
69+ return {
70+ type : "insert" ,
71+ table : { type : "table_ref" , ...tn } ,
72+ columns : colList . asIteration ( ) . children . map ( ( c ) => c . toAST ( ) as string ) ,
73+ rows : rows . asIteration ( ) . children . map ( ( r ) => r . toAST ( ) as ValuesRow ) ,
74+ } satisfies InsertStatement as ASTNode ;
75+ } ,
76+
77+ InsertStatement_noCols ( _insert , _into , tableName , _values , rows ) {
78+ const tn = tableName . toAST ( ) as TableName ;
79+ return {
80+ type : "insert" ,
81+ table : { type : "table_ref" , ...tn } ,
82+ columns : null ,
83+ rows : rows . asIteration ( ) . children . map ( ( r ) => r . toAST ( ) as ValuesRow ) ,
84+ } satisfies InsertStatement as ASTNode ;
85+ } ,
86+
87+ ValuesRow ( _open , list , _close ) {
88+ return {
89+ type : "values_row" ,
90+ values : list . asIteration ( ) . children . map ( ( v ) => v . toAST ( ) as WhereValue ) ,
91+ } satisfies ValuesRow as ASTNode ;
92+ } ,
93+
94+ UpdateStatement ( _update , tableName , _set , assignments , whereClause ) {
95+ const tn = tableName . toAST ( ) as TableName ;
96+ const whereIter = whereClause . children ;
97+ const where : WhereRoot | null =
98+ whereIter . length > 0
99+ ? { type : "where_root" , inner : whereIter [ 0 ] ! . toAST ( ) as WhereExpr }
100+ : null ;
101+ return {
102+ type : "update" ,
103+ table : { type : "table_ref" , ...tn } ,
104+ assignments : assignments . asIteration ( ) . children . map ( ( a ) => a . toAST ( ) as Assignment ) ,
105+ where,
106+ } satisfies UpdateStatement as ASTNode ;
107+ } ,
108+
109+ Assignment ( column , _eq , value ) {
110+ return {
111+ type : "assignment" ,
112+ column : column . toAST ( ) as string ,
113+ value : value . toAST ( ) as WhereValue ,
114+ } satisfies Assignment as ASTNode ;
60115 } ,
61116
62117 SelectStatement (
@@ -825,7 +880,7 @@ semantics.addOperation<ASTNode>("toAST()", {
825880 } ,
826881} ) ;
827882
828- export function parseSql ( expr : string ) : Result < SelectStatement > {
883+ export function parseStatement ( expr : string ) : Result < Statement > {
829884 const matchResult = grammar . match ( expr ) ;
830885 if ( matchResult . failed ( ) ) {
831886 const [ message ] = matchResult . message . split ( "\nExpected" ) ;
@@ -836,11 +891,20 @@ export function parseSql(expr: string): Result<SelectStatement> {
836891 ) ;
837892 }
838893 try {
839- return Ok ( semantics ( matchResult ) . toAST ( ) as SelectStatement ) ;
894+ return Ok ( semantics ( matchResult ) . toAST ( ) as Statement ) ;
840895 } catch ( e ) {
841896 if ( e instanceof SanitiseError ) {
842897 return Err ( e ) ;
843898 }
844899 throw e ;
845900 }
846901}
902+
903+ export function parseSql ( expr : string ) : Result < SelectStatement > {
904+ const res = parseStatement ( expr ) ;
905+ if ( ! res . ok ) return res ;
906+ if ( res . data . type !== "select" ) {
907+ return Err ( new SanitiseError ( `Expected SELECT statement, got ${ res . data . type . toUpperCase ( ) } ` ) ) ;
908+ }
909+ return Ok ( res . data ) ;
910+ }
0 commit comments