From: | Heikki Linnakangas <hlinnakangas(at)vmware(dot)com> |
---|---|
To: | Hiroshi Inoue <inoue(at)tpf(dot)co(dot)jp> |
Cc: | Christoph Berg <christoph(dot)berg(at)credativ(dot)de>, PostgreSQL ODBC <pgsql-odbc(at)postgresql(dot)org>, psqlodbc(at)packages(dot)debian(dot)org |
Subject: | Re: 09.03.0100 cursor failures on various architectures |
Date: | 2014-02-25 16:56:16 |
Message-ID: | 530CCB30.8090606@vmware.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | 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
From | Date | Subject | |
---|---|---|---|
Next Message | Ramesh Reddy | 2014-02-25 23:19:08 | Kerberos/GSSAPI Instructions |
Previous Message | Hiroshi Inoue | 2014-02-25 15:13:12 | Re: 09.03.0100 cursor failures on various architectures |