dttung2905 commented on code in PR #85:
URL:
https://github.com/apache/terraform-provider-iceberg/pull/85#discussion_r3696772611
##########
internal/provider/table_schema.go:
##########
@@ -102,6 +102,142 @@ func (s *icebergTableSchema) FromIceberg(icebergSchema
*iceberg.Schema) error {
return json.Unmarshal(b, s)
}
+// fieldIDUnset reports an unspecified field ID: null, unknown, or 0 (Iceberg
+// reserves 0 for the table root).
+func fieldIDUnset(id types.Int64) bool {
+ return id.IsNull() || id.IsUnknown() || id.ValueInt64() == 0
+}
+
+// assignFieldIDs fills unset IDs (nested struct/list/map included) with fresh
+// values above startAfter and every existing ID, preserving user-set ones.
Pass
+// the table's last-column-id on update.
+func (s *icebergTableSchema) assignFieldIDs(startAfter int64) {
+ maxID := startAfter
+
+ var scan func(fields []icebergTableSchemaField)
+ scan = func(fields []icebergTableSchemaField) {
+ for _, f := range fields {
+ maxID = maxSetID(maxID, f.ID)
+ if f.ListProperties != nil {
+ maxID = maxSetID(maxID, f.ListProperties.ID)
+ }
+ if f.MapProperties != nil {
+ maxID = maxSetID(maxID, f.MapProperties.KeyID)
+ maxID = maxSetID(maxID, f.MapProperties.ValueID)
+ }
+ if f.StructProperties != nil {
+ scan(f.StructProperties.Fields)
+ }
+ }
+ }
+ scan(s.Fields)
+
+ next := func() types.Int64 {
+ maxID++
+
+ return types.Int64Value(maxID)
+ }
+
+ var assign func(fields []icebergTableSchemaField)
+ assign = func(fields []icebergTableSchemaField) {
+ for i := range fields {
+ f := &fields[i]
+ if fieldIDUnset(f.ID) {
+ f.ID = next()
+ }
+ if f.ListProperties != nil &&
fieldIDUnset(f.ListProperties.ID) {
+ f.ListProperties.ID = next()
+ }
+ if f.MapProperties != nil {
+ if fieldIDUnset(f.MapProperties.KeyID) {
+ f.MapProperties.KeyID = next()
+ }
+ if fieldIDUnset(f.MapProperties.ValueID) {
+ f.MapProperties.ValueID = next()
+ }
+ }
+ if f.StructProperties != nil {
+ assign(f.StructProperties.Fields)
+ }
+ }
+ }
+ assign(s.Fields)
+}
+
+func maxSetID(current int64, id types.Int64) int64 {
+ if fieldIDUnset(id) {
+ return current
+ }
+ if v := id.ValueInt64(); v > current {
+ return v
+ }
+
+ return current
+}
+
+// fieldIDs holds one field's IDs: the field plus any list/map
element/key/value.
+type fieldIDs struct {
+ id types.Int64
+ element types.Int64
+ key types.Int64
+ value types.Int64
+}
+
+// resolveFieldIDs reuses prior IDs for same-named fields (matched by path, so
+// nested fields stay scoped to their parent), keeping IDs stable across
+// inserts/reorders. Fills only unset IDs.
+func (s *icebergTableSchema) resolveFieldIDs(prior *icebergTableSchema) {
+ byPath := map[string]fieldIDs{}
+
+ var index func(path string, fields []icebergTableSchemaField)
+ index = func(path string, fields []icebergTableSchemaField) {
+ for _, f := range fields {
+ key := path + "/" + f.Name
Review Comment:
since we use this to be the key, what happen during column rename without
setting `id` means allocating a new id and drop the old column. If we
intentionally do that, its worth to note that in the doc, else we should take
care of such case to have true rename column action
--
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]