Skip to content

Commit

Permalink
Fix literals format
Browse files Browse the repository at this point in the history
  • Loading branch information
apstndb committed Dec 19, 2024
1 parent 1efca7f commit 2f3206c
Show file tree
Hide file tree
Showing 12 changed files with 67 additions and 46 deletions.
2 changes: 1 addition & 1 deletion testdata/result/expr/cast_as_typename.sql.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ CAST('order_number: "123"' AS examples.shipping.`Order`)
}

--- SQL
CAST("order_number: \"123\"" AS examples.shipping.`Order`)
CAST('order_number: "123"' AS examples.shipping.`Order`)
2 changes: 1 addition & 1 deletion testdata/result/expr/json_literal.sql.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ JSON '{"s": "foo", "n": 42}'
}

--- SQL
JSON "{\"s\": \"foo\", \"n\": 42}"
JSON '{"s": "foo", "n": 42}'
2 changes: 1 addition & 1 deletion testdata/result/query/select_literals_all.sql.txt
Original file line number Diff line number Diff line change
Expand Up @@ -597,4 +597,4 @@ lines''',
}

--- SQL
SELECT "abc", "it\'s", "it\'s", "Title: \"Boy\"", "abc", "it\'s", "Title:\"Boy\"", "two\nlines", "why\?", "abc+", "abc+", "abc+", "f\\(abc,(.*),def\\)", B"abc", B"abc", B"abc", B"abc+", B"abc+", B"abc", 123, 0xABC, -123, -0xABC, 123.456e-67, .1E4, 58., 4e2, [1, 2, 3], ["x", "y", "xy"], ARRAY[1, 2, 3], ARRAY<STRING>["x", "y", "xy"], ARRAY<INT64>[], ARRAY(SELECT STRUCT(1, 2, 3)), ARRAY(SELECT (1, 2, 3)), DATE "2014-09-27", DATE("2014-09-27"), TIMESTAMP "2014-09-27 12:30:00.45-08", TIMESTAMP "2014-09-27 12:30:00.45 America/Los_Angeles", TIMESTAMP "2014-09-27", TIMESTAMP("2014-09-27"), JSON "1", JSON "[1, 2]", JSON "{}", NUMERIC "0", NUMERIC "0", TRUE, FALSE
SELECT "abc", "it's", "it's", 'Title: "Boy"', "abc", "it's", 'Title:"Boy"', "two\nlines", "why\?", "abc+", "abc+", "abc+", "f\\(abc,(.*),def\\)", b"abc", b"abc", b"abc", b"abc+", b"abc+", b"abc", 123, 0xABC, -123, -0xABC, 123.456e-67, .1E4, 58., 4e2, [1, 2, 3], ["x", "y", "xy"], ARRAY[1, 2, 3], ARRAY<STRING>["x", "y", "xy"], ARRAY<INT64>[], ARRAY(SELECT STRUCT(1, 2, 3)), ARRAY(SELECT (1, 2, 3)), DATE "2014-09-27", DATE("2014-09-27"), TIMESTAMP "2014-09-27 12:30:00.45-08", TIMESTAMP "2014-09-27 12:30:00.45 America/Los_Angeles", TIMESTAMP "2014-09-27", TIMESTAMP("2014-09-27"), JSON "1", JSON "[1, 2]", JSON "{}", NUMERIC "0", NUMERIC "0", TRUE, FALSE
2 changes: 1 addition & 1 deletion testdata/result/query/select_literals_bytes.sql.txt
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,4 @@ SELECT
}

--- SQL
SELECT B"abc", B"abc", B"abc", B"abc\n", B"abc+", B"abc+", B"abc", B"abc\\n", B"\x00", B"\?\?\?"
SELECT b"abc", b"abc", b"abc", b"abc\n", b"abc+", b"abc+", b"abc", b"abc\\n", b"\x00", b"\?\?\?"
2 changes: 1 addition & 1 deletion testdata/result/query/select_literals_string.sql.txt
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,4 @@ lines''',
}

--- SQL
SELECT "abc!", "a\nb!", "=!", "=!", "=!", "=!", "=!", "‼!", "🐈!", "it\'s", "it\'s", "Title: \"Boy\"", "abc", "it\'s", "Title:\"Boy\"", "two\nlines", "why\?", "abc+", "abc+", "abc+", "f\\(abc,(.*),def\\)"
SELECT "abc!", "a\nb!", "=!", "=!", "=!", "=!", "=!", "‼!", "🐈!", "it's", "it's", 'Title: "Boy"', "abc", "it's", 'Title:"Boy"', "two\nlines", "why\?", "abc+", "abc+", "abc+", "f\\(abc,(.*),def\\)"
2 changes: 1 addition & 1 deletion testdata/result/query/select_subscript_operators.sql.txt
Original file line number Diff line number Diff line change
Expand Up @@ -492,4 +492,4 @@ select
}

--- SQL
SELECT [1, 2, 3][OFFSET(1)], [1, 2, 3][ORDINAL(1)], [1, 2, 3][SAFE_OFFSET(1)], [1, 2, 3][ORDINAL(1)], [1, 2, 3][1], STRUCT(1, 2, 3)[OFFSET(1)], STRUCT(1, 2, 3)[ORDINAL(1)], STRUCT(1, 2, 3)[SAFE_OFFSET(1)], STRUCT(1, 2, 3)[ORDINAL(1)], STRUCT(1, 2, 3)[1], JSON "[1, 2, 3]"[1], JSON "{\"a\": 1, \"b\": 2, \"c\": 3}"["a"]
SELECT [1, 2, 3][OFFSET(1)], [1, 2, 3][ORDINAL(1)], [1, 2, 3][SAFE_OFFSET(1)], [1, 2, 3][ORDINAL(1)], [1, 2, 3][1], STRUCT(1, 2, 3)[OFFSET(1)], STRUCT(1, 2, 3)[ORDINAL(1)], STRUCT(1, 2, 3)[SAFE_OFFSET(1)], STRUCT(1, 2, 3)[ORDINAL(1)], STRUCT(1, 2, 3)[1], JSON "[1, 2, 3]"[1], JSON '{"a": 1, "b": 2, "c": 3}'["a"]
2 changes: 1 addition & 1 deletion testdata/result/statement/select_literals_all.sql.txt
Original file line number Diff line number Diff line change
Expand Up @@ -597,4 +597,4 @@ lines''',
}

--- SQL
SELECT "abc", "it\'s", "it\'s", "Title: \"Boy\"", "abc", "it\'s", "Title:\"Boy\"", "two\nlines", "why\?", "abc+", "abc+", "abc+", "f\\(abc,(.*),def\\)", B"abc", B"abc", B"abc", B"abc+", B"abc+", B"abc", 123, 0xABC, -123, -0xABC, 123.456e-67, .1E4, 58., 4e2, [1, 2, 3], ["x", "y", "xy"], ARRAY[1, 2, 3], ARRAY<STRING>["x", "y", "xy"], ARRAY<INT64>[], ARRAY(SELECT STRUCT(1, 2, 3)), ARRAY(SELECT (1, 2, 3)), DATE "2014-09-27", DATE("2014-09-27"), TIMESTAMP "2014-09-27 12:30:00.45-08", TIMESTAMP "2014-09-27 12:30:00.45 America/Los_Angeles", TIMESTAMP "2014-09-27", TIMESTAMP("2014-09-27"), JSON "1", JSON "[1, 2]", JSON "{}", NUMERIC "0", NUMERIC "0", TRUE, FALSE
SELECT "abc", "it's", "it's", 'Title: "Boy"', "abc", "it's", 'Title:"Boy"', "two\nlines", "why\?", "abc+", "abc+", "abc+", "f\\(abc,(.*),def\\)", b"abc", b"abc", b"abc", b"abc+", b"abc+", b"abc", 123, 0xABC, -123, -0xABC, 123.456e-67, .1E4, 58., 4e2, [1, 2, 3], ["x", "y", "xy"], ARRAY[1, 2, 3], ARRAY<STRING>["x", "y", "xy"], ARRAY<INT64>[], ARRAY(SELECT STRUCT(1, 2, 3)), ARRAY(SELECT (1, 2, 3)), DATE "2014-09-27", DATE("2014-09-27"), TIMESTAMP "2014-09-27 12:30:00.45-08", TIMESTAMP "2014-09-27 12:30:00.45 America/Los_Angeles", TIMESTAMP "2014-09-27", TIMESTAMP("2014-09-27"), JSON "1", JSON "[1, 2]", JSON "{}", NUMERIC "0", NUMERIC "0", TRUE, FALSE
2 changes: 1 addition & 1 deletion testdata/result/statement/select_literals_bytes.sql.txt
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,4 @@ SELECT
}

--- SQL
SELECT B"abc", B"abc", B"abc", B"abc\n", B"abc+", B"abc+", B"abc", B"abc\\n", B"\x00", B"\?\?\?"
SELECT b"abc", b"abc", b"abc", b"abc\n", b"abc+", b"abc+", b"abc", b"abc\\n", b"\x00", b"\?\?\?"
2 changes: 1 addition & 1 deletion testdata/result/statement/select_literals_string.sql.txt
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,4 @@ lines''',
}

--- SQL
SELECT "abc!", "a\nb!", "=!", "=!", "=!", "=!", "=!", "‼!", "🐈!", "it\'s", "it\'s", "Title: \"Boy\"", "abc", "it\'s", "Title:\"Boy\"", "two\nlines", "why\?", "abc+", "abc+", "abc+", "f\\(abc,(.*),def\\)"
SELECT "abc!", "a\nb!", "=!", "=!", "=!", "=!", "=!", "‼!", "🐈!", "it's", "it's", 'Title: "Boy"', "abc", "it's", 'Title:"Boy"', "two\nlines", "why\?", "abc+", "abc+", "abc+", "f\\(abc,(.*),def\\)"
Original file line number Diff line number Diff line change
Expand Up @@ -492,4 +492,4 @@ select
}

--- SQL
SELECT [1, 2, 3][OFFSET(1)], [1, 2, 3][ORDINAL(1)], [1, 2, 3][SAFE_OFFSET(1)], [1, 2, 3][ORDINAL(1)], [1, 2, 3][1], STRUCT(1, 2, 3)[OFFSET(1)], STRUCT(1, 2, 3)[ORDINAL(1)], STRUCT(1, 2, 3)[SAFE_OFFSET(1)], STRUCT(1, 2, 3)[ORDINAL(1)], STRUCT(1, 2, 3)[1], JSON "[1, 2, 3]"[1], JSON "{\"a\": 1, \"b\": 2, \"c\": 3}"["a"]
SELECT [1, 2, 3][OFFSET(1)], [1, 2, 3][ORDINAL(1)], [1, 2, 3][SAFE_OFFSET(1)], [1, 2, 3][ORDINAL(1)], [1, 2, 3][1], STRUCT(1, 2, 3)[OFFSET(1)], STRUCT(1, 2, 3)[ORDINAL(1)], STRUCT(1, 2, 3)[SAFE_OFFSET(1)], STRUCT(1, 2, 3)[ORDINAL(1)], STRUCT(1, 2, 3)[1], JSON "[1, 2, 3]"[1], JSON '{"a": 1, "b": 2, "c": 3}'["a"]
79 changes: 50 additions & 29 deletions token/quote.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,53 @@ import (

// QuoteSQLString returns quoted string with SQL string escaping.
func QuoteSQLString(s string) string {
quote := suitableQuote([]byte(s))

var buf bytes.Buffer
buf.WriteByte('"')
quoteSQLStringContent(s, &buf)
buf.WriteByte('"')
buf.WriteRune(quote)
quoteSQLStringContent(quote, s, &buf)
buf.WriteRune(quote)
return buf.String()
}

func suitableQuote(b []byte) rune {
var hasSingle, hasDouble bool
for _, b := range b {
switch b {
case '\'':
hasSingle = true
case '"':
hasDouble = true
}
}
if !hasSingle && hasDouble {
return '\''
}
return '"'
}

// QuoteSQLString returns quoted string with SQL bytes escaping.
func QuoteSQLBytes(bs []byte) string {
quote := suitableQuote(bs)

var buf bytes.Buffer
buf.WriteString("B\"")
buf.WriteString("b")
buf.WriteRune(quote)
for _, b := range bs {
q := quoteSingleEscape(rune(b))
q := quoteSingleEscape(quote, rune(b))
if q != "" {
buf.WriteString(q)
continue
}
if char.IsPrint(b) {

// Note: char.IsPrint(' ') is false
if b == ' ' || char.IsPrint(b) {
buf.WriteByte(b)
continue
}
fmt.Fprintf(&buf, "\\x%02X", uint64(b))
fmt.Fprintf(&buf, `\x%02x`, uint64(b))
}
buf.WriteRune('"')
buf.WriteRune(quote)
return buf.String()
}

Expand All @@ -46,14 +69,14 @@ func QuoteSQLIdent(s string) string {

var buf bytes.Buffer
buf.WriteByte('`')
quoteSQLStringContent(s, &buf)
quoteSQLStringContent('`', s, &buf)
buf.WriteByte('`')
return buf.String()
}

func quoteSQLStringContent(s string, buf *bytes.Buffer) {
func quoteSQLStringContent(quote rune, s string, buf *bytes.Buffer) {
for _, r := range s {
q := quoteSingleEscape(r)
q := quoteSingleEscape(quote, r)
if q != "" {
buf.WriteString(q)
continue
Expand All @@ -63,39 +86,37 @@ func quoteSQLStringContent(s string, buf *bytes.Buffer) {
continue
}
if r > 0xFFFF {
fmt.Fprintf(buf, "\\U%08X", uint64(r))
fmt.Fprintf(buf, `\U%08x`, uint64(r))
} else {
fmt.Fprintf(buf, "\\u%04X", uint64(r))
fmt.Fprintf(buf, `\u%04x`, uint64(r))
}
}
}

func quoteSingleEscape(r rune) string {
func quoteSingleEscape(quote, r rune) string {
if quote == r {
return `\` + string(r)
}

switch r {
case '\a':
return "\\a"
return `\a`
case '\b':
return "\\b"
return `\b`
case '\f':
return "\\f"
return `\f`
case '\n':
return "\\n"
return `\n`
case '\r':
return "\\r"
return `\r`
case '\t':
return "\\t"
return `\t`
case '\v':
return "\\v"
case '"':
return "\\\""
case '\'':
return "\\'"
case '`':
return "\\`"
return `\v`
case '?':
return "\\?"
return `\?`
case '\\':
return "\\\\"
return `\\`
}
return ""
}
Expand Down
14 changes: 7 additions & 7 deletions token/quote_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ var quoteTestCases = []struct {
input string
str, bytes, id string
}{
{"foo", `"foo"`, `B"foo"`, "foo"},
{"if", `"if"`, `B"if"`, "`if`"},
{"\u0000", `"\u0000"`, `B"\x00"`, "`\\u0000`"},
{"\U0010FFFF", `"\U0010FFFF"`, `B"\xF4\x8F\xBF\xBF"`, "`\\U0010FFFF`"},
{"a\u2060b", `"a\u2060b"`, `B"a\xE2\x81\xA0b"`, "`a\\u2060b`"},
{"\a\b\f\n\r\t\v\"'?\\", `"\a\b\f\n\r\t\v\"\'\?\\"`, `B"\a\b\f\n\r\t\v\"\'\?\\"`, "`\\a\\b\\f\\n\\r\\t\\v\\\"\\'\\?\\\\`"},
{"`", "\"\\`\"", "B\"\\`\"", "`\\``"},
{"foo", `"foo"`, `b"foo"`, "foo"},
{"if", `"if"`, `b"if"`, "`if`"},
{"\u0000", `"\u0000"`, `b"\x00"`, "`\\u0000`"},
{"\U0010FFFF", `"\U0010ffff"`, `b"\xf4\x8f\xbf\xbf"`, "`\\U0010ffff`"},
{"a\u2060b", `"a\u2060b"`, `b"a\xe2\x81\xa0b"`, "`a\\u2060b`"},
{"\a\b\f\n\r\t\v\"'?\\", `"\a\b\f\n\r\t\v\"'\?\\"`, `b"\a\b\f\n\r\t\v\"'\?\\"`, "`\\a\\b\\f\\n\\r\\t\\v\"'\\?\\\\`"},
{"`", "\"`\"", "b\"`\"", "`\\``"},
}

func TestQuote(t *testing.T) {
Expand Down

0 comments on commit 2f3206c

Please sign in to comment.