From 6687a7a5cdfb6452d46ed1c85a4224c30c3d5169 Mon Sep 17 00:00:00 2001 From: Hein Date: Mon, 28 Sep 2026 12:01:38 +0200 Subject: [PATCH] fix(bun): spread variadic args correctly in ColumnExpr --- pkg/common/adapters/database/bun.go | 2 +- .../adapters/database/bun_columnexpr_test.go | 31 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 pkg/common/adapters/database/bun_columnexpr_test.go diff --git a/pkg/common/adapters/database/bun.go b/pkg/common/adapters/database/bun.go index 691bde7..de65185 100644 --- a/pkg/common/adapters/database/bun.go +++ b/pkg/common/adapters/database/bun.go @@ -339,7 +339,7 @@ func (b *BunSelectQuery) Column(columns ...string) common.SelectQuery { func (b *BunSelectQuery) ColumnExpr(query string, args ...interface{}) common.SelectQuery { if len(args) > 0 { - b.query = b.query.ColumnExpr(query, args) + b.query = b.query.ColumnExpr(query, args...) } else { b.query = b.query.ColumnExpr(query) } diff --git a/pkg/common/adapters/database/bun_columnexpr_test.go b/pkg/common/adapters/database/bun_columnexpr_test.go new file mode 100644 index 0000000..7c3f96a --- /dev/null +++ b/pkg/common/adapters/database/bun_columnexpr_test.go @@ -0,0 +1,31 @@ +package database + +import ( + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +// TestBunSelectQuery_ColumnExpr_SpreadsArgs is a regression test for a bug +// where ColumnExpr passed its variadic args slice as a single argument +// (b.query.ColumnExpr(query, args) instead of args...), causing bun to +// serialize the arg slice itself (e.g. producing `'["{product,cost}"]'` +// instead of `'{product,cost}'` for a JSON path parameter). +func TestBunSelectQuery_ColumnExpr_SpreadsArgs(t *testing.T) { + db := setupBunTestDB(t) + defer db.Close() + + adapter := NewBunAdapter(db) + + sq := adapter.NewSelect(). + Table("test_inserts"). + ColumnExpr("(jsonvalue #>> ?::text[]) AS jsonvalue_product_cost", "{product,cost}") + + bsq, ok := sq.(*BunSelectQuery) + require.True(t, ok, "expected *BunSelectQuery") + + sqlStr := bsq.query.String() + require.NotContains(t, sqlStr, `["{product,cost}"]`, "arg slice must not be serialized as a JSON array: %s", sqlStr) + require.True(t, strings.Contains(sqlStr, `'{product,cost}'`), "expected the bound text[] literal in SQL: %s", sqlStr) +}