Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(normalizer): normalize to no backquote #45

Merged
merged 2 commits into from
Jan 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions normalizer/query_normalizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,31 @@ import (
"strings"
)

// IN (?, ?, ?) -> IN (?)
// VALUES (?, ?, ?) -> VALUES (?)

var spaceRegex = regexp.MustCompile(`\s+`)
var inRegex = regexp.MustCompile(`IN\s+\((\?,\s*)+\?\)`)
var valuesRegex = regexp.MustCompile(`VALUES\s+\((\?,\s*)+\?\)`)

func NormalizeQuery(query string) string {
// remove spaces
query = strings.ReplaceAll(query, "\r", " ")
query = strings.ReplaceAll(query, "\n", " ")
query = strings.ReplaceAll(query, "\t", " ")
query = spaceRegex.ReplaceAllString(query, " ")
query = strings.TrimSpace(query)

// remove backquotes
query = strings.ReplaceAll(query, "`", "")

// IN (?, ?, ?) -> IN (?)
query = inRegex.ReplaceAllString(query, "IN (?)")

// VALUES (?, ?, ?) -> VALUES (?)
query = valuesRegex.ReplaceAllString(query, "VALUES (?)")

// add semicolon
if !strings.HasSuffix(query, ";") {
query += ";"
}

return query
}
20 changes: 12 additions & 8 deletions normalizer/query_normalizer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,28 @@ func TestNormalizeQuery(t *testing.T) {
expected string
}{
{
query: " SELECT * from `table`; ",
expected: "SELECT * from `table`;",
query: " SELECT * from table; ",
expected: "SELECT * from table;",
},
{
query: "SELECT `id` from `table`;",
expected: "SELECT `id` from `table`;",
query: "SELECT * \t\n from table;",
expected: "SELECT * from table;",
},
{
query: "SELECT `id` from table;",
expected: "SELECT id from table;",
},
{
query: "INSERT INTO table (name, col) VALUES (?, ?);",
expected: "INSERT INTO table (name, col) VALUES (?);",
},
{
query: "DELETE FROM `table` WHERE id IN (?, ?, ?, ?);",
expected: "DELETE FROM `table` WHERE id IN (?);",
query: "DELETE FROM table WHERE id IN (?, ?, ?, ?);",
expected: "DELETE FROM table WHERE id IN (?);",
},
{
query: "SELECT * FROM `table`",
expected: "SELECT * FROM `table`;",
query: "SELECT * FROM table",
expected: "SELECT * FROM table;",
},
}
for _, tt := range tests {
Expand Down
4 changes: 2 additions & 2 deletions sql_parser/stringer.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,13 @@ func (n ColumnsNode) String() string {
var _ SQLNode = ColumnNode{}

func (n ColumnNode) String() string {
return fmt.Sprintf("`%s`", n.Name)
return n.Name
}

var _ SQLNode = TableNode{}

func (n TableNode) String() string {
return fmt.Sprintf("`%s`", n.Name)
return n.Name
}

var _ SQLNode = ValuesNode{}
Expand Down
16 changes: 8 additions & 8 deletions sql_parser/stringer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ func TestStringer(t *testing.T) {
Values: SelectValuesNode{Values: []SQLNode{SelectValueColumnNode{Column: ColumnNode{Name: "id"}}}},
Table: TableNode{Name: "users"},
},
expected: "SELECT `id` FROM `users`;",
expected: "SELECT id FROM users;",
},
{
expected: "SELECT * FROM `users` WHERE `id` = ?;",
expected: "SELECT * FROM users WHERE id = ?;",
input: SelectStmtNode{
Values: SelectValuesNode{Values: []SQLNode{SelectValueAsteriskNode{}}},
Table: TableNode{Name: "users"},
Expand Down Expand Up @@ -56,7 +56,7 @@ func TestStringer(t *testing.T) {
},
},
},
expected: "SELECT `name`, `age` FROM `users` WHERE `age` > 18 AND `name` LIKE '%test%';",
expected: "SELECT name, age FROM users WHERE age > 18 AND name LIKE '%test%';",
},
{
input: SelectStmtNode{
Expand All @@ -72,7 +72,7 @@ func TestStringer(t *testing.T) {
},
},
},
expected: "SELECT * FROM `users` WHERE `id` IN (1, 2, 3);",
expected: "SELECT * FROM users WHERE id IN (1, 2, 3);",
},
{
input: SelectStmtNode{
Expand Down Expand Up @@ -103,7 +103,7 @@ func TestStringer(t *testing.T) {
Limit: &LimitNode{Limit: NumberNode{Value: 10}},
Offset: &OffsetNode{Offset: NumberNode{Value: 0}},
},
expected: "SELECT COUNT(*) FROM `users` WHERE `id` = ? AND `name` = 'Alice' ORDER BY `id` ASC LIMIT 10 OFFSET 0;",
expected: "SELECT COUNT(*) FROM users WHERE id = ? AND name = 'Alice' ORDER BY id ASC LIMIT 10 OFFSET 0;",
},
{
input: UpdateStmtNode{
Expand All @@ -124,7 +124,7 @@ func TestStringer(t *testing.T) {
},
},
},
expected: "UPDATE `users` SET `name` = 'Bob', `age` = 20 WHERE `id` = ?;",
expected: "UPDATE users SET name = 'Bob', age = 20 WHERE id = ?;",
},
{
input: DeleteStmtNode{
Expand All @@ -139,7 +139,7 @@ func TestStringer(t *testing.T) {
},
},
},
expected: "DELETE FROM `users` WHERE `id` = ?;",
expected: "DELETE FROM users WHERE id = ?;",
},
{
input: InsertStmtNode{
Expand All @@ -151,7 +151,7 @@ func TestStringer(t *testing.T) {
Values: []SQLNode{StringNode{Value: "Cathy"}, NumberNode{Value: 30}},
},
},
expected: "INSERT INTO `users` (`name`, `age`) VALUES ('Cathy', 30);",
expected: "INSERT INTO users (name, age) VALUES ('Cathy', 30);",
},
}

Expand Down
Loading