uptrace/bun

Unexpected Data Truncation in CTE with Type Casting During Bulk Update

Open

#1,093 opened on 2025年1月1日

GitHub で見る
 (7 comments) (0 reactions) (1 assignee)Go (4,826 stars) (279 forks)user submission
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.

コントリビューターガイド

Unexpected Data Truncation in CTE with Type Casting During Bulk Update · uptrace/bun#1093 | Good First Issue