Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linux openSUSE Tumbleweed connection to MariaDB stopped working with version 5.x.x #1329

Open
dhamonex opened this issue Feb 26, 2024 · 12 comments
Labels
v5 behavior behavior change from v4

Comments

@dhamonex
Copy link

Environment

  • Python: Python 3.11.8
  • pyodbc: 5.1.0 (installed in venv via pip)
  • OS: openSUSE Tumbleweed 20240225
  • DB: MariaDB
  • driver: mariadb-connector-odbc-3.1.10

Issue

Connection to MariaDB fails with an following error:

pyodbc.Error: ('HY000', 'The driver did not supply an error!')

Connection with previous version 4.0.39 of pyodbc worked without any issues, connection via isql is also connecting without an error.

Example script with strace

The following scripts produces the attached straces for 4.0.39 and 5.1.0:

import pyodbc

pyodbc.connect("dsn=mysql")

Used .odbc.ini

[mysql]
Description = "DSN Description"
Driver = /usr/lib64/mariadb/libmaodbc.so
Server = localhost
User = root
Password = xxxx
Database = test

Straces:
pyodbc_4.0.39.txt
pyodbc_5.1.0.txt

@v-chojas
Copy link
Contributor

An ODBC trace will be more useful to compare the differences.

@gordthompson
Copy link
Collaborator

FWIW, the strace outputs show no evidence of pyodbc loading shared objects from different locations with v4 vs v5.

Also, this code works fine under Ubuntu 22.04 with pyodbc 5.1.0 and MariaDB Connector/ODBC v3.1.15 so pyodbc_5 does not have a problem with libmaodbc per se.

import pyodbc

print(pyodbc.version)
# 5.1.0

cnxn = pyodbc.connect(
    "Driver=MariaDB Unicode;"
    "Server=192.168.0.199;"
    "UID=scott;"
    "PWD=tiger;"
    "Database=test;"
)
print(cnxn.getinfo(pyodbc.SQL_DRIVER_NAME))
# libmaodbc.so
print(cnxn.getinfo(pyodbc.SQL_DRIVER_VER))
# 03.01.0015
crsr = cnxn.cursor()
print(crsr.execute("select version()").fetchval())
# 10.5.5-MariaDB-1:10.5.5+maria~focal

@dhamonex
Copy link
Author

I've created some ODBC traces for both pyodbc versions:

pyodbc_5.1.0_odbctrace.log
pyodbc_4.0.39_odbctrace.log

@gordthompson
Copy link
Collaborator

Aha. So in both cases pyodbc calls SQLDriverConnectW which returns SQL_ERROR. pyodbc_4 immediately calls SQLDriverConnect which succeeds. pyodbc_5 calls SQLGetDiagRecW which returns SQL_NO_DATA. I don't know for sure if SQLGetDiagRecW returning SQL_NO_DATA translates into a 'The driver did not supply an error!' exception, but it seems plausible.

It appears that pyodbc_4 did not worry too much about SQLDriverConnectW failing and just soldiered on with SQLDriverConnect, while pyodbc_5 tries to find out why SQLDriverConnectW failed. Maybe pyodbc_5 just needs behave like pyodbc_4 in this particular case.

@gordthompson
Copy link
Collaborator

@dhamonex - Do you get the error with pyodbc_5 if you use

conn = pyodbc.connect(
    connection_string,
    ansi=True
)

@dhamonex
Copy link
Author

I'm getting the same error as before, I've also attached the ODBC trace for ansi=True:

pyodbc_5.1.0_ansi_odbctrace.log

@gordthompson
Copy link
Collaborator

gordthompson commented Feb 29, 2024

Okay, thanks. It looks like 5c1f1c0 completely removed the ansi flag, so it doesn't do anything any more. 🤷

I've tried a couple of older "ANSI" drivers (MySQL and PostgreSQL) but they seem to be okay with SQLDriverConnectW so I don't really know if this is a deficiency of that particular MariaDB driver or is something that pyodbc_5 should be able to handle. (Given the idiosyncrasies of all the ODBC drivers out there I would hope for the latter, but I'm not really qualified to say.)

@gordthompson
Copy link
Collaborator

@v-chojas - Does the ODBC spec say anything about drivers returning SQL_ERROR for SQLDriverConnectW if they simply do not "do" Unicode?

@v-chojas
Copy link
Contributor

v-chojas commented Mar 7, 2024

If the driver doesn't have the W functions the DM should do the narrowing conversion and then call the A function of the driver if the application calls the W function of the DM. However there has been a history of bugs around that part, especially in the DM and confusion between character and byte counts for length parameters. There may also be drivers that have both A and W functions, but one of them doesn't work. What version of unixodbc is the OP using?

@gordthompson
Copy link
Collaborator

What version of unixodbc is the OP using?

@dhamonex - You could ask your package manager or use the odbcinst -j command to check.

@dhamonex
Copy link
Author

dhamonex commented Mar 7, 2024

Tumbleweed is using unixODBC 2.3.12 the applied patches can be viewed here: https://build.opensuse.org/package/show/openSUSE%3AFactory/unixODBC

@laurentderu
Copy link

FWIW the same problem occurs on Debian Bullseye, which ships odbc-mariadb version 3.1.9 and unixodbc version 2.3.6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v5 behavior behavior change from v4
Projects
None yet
Development

No branches or pull requests

4 participants