diff --git a/bind.go b/bind.go index ec0da4e7..4e1fd9fc 100644 --- a/bind.go +++ b/bind.go @@ -19,6 +19,7 @@ const ( DOLLAR NAMED AT + COLON ) var defaultBinds = map[int][]string{ @@ -78,6 +79,8 @@ func Rebind(bindType int, query string) string { rqb = append(rqb, ':', 'a', 'r', 'g') case AT: rqb = append(rqb, '@', 'p') + case COLON: + rqb = append(rqb, ':') } j++ diff --git a/named.go b/named.go index 728aa04d..6fdf41ab 100644 --- a/named.go +++ b/named.go @@ -383,6 +383,12 @@ func compileNamedQuery(qs []byte, bindType int) (query string, names []string, e rebound = append(rebound, byte(b)) } currentVar++ + case COLON: + rebound = append(rebound, ':') + for _, b := range strconv.Itoa(currentVar) { + rebound = append(rebound, byte(b)) + } + currentVar++ case AT: rebound = append(rebound, '@', 'p') for _, b := range strconv.Itoa(currentVar) { diff --git a/named_test.go b/named_test.go index 8481b35b..b5fe5565 100644 --- a/named_test.go +++ b/named_test.go @@ -8,8 +8,8 @@ import ( func TestCompileQuery(t *testing.T) { table := []struct { - Q, R, D, T, N string - V []string + Q, R, D, T, N, C string + V []string }{ // basic test for named parameters, invalid char ',' terminating { @@ -18,6 +18,7 @@ func TestCompileQuery(t *testing.T) { D: `INSERT INTO foo (a,b,c,d) VALUES ($1, $2, $3, $4)`, T: `INSERT INTO foo (a,b,c,d) VALUES (@p1, @p2, @p3, @p4)`, N: `INSERT INTO foo (a,b,c,d) VALUES (:name, :age, :first, :last)`, + C: `INSERT INTO foo (a,b,c,d) VALUES (:1, :2, :3, :4)`, V: []string{"name", "age", "first", "last"}, }, // This query tests a named parameter ending the string as well as numbers @@ -27,6 +28,7 @@ func TestCompileQuery(t *testing.T) { D: `SELECT * FROM a WHERE first_name=$1 AND last_name=$2`, T: `SELECT * FROM a WHERE first_name=@p1 AND last_name=@p2`, N: `SELECT * FROM a WHERE first_name=:name1 AND last_name=:name2`, + C: `SELECT * FROM a WHERE first_name=:1 AND last_name=:2`, V: []string{"name1", "name2"}, }, { @@ -35,6 +37,7 @@ func TestCompileQuery(t *testing.T) { D: `SELECT ":foo" FROM a WHERE first_name=$1 AND last_name=$2`, T: `SELECT ":foo" FROM a WHERE first_name=@p1 AND last_name=@p2`, N: `SELECT ":foo" FROM a WHERE first_name=:name1 AND last_name=:name2`, + C: `SELECT ":foo" FROM a WHERE first_name=:1 AND last_name=:2`, V: []string{"name1", "name2"}, }, { @@ -43,6 +46,7 @@ func TestCompileQuery(t *testing.T) { D: `SELECT 'a:b:c' || first_name, '::ABC:_:' FROM person WHERE first_name=$1 AND last_name=$2`, T: `SELECT 'a:b:c' || first_name, '::ABC:_:' FROM person WHERE first_name=@p1 AND last_name=@p2`, N: `SELECT 'a:b:c' || first_name, '::ABC:_:' FROM person WHERE first_name=:first_name AND last_name=:last_name`, + C: `SELECT 'a:b:c' || first_name, '::ABC:_:' FROM person WHERE first_name=:1 AND last_name=:2`, V: []string{"first_name", "last_name"}, }, { @@ -51,6 +55,7 @@ func TestCompileQuery(t *testing.T) { D: `SELECT @name := "name", $1, $2, $3`, N: `SELECT @name := "name", :age, :first, :last`, T: `SELECT @name := "name", @p1, @p2, @p3`, + C: `SELECT @name := "name", :1, :2, :3`, V: []string{"age", "first", "last"}, }, /* This unicode awareness test sadly fails, because of our byte-wise worldview. @@ -96,6 +101,12 @@ func TestCompileQuery(t *testing.T) { if qq != test.N { t.Errorf("\nexpected: `%s`\ngot: `%s`\n(len: %d vs %d)", test.N, qq, len(test.N), len(qq)) } + + qc, _, _ := compileNamedQuery([]byte(test.Q), COLON) + if qc != test.C { + t.Errorf("\nexpected: `%s`\ngot: `%s`\n(len: %d vs %d)", test.C, qc, len(test.C), len(qc)) + } + } }