SQL Minifier Truncates Queries When -- Appears Inside a String
A tool that compresses SQL into one line looks like a simple job: strip whitespace, line breaks, and comments to shrink the size. But when the "strip comments" step reaches inside a string literal, the result isn't just quietly wrong — the query itself can break. This article reads the actual source of the SQL Minifier, verifies the bug reproduces, and breaks down the cause.
1. The inherent ambiguity of SQL comment syntax
In SQL, -- starts a single-line comment that runs to the next line break, and /* ... */ is a block comment. The problem is that these same symbols can also appear inside a string literal. Two hyphens landing inside a string value by coincidence — as in WHERE note='A--B' — is not rare in practice: it shows up in URLs (https://a--b.example.com), columns that store code snippets, free-text fields, and more. If a parser strips everything after -- using a regex alone, with no notion of "am I currently inside a string," the concept of a string boundary is simply ignored.
2. Checking the actual code: it's a processing-order problem
Pulled directly from the tool's minify() function, the core logic looks like this.
if(rmComments){ sql=sql.replace(/\/\*[\s\S]*?\*\//g,' ').replace(/--[^\n]*/g,' '); }
// Protect string literals (placeholder substitution) — only runs at this point
const strings=[]; sql=sql.replace(/'[^']*'/g, m => { strings.push(m); return '__STR'+(strings.length-1)+'__'; });
Whitespace collapsing and keyword uppercasing first swap strings out for placeholders like __STR0__, process the rest, and restore the strings last — so they never touch string values. But the comment-removal code runs before that protection logic. In other words, when the regex /--[^\n]*/g scans the raw SQL string, there is nothing in the code that can tell which -- is a real comment and which one is sitting inside a string value.
3. Reproducing it: the query actually gets cut
Here's what actually happens when you feed the following inputs in with comment removal turned on.
| Input | Output | Result |
|---|---|---|
WHERE note='A--B' AND x=1 | WHERE note='A | Unterminated quote; everything after it is lost |
note='a/*b*/c' | note='a c' | The quote stays closed so there's no error, but the value is silently altered |
The first case is serious. Everything after -- (B' AND x=1) is treated as a "single-line comment" and stripped, leaving SQL with a syntax error from an unclosed quote. The second case is more dangerous — it looks syntactically fine, but the string value you meant to store (a/*b*/c) has been silently changed to a c, so it runs, but the data is corrupted. Neither case raises a separate error message, so unless you compare the output by eye, it's easy to miss.
4. Why this design happened
This ordering isn't really a "design mistake" so much as a trap that's almost unavoidable when you implement minification with regex substitutions instead of actually tokenizing the SQL. Done correctly, you'd have to identify and protect string literals first, then strip comments only from what's left. This tool does follow that order for whitespace collapsing and uppercasing (which is why those two features are safe), but the comment-removal step alone is placed ahead of string protection — so safety varies feature by feature within the same file. A tool that actually parses the syntax, like the SQL Validator, wouldn't have this problem in the first place.
5. How to use it safely in practice
- If your string values might contain URLs, code, or free text, turn off comment removal. Whitespace collapsing alone still gives you a meaningful size reduction.
- If you do turn on comment removal, always visually compare the minified result before running it. Just checking that the number of quotes doesn't end up odd will catch most cases of the first failure type.
- For queries that go into a production database, treat minification as a deployment convenience only — keep the original, unminified SQL under version control separately.
FAQ
Q. Does this bug actually reproduce, or is it just theoretical?
It reproduces. Running the tool's actual minify() function, you can directly confirm that the input WHERE note='A--B' AND x=1 gets cut down to WHERE note='A when the comment-removal option is on.
Q. Do whitespace collapsing or keyword uppercasing have the same problem?
No. Both of those features first swap string literals out for placeholders, process the rest, and restore the strings at the end, so they never touch string values. The problem only occurs at the comment-removal step.
Q. How do I avoid this problem?
If your SQL string values might coincidentally contain -- or /*, either turn off comment removal or always visually double-check the minified result.
Q. Does the query also get cut when a block-comment marker appears inside a string?
No, it doesn't get cut, but the value gets silently altered. note='a/*b*/c' turns into note='a c' — it still runs, but the stored data no longer matches the original.