This is an automated email from the ASF dual-hosted git repository.

zeroshade pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iceberg-terraform.git


The following commit(s) were added to refs/heads/main by this push:
     new 44d2417  Adds support for partition spec + sort order (#23)
44d2417 is described below

commit 44d241743da55a90dc2575afb13db903ba4116c3
Author: Alex Stephen <[email protected]>
AuthorDate: Tue Mar 24 09:18:16 2026 -0700

    Adds support for partition spec + sort order (#23)
    
    * Partition spec and sort ID
    
    * PR changes
---
 go.mod                                   |   1 +
 go.sum                                   |   2 +
 internal/provider/resource_table.go      | 228 ++++++++++++++++++++++++++++++-
 internal/provider/resource_table_test.go | 160 ++++++++++++++++++++++
 internal/provider/table_schema.go        | 107 +++++++++++++++
 5 files changed, 496 insertions(+), 2 deletions(-)

diff --git a/go.mod b/go.mod
index 5851bc2..e6520a6 100644
--- a/go.mod
+++ b/go.mod
@@ -20,6 +20,7 @@ go 1.25.1
 require (
        github.com/apache/iceberg-go v0.4.1-0.20260201105728-7cfbf238ee7f
        github.com/hashicorp/terraform-plugin-framework v1.17.0
+       github.com/hashicorp/terraform-plugin-framework-validators v0.17.0
        github.com/hashicorp/terraform-plugin-go v0.29.0
        github.com/hashicorp/terraform-plugin-log v0.10.0
        github.com/hashicorp/terraform-plugin-testing v1.14.0
diff --git a/go.sum b/go.sum
index 5d48a01..cf0f2d7 100644
--- a/go.sum
+++ b/go.sum
@@ -361,6 +361,8 @@ github.com/hashicorp/terraform-json v0.27.2 
h1:BwGuzM6iUPqf9JYM/Z4AF1OJ5VVJEEzoK
 github.com/hashicorp/terraform-json v0.27.2/go.mod 
h1:GzPLJ1PLdUG5xL6xn1OXWIjteQRT2CNT9o/6A9mi9hE=
 github.com/hashicorp/terraform-plugin-framework v1.17.0 
h1:JdX50CFrYcYFY31gkmitAEAzLKoBgsK+iaJjDC8OexY=
 github.com/hashicorp/terraform-plugin-framework v1.17.0/go.mod 
h1:4OUXKdHNosX+ys6rLgVlgklfxN3WHR5VHSOABeS/BM0=
+github.com/hashicorp/terraform-plugin-framework-validators v0.17.0 
h1:0uYQcqqgW3BMyyve07WJgpKorXST3zkpzvrOnf3mpbg=
+github.com/hashicorp/terraform-plugin-framework-validators v0.17.0/go.mod 
h1:VwdfgE/5Zxm43flraNa0VjcvKQOGVrcO4X8peIri0T0=
 github.com/hashicorp/terraform-plugin-go v0.29.0 
h1:1nXKl/nSpaYIUBU1IG/EsDOX0vv+9JxAltQyDMpq5mU=
 github.com/hashicorp/terraform-plugin-go v0.29.0/go.mod 
h1:vYZbIyvxyy0FWSmDHChCqKvI40cFTDGSb3D8D70i9GM=
 github.com/hashicorp/terraform-plugin-log v0.10.0 
h1:eu2kW6/QBVdN4P3Ju2WiB2W3ObjkAsyfBsL3Wh1fj3g=
diff --git a/internal/provider/resource_table.go 
b/internal/provider/resource_table.go
index b22971b..b06e068 100644
--- a/internal/provider/resource_table.go
+++ b/internal/provider/resource_table.go
@@ -28,6 +28,8 @@ import (
        rscschema 
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
        
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
        
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+       "github.com/hashicorp/terraform-plugin-framework/schema/validator"
+       
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
        "github.com/hashicorp/terraform-plugin-framework/types"
        "github.com/hashicorp/terraform-plugin-framework/types/basetypes"
        "github.com/hashicorp/terraform-plugin-log/tflog"
@@ -46,6 +48,8 @@ type icebergTableResourceModel struct {
        Namespace        types.List   `tfsdk:"namespace"`
        Name             types.String `tfsdk:"name"`
        Schema           types.Object `tfsdk:"schema"`
+       PartitionSpec    types.Object `tfsdk:"partition_spec"`
+       SortOrder        types.Object `tfsdk:"sort_order"`
        UserProperties   types.Map    `tfsdk:"user_properties"`
        ServerProperties types.Map    `tfsdk:"server_properties"`
 }
@@ -96,6 +100,76 @@ func (r *icebergTableResource) Schema(_ context.Context, _ 
resource.SchemaReques
                                        },
                                },
                        },
+                       "partition_spec": rscschema.SingleNestedAttribute{
+                               Description: "The partition spec of the table.",
+                               Optional:    true,
+                               Computed:    true,
+                               Attributes: map[string]rscschema.Attribute{
+                                       "fields": rscschema.ListNestedAttribute{
+                                               Description: "The fields of the 
partition spec.",
+                                               Required:    true,
+                                               NestedObject: 
rscschema.NestedAttributeObject{
+                                                       Attributes: 
map[string]rscschema.Attribute{
+                                                               "source_ids": 
rscschema.ListAttribute{
+                                                                       
Description: "The source field IDs.",
+                                                                       
Required:    true,
+                                                                       
ElementType: types.Int64Type,
+                                                               },
+                                                               "field_id": 
rscschema.Int64Attribute{
+                                                                       
Description: "The partition field ID.",
+                                                                       
Optional:    true,
+                                                                       
Computed:    true,
+                                                               },
+                                                               "name": 
rscschema.StringAttribute{
+                                                                       
Description: "The partition field name.",
+                                                                       
Required:    true,
+                                                               },
+                                                               "transform": 
rscschema.StringAttribute{
+                                                                       
Description: "The partition transform.",
+                                                                       
Required:    true,
+                                                               },
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+                       "sort_order": rscschema.SingleNestedAttribute{
+                               Description: "The sort order of the table.",
+                               Optional:    true,
+                               Computed:    true,
+                               Attributes: map[string]rscschema.Attribute{
+                                       "fields": rscschema.ListNestedAttribute{
+                                               Description: "The fields of the 
sort order.",
+                                               Required:    true,
+                                               NestedObject: 
rscschema.NestedAttributeObject{
+                                                       Attributes: 
map[string]rscschema.Attribute{
+                                                               "source_id": 
rscschema.Int64Attribute{
+                                                                       
Description: "The source field ID.",
+                                                                       
Required:    true,
+                                                               },
+                                                               "transform": 
rscschema.StringAttribute{
+                                                                       
Description: "The sort transform.",
+                                                                       
Required:    true,
+                                                               },
+                                                               "direction": 
rscschema.StringAttribute{
+                                                                       
Description: "The sort direction (asc or desc).",
+                                                                       
Required:    true,
+                                                                       
Validators: []validator.String{
+                                                                               
stringvalidator.OneOf("asc", "desc"),
+                                                                       },
+                                                               },
+                                                               "null_order": 
rscschema.StringAttribute{
+                                                                       
Description: "The null order (nulls-first or nulls-last).",
+                                                                       
Required:    true,
+                                                                       
Validators: []validator.String{
+                                                                               
stringvalidator.OneOf("nulls-first", "nulls-last"),
+                                                                       },
+                                                               },
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
                        "user_properties": rscschema.MapAttribute{
                                Description: "User-defined properties for the 
table.",
                                Optional:    true,
@@ -301,8 +375,41 @@ func (r *icebergTableResource) Create(ctx context.Context, 
req resource.CreateRe
                }
        }
 
-       // TODO: Add PartitionSpec support
-       tbl, err := r.catalog.CreateTable(ctx, tableIdent, tblSchema, 
catalog.WithProperties(userProps))
+       createOpts := []catalog.CreateTableOpt{
+               catalog.WithProperties(userProps),
+       }
+
+       if !data.PartitionSpec.IsNull() && !data.PartitionSpec.IsUnknown() {
+               var spec icebergTablePartitionSpec
+               diags = data.PartitionSpec.As(ctx, &spec, 
basetypes.ObjectAsOptions{})
+               resp.Diagnostics.Append(diags...)
+               if resp.Diagnostics.HasError() {
+                       return
+               }
+               icebergSpec, err := spec.ToIceberg()
+               if err != nil {
+                       resp.Diagnostics.AddError("failed to convert partition 
spec", err.Error())
+                       return
+               }
+               createOpts = append(createOpts, 
catalog.WithPartitionSpec(icebergSpec))
+       }
+
+       if !data.SortOrder.IsNull() && !data.SortOrder.IsUnknown() {
+               var order icebergTableSortOrder
+               diags = data.SortOrder.As(ctx, &order, 
basetypes.ObjectAsOptions{})
+               resp.Diagnostics.Append(diags...)
+               if resp.Diagnostics.HasError() {
+                       return
+               }
+               icebergOrder, err := order.ToIceberg()
+               if err != nil {
+                       resp.Diagnostics.AddError("failed to convert sort 
order", err.Error())
+                       return
+               }
+               createOpts = append(createOpts, 
catalog.WithSortOrder(icebergOrder))
+       }
+
+       tbl, err := r.catalog.CreateTable(ctx, tableIdent, tblSchema, 
createOpts...)
        if err != nil {
                resp.Diagnostics.AddError("failed to create table", err.Error())
                return
@@ -406,6 +513,8 @@ func (r *icebergTableResource) Update(ctx context.Context, 
req resource.UpdateRe
 
        updates = append(updates, r.calculatePropertyUpdates(ctx, &plan, 
&state, &resp.Diagnostics)...)
        updates = append(updates, r.calculateSchemaUpdates(ctx, &plan, &state, 
&resp.Diagnostics)...)
+       updates = append(updates, r.calculatePartitionUpdates(ctx, &plan, tbl, 
&resp.Diagnostics)...)
+       updates = append(updates, r.calculateSortOrderUpdates(ctx, &plan, tbl, 
&resp.Diagnostics)...)
 
        if resp.Diagnostics.HasError() {
                return
@@ -507,6 +616,91 @@ func (r *icebergTableResource) calculateSchemaUpdates(ctx 
context.Context, plan,
        return nil
 }
 
+func (r *icebergTableResource) calculatePartitionUpdates(ctx context.Context, 
plan *icebergTableResourceModel, tbl *table.Table, diags *diag.Diagnostics) 
[]table.Update {
+       spec := tbl.Spec()
+       if plan.PartitionSpec.IsUnknown() {
+               if spec.NumFields() > 0 {
+                       // Create a new unpartitioned spec and set it as default
+                       unpartitionedSpec := iceberg.NewPartitionSpec()
+                       return []table.Update{
+                               
table.NewAddPartitionSpecUpdate(&unpartitionedSpec, false),
+                               table.NewSetDefaultSpecUpdate(-1),
+                       }
+               }
+               return nil
+       }
+
+       if plan.PartitionSpec.IsNull() {
+               return nil
+       }
+
+       var planSpec icebergTablePartitionSpec
+       d := plan.PartitionSpec.As(ctx, &planSpec, basetypes.ObjectAsOptions{})
+       diags.Append(d...)
+
+       if diags.HasError() {
+               return nil
+       }
+
+       newIcebergSpec, err := planSpec.ToIceberg()
+       if err != nil {
+               diags.AddError("failed to convert partition spec", err.Error())
+               return nil
+       }
+
+       // Compare with current spec
+       if !spec.CompatibleWith(newIcebergSpec) {
+               return []table.Update{
+                       table.NewAddPartitionSpecUpdate(newIcebergSpec, false),
+                       table.NewSetDefaultSpecUpdate(-1),
+               }
+       }
+
+       return nil
+}
+
+func (r *icebergTableResource) calculateSortOrderUpdates(ctx context.Context, 
plan *icebergTableResourceModel, tbl *table.Table, diags *diag.Diagnostics) 
[]table.Update {
+       if plan.SortOrder.IsUnknown() {
+               if tbl.SortOrder().OrderID() != 0 {
+                       // Create a new unsorted order and set it as default
+                       unsortedOrder := table.UnsortedSortOrder
+                       return []table.Update{
+                               table.NewAddSortOrderUpdate(&unsortedOrder),
+                               table.NewSetDefaultSortOrderUpdate(0),
+                       }
+               }
+               return nil
+       }
+
+       if plan.SortOrder.IsNull() {
+               return nil
+       }
+
+       var planOrder icebergTableSortOrder
+       d := plan.SortOrder.As(ctx, &planOrder, basetypes.ObjectAsOptions{})
+       diags.Append(d...)
+
+       if diags.HasError() {
+               return nil
+       }
+
+       newIcebergOrder, err := planOrder.ToIceberg()
+       if err != nil {
+               diags.AddError("failed to convert sort order", err.Error())
+               return nil
+       }
+
+       // Compare with current sort order
+       if !tbl.SortOrder().Equals(newIcebergOrder) {
+               return []table.Update{
+                       table.NewAddSortOrderUpdate(&newIcebergOrder),
+                       table.NewSetDefaultSortOrderUpdate(-1),
+               }
+       }
+
+       return nil
+}
+
 func (r *icebergTableResource) syncTableToModel(ctx context.Context, tbl 
*table.Table, model *icebergTableResourceModel, diags *diag.Diagnostics) {
        // Update ServerProperties
        serverProperties, d := types.MapValueFrom(ctx, types.StringType, 
tbl.Properties())
@@ -530,6 +724,36 @@ func (r *icebergTableResource) syncTableToModel(ctx 
context.Context, tbl *table.
                return
        }
 
+       // Update PartitionSpec
+       icebergSpec := tbl.Spec()
+       if icebergSpec.NumFields() > 0 {
+               var updatedSpec icebergTablePartitionSpec
+               if err := updatedSpec.FromIceberg(icebergSpec); err != nil {
+                       diags.AddError("failed to convert iceberg partition 
spec to terraform partition spec", err.Error())
+                       return
+               }
+               var d3 diag.Diagnostics
+               model.PartitionSpec, d3 = types.ObjectValueFrom(ctx, 
icebergTablePartitionSpec{}.AttrTypes(), updatedSpec)
+               diags.Append(d3...)
+       } else {
+               model.PartitionSpec = 
types.ObjectNull(icebergTablePartitionSpec{}.AttrTypes())
+       }
+
+       // Update SortOrder
+       icebergOrder := tbl.SortOrder()
+       if icebergOrder.Len() > 0 {
+               var updatedOrder icebergTableSortOrder
+               if err := updatedOrder.FromIceberg(icebergOrder); err != nil {
+                       diags.AddError("failed to convert iceberg sort order to 
terraform sort order", err.Error())
+                       return
+               }
+               var d4 diag.Diagnostics
+               model.SortOrder, d4 = types.ObjectValueFrom(ctx, 
icebergTableSortOrder{}.AttrTypes(), updatedOrder)
+               diags.Append(d4...)
+       } else {
+               model.SortOrder = 
types.ObjectNull(icebergTableSortOrder{}.AttrTypes())
+       }
+
        // Update UserProperties to match reality for tracked keys
        if !model.UserProperties.IsNull() {
                planProps := make(map[string]string)
diff --git a/internal/provider/resource_table_test.go 
b/internal/provider/resource_table_test.go
index a7c4868..be73c65 100644
--- a/internal/provider/resource_table_test.go
+++ b/internal/provider/resource_table_test.go
@@ -17,6 +17,7 @@ package provider
 import (
        "fmt"
        "os"
+       "regexp"
        "testing"
 
        "github.com/hashicorp/terraform-plugin-testing/helper/resource"
@@ -376,3 +377,162 @@ resource "iceberg_table" "full" {
 }
 `, tableName)
 }
+
+func TestAccIcebergTablePartitionSpecAndSortOrder(t *testing.T) {
+       catalogURI := os.Getenv("ICEBERG_CATALOG_URI")
+       if catalogURI == "" {
+               catalogURI = "http://localhost:8181";
+       }
+
+       providerCfg := fmt.Sprintf(providerConfig, catalogURI)
+       tableName := "partition_sort_test_table"
+
+       resource.Test(t, resource.TestCase{
+               PreCheck:                 func() { testAccPreCheck(t) },
+               ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
+               Steps: []resource.TestStep{
+                       {
+                               Config: 
testAccIcebergTablePartitionSortConfig(providerCfg, tableName, "bucket[16]", 
"asc"),
+                               Check: resource.ComposeTestCheckFunc(
+                                       
resource.TestCheckResourceAttr("iceberg_table.test", "name", tableName),
+                                       
resource.TestCheckResourceAttr("iceberg_table.test", "partition_spec.fields.#", 
"1"),
+                                       
resource.TestCheckResourceAttr("iceberg_table.test", 
"partition_spec.fields.0.source_ids.0", "1"),
+                                       
resource.TestCheckResourceAttr("iceberg_table.test", 
"partition_spec.fields.0.field_id", "1000"),
+                                       
resource.TestCheckResourceAttr("iceberg_table.test", 
"partition_spec.fields.0.name", "id_bucket"),
+                                       
resource.TestCheckResourceAttr("iceberg_table.test", 
"partition_spec.fields.0.transform", "bucket[16]"),
+
+                                       
resource.TestCheckResourceAttr("iceberg_table.test", "sort_order.fields.#", 
"1"),
+                                       
resource.TestCheckResourceAttr("iceberg_table.test", 
"sort_order.fields.0.source_id", "1"),
+                                       
resource.TestCheckResourceAttr("iceberg_table.test", 
"sort_order.fields.0.transform", "identity"),
+                                       
resource.TestCheckResourceAttr("iceberg_table.test", 
"sort_order.fields.0.direction", "asc"),
+                                       
resource.TestCheckResourceAttr("iceberg_table.test", 
"sort_order.fields.0.null_order", "nulls-first"),
+                               ),
+                       },
+                       {
+                               Config: 
testAccIcebergTablePartitionSortConfig(providerCfg, tableName, "bucket[32]", 
"desc"),
+                               Check: resource.ComposeTestCheckFunc(
+                                       
resource.TestCheckResourceAttr("iceberg_table.test", "name", tableName),
+                                       
resource.TestCheckResourceAttr("iceberg_table.test", "partition_spec.fields.#", 
"1"),
+                                       
resource.TestCheckResourceAttr("iceberg_table.test", 
"partition_spec.fields.0.transform", "bucket[32]"),
+                                       
resource.TestCheckResourceAttr("iceberg_table.test", "sort_order.fields.#", 
"1"),
+                                       
resource.TestCheckResourceAttr("iceberg_table.test", 
"sort_order.fields.0.direction", "desc"),
+                               ),
+                       },
+                       {
+                               Config:      
testAccIcebergTablePartitionSortConfig(providerCfg, tableName, "bucket[32]", 
"invalid"),
+                               ExpectError: regexp.MustCompile(`(?s)Attribute 
sort_order\.fields\[0\]\.direction value must be one of:.*"asc".*"desc".*got: 
"invalid"`),
+                       },
+                       {
+                               Config:      
testAccIcebergTableInvalidNullOrderConfig(providerCfg, tableName),
+                               ExpectError: regexp.MustCompile(`(?s)Attribute 
sort_order\.fields\[0\]\.null_order value must be one 
of:.*"nulls-first".*"nulls-last".*got: "invalid"`),
+                       },
+                       {
+                               Config: 
testAccIcebergTableNoPartitionSortConfig(providerCfg, tableName),
+                               Check: resource.ComposeTestCheckFunc(
+                                       
resource.TestCheckResourceAttr("iceberg_table.test", "name", tableName),
+                                       
resource.TestCheckResourceAttr("iceberg_table.test", "partition_spec.fields.#", 
"0"),
+                                       
resource.TestCheckResourceAttr("iceberg_table.test", "sort_order.fields.#", 
"0"),
+                               ),
+                       },
+               },
+       })
+}
+
+func testAccIcebergTableNoPartitionSortConfig(providerCfg string, tableName 
string) string {
+       return providerCfg + fmt.Sprintf(`
+resource "iceberg_namespace" "db3" {
+  name = ["db3"]
+}
+
+resource "iceberg_table" "test" {
+  namespace = iceberg_namespace.db3.name
+  name      = "%s"
+  schema = {
+    fields = [
+      {
+        id       = 1
+        name     = "id"
+        type     = "long"
+        required = true
+      }
+    ]
+  }
+}
+`, tableName)
+}
+
+func testAccIcebergTableInvalidNullOrderConfig(providerCfg string, tableName 
string) string {
+       return providerCfg + fmt.Sprintf(`
+resource "iceberg_namespace" "db3" {
+  name = ["db3"]
+}
+
+resource "iceberg_table" "test" {
+  namespace = iceberg_namespace.db3.name
+  name      = "%s"
+  schema = {
+    fields = [
+      {
+        id       = 1
+        name     = "id"
+        type     = "long"
+        required = true
+      }
+    ]
+  }
+  sort_order = {
+    fields = [
+      {
+        source_id  = 1
+        transform  = "identity"
+        direction  = "asc"
+        null_order = "invalid"
+      }
+    ]
+  }
+}
+`, tableName)
+}
+
+func testAccIcebergTablePartitionSortConfig(providerCfg string, tableName 
string, partitionTransform string, sortDirection string) string {
+       return providerCfg + fmt.Sprintf(`
+resource "iceberg_namespace" "db3" {
+  name = ["db3"]
+}
+
+resource "iceberg_table" "test" {
+  namespace = iceberg_namespace.db3.name
+  name      = "%s"
+  schema = {
+    fields = [
+      {
+        id       = 1
+        name     = "id"
+        type     = "long"
+        required = true
+      }
+    ]
+  }
+  partition_spec = {
+    fields = [
+      {
+        source_ids = [1]
+        field_id   = 1000
+        name       = "id_bucket"
+        transform  = "%s"
+      }
+    ]
+  }
+  sort_order = {
+    fields = [
+      {
+        source_id  = 1
+        transform  = "identity"
+        direction  = "%s"
+        null_order = "nulls-first"
+      }
+    ]
+  }
+}
+`, tableName, partitionTransform, sortDirection)
+}
diff --git a/internal/provider/table_schema.go 
b/internal/provider/table_schema.go
index 85e7da4..d47e853 100644
--- a/internal/provider/table_schema.go
+++ b/internal/provider/table_schema.go
@@ -20,6 +20,7 @@ import (
        "strings"
 
        "github.com/apache/iceberg-go"
+       "github.com/apache/iceberg-go/table"
        "github.com/hashicorp/terraform-plugin-framework/attr"
        "github.com/hashicorp/terraform-plugin-framework/types"
 )
@@ -95,6 +96,112 @@ func (s *icebergTableSchema) FromIceberg(icebergSchema 
*iceberg.Schema) error {
        return json.Unmarshal(b, s)
 }
 
+type icebergTablePartitionSpec struct {
+       Fields []icebergTablePartitionField `tfsdk:"fields" json:"fields"`
+}
+
+func (s icebergTablePartitionSpec) AttrTypes() map[string]attr.Type {
+       return map[string]attr.Type{
+               "fields": types.ListType{
+                       ElemType: types.ObjectType{
+                               AttrTypes: 
icebergTablePartitionField{}.AttrTypes(),
+                       },
+               },
+       }
+}
+
+func (s *icebergTablePartitionSpec) ToIceberg() (*iceberg.PartitionSpec, 
error) {
+       b, err := json.Marshal(s)
+       if err != nil {
+               return nil, err
+       }
+       var icebergSpec iceberg.PartitionSpec
+       if err := json.Unmarshal(b, &icebergSpec); err != nil {
+               return nil, err
+       }
+       return &icebergSpec, nil
+}
+
+func (s *icebergTablePartitionSpec) FromIceberg(icebergSpec 
iceberg.PartitionSpec) error {
+       s.Fields = make([]icebergTablePartitionField, 0, 
icebergSpec.NumFields())
+       for field := range icebergSpec.Fields() {
+               fieldID := int64(field.FieldID)
+               s.Fields = append(s.Fields, icebergTablePartitionField{
+                       SourceIDs: []int64{int64(field.SourceID)},
+                       FieldID:   &fieldID,
+                       Name:      field.Name,
+                       Transform: field.Transform.String(),
+               })
+       }
+       return nil
+}
+
+type icebergTablePartitionField struct {
+       SourceIDs []int64 `tfsdk:"source_ids" json:"source-ids"`
+       FieldID   *int64  `tfsdk:"field_id" json:"field-id,omitempty"`
+       Name      string  `tfsdk:"name" json:"name"`
+       Transform string  `tfsdk:"transform" json:"transform"`
+}
+
+func (icebergTablePartitionField) AttrTypes() map[string]attr.Type {
+       return map[string]attr.Type{
+               "source_ids": types.ListType{ElemType: types.Int64Type},
+               "field_id":   types.Int64Type,
+               "name":       types.StringType,
+               "transform":  types.StringType,
+       }
+}
+
+type icebergTableSortOrder struct {
+       Fields []icebergTableSortField `tfsdk:"fields" json:"fields"`
+}
+
+func (s icebergTableSortOrder) AttrTypes() map[string]attr.Type {
+       return map[string]attr.Type{
+               "fields": types.ListType{
+                       ElemType: types.ObjectType{
+                               AttrTypes: icebergTableSortField{}.AttrTypes(),
+                       },
+               },
+       }
+}
+
+func (s *icebergTableSortOrder) ToIceberg() (table.SortOrder, error) {
+       b, err := json.Marshal(s)
+       if err != nil {
+               return table.SortOrder{}, err
+       }
+       var icebergOrder table.SortOrder
+       if err := json.Unmarshal(b, &icebergOrder); err != nil {
+               return table.SortOrder{}, err
+       }
+       return icebergOrder, nil
+}
+
+func (s *icebergTableSortOrder) FromIceberg(icebergOrder table.SortOrder) 
error {
+       b, err := json.Marshal(icebergOrder)
+       if err != nil {
+               return err
+       }
+       return json.Unmarshal(b, s)
+}
+
+type icebergTableSortField struct {
+       SourceID  int64  `tfsdk:"source_id" json:"source-id"`
+       Transform string `tfsdk:"transform" json:"transform"`
+       Direction string `tfsdk:"direction" json:"direction"`
+       NullOrder string `tfsdk:"null_order" json:"null-order"`
+}
+
+func (icebergTableSortField) AttrTypes() map[string]attr.Type {
+       return map[string]attr.Type{
+               "source_id":  types.Int64Type,
+               "transform":  types.StringType,
+               "direction":  types.StringType,
+               "null_order": types.StringType,
+       }
+}
+
 type icebergTableSchemaField struct {
        ID               types.Int64                              `tfsdk:"id" 
json:"id"`
        Name             string                                   `tfsdk:"name" 
json:"name"`

Reply via email to