mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-26 05:06:28 +00:00
fix(rt): allow duplicate query arguments (#10809)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user