Skip to content

Commit 39e3444

Browse files
committed
Add tests for pass-through data types and enhance float vector handling
1 parent cb9f872 commit 39e3444

1 file changed

Lines changed: 102 additions & 10 deletions

File tree

‎tests/client/test_cursor.py‎

Lines changed: 102 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -459,8 +459,8 @@ def test_execute_time_converter(mocked_connection):
459459
"col_types": [20],
460460
"cols": ["t"],
461461
"rows": [
462-
[[45045000000, 0]], # 12:30:45 UTC
463-
[[45045123456, 7200]], # 12:30:45.123456 +02:00
462+
[[45045000000, 0]], # 12:30:45 UTC
463+
[[45045123456, 7200]], # 12:30:45.123456 +02:00
464464
[None],
465465
],
466466
"rowcount": 3,
@@ -474,10 +474,16 @@ def test_execute_time_converter(mocked_connection):
474474
result = cursor.fetchall()
475475

476476
assert result == [
477-
[datetime.time(12, 30, 45, 0,
478-
tzinfo=datetime.timezone.utc)],
479-
[datetime.time(12, 30, 45, 123456,
480-
tzinfo=datetime.timezone(datetime.timedelta(hours=2)))],
477+
[datetime.time(12, 30, 45, 0, tzinfo=datetime.timezone.utc)],
478+
[
479+
datetime.time(
480+
12,
481+
30,
482+
45,
483+
123456,
484+
tzinfo=datetime.timezone(datetime.timedelta(hours=2)),
485+
)
486+
],
481487
[None],
482488
]
483489

@@ -606,7 +612,71 @@ def test_bit_without_converter(mocked_connection):
606612
assert cursor.fetchone() == ["B'0110'"]
607613

608614

609-
def test_execute_with_converter_and_invalid_data_type(mocked_connection):
615+
@pytest.mark.parametrize(
616+
("type_id", "wire_value"),
617+
[
618+
(17, "1 day 00:00:00"),
619+
(18, ["over", "U", "unreserved"]),
620+
(28, [0.1, 0.2]),
621+
(29, "a5b3c1e0-1b7f-4f3e-9a2d-6c4e8f0a1b2c"),
622+
(30, "int4"),
623+
],
624+
ids=["interval", "row", "float_vector", "uuid", "regtype"],
625+
)
626+
def test_pass_through_data_types(mocked_connection, type_id, wire_value):
627+
"""
628+
Verify that types without a dedicated converter are passed through
629+
unchanged instead of raising.
630+
"""
631+
converter = DefaultTypeConverter()
632+
cursor = mocked_connection.cursor(converter=converter)
633+
response = {
634+
"col_types": [type_id],
635+
"cols": ["foo"],
636+
"rows": [[wire_value]],
637+
"rowcount": 1,
638+
"duration": 123,
639+
}
640+
with mock.patch.object(
641+
mocked_connection.client, "sql", return_value=response
642+
):
643+
cursor.execute("")
644+
assert cursor.fetchone() == [wire_value]
645+
646+
647+
def test_pass_through_data_types_registered_in_enum():
648+
"""Verify the enum stays in sync with the documented type identifiers."""
649+
assert DataType(17) is DataType.INTERVAL
650+
assert DataType(18) is DataType.ROW
651+
assert DataType(28) is DataType.FLOAT_VECTOR
652+
assert DataType(29) is DataType.UUID
653+
assert DataType(30) is DataType.REGTYPE
654+
655+
656+
def test_float_vector_with_time_zone(mocked_connection):
657+
"""
658+
Verify a `FLOAT_VECTOR` column on a timezone-aware cursor.
659+
"""
660+
cursor = mocked_connection.cursor(time_zone="+0000")
661+
response = {
662+
"col_types": [28],
663+
"cols": ["embedding"],
664+
"rows": [[[0.1, 0.2]]],
665+
"rowcount": 1,
666+
"duration": 123,
667+
}
668+
with mock.patch.object(
669+
mocked_connection.client, "sql", return_value=response
670+
):
671+
cursor.execute("")
672+
assert cursor.fetchone() == [[0.1, 0.2]]
673+
674+
675+
def test_execute_with_converter_and_unknown_data_type(mocked_connection):
676+
"""
677+
Verify that a type identifier unknown to this client degrades to the
678+
default converter.
679+
"""
610680
converter = DefaultTypeConverter()
611681

612682
# Create a `Cursor` object with converter.
@@ -625,9 +695,7 @@ def test_execute_with_converter_and_invalid_data_type(mocked_connection):
625695
mocked_connection.client, "sql", return_value=response
626696
):
627697
cursor.execute("")
628-
with pytest.raises(ValueError) as e:
629-
cursor.fetchone()
630-
assert e.exception.args == "999 is not a valid DataType"
698+
assert cursor.fetchone() == ["n/a"]
631699

632700

633701
def test_execute_array_with_converter(mocked_connection):
@@ -675,6 +743,30 @@ def test_execute_array_with_converter_invalid(mocked_connection):
675743
)
676744

677745

746+
def test_execute_array_with_converter_unknown_outer_type(mocked_connection):
747+
"""
748+
Verify an unknown outer type in a collection definition still raises.
749+
"""
750+
converter = DefaultTypeConverter()
751+
cursor = mocked_connection.cursor(converter=converter)
752+
response = {
753+
"col_types": [[999, 5]],
754+
"cols": ["address"],
755+
"rows": [[["10.10.10.1"]]],
756+
"rowcount": 1,
757+
"duration": 123,
758+
}
759+
with mock.patch.object(
760+
mocked_connection.client, "sql", return_value=response
761+
):
762+
cursor.execute("")
763+
with pytest.raises(
764+
ValueError,
765+
match="Data type 999 is not implemented as collection type",
766+
):
767+
cursor.fetchone()
768+
769+
678770
def test_execute_nested_array_with_converter(mocked_connection):
679771
converter = DefaultTypeConverter()
680772
cursor = mocked_connection.cursor(converter=converter)

0 commit comments

Comments
 (0)