Bug#413534: Another 64bit problem (binding SQL_C_SLONG values)

2007-03-12 Thread Enrico Zini
On Sun, Mar 11, 2007 at 09:06:16PM -0700, Steve Langasek wrote:

 On Sun, Mar 11, 2007 at 07:30:04PM +, Enrico Zini wrote:
  http://msdn2.microsoft.com/en-us/library/ms714556.aspx
  says that SQL_C_SLONG represents a long int.
 
 Microsoft's docs are totally useless for correctly implementing ODBC on
 64-bit architectures.  Please explain the /problem/ you're trying to solve,
 preferably with a reproducible use case.

Sorry.  What's a good authoritative API reference then?

I'm attaching a C program that reproduces the problem: it prints:

  Foo is -4294967295

where it should instead print:

  Foo is 1



Ciao,

Enrico

-- 
GPG key: 1024D/797EBFAB 2000-12-05 Enrico Zini [EMAIL PROTECTED]
#include stdio.h
#include stdlib.h
#include sql.h
#include sqlext.h

void check(SQLSMALLINT handletype, SQLHSTMT stm, int res)
{
	if ((res != SQL_SUCCESS)  (res != SQL_SUCCESS_WITH_INFO))
	{
		static const int strsize = 200;
		char stat[10], msg[strsize];
		SQLINTEGER err;
		SQLSMALLINT mlen;
		SQLGetDiagRec(handletype, stm, 1, (unsigned char*)stat, err, (unsigned char*)msg, strsize, mlen);
		if (mlen  strsize) mlen = strsize;
		fprintf(stderr, Error %d %s: %.*s\n, err, stat, mlen, msg);
		exit(1);
	}
}

void checkenv(SQLHENV stm, int res)
{
	check(SQL_HANDLE_ENV, stm, res);
}
void checkdbc(SQLHSTMT stm, int res)
{
	check(SQL_HANDLE_DBC, stm, res);
}
void checkstm(SQLHSTMT stm, int res)
{
	check(SQL_HANDLE_STMT, stm, res);
}

int main()
{
	SQLHENV dba_od_env;
	SQLHDBC od_conn;
	SQLHSTMT stm;
	long foo;

	SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, dba_od_env);
	checkenv(dba_od_env, SQLSetEnvAttr(dba_od_env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0));

	SQLAllocHandle(SQL_HANDLE_DBC, dba_od_env, od_conn);

	printf(Connecting\n);
	checkdbc(od_conn, SQLConnect(od_conn, test, SQL_NTS, enrico, SQL_NTS, , SQL_NTS));

	SQLAllocHandle(SQL_HANDLE_STMT, od_conn, stm);

	printf(Creating table\n);
	checkstm(stm, SQLExecDirect(stm, CREATE TABLE foo (id INTEGER), SQL_NTS));
	printf(Populating table\n);
	checkstm(stm, SQLExecDirect(stm, INSERT INTO foo VALUES (1), SQL_NTS));

	/* Init foo with some garbage, to catch the case in which it's filled
	 * in only partially */
	foo=-1;

	checkstm(stm, SQLBindCol(stm, 1, SQL_C_SLONG, foo, sizeof(foo), 0));
	printf(Querying table\n);
	checkstm(stm, SQLExecDirect(stm, SELECT id FROM foo, SQL_NTS));

	if (SQLFetch(stm) == SQL_NO_DATA)
		fprintf(stderr, No results for foo\n);

	printf(Foo is %ld\n, foo);

	checkstm(stm, SQLCloseCursor(stm));

	printf(Dropping table\n);
	checkstm(stm, SQLExecDirect(stm, DROP TABLE foo, SQL_NTS));

	return 0;
}


signature.asc
Description: Digital signature


Bug#413534: Another 64bit problem (binding SQL_C_SLONG values)

2007-03-12 Thread Steinar H. Gunderson
On Sun, Mar 11, 2007 at 07:30:04PM +, Enrico Zini wrote:
 convert.c has it like this:
 
   case SQL_C_SLONG:
   case SQL_C_LONG:
   len = 4;
   if (bind_size  0)
   *((SDWORD *) rgbValueBindRow) = atol(neut_str);
   else
   *((SDWORD *) rgbValue + bind_row) = atol(neut_str);
   break;
 
 but here on amd64 sizeof(long int) == 8.

This seems to have been discussed on the unixodbc-dev lists earlier, look at
the thread starting with:

  http://mail.easysoft.com/pipermail/unixodbc-dev/2005-March/000396.html

In particular, there's a message saying that this is indeed expected
behavior (ie. that the driver was wrong in 2005):

  http://mail.easysoft.com/pipermail/unixodbc-dev/2005-March/000397.html

The discussion was sent on to the pgsql-odbc mailing list:

  http://archives.postgresql.org/pgsql-odbc/2005-03/msg7.php

The patch from that thread seems to have fixed it _to_ the current behavior
(and it's present, although quite a bit modified, in the version in sid).
IOW, I believe there's consensus that SQL_C_LONG should map to _int_, as it
currently does, and Enrico's test case is wrong.

I found one bug (even after applying the patch that was discussed in the bug
log) by peering through the warnings (thank goodness for -Wno-sign-compare
-Wno-pointer-sign), though: FORMATI64 (convert.c:192) should be %ld and not
%lld on 64-bits archs (it's within an #ifdef ODBCINT64), and likewise for
FORMATI64U on the line below. It's really only the compiler warning, though
(that long != long long), as they are both 64 bits in practice. Hardly
anything one would want to change during a freeze. :-)

/* Steinar */
-- 
Homepage: http://www.sesse.net/


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]



Bug#413534: Another 64bit problem (binding SQL_C_SLONG values)

2007-03-12 Thread Steve Langasek
On Mon, Mar 12, 2007 at 11:02:30AM +, Enrico Zini wrote:
 On Sun, Mar 11, 2007 at 09:06:16PM -0700, Steve Langasek wrote:

  On Sun, Mar 11, 2007 at 07:30:04PM +, Enrico Zini wrote:
   http://msdn2.microsoft.com/en-us/library/ms714556.aspx
   says that SQL_C_SLONG represents a long int.

  Microsoft's docs are totally useless for correctly implementing ODBC on
  64-bit architectures.  Please explain the /problem/ you're trying to solve,
  preferably with a reproducible use case.

 Sorry.  What's a good authoritative API reference then?

Unfortunately, there isn't one.  Microsoft is the standard-bearer for ODBC,
they just don't know jack about 64-bit implementation issues.  There have
been some incremental improvements to the ODBC spec vis-à-vis 64-bit
platforms, but getting things working on 64-bit archs as we have in Debian
still requires some deviation from the 32-bit-minded spec.

Anyway, with Steinar's follow-up, I guess this part is definitely Not-A-Bug,
and I'll focus on the bits reported earlier.

Thanks,
-- 
Steve Langasek   Give me a lever long enough and a Free OS
Debian Developer   to set it on, and I can move the world.
[EMAIL PROTECTED]   http://www.debian.org/



Bug#413534: Another 64bit problem (binding SQL_C_SLONG values)

2007-03-11 Thread Enrico Zini
Hello,

http://msdn2.microsoft.com/en-us/library/ms714556.aspx
says that SQL_C_SLONG represents a long int.

convert.c has it like this:

case SQL_C_SLONG:
case SQL_C_LONG:
len = 4;
if (bind_size  0)
*((SDWORD *) rgbValueBindRow) = atol(neut_str);
else
*((SDWORD *) rgbValue + bind_row) = atol(neut_str);
break;

but here on amd64 sizeof(long int) == 8.  I had a look at upstream:

http://cvs.pgfoundry.org/cgi-bin/cvsweb.cgi/psqlodbc/psqlodbc/convert.c?rev=1.155content-type=text/x-cvsweb-markup

and it looks like it's still wrong.


Ciao,

Enrico

-- 
GPG key: 1024D/797EBFAB 2000-12-05 Enrico Zini [EMAIL PROTECTED]


signature.asc
Description: Digital signature


Bug#413534: Another 64bit problem (binding SQL_C_SLONG values)

2007-03-11 Thread Steve Langasek
Enrico,

On Sun, Mar 11, 2007 at 07:30:04PM +, Enrico Zini wrote:
 http://msdn2.microsoft.com/en-us/library/ms714556.aspx
 says that SQL_C_SLONG represents a long int.

Microsoft's docs are totally useless for correctly implementing ODBC on
64-bit architectures.  Please explain the /problem/ you're trying to solve,
preferably with a reproducible use case.

-- 
Steve Langasek   Give me a lever long enough and a Free OS
Debian Developer   to set it on, and I can move the world.
[EMAIL PROTECTED]   http://www.debian.org/


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of unsubscribe. Trouble? Contact [EMAIL PROTECTED]