From c7b333fb95bae95c25577a68356f788656c84488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20M=C3=B6hlmann?= Date: Sat, 27 Sep 2025 16:16:15 +0300 Subject: [PATCH] fix(rt): allow duplicate query arguments (#10809) --- backend/v3/storage/database/statement.go | 18 +-------------- backend/v3/storage/database/statement_test.go | 22 +++++++------------ 2 files changed, 9 insertions(+), 31 deletions(-) diff --git a/backend/v3/storage/database/statement.go b/backend/v3/storage/database/statement.go index 77af573f5ee..f7e7a131c51 100644 --- a/backend/v3/storage/database/statement.go +++ b/backend/v3/storage/database/statement.go @@ -1,7 +1,6 @@ package database import ( - "encoding/hex" "strconv" "strings" ) @@ -17,8 +16,7 @@ const ( // StatementBuilder is a helper to build SQL statement. type StatementBuilder struct { strings.Builder - args []any - existingArgs map[any]string + args []any } type argWriter interface { @@ -47,30 +45,16 @@ func (b *StatementBuilder) WriteArgs(args ...any) { // AppendArg adds the argument to the statement and returns the placeholder. func (b *StatementBuilder) AppendArg(arg any) (placeholder string) { - if b.existingArgs == nil { - b.existingArgs = make(map[any]string) - } - // the key is used to work around the following panic: - // runtime error: hash of unhashable type []uint8 - key := arg - if argBytes, ok := arg.([]uint8); ok { - key = `\\bytes-` + hex.EncodeToString(argBytes) - } - if placeholder, ok := b.existingArgs[key]; ok { - return placeholder - } if instruction, ok := arg.(Instruction); ok { return string(instruction) } b.args = append(b.args, arg) placeholder = "$" + strconv.Itoa(len(b.args)) - b.existingArgs[key] = placeholder return placeholder } // AppendArgs adds the arguments to the statement and doesn't return the placeholders. -// If an argument is already added, it will not be added again. func (b *StatementBuilder) AppendArgs(args ...any) { for _, arg := range args { b.AppendArg(arg) diff --git a/backend/v3/storage/database/statement_test.go b/backend/v3/storage/database/statement_test.go index 147043e8c28..90a2b5d6914 100644 --- a/backend/v3/storage/database/statement_test.go +++ b/backend/v3/storage/database/statement_test.go @@ -8,13 +8,12 @@ import ( ) func TestStatementBuilder_AppendArg(t *testing.T) { - t.Run("same arg returns same placeholder", func(t *testing.T) { + t.Run("same arg returns different placeholder", func(t *testing.T) { var b StatementBuilder placeholder1 := b.AppendArg("same") placeholder2 := b.AppendArg("same") - assert.Equal(t, placeholder1, placeholder2) - assert.Len(t, b.Args(), 1) - assert.Len(t, b.existingArgs, 1) + assert.NotEqual(t, placeholder1, placeholder2) + assert.Len(t, b.Args(), 2) }) t.Run("same arg different types", func(t *testing.T) { @@ -23,9 +22,8 @@ func TestStatementBuilder_AppendArg(t *testing.T) { placeholder2 := b.AppendArg([]byte("same")) placeholder3 := b.AppendArg("same") assert.NotEqual(t, placeholder1, placeholder2) - assert.Equal(t, placeholder1, placeholder3) - assert.Len(t, b.Args(), 2) - assert.Len(t, b.existingArgs, 2) + assert.NotEqual(t, placeholder1, placeholder3) + assert.Len(t, b.Args(), 3) }) t.Run("Instruction args are always different", func(t *testing.T) { @@ -34,30 +32,26 @@ func TestStatementBuilder_AppendArg(t *testing.T) { placeholder2 := b.AppendArg(DefaultInstruction) assert.Equal(t, placeholder1, placeholder2) assert.Len(t, b.Args(), 0) - assert.Len(t, b.existingArgs, 0) }) } func TestStatementBuilder_AppendArgs(t *testing.T) { - t.Run("same arg returns same placeholder", func(t *testing.T) { + t.Run("same arg returns different placeholder", func(t *testing.T) { var b StatementBuilder b.AppendArgs("same", "same") - assert.Len(t, b.Args(), 1) - assert.Len(t, b.existingArgs, 1) + assert.Len(t, b.Args(), 2) }) t.Run("same arg different types", func(t *testing.T) { var b StatementBuilder b.AppendArgs("same", []byte("same"), "same") - assert.Len(t, b.Args(), 2) - assert.Len(t, b.existingArgs, 2) + assert.Len(t, b.Args(), 3) }) t.Run("Instruction args are always different", func(t *testing.T) { var b StatementBuilder b.AppendArgs(DefaultInstruction, DefaultInstruction) assert.Len(t, b.Args(), 0) - assert.Len(t, b.existingArgs, 0) }) }