-
Notifications
You must be signed in to change notification settings - Fork 1
Description
The driver generates invalid PL/SQL code when performing bulk inserts with RETURNING clauses. The issue occurs in the OUT parameter assignment section of the generated PL/SQL block.
The driver generates invalid assignment statements like:
IF l_inserted_records.COUNT > 0 THEN 0 := l_inserted_records(1)."id"; END IF; IF l_inserted_records.COUNT > 0 THEN NULL := l_inserted_records(1)."created_at"; END IF;
Should generate valid PL/SQL assignments to OUT parameters like:
IF l_inserted_records.COUNT > 0 THEN :1 := l_inserted_records(1)."id"; END IF; IF l_inserted_records.COUNT > 0 THEN :2 := l_inserted_records(1)."created_at"; END IF;
Error:
ORA-06550: line 73, column 70:
PLS-00382: expression is of wrong type
ORA-06550: line 73, column 40:
PL/SQL: Statement ignored
Below is the test that tries to bulk insert multiple records that have fields with default database values (which triggers RETURNING clause usage).
Bulk insert operations fail when RETURNING clauses are needed, which affects any struct with auto-increment IDs or default timestamp fields.
Try this function in serializer_test.go:
`
func TestSerializerBulkInsert(t *testing.T) {
schema.RegisterSerializer("custom", NewCustomSerializer("hello"))
DB.Migrator().DropTable(adaptorSerializerModel(&SerializerStruct{}))
if err := DB.Migrator().AutoMigrate(adaptorSerializerModel(&SerializerStruct{})); err != nil {
t.Fatalf("no error should happen when migrate scanner, valuer struct, got error %v", err)
}
// Test bulk insert with serialized fields
data := []SerializerStruct{
{
Name: []byte("user1"),
Roles: []string{"admin", "user"},
Contracts: map[string]interface{}{"type": "full-time", "salary": 5000},
CustomSerializerString: "world1",
},
{
Name: []byte("user2"),
Roles: []string{"user"},
Contracts: map[string]interface{}{"type": "part-time", "salary": 2000},
CustomSerializerString: "world2",
},
}
if err := DB.Create(&data).Error; err != nil {
t.Fatalf("failed to bulk create data, got error %v", err)
}
var results []SerializerStruct
if err := DB.Find(&results).Error; err != nil {
t.Fatalf("failed to query bulk data, got error %v", err)
}
tests.AssertEqual(t, len(results), 2)
// Verify serialized data was properly stored and retrieved
for i, result := range results {
tests.AssertEqual(t, result.Roles, data[i].Roles)
tests.AssertEqual(t, result.Contracts, data[i].Contracts)
}
}
`