RE: Bug report: x64 Row status Array uses wrong data type

From: Jari Siikarla <jari(dot)siikarla(at)ddswireless(dot)com>
To: "Inoue, Hiroshi" <h-inoue(at)dream(dot)email(dot)ne(dot)jp>
Cc: "pgsql-odbc(at)postgresql(dot)org" <pgsql-odbc(at)postgresql(dot)org>
Subject: RE: Bug report: x64 Row status Array uses wrong data type
Date: 2018-05-14 06:59:57
Message-ID: 08FA934FA252D048A8B6D2018D96549A262C9169@CAEX2010.digital-dispatch.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-odbc


Hi Hiroshi

Hi Jari,
On 2018/05/11 18:33, Jari Siikarla wrote:
Hi

Thank you for psq odbc driver!

I’ve found an issue with 64 bit driver.
The array returned from fetch for row statuses uses 16 bit values
instead of 64 bit values.

Tested on x64 Windows (7, 10, srv2012 and srv2016)
with 64 bit psqlodbc-09.06.0500 (Unicode and ANSI)
Client is set ODBC version 2

Changing SQLUSMALLINT to SQLSETPOSIROW in descriptor.h
for two structs and in the code handling these structs fixed the issue.
Code in psqlodbc-10.02.0000 is the same for these parts.

Where can I find the description that SQL_ATTR_ROW_STATUS_PTR
(or SQL_ATTR_PARAM_STATUS_PTR) doesn't point to an array of
SQLUSMALLINT but SQLSETPOSIROW?

This is from observing workings of existing code. Not from ODBC specification.
Having a functionality on a platform with a provider really doesn’t mean that the functionality is by specks ☹

Oracle 11.1-12 64 bit ODBC driver on Windows returns 64 bit values for row statuses and 32 bit driver returns 16 bit values.

SQLSETPOSIROW follows this 16/64 bit definition nicely, so we used it in calling code when migrating the DB code to x64.
https://docs.microsoft.com/en-us/sql/odbc/reference/odbc-64-bit-information?view=sql-server-2017

“ODBC 64-Bit Information”

SQLSetStmtAttr
When the Attribute parameter has one of the following values, a 64-bit value is passed in *ValuePtr:

SQL_ATTR_ROW_STATUS_PTR

We hit a related bug in Oracle 11.2 ODBC 32 bit driver on x64 windows. (This has been fixed):
https://support.oracle.com/knowledge/Oracle%20Database%20Products/1472987_1.html

“ODBC Row Status Array (SQL_ATTR_ROW_STATUS_PTR) Populated As SQLUINTEGER Rather Than SQLUSMALLINT”

This issue reproduces with all versions of the Oracle ODBC driver since 11.1.0.6. It is a 32-bit-only problem;
in 64-bit mode the status values are 64-bit and this has been correctly implemented
(the bug being due most likely to a simple oversight and some inconsistency between 32-bit and 64-bit Windows:
if a value is 64 bits in 64-bit mode then it would be expected to be 32 bits in 32-bit mode, but in fact it is 16 bits in 32-bit mode).

I’m adding the support for PG alongside Oracle and this disparity is causing some head scratching.
I hope I don’t have to resort to if (((char*) pRowStatus)[2])

Thank you,
Jari Siikarla

struct IRDFields_
{
StatementClass *stmt;
SQLULEN *rowsFetched;
-> SQLSETPOSIROW *rowStatusArray;
UInt4 nfields;
SQLSMALLINT allocated;
FIELD_INFO **fi;
};

struct IPDFields_
{
SQLULEN *param_processed_ptr;
-> SQLSETPOSIROW *param_status_ptr;
SQLSMALLINT allocated;
ParameterImplClass *parameters;
};

Below pseudo code reproduces the issue:

SQLUINTEGER rowsFetched=0;
SQLSETPOSIROW pRowStatus[1];
SQLRETURN retCode;

pRowStatus[0]=-1; // 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF

retCode=SQLSetStmtAttr(hStmt, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER)1, 0);
retCode=SQLSetStmtAttr(hStmt, SQL_ATTR_ROWS_FETCHED_PTR, &rowsFetched, 0);
retCode=SQLSetStmtAttr(hStmt, SQL_ATTR_ROW_STATUS_PTR, pRowStatus, 0);
retCode=SQLFetchScroll(hStmt, SQL_FETCH_NEXT, 1);

// pRowStatus
// after fetch 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00
// exected to be 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

Thank you,
Jari Siikarla

In response to

Responses

Browse pgsql-odbc by date

  From Date Subject
Next Message Ashraf Parakkuth Thattasseri 2018-05-14 08:11:38 32-bit odbc source compilation failed
Previous Message Maxim Zakharov 2018-05-14 02:49:46 Build with Oracle Solaris Studio