Skip to content

Commit 617c375

Browse files
committed
cgosqlite: support named parameters with $ prefix
This allows using the "$VVV" syntax for named parameters in SQLite, as described in https://sqlite.org/c3ref/bind_blob.html Updates tailscale/corp#35883 Signed-off-by: Andrew Dunham <andrew@tailscale.com>
1 parent e28eaf5 commit 617c375

2 files changed

Lines changed: 42 additions & 0 deletions

File tree

cgosqlite/cgosqlite.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,9 @@ func (stmt *Stmt) BindParameterIndexSearch(name string) int {
357357
if i := stmt.BindParameterIndex("@" + name); i > 0 {
358358
return i
359359
}
360+
if i := stmt.BindParameterIndex("$" + name); i > 0 {
361+
return i
362+
}
360363
return stmt.BindParameterIndex("?" + name)
361364
}
362365

cgosqlite/cgosqlite_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,45 @@ import (
88
"github.com/tailscale/sqlite/sqliteh"
99
)
1010

11+
func TestBindParameterIndexSearch(t *testing.T) {
12+
db, err := Open(filepath.Join(t.TempDir(), "test.db"), sqliteh.OpenFlagsDefault, "")
13+
if err != nil {
14+
t.Fatal(err)
15+
}
16+
defer db.Close()
17+
18+
tests := []struct {
19+
name string
20+
query string
21+
param string
22+
wantOK bool
23+
}{
24+
{"colon", "SELECT :foo", "foo", true},
25+
{"at_sybol", "SELECT @foo", "foo", true},
26+
{"dollar", "SELECT $foo", "foo", true},
27+
{"question", "SELECT ?123", "123", true},
28+
{"not_found", "SELECT :bar", "foo", false},
29+
{"dollar_multiple_params", "SELECT $a, $b, $c", "b", true},
30+
}
31+
32+
for _, tt := range tests {
33+
t.Run(tt.name, func(t *testing.T) {
34+
stmt, _, err := db.Prepare(tt.query, 0)
35+
if err != nil {
36+
t.Fatalf("Prepare %q: %v", tt.query, err)
37+
}
38+
defer stmt.Finalize()
39+
40+
idx := stmt.BindParameterIndexSearch(tt.param)
41+
gotOK := idx > 0
42+
if gotOK != tt.wantOK {
43+
t.Errorf("BindParameterIndexSearch(%q) = %d, wantOK=%v gotOK=%v",
44+
tt.param, idx, tt.wantOK, gotOK)
45+
}
46+
})
47+
}
48+
}
49+
1150
func TestColumnBlob(t *testing.T) {
1251
// Run the test with and without the SetAlwaysCopyBlob flag enabled.
1352
cases := []struct {

0 commit comments

Comments
 (0)