[CONPY-270] string coercion not applied to UUID when value is in RETURNING, contradicting cursor.description Created: 2023-09-29  Updated: 2023-10-11  Resolved: 2023-10-11

Status: Closed
Project: MariaDB Connector/Python
Component/s: DBAPI 2.0
Affects Version/s: 1.1.7
Fix Version/s: 1.1.8

Type: Bug Priority: Major
Reporter: Mike Bayer Assignee: Georg Richter
Resolution: Fixed Votes: 0
Labels: None
Environment:

linux


Issue Links:
Blocks
is blocked by CONPY-271 cursor metadata property Closed
Python Version: 3.11

 Description   

script below fails assertions as the UUID value is returned as a bytes when it's coming from RETURNING, even though cursor.description shows it as datatype 254 (STRING)

 
 
import mariadb
import uuid
 
 
conn = mariadb.connect(
    user="scott", password="tiger", host="mariadb111", database="test"
)
 
cursor = conn.cursor()
 
cursor.execute(
    """
    CREATE TABLE IF NOT EXISTS uuid_test (data UUID NOT NULL)
"""
)
 
 
def test_uuid_select():
    the_uuid = uuid.uuid4()
    cursor.execute("INSERT INTO uuid_test (data) VALUES (%s)", (the_uuid.hex,))
 
    cursor.execute("SELECT data FROM uuid_test WHERE data=%s", (the_uuid.hex,))
 
    assert cursor.description[0][1] == mariadb.STRING
    assert cursor.description[0][1] != mariadb.BINARY
    print(
        f"SELECT: the datatype given in cursor.description "
        f"{cursor.description[0][1]} and this is STRING, and is not a BINARY"
    )
 
    result_value = cursor.fetchone()[0]
    assert isinstance(result_value, str)
    assert result_value == str(the_uuid)
 
 
def test_uuid_returning():
    the_uuid = uuid.uuid4()
    cursor.execute(
        "INSERT INTO uuid_test (data) VALUES (%s) RETURNING data",
        (the_uuid.hex,),
    )
 
    assert cursor.description[0][1] == mariadb.STRING
    assert cursor.description[0][1] != mariadb.BINARY
    print(
        f"RETURNING: the datatype in cursor.description "
        f"is {cursor.description[0][1]} and this is STRING, "
        "and is not a BINARY"
    )
 
    result_value = cursor.fetchone()[0]
    assert isinstance(
        result_value, str
    ), f"yet for RETURNING, we are getting back a binary: {result_value!r}"
    assert result_value == str(the_uuid)
 
 
test_uuid_select()
test_uuid_returning()

output shows correct behavior for SELECT, incorrect for INSERT...RETURNING

SELECT: the datatype given in cursor.description 254 and this is STRING, and is not a BINARY
RETURNING: the datatype in cursor.description is 254 and this is STRING, and is not a BINARY
Traceback (most recent call last):
  File "/mnt/photon_home/classic/dev/sqlalchemy/test3.py", line 59, in <module>
    test_uuid_returning()
  File "/mnt/photon_home/classic/dev/sqlalchemy/test3.py", line 52, in test_uuid_returning
    assert isinstance(
AssertionError: yet for RETURNING, we are getting back a binary: b'4482d57d-8233-4686-9afc-67882eaa6500'



 Comments   
Comment by Georg Richter [ 2023-10-04 ]

Instead of checking (field->flags & BINARY_FLAG) we need to check the character set, if it's binary (=63), PyBytes will be returned.

This will be fixed with implementation of CONPY-271 - for extended field types and field formats currently only JSON is supported.

Comment by Georg Richter [ 2023-10-11 ]

Fixed together with implementation of CONPY-271

Generated at Thu Feb 08 03:31:31 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.