Re: 09.03.0100 cursor failures on various architectures - Mailing list pgsql-odbc

From Heikki Linnakangas
Subject Re: 09.03.0100 cursor failures on various architectures
Date
Msg-id 530CCB30.8090606@vmware.com
Whole thread Raw
In response to Re: 09.03.0100 cursor failures on various architectures  (Hiroshi Inoue <inoue@tpf.co.jp>)
Responses Re: 09.03.0100 cursor failures on various architectures
List pgsql-odbc
On 02/25/2014 05:13 PM, Hiroshi Inoue wrote:
>> >1. Most applications are written with the assumption that SQL_C_LONG
>> >means the native C data type "long". That's clearly what SQL_C_LONG was
>> >supposed to mean when the ODBC specification was written, and that's
>> >what Microsoft's sample code does.
>> >
>> >2. That's*not*  how psqlODBC or unixODBC interprets it. With unixODBC,
>> >you should use the C data type "SQLINTEGER" with SQL_C_LONG.
>> >
>> >3. For maximum portability, an application should avoid using SQL_C_xx.
>> >Instead, always use SQL_INTEGER or SQL_BIGINT, with an SQLINTEGER or
>> >SQLBIGINT variable, and cast to native C types.
>> >
>> >We should document this somewhere, like in the FAQ..
> Unfortunately I'm not happy with your summary.
>
> My point is simple.
> Use ODBC data type variables instead of native C data ones when calling
> ODBC APIs.

Hmm, isn't that the same as my point 3?

I was thinking of something like below for the docs:

----
Don't use SQL_C_xxx. They are not part of the SQL/CLI specification, and
hence not reliably portable across platforms. Instead, use the ODBC
variable data types, like SQLINTEGER and SQLBIGINT, and the
corresponding type codes (e.g. SQL_INTEGER and SQL_BIGINT).

For example, the following code is not portable:

long        empID;
...
SQLBindCol(stmt, 1, SQL_C_LONG, (SQLPOINTER) &empID,
     sizeof(long), &indicator);

Instead, do this:

SQLINTEGER  empID;
...
SQLBindCol(stmt, 1, SQL_INTEGER, (SQLPOINTER) &empID,
     sizeof(SQLINTEGER), &indicator);

And if necessary, cast to the C type:

long lEmpID = (long) empID;


SQL_C_LONG, SQL_C_SLONG and SQL_C_ULONG in particular are known to be a
problem, as the width of the C datatype "long" varies, but unixODBC and
the psqlODBC driver always maps SQL_C_LONG to a 32-bit data type,
regardless of the width of "long" on the platform. An application using
SQL_C_LONG and "long" will not work correctly on a platform where
sizeof(long) == 8. It is easily seen on big-endian systems, where the
values returned will be off by 2^32, but can also lead to difficult to
find bugs on little-endian systems, as the driver will not initialize
the high 4 bytes.
----

- Heikki


pgsql-odbc by date:

Previous
From: Hiroshi Inoue
Date:
Subject: Re: 09.03.0100 cursor failures on various architectures
Next
From: Ramesh Reddy
Date:
Subject: Kerberos/GSSAPI Instructions