IGNITE-10691: Python thin client: UUID marshalling fix
This closes #6296
diff --git a/pyignite/datatypes/standard.py b/pyignite/datatypes/standard.py
index cc5b955..8808da2 100644
--- a/pyignite/datatypes/standard.py
+++ b/pyignite/datatypes/standard.py
@@ -246,10 +246,16 @@
"""
Universally unique identifier (UUID), aka Globally unique identifier
(GUID). Payload takes up 16 bytes.
+
+ Byte order in :py:meth:`~pyignite.datatypes.standard.UUIDObject.to_python`
+ and :py:meth:`~pyignite.datatypes.standard.UUIDObject.from_python` methods
+ is changed for compatibility with `java.util.UUID`.
"""
type_code = TC_UUID
_object_c_type = None
+ UUID_BYTE_ORDER = (7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8)
+
@classmethod
def build_c_type(cls):
if cls._object_c_type is None:
@@ -274,7 +280,7 @@
cls.type_code,
byteorder=PROTOCOL_BYTE_ORDER
)
- for i, byte in enumerate(bytearray(value.bytes)):
+ for i, byte in zip(cls.UUID_BYTE_ORDER, bytearray(value.bytes)):
data_object.value[i] = byte
return bytes(data_object)
@@ -285,7 +291,10 @@
byteorder=PROTOCOL_BYTE_ORDER
):
return None
- return uuid.UUID(bytes=bytes(ctypes_object.value))
+ uuid_array = bytearray(ctypes_object.value)
+ return uuid.UUID(
+ bytes=bytes([uuid_array[i] for i in cls.UUID_BYTE_ORDER])
+ )
class TimestampObject(StandardObject):
diff --git a/tests/test_datatypes.py b/tests/test_datatypes.py
index d7c7977..b68ba8c 100644
--- a/tests/test_datatypes.py
+++ b/tests/test_datatypes.py
@@ -132,3 +132,45 @@
result = cache_get(client, cache, 'my_key')
assert result.status == 0
assert result.value == value
+
+
+@pytest.mark.parametrize(
+ 'uuid_string',
+ [
+ 'd57babad-7bc1-4c82-9f9c-e72841b92a85',
+ '5946c0c0-2b76-479d-8694-a2e64a3968da',
+ 'a521723d-ad5d-46a6-94ad-300f850ef704',
+ ]
+)
+def test_uuid_representation(client, uuid_string):
+ """ Test if textual UUID representation is correct. """
+ uuid_value = uuid.UUID(uuid_string)
+
+ # initial cleanup
+ client.sql("DROP TABLE test_uuid_repr IF EXISTS")
+ # create table with UUID field
+ client.sql(
+ "CREATE TABLE test_uuid_repr (id INTEGER PRIMARY KEY, uuid_field UUID)"
+ )
+ # use uuid.UUID class to insert data
+ client.sql(
+ "INSERT INTO test_uuid_repr(id, uuid_field) VALUES (?, ?)",
+ query_args=[1, uuid_value]
+ )
+ # use hex string to retrieve data
+ result = client.sql(
+ "SELECT * FROM test_uuid_repr WHERE uuid_field='{}'".format(
+ uuid_string
+ )
+ )
+
+ # finalize query
+ result = list(result)
+
+ # final cleanup
+ client.sql("DROP TABLE test_uuid_repr IF EXISTS")
+
+ # if a line was retrieved, our test was successful
+ assert len(result) == 1
+ # doublecheck
+ assert result[0][1] == uuid_value