From 4c69699c8d4aa5bb185be5fa32b5e14aa51f0054 Mon Sep 17 00:00:00 2001 From: Mike Johnson Date: Sat, 20 Dec 2025 07:41:42 -0800 Subject: [PATCH 1/2] fix panic on in list expansion with a subselect --- bind.go | 5 +++-- bind_test.go | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/bind.go b/bind.go index 266e14e..034272b 100644 --- a/bind.go +++ b/bind.go @@ -212,8 +212,9 @@ func In(query string, args ...interface{}) (string, []interface{}, error) { argMeta := meta[arg] arg++ - // not an in-list - if !inIn { + if !inIn || !argMeta.v.IsValid() { + // this QuestionMark is not in an in-list that needs expansion. + // if v is invalid, then the arg isn't a slice newArgs = append(newArgs, argMeta.i) buf.WriteString(token.Text) continue diff --git a/bind_test.go b/bind_test.go index 77baafa..b1d9016 100644 --- a/bind_test.go +++ b/bind_test.go @@ -3,6 +3,10 @@ package sqlx import ( "math/rand" "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func oldBindType(driverName string) int { @@ -77,3 +81,14 @@ func BenchmarkBindSpeed(b *testing.B) { }) } + +func TestInNotSlice(t *testing.T) { + now := time.Now() + args := []any{[]string{"a", "b"}, now} + query := ` SELECT * FROM person WHERE first_name IN (?) AND id IN ( SELECT id FROM something WHERE created_at = ? )` + insql, newArgs, err := In(query, args...) + require.NoError(t, err) + assert.Contains(t, insql, "IN (?, ?)") + assert.Contains(t, insql, "WHERE created_at = ? )") + assert.Equal(t, []any{"a", "b", now}, newArgs) +} From 1da3f9346d9eae3068241b7ad3a2e7a02776c834 Mon Sep 17 00:00:00 2001 From: Mike Johnson Date: Fri, 26 Dec 2025 13:07:36 -0800 Subject: [PATCH 2/2] apply name suggestion --- bind.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bind.go b/bind.go index 0a710c1..178c189 100644 --- a/bind.go +++ b/bind.go @@ -211,10 +211,9 @@ func In(query string, args ...any) (string, []any, error) { argMeta := meta[arg] arg++ + isSlice := argMeta.v.IsValid() - if !inIn || !argMeta.v.IsValid() { - // this QuestionMark is not in an in-list that needs expansion. - // if v is invalid, then the arg isn't a slice + if !inIn || !isSlice { newArgs = append(newArgs, argMeta.i) buf.WriteString(token.Text) continue