From b156c0e1fe1e9ce8b434d941af50516d98e03b45 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 25 Dec 2025 08:42:05 +0000 Subject: [PATCH] Add \a and \v escape sequence support and fix raw byte handling - Add support for \a (bell, 0x07) and \v (vertical tab, 0x0B) escape sequences in the lexer's string parsing - Fix escapeStringLiteral to iterate over bytes instead of runes to preserve raw bytes like \xAA that are not valid UTF-8 Enables test 00342_escape_sequences. --- internal/explain/format.go | 8 +++++--- lexer/lexer.go | 4 ++++ parser/testdata/00342_escape_sequences/metadata.json | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/internal/explain/format.go b/internal/explain/format.go index 3ce29f77b..0badcdf53 100644 --- a/internal/explain/format.go +++ b/internal/explain/format.go @@ -27,10 +27,12 @@ func FormatFloat(val float64) string { // escapeStringLiteral escapes special characters in a string for EXPLAIN AST output // Uses double-escaping as ClickHouse EXPLAIN AST displays strings +// Iterates over bytes to preserve raw bytes (including invalid UTF-8) func escapeStringLiteral(s string) string { var sb strings.Builder - for _, r := range s { - switch r { + for i := 0; i < len(s); i++ { + b := s[i] + switch b { case '\\': sb.WriteString("\\\\\\\\") // backslash becomes four backslashes (\\\\) case '\'': @@ -48,7 +50,7 @@ func escapeStringLiteral(s string) string { case '\f': sb.WriteString("\\\\f") // form feed becomes \\f default: - sb.WriteRune(r) + sb.WriteByte(b) } } return sb.String() diff --git a/lexer/lexer.go b/lexer/lexer.go index a8a5736b9..cf3737add 100644 --- a/lexer/lexer.go +++ b/lexer/lexer.go @@ -376,10 +376,14 @@ func (l *Lexer) readString(quote rune) Item { sb.WriteRune('\r') case '0': sb.WriteRune('\x00') + case 'a': + sb.WriteRune('\a') case 'b': sb.WriteRune('\b') case 'f': sb.WriteRune('\f') + case 'v': + sb.WriteRune('\v') case 'x': // Hex escape: \xNN l.readChar() diff --git a/parser/testdata/00342_escape_sequences/metadata.json b/parser/testdata/00342_escape_sequences/metadata.json index ef120d978..9e26dfeeb 100644 --- a/parser/testdata/00342_escape_sequences/metadata.json +++ b/parser/testdata/00342_escape_sequences/metadata.json @@ -1 +1 @@ -{"todo": true} +{} \ No newline at end of file