badalprasadsingh commented on code in PR #524: URL: https://github.com/apache/iceberg-go/pull/524#discussion_r2323747282
########## manifest.go: ########## @@ -1461,33 +1598,114 @@ func mapToAvroColMap[K comparable, V any](m map[K]V) *[]colMap[K, V] { return &out } -func avroPartitionData(input map[int]any, logicalTypes map[int]avro.LogicalType) map[int]any { +func avroPartitionData(input map[int]any, logicalTypes map[int]avro.LogicalType, fixedSizes map[int]int) map[int]any { out := make(map[int]any) for k, v := range input { if logical, ok := logicalTypes[k]; ok { - switch logical { - case avro.Date: - out[k] = Date(v.(time.Time).Truncate(24*time.Hour).Unix() / int64((time.Hour * 24).Seconds())) - case avro.TimeMillis: - out[k] = Time(v.(time.Duration).Milliseconds()) - case avro.TimeMicros: - out[k] = Time(v.(time.Duration).Microseconds()) - case avro.TimestampMillis: - out[k] = Timestamp(v.(time.Time).UTC().UnixMilli()) - case avro.TimestampMicros: - out[k] = Timestamp(v.(time.Time).UTC().UnixMicro()) - default: - out[k] = v - } - - continue + out[k] = convertLogicalTypeValue(v, logical, fixedSizes[k]) + } else { + out[k] = convertDefaultValue(v, fixedSizes[k]) } - out[k] = v } return out } +func convertLogicalTypeValue(v any, logicalType avro.LogicalType, fixedSize int) any { + switch logicalType { + case avro.Date: + return convertDateValue(v) + case avro.TimeMicros: + return convertTimeMicrosValue(v) + case avro.TimestampMicros: + return convertTimestampMicrosValue(v) + case avro.Decimal: + return convertDecimalValue(v, fixedSize) + default: + return v + } +} + +func convertDateValue(v any) any { + if t, ok := v.(time.Time); ok { + return map[string]any{"int.date": int32(t.Truncate(24*time.Hour).Unix() / int64((time.Hour * 24).Seconds()))} + } + if d, ok := v.(Date); ok { + return map[string]any{"int.date": int32(d)} + } + + return v +} + +func convertTimeMicrosValue(v any) any { + if t, ok := v.(Time); ok { + return map[string]any{"long.time-micros": int64(t)} + } + if d, ok := v.(time.Duration); ok { + return map[string]any{"long.time-micros": d.Microseconds()} + } + + return v +} + +func convertTimestampMicrosValue(v any) any { + if t, ok := v.(time.Time); ok { + return map[string]any{"long.timestamp-micros": t.UTC().UnixMicro()} + } + if ts, ok := v.(Timestamp); ok { + return map[string]any{"long.timestamp-micros": int64(ts)} + } + + return v +} + +func convertDecimalValue(v any, fixedSize int) any { + if v == nil { + return map[string]any{"null": nil} + } + + dec, ok := v.(Decimal) + if !ok { + return v + } + + bytes, err := DecimalLiteral(dec).MarshalBinary() + if err != nil { + return v + } + fixedArray := convertToFixedArray(padOrTruncateBytes(bytes, fixedSize), fixedSize) Review Comment: Because in case of a `Nullable` Decimal Schema, decimal value has to be converted to `fixed` length bytes to satisfy Avro's decimal logical type requirements. This is a common behaviour in `iceberg-java` as well, and according to our `avro_schemas.go` defintion at [here](https://github.com/apache/iceberg-go/blob/0a565193d51faaf4c0566331a4443bbfc11e647f/internal/avro_schemas.go#L50) we should convert it to `fixed` type. -- 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: issues-unsubscr...@iceberg.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: issues-unsubscr...@iceberg.apache.org For additional commands, e-mail: issues-h...@iceberg.apache.org