From bce92c688c3f839e5948005a44b8494b4a2dc57c Mon Sep 17 00:00:00 2001 From: Alan Braithwaite Date: Thu, 8 Apr 2021 11:17:44 -0400 Subject: [PATCH] named: support mysql 5.7 and earlier syntax --- named.go | 8 +++++--- named_test.go | 22 ++++++++++++++++------ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/named.go b/named.go index 1f416121..89329d28 100644 --- a/named.go +++ b/named.go @@ -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 diff --git a/named_test.go b/named_test.go index 70bc4484..1967d79f 100644 --- a/named_test.go +++ b/named_test.go @@ -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)`, @@ -354,6 +348,20 @@ 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 { @@ -361,6 +369,8 @@ func TestFixBounds(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) } }) }