uptrace/bun
GitHub で見るUnexpected Data Truncation in CTE with Type Casting During Bulk Update
Open
#1,093 opened on 2025年1月1日
enhancementhelp wanted
説明
Hello,
I have encountered an issue with data truncation caused by type casting for a bulk update with CTEs. Below is a minimal reproducible example and the SQL query generated by the ORM (this code is in internal/dbtest/pg_test.go ):
func TestBulkUpdate(t *testing.T) {
type Model struct {
ID int64
Name string `bun:",type:varchar(3)"`
}
db := pg(t)
t.Cleanup(func() { db.Close() })
mustResetModel(t, ctx, db, (*Model)(nil))
models := []*Model{
{ID: 1, Name: "foo"},
{ID: 2, Name: "bar"},
}
_, err := db.NewInsert().Model(&models).Exec(ctx)
require.NoError(t, err)
models[0].Name = "abcd"
res, err := db.NewUpdate().
With("_data", db.NewValues(&models)).
Model((*Model)(nil)).
TableExpr("_data").
Set("name = _data.name").
Where("model.id = _data.id").
Exec(ctx)
require.NoError(t, err) // pass
require.Equal(t, models[0].Name, updatedModels[0].Name) // failed (expected: abcd, actual: abc)
}
generated sql:
WITH "_data" ("id", "name") AS (
VALUES (1::BIGINT, 'abcd'::varchar(3)), (2::BIGINT, 'bar'::varchar(3))
)
UPDATE "models" AS "model"
SET name = _data.name
FROM _data
WHERE (model.id = _data.id)
The issue occurs because of the type casting in the VALUES clause ('abcd'::varchar(3)), which results in data truncation ('abcd' becomes 'abc'). This behavior seems problematic for the following reasons:
- The ORM silently truncates data without throwing any error or warning.
- This could lead to unexpected data loss, especially if the developer is unaware of the database type constraints.
- It does not align with the general expectation of ORMs preventing silent data corruption.
Could the ORM be enhanced to either:
- Avoid type casting in CTEs when it's not strictly necessary?
- Add a configuration option to handle this behavior explicitly?
Thank you for your time and consideration. Let me know if you need any further details or clarifications.