Fokko commented on code in PR #5030:
URL: https://github.com/apache/iceberg/pull/5030#discussion_r910700760


##########
python/src/iceberg/transforms.py:
##########
@@ -267,39 +272,132 @@ def satisfies_order_of(self, other: Transform) -> bool:
         return other.preserves_order
 
     def to_human_string(self, value: Optional[S]) -> str:
-        return self._human_string(value)
+        return _human_string(value, self._type) if value is not None else 
"null"
 
-    @singledispatchmethod
-    def _human_string(self, value: Optional[S]) -> str:
-        return str(value) if value is not None else "null"
 
-    @_human_string.register(bytes)
-    def _(self, value: bytes) -> str:
-        return _base64encode(value)
+class TruncateTransform(Transform[S, S]):
+    """A transform for truncating a value to a specified width.
+    Args:
+      source_type (Type): An Iceberg Type of IntegerType, LongType, 
StringType, BinaryType or DecimalType
+      width (int): The truncate width
+    Raises:
+      ValueError: If a type is provided that is incompatible with a Truncate 
transform
+    """
+
+    def __init__(self, source_type: IcebergType, width: int):
+        assert width > 0, f"width ({width}) should be greater than 0"
+        super().__init__(
+            f"truncate[{width}]",
+            f"transforms.truncate(source_type={repr(source_type)}, 
width={width})",
+        )
+        self._type = source_type
+        self._width = width
 
-    @_human_string.register(int)
-    def _(self, value: int) -> str:
-        return self._int_to_human_string(self._type, value)
+    @property
+    def width(self) -> int:
+        return self._width
 
-    @singledispatchmethod
-    def _int_to_human_string(self, _: IcebergType, value: int) -> str:
-        return str(value)
+    @property
+    def type(self) -> IcebergType:
+        return self._type
 
-    @_int_to_human_string.register(DateType)
-    def _(self, _: IcebergType, value: int) -> str:
-        return datetime.to_human_day(value)
+    def apply(self, value: Optional[S]) -> Optional[S]:
+        return _truncate_value(value, self._width) if value is not None else 
None
 
-    @_int_to_human_string.register(TimeType)
-    def _(self, _: IcebergType, value: int) -> str:
-        return datetime.to_human_time(value)
+    def can_transform(self, source: IcebergType) -> bool:
+        return self._type == source
+
+    def result_type(self, source: IcebergType) -> IcebergType:
+        return source
+
+    @property
+    def preserves_order(self) -> bool:
+        return True
+
+    def satisfies_order_of(self, other: Transform) -> bool:
+        if self == other:
+            return True
+        elif isinstance(self._type, StringType) and isinstance(other, 
TruncateTransform) and isinstance(other.type, StringType):
+            return self._width >= other.width
+
+        return False
+
+    def to_human_string(self, value: Optional[S]) -> str:
+        if value is None:
+            return "null"
+        elif isinstance(value, bytes):
+            return _base64encode(value)
+        else:
+            return str(value)
 
-    @_int_to_human_string.register(TimestampType)
-    def _(self, _: IcebergType, value: int) -> str:
-        return datetime.to_human_timestamp(value)
 
-    @_int_to_human_string.register(TimestamptzType)
-    def _(self, _: IcebergType, value: int) -> str:
-        return datetime.to_human_timestamptz(value)
+@singledispatch
+def _human_string(value: Any, _type: IcebergType) -> str:

Review Comment:
   Instead of having two singledispatches, we could also turn everything into 
one where we match on the type first. This would simplify the logic a bit.
   ```suggestion
   def _human_string(_type: IcebergType, value: Any) -> str:
   ```



-- 
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