Thread: ODBC : SQLGetData question
Hi,
I have a question regarding ODBC call SQLGetData.SQLGetData(my_stmt, my_col_no, SQL_C_CHAR, &my_max_len, 0, &my_buff_len)
In case the column value is 'PG' then the value of my_buff_length gets populated as 2 which is the expected value but in the call above in case the table's column has value NULL then value of my_buff_len gets populated as 4294967295 which is 4GB,
instead shouldn't my_buff_len get populated as SQL_NULL_DATA?
Postgres ODBC Driver version - 9.2.1
Platform - RHEL 5
Regards..Hi, SQLGetData expects the buffer length parameter to be a SQLLEN variable, which is a signed type. SQL_NULL_DATA is defined as -1, which is 4294967295 if you interpret it as an unsigned type. Your my_buff_len variable is being set to SQL_NULL_DATA correctly, but you are looking at it wrong. Change it to be the correct type, and it will work as you expect. Regards, Harun On 14/05/14 13:23, Dev Kumkar wrote: > Hi, > > I have a question regarding ODBC call SQLGetData. > > SQLGetData(my_stmt, my_col_no, SQL_C_CHAR, &my_max_len, 0, &my_buff_len) > > In case the column value is 'PG' then the value of my_buff_length gets > populated as 2 which is the expected value but in the call above in > case the table's column has value NULL then value of my_buff_len gets > populated as 4294967295 which is 4GB, > instead shouldn't my_buff_len get populated as SQL_NULL_DATA? > > Postgres ODBC Driver version - 9.2.1 > Platform - RHEL 5 > > Regards..
On Wed, May 14, 2014 at 12:10 PM, aihtdikh <aihtdikh@gmail.com> wrote:
Thanks for the reply.
my_buff_len is defined as SQLLEN
SQLLEN my_buff_len;
SQLGetData(my_stmt, my_col_no, SQL_C_CHAR, &my_max_len, 0, &my_buff_len)
Hi,
SQLGetData expects the buffer length parameter to be a SQLLEN variable, which is a signed type.
SQL_NULL_DATA is defined as -1, which is 4294967295 if you interpret it as an unsigned type.
Your my_buff_len variable is being set to SQL_NULL_DATA correctly, but you are looking at it wrong.
Change it to be the correct type, and it will work as you expect.
Regards,
Harun
Thanks for the reply.
my_buff_len is defined as SQLLEN
SQLLEN my_buff_len;
SQLGetData(my_stmt, my_col_no, SQL_C_CHAR, &my_max_len, 0, &my_buff_len)
if (my_buff_len == SQL_NULL_DATA)
{
{
// Doesn't come here
}
What is being missed above?
Regards...
On Wed, May 14, 2014 at 12:51 PM, Dev Kumkar <devdas.kumkar@gmail.com> wrote:
On Wed, May 14, 2014 at 12:10 PM, aihtdikh <aihtdikh@gmail.com> wrote:Hi,
SQLGetData expects the buffer length parameter to be a SQLLEN variable, which is a signed type.
SQL_NULL_DATA is defined as -1, which is 4294967295 if you interpret it as an unsigned type.
Your my_buff_len variable is being set to SQL_NULL_DATA correctly, but you are looking at it wrong.
Change it to be the correct type, and it will work as you expect.
Regards,
Harun
Thanks for the reply.
my_buff_len is defined as SQLLEN
SQLLEN my_buff_len;
SQLGetData(my_stmt, my_col_no, SQL_C_CHAR, &my_max_len, 0, &my_buff_len)if (my_buff_len == SQL_NULL_DATA)
{// Doesn't come here}What is being missed above?Regards...
if ((int)my_buff_len == SQL_NULL_DATA)
{
// will come here
} The above casting solves the problem, please review?
Regards...
Regards...
On 14/05/14 08:46, Dev Kumkar wrote:
On Wed, May 14, 2014 at 12:51 PM, Dev Kumkar <devdas.kumkar@gmail.com> wrote:On Wed, May 14, 2014 at 12:10 PM, aihtdikh <aihtdikh@gmail.com> wrote:Hi,
SQLGetData expects the buffer length parameter to be a SQLLEN variable, which is a signed type.
SQL_NULL_DATA is defined as -1, which is 4294967295 if you interpret it as an unsigned type.
Your my_buff_len variable is being set to SQL_NULL_DATA correctly, but you are looking at it wrong.
Change it to be the correct type, and it will work as you expect.
Regards,
Harun
Thanks for the reply.
my_buff_len is defined as SQLLEN
SQLLEN my_buff_len;
SQLGetData(my_stmt, my_col_no, SQL_C_CHAR, &my_max_len, 0, &my_buff_len)if (my_buff_len == SQL_NULL_DATA)
{// Doesn't come here}What is being missed above?Regards...
if ((int)my_buff_len == SQL_NULL_DATA)
{// will come here}The above casting solves the problem, please review?
Regards...
Just to suggest.
I would guess the application expects sizeof( SQLLEN ) == 8 and the driver sizeof( SQLLEN ) == 4
--
Nick Gorham
On 14/05/14 15:46, Dev Kumkar wrote: > > > my_buff_len is defined as SQLLEN > SQLLEN my_buff_len; > > > if ((int)my_buff_len == SQL_NULL_DATA) > { > // will come here > } > > The above casting solves the problem, please review? > That will work around the issue, but I'm stumped as to why it was not working for you already. It seems like your platform must be 64bit, and something somewhere is converting what should be a 64bit SQLLEN into a 32bit value, but I can't find anywhere in the source that does anything unsafe in this regard - it's SQLLEN all the way. Edit: Ah, Nick may be on the right path there. Could the driver have been compiled with a different sqltypes.h than the application? If so, you could try compiling the driver under the same setup as your application to see if that fixes it. Regards, Harun
On Wed, May 14, 2014 at 2:17 PM, aihtdikh <aihtdikh@gmail.com> wrote:
That will work around the issue, but I'm stumped as to why it was not working for you already.
It seems like your platform must be 64bit, and something somewhere is converting what should be a 64bit SQLLEN into a 32bit value, but I can't find anywhere in the source that does anything unsafe in this regard - it's SQLLEN all the way.
Edit: Ah, Nick may be on the right path there.
Could the driver have been compiled with a different sqltypes.h than the application?
If so, you could try compiling the driver under the same setup as your application to see if that fixes it.
Regards,
Harun
Yes, the platform is 64-bit.
We are deploying the driver as it is and not compiling it in-house currently.
Do you see any issues with the (int) typecast done for SQLLEN?
Regards...
On 14/05/14 17:07, Dev Kumkar wrote: > Yes, the platform is 64-bit. > We are deploying the driver as it is and not compiling it in-house > currently. > > Do you see any issues with the (int) typecast done for SQLLEN? > It will certainly work for this call to SQLGetData, now that you know the workaround. However, I can't guess where else issues may appear if there really is a mismatch in data size between the driver, odbc manager and/or the application. It may work right now, but for me, I would certainly be trying to get to the bottom of it in case it causes more weird problems. Regards, Harun
On 14/05/14 10:07, Dev Kumkar wrote:
On Wed, May 14, 2014 at 2:17 PM, aihtdikh <aihtdikh@gmail.com> wrote:That will work around the issue, but I'm stumped as to why it was not working for you already.
It seems like your platform must be 64bit, and something somewhere is converting what should be a 64bit SQLLEN into a 32bit value, but I can't find anywhere in the source that does anything unsafe in this regard - it's SQLLEN all the way.
Edit: Ah, Nick may be on the right path there.
Could the driver have been compiled with a different sqltypes.h than the application?
If so, you could try compiling the driver under the same setup as your application to see if that fixes it.
Regards,
HarunYes, the platform is 64-bit.We are deploying the driver as it is and not compiling it in-house currently.
In that case compile the application with the same setup as the driver.
Do you see any issues with the (int) typecast done for SQLLEN?
Yes, if your app ever expects the driver to return an array of results (for example) it will go badly wrong very quickly. Also, if the driver is 64 bit SQLLEN and the application 32 bit, a SQLGetData will be writing to memory that happens to be after the indicator variable, that will not end well.
--
Nick
On Wed, May 14, 2014 at 3:38 PM, Nick Gorham <nick@lurcher.org> wrote:
In that case compile the application with the same setup as the driver.Yes, the platform is 64-bit.We are deploying the driver as it is and not compiling it in-house currently.
Thanks again for the help here. I think as you mentioned before the application expects sizeof( SQLLEN ) == 8 and the driver sizeof( SQLLEN ) == 4 which results into this issue.
Actually tried to initialize my_buff_len = SQL_NULL_DATA;
Actually tried to initialize my_buff_len = SQL_NULL_DATA;
The next printf correctly prints the value of my_buff_length as -1.
Only after SQLGetData(my_stmt, my_col_no, SQL_C_CHAR, &my_max_len, 0, &my_buff_len) the value of my_buff_len becomes 429496729.
Is it possible the ODBC header files on machine where am compiling application is having issues or as you mentioned before its the issue with the environment with which ODBC driver was compiled?
Am downloading the driver from here: 9.2.1 ODBC Driver
http://yum.postgresql.org/9.3/redhat/rhel-5.0-x86_64/
Regards...