From de7587e5fd123cf8025ef5e5dc281a5af82455c6 Mon Sep 17 00:00:00 2001 From: Max Freedom Pollard <272618364+MaxFreedomPollard@users.noreply.github.com> Date: Mon, 7 Sep 2026 08:09:39 -0400 Subject: [PATCH] fix(singlestoredb): support % as the modulo operator Formatting a SingleStoreDB query that uses % throws instead of returning SQL: format('SELECT 25 % 7', { language: 'singlestoredb' }) Parse error: Unexpected "% 7" at line 1 column 11. SingleStore documents three equivalent modulo forms, MOD(a, b), a MOD b and a % b. The first two format fine, the third does not. The tokenizer builds its OPERATOR rule from a fixed standard set (+ - / > < = <> <= >= !=) plus the dialect's own cfg.operators list, in src/lexer/Tokenizer.ts. % is not in the standard set, and the operators array in src/languages/singlestoredb/singlestoredb.formatter.ts omits it, so no rule matches the character and TokenizerEngine raises a parse error. Every MySQL-family sibling (mysql, mariadb, tidb) lists '%' first in the same array; the SingleStoreDB copy dropped it. Add '%' to that array, in the same leading position the siblings use. regexFactory.operator sorts the alternatives by length descending, so SingleStore's ::% conversion path-operator still matches before the bare %. --- .../singlestoredb/singlestoredb.formatter.ts | 1 + test/singlestoredb.test.ts | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/languages/singlestoredb/singlestoredb.formatter.ts b/src/languages/singlestoredb/singlestoredb.formatter.ts index 5f4d236950..bcd917165d 100644 --- a/src/languages/singlestoredb/singlestoredb.formatter.ts +++ b/src/languages/singlestoredb/singlestoredb.formatter.ts @@ -265,6 +265,7 @@ export const singlestoredb: DialectOptions = { ], lineCommentTypes: ['--', '#'], operators: [ + '%', ':=', '&', '|', diff --git a/test/singlestoredb.test.ts b/test/singlestoredb.test.ts index 24cd21745b..ce587bfb3e 100644 --- a/test/singlestoredb.test.ts +++ b/test/singlestoredb.test.ts @@ -35,7 +35,22 @@ describe('SingleStoreDbFormatter', () => { ]); supportsOperators( format, - [...standardOperators, ':=', '&', '|', '^', '~', '<<', '>>', '<=>', '&&', '||', ':>', '!:>'], + [ + ...standardOperators, + '%', + ':=', + '&', + '|', + '^', + '~', + '<<', + '>>', + '<=>', + '&&', + '||', + ':>', + '!:>', + ], { any: true } ); supportsLimiting(format, { limit: true, offset: true });