mattfaltyn opened a new issue, #1903:
URL: https://github.com/apache/iceberg-go/issues/1903

   ### Apache Iceberg version
   
   main (development) at `c9813324fb8617ba5c889d939b0d883e85f7eb1e`
   
   ### Please describe the bug 🐞
   
   `UpdateSchema` silently drops an additional column when a move is staged 
relative to a column that is deleted in the same update.
   
   Given a schema with `id`, `name`, and `age`, both operation orders succeed:
   
   ```go
   update.DeleteColumn([]string{"name"}).
       MoveBefore([]string{"age"}, []string{"name"})
   ```
   
   ```go
   update.MoveBefore([]string{"age"}, []string{"name"}).
       DeleteColumn([]string{"name"})
   ```
   
   `Apply()` returns no error, but the resulting schema contains only `id`. The 
requested deletion of `name` also removes `age` unintentionally. `Commit()` 
builds its persisted schema update from this result.
   
   Minimal reproduction:
   
   ```go
   schema := iceberg.NewSchema(1,
       iceberg.NestedField{ID: 1, Name: "id", Type: 
iceberg.PrimitiveTypes.Int32, Required: true},
       iceberg.NestedField{ID: 2, Name: "name", Type: 
iceberg.PrimitiveTypes.String},
       iceberg.NestedField{ID: 3, Name: "age", Type: 
iceberg.PrimitiveTypes.Int32},
   )
   metadata, err := table.NewMetadata(schema, nil, table.UnsortedSortOrder, "", 
nil)
   require.NoError(t, err)
   tbl := table.New(table.Identifier{"db", "people"}, metadata, "", nil, nil)
   
   updated, err := table.NewUpdateSchema(tbl.NewTransaction(), true, true).
       DeleteColumn([]string{"name"}).
       MoveBefore([]string{"age"}, []string{"name"}).
       Apply()
   
   require.NoError(t, err)
   require.Equal(t, []string{"id"}, fieldNames(updated.Fields())) // age is 
silently lost
   ```
   
   Expected behavior: reject the conflicting operations with an actionable 
error. A move cannot be applied relative to a field that will not exist in the 
resulting schema.
   
   Root cause: `moveColumn` validates that the moved field is not deleted, but 
does not validate its relative target. Later, `moveFields` removes the moved 
field before searching for the target; when the target is absent, it continues 
without reinserting the moved field.
   
   This is distinct from #1685/#1686 (moving newly added nested fields), 
#1687/#1688 (adding beneath deleted ancestors), and #1778/#1779 (deleting a 
field with its own pending update).
   
   I will submit a focused fix with regression coverage for both operation 
orders and both `MoveBefore` and `MoveAfter`.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to