@@ -254,3 +254,100 @@ func TestKeyspaceToNonQualifiedTable(t *testing.T) {
254254 AddKeyspace (stmt , "ks2" )
255255 require .Equal (t , "select col, col + (select 1 from ks2.t4) from ks.t join ks2.t2 join (select 1 from ks2.t3) as x where t.id = t2.id and x.id = t.id" , String (stmt ))
256256}
257+
258+ // TestVersionedCommentParsing tests MySQL versioned comment handling.
259+ // All expectations validated against MySQL 8.4.
260+ func TestVersionedCommentParsing (t * testing.T ) {
261+ parser , err := New (Options {MySQLServerVersion : "8.1.20" })
262+ require .NoError (t , err )
263+
264+ tests := []struct {
265+ name string
266+ query string
267+ expected string // expected formatted output after parse
268+ isError bool
269+ errMsg string // if isError, the expected error message
270+ }{
271+ {
272+ name : "expanded (version matches)" ,
273+ query : "SELECT /*!80100 JSON_VALUE(col, '$.x') AS jval, */ id FROM t" ,
274+ expected : "select json_value(col, '$.x') as jval, id from t" ,
275+ },
276+ {
277+ name : "discarded (version too new)" ,
278+ query : "SELECT /*!90000 UPPER('hidden'), */ 42" ,
279+ expected : "select 42 from dual" ,
280+ },
281+ {
282+ name : "no version number (always expanded)" ,
283+ query : "SELECT /*! 1 + 1 */ FROM dual" ,
284+ expected : "select 1 + 1 from dual" ,
285+ },
286+ {
287+ name : "nested regular comment inside version comment" ,
288+ query : "SELECT /*!80100 1 /* a comment */ + 2 */" ,
289+ expected : "select 1 + 2 from dual" ,
290+ },
291+ {
292+ name : "nested version comment inside version comment treated as regular comment" ,
293+ query : "SELECT /*!80100 1 /*!99999 noise */ + 2 */" ,
294+ expected : "select 1 + 2 from dual" ,
295+ },
296+ {
297+ name : "unclosed version comment" ,
298+ query : "SELECT /*!80100 1 + 2" ,
299+ isError : true ,
300+ errMsg : "syntax error at position 22" ,
301+ },
302+ {
303+ name : "version number without whitespace after digits" ,
304+ query : "SELECT 1 + /*!801002*/" ,
305+ expected : "select 1 + 2 from dual" ,
306+ },
307+ {
308+ name : "empty version comment" ,
309+ query : "SELECT 1 /*!80100 */" ,
310+ expected : "select 1 from dual" ,
311+ },
312+ {
313+ name : "fewer than 5 version digits are treated as content" ,
314+ query : "SELECT /*!8010*/ FROM dual" ,
315+ expected : "select 8010 from dual" ,
316+ },
317+ {
318+ name : "non-digits after /*! are treated as content" ,
319+ query : "SELECT /*! 1 + 2*/ FROM dual" ,
320+ expected : "select 1 + 2 from dual" ,
321+ },
322+ {
323+ name : "no space before closing */" ,
324+ query : "SELECT /*!80100 42*/ FROM dual" ,
325+ expected : "select 42 from dual" ,
326+ },
327+ {
328+ name : "nested comment inside skipped version comment" ,
329+ query : "SELECT /*!90000 1 /* nested */ + 2 */ 42" ,
330+ expected : "select 42 from dual" ,
331+ },
332+ {
333+ name : "nested version comment inside skipped version comment" ,
334+ query : "SELECT /*!90000 1 /*!99999 nested */ + 2 */ 42" ,
335+ expected : "select 42 from dual" ,
336+ },
337+ }
338+
339+ for _ , tt := range tests {
340+ t .Run (tt .name , func (t * testing.T ) {
341+ stmt , err := parser .Parse (tt .query )
342+ if tt .isError {
343+ require .Error (t , err , "expected parse error for: %s" , tt .query )
344+ if tt .errMsg != "" {
345+ assert .EqualError (t , err , tt .errMsg )
346+ }
347+ return
348+ }
349+ require .NoError (t , err , "unexpected error for: %s" , tt .query )
350+ assert .Equal (t , tt .expected , String (stmt ))
351+ })
352+ }
353+ }
0 commit comments