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

named: support mysql 5.7 and earlier syntax #721

Closed
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
8 changes: 5 additions & 3 deletions named.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,13 +224,15 @@ func bindStruct(bindType int, query string, arg interface{}, m *reflectx.Mapper)
return bound, arglist, nil
}

var valueBracketReg = regexp.MustCompile(`(?i)VALUES\s*(\([^(]*.[^(]\))`)
var valueBracketReg = regexp.MustCompile(`(?i)VALUES\s*(\([^\(]*\))`)

func fixBound(bound string, loop int) string {

loc := valueBracketReg.FindAllStringSubmatchIndex(bound, -1)
// Either no VALUES () found or more than one found??
if len(loc) != 1 {
// Either no VALUES () found or
// More than one match may be found due to MySQL values syntax, however
// only the first match will be used for changing the query
if len(loc) < 1 {
return bound
}
// defensive guard. loc should be len 4 representing the starting and
Expand Down
22 changes: 16 additions & 6 deletions named_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,12 +336,6 @@ func TestFixBounds(t *testing.T) {
expect: `INSERT INTO foo (a,b,c,d) (:name, :age, :first, :last)`,
loop: 2,
},
{
name: `found twice test`,
query: `INSERT INTO foo (a,b,c,d) VALUES (:name, :age, :first, :last) VALUES (:name, :age, :first, :last)`,
expect: `INSERT INTO foo (a,b,c,d) VALUES (:name, :age, :first, :last) VALUES (:name, :age, :first, :last)`,
loop: 2,
},
{
name: `nospace`,
query: `INSERT INTO foo (a,b) VALUES(:a, :b)`,
Expand All @@ -354,13 +348,29 @@ func TestFixBounds(t *testing.T) {
expect: `INSERT INTO foo (a,b) values(:a, :b),(:a, :b)`,
loop: 2,
},
{
name: `mysql values syntax test`,
query: `INSERT INTO foo (a,b,c,d) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE a=VALUES(a),b=VALUES(b),c=VALUES(c),d=VALUES(d)`,
expect: `INSERT INTO foo (a,b,c,d) VALUES (?, ?, ?, ?),(?, ?, ?, ?) ON DUPLICATE KEY UPDATE a=VALUES(a),b=VALUES(b),c=VALUES(c),d=VALUES(d)`,
loop: 2,
},
// This is invalid SQL, but expected behavior to support the above mysql behavior
// garbage in, garbage out. sqlx does not detect already-broken SQL by design
{
name: `found twice test`,
query: `INSERT INTO foo (a,b,c,d) VALUES (:name, :age, :first, :last) VALUES (:name, :age, :first, :last)`,
expect: `INSERT INTO foo (a,b,c,d) VALUES (:name, :age, :first, :last),(:name, :age, :first, :last) VALUES (:name, :age, :first, :last)`,
loop: 2,
},
}

for _, tc := range table {
t.Run(tc.name, func(t *testing.T) {
res := fixBound(tc.query, tc.loop)
if res != tc.expect {
t.Errorf("mismatched results")
t.Logf("expected: %s", tc.expect)
t.Logf("actual: %s", res)
}
})
}
Expand Down