Details
-
Bug
-
Resolution: Fixed
-
P4: Low
-
5.9.6
-
None
-
Win7, Microsoft SQL Server, OBDC
-
-
efce30bb4 (dev)
Description
Hi,
This is not a major issue but when activating the Trace of my ODBC server and performing query using QSqlQuery with a QString value to get the value of a NVARCHAR field it generates an error in the ODBC Trace log file. But I do get the value.
Here is the cpp code :
// Code snippet ... m_db = QSqlDatabase::database("MyODBCConnectionName"); QSqlQuery query(m_db); if (query.exec("SELECT myText FROM table1")) { // myText in an NVARCHAR in table1 and table1 isn't empty QString val = query.value(0).toString(); // // val = "CONTENT_OF_myText" } ...
The following lines in SQL.LOG are generated when performing query.value(0).toString() :
client 2f50-2320 ENTER SQLGetData HSTMT 0x0000000003940CC0 UWORD 1 SWORD -8 <SQL_C_WCHAR> PTR 0x0000000000000000 SQLLEN 0 SQLLEN * 0x000000000434E4C8 client 2f50-2320 EXIT SQLGetData with return code -1 (SQL_ERROR) HSTMT 0x0000000003940CC0 UWORD 1 SWORD -8 <SQL_C_WCHAR> PTR 0x0000000000000000 SQLLEN 0 SQLLEN * 0x000000000434E4C8 DIAG [S1009] [Microsoft][Gestionnaire de pilotes ODBC] Valeur d'argument non valide (0) client 2f50-2320 ENTER SQLGetData HSTMT 0x0000000003940CC0 UWORD 1 SWORD -8 <SQL_C_WCHAR> PTR 0x000000000434E6B0 SQLLEN 92 SQLLEN * 0x000000000434E4C8 client 2f50-2320 EXIT SQLGetData with return code 0 (SQL_SUCCESS) HSTMT 0x0000000003940CC0 UWORD 1 SWORD -8 <SQL_C_WCHAR> PTR 0x000000000434E6B0 [ 54] "CONTENT_OF_myText" SQLLEN 92 SQLLEN * 0x000000000434E4C8 (54)
Looking at some source code here : https://gitlab.com/pteam/pteam-qtbase/blob/latest/src/sql/drivers/odbc/qsql_odbc.cpp
It appears that the first call of SQLGetData to get the buffer size in qGetStringData(...) return an error :
// in src/sql/drivers/odbc/qsql_odbc.cpp ... static QString qGetStringData(SQLHANDLE hStmt, int column, int colSize, bool unicode = false) { QString fieldVal; SQLRETURN r = SQL_ERROR; SQLLEN lengthIndicator = 0; // NB! colSize must be a multiple of 2 for unicode enabled DBs if (colSize <= 0) { colSize = 256; } else if (colSize > 65536) { // limit buffer size to 64 KB colSize = 65536; } else { colSize++; // make sure there is room for more than the 0 termination } if(unicode) { r = SQLGetData(hStmt, column+1, SQL_C_TCHAR, NULL, 0, &lengthIndicator); if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && lengthIndicator > 0) colSize = lengthIndicator/sizeof(SQLTCHAR) + 1; QVarLengthArray<SQLTCHAR> buf(colSize); memset(buf.data(), 0, colSize*sizeof(SQLTCHAR)); while (true) { r = SQLGetData(hStmt, column+1, SQL_C_TCHAR, (SQLPOINTER)buf.data(), colSize*sizeof(SQLTCHAR), &lengthIndicator); if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { if (lengthIndicator == SQL_NULL_DATA || lengthIndicator == SQL_NO_TOTAL) { fieldVal.clear(); break; } // if SQL_SUCCESS_WITH_INFO is returned, indicating that // more data can be fetched, the length indicator does NOT // contain the number of bytes returned - it contains the // total number of bytes that CAN be fetched // colSize-1: remove 0 termination when there is more data to fetch int rSize = (r == SQL_SUCCESS_WITH_INFO) ? colSize : lengthIndicator/sizeof(SQLTCHAR); fieldVal += fromSQLTCHAR(buf, rSize); if (lengthIndicator < SQLLEN(colSize*sizeof(SQLTCHAR))) { // workaround for Drivermanagers that don't return SQL_NO_DATA break; } } else if (r == SQL_NO_DATA) { break; } else { qWarning() << "qGetStringData: Error while fetching data (" << qWarnODBCHandle(SQL_HANDLE_STMT, hStmt) << ')'; fieldVal.clear(); break; } } } else { r = SQLGetData(hStmt, column+1, SQL_C_CHAR, NULL, 0, &lengthIndicator); if ((r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) && lengthIndicator > 0) colSize = lengthIndicator + 1; QVarLengthArray<SQLCHAR> buf(colSize); while (true) { r = SQLGetData(hStmt, column+1, SQL_C_CHAR, (SQLPOINTER)buf.data(), colSize, &lengthIndicator); if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO) { if (lengthIndicator == SQL_NULL_DATA || lengthIndicator == SQL_NO_TOTAL) { fieldVal.clear(); break; } // if SQL_SUCCESS_WITH_INFO is returned, indicating that // more data can be fetched, the length indicator does NOT // contain the number of bytes returned - it contains the // total number of bytes that CAN be fetched // colSize-1: remove 0 termination when there is more data to fetch int rSize = (r == SQL_SUCCESS_WITH_INFO) ? colSize : lengthIndicator; fieldVal += QString::fromUtf8((const char *)buf.constData(), rSize); if (lengthIndicator < SQLLEN(colSize)) { // workaround for Drivermanagers that don't return SQL_NO_DATA break; } } else if (r == SQL_NO_DATA) { break; } else { qWarning() << "qGetStringData: Error while fetching data (" << qWarnODBCHandle(SQL_HANDLE_STMT, hStmt) << ')'; fieldVal.clear(); break; } } } return fieldVal; }
This is not major as we get the value at the end. But the SQLGetData(...) with NULL and 0 do return an error.
Here is how I actived this Trace log :
Attachments
Issue Links
- duplicates
-
QTBUG-23675 QVariant bug on text fields with the ODBC driver for IBM iSeries application distributed by IBM with the iSeries Access for Linux.
-
- Closed
-
-
QTBUG-110803 ODBC SQL driver: UB in qGetStringData() in use of SQLGetData()
-
- Closed
-
- is duplicated by
-
QTBUG-23675 QVariant bug on text fields with the ODBC driver for IBM iSeries application distributed by IBM with the iSeries Access for Linux.
-
- Closed
-