@@ -126,7 +126,7 @@ struct SQLTokenizer: Sendable {
126126 tokens.append(Token(kind: .star, range: start..<i))
127127
128128 // Number (digit or leading dot followed by digit)
129− case _ where c.isNumber || (c == "." && peek(sql, at: i, offset: 1)?.isNumber == true):
129+ case _ where isASCIIDigit(c) || (c == "." && peek(sql, at: i, offset: 1).map(isASCIIDigit) == true):
130130 consumeNumber(&i, in: sql)
131131 tokens.append(Token(kind: .number(String(sql[start..<i])), range: start..<i))
132132
@@ -255,6 +255,15 @@ struct SQLTokenizer: Sendable {
255255 return value // unterminated
256256 }
257257
258+ /// SQL number literals use only ASCII digits. `Character.isNumber` also
259+ /// matches Unicode numerics (`²`, `½`, Arabic-Indic digits, etc.), which
260+ /// DataFusion's lexer rejects — accepting them here would tokenize those
261+ /// characters as numbers and diverge token offsets from the server, throwing
262+ /// off `errorHighlightRange` mapping.
263+ private static func isASCIIDigit(_ c: Character) -> Bool {
264+ c.isASCII && c.isNumber
265+ }
266+
258267 private static func consumeNumber(_ i: inout String.Index, in sql: String) {
259268 // Digits with at most one decimal point, so malformed input like
260269 // `1.2.3` doesn't get swallowed into a single number token.
@@ -265,7 +274,7 @@ struct SQLTokenizer: Sendable {
265274 seenDot = true
266275 return true
267276 }
268− return c.isNumber
277+ return isASCIIDigit(c)
269278 })
270279 // Exponent — only consume `e`/`E` (and an optional sign) when actual
271280 // exponent digits follow, so `1e` or `1e+` aren't swallowed whole and
@@ -275,9 +284,9 @@ struct SQLTokenizer: Sendable {
275284 if lookahead < sql.endIndex, sql[lookahead] == "+" || sql[lookahead] == "-" {
276285 sql.formIndex(after: &lookahead)
277286 }
278− if lookahead < sql.endIndex, sql[lookahead].isNumber {
287+ if lookahead < sql.endIndex, isASCIIDigit(sql[lookahead]) {
279288 i = lookahead
280− advance(&i, in: sql, while: { $0.isNumber })
289+ advance(&i, in: sql, while: { isASCIIDigit($0) })
281290 }
282291 }
283292 }