YongpingZhang / pyodbc

Automatically exported from code.google.com/p/pyodbc
MIT No Attribution
0 stars 0 forks source link

Incorrect handling of negative numbers in a resultset #216

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Environment: OSX 10.6.8, system Python, Freetds .91, connecting to MSSQL 2008.

$ tsql -C
Compile-time settings (established with the "configure" script)
                            Version: freetds v0.91
             freetds.conf directory: /usr/local/Cellar/freetds/0.91/etc
     MS db-lib source compatibility: yes
        Sybase binary compatibility: no
                      Thread safety: yes
                      iconv library: yes
                        TDS version: 7.1
                              iODBC: no
                           unixodbc: yes
              SSPI "trusted" logins: no
                           Kerberos: no

Connecting to MSSQL over ODBC directly:

$ iodbctest
iODBC Demonstration program
This program shows an interactive SQL processor
Driver Manager: 03.52.0607.1008

Enter ODBC connect string (? shows list): 
DRIVER={tds};SERVER=...;PORT=1433;DATABASE=...;UID=...;PWD=...
Driver: 0.91 (libtdsodbc.so)

SQL>select -1;

-----------
-1         

 result set 1 returned 1 rows.

BUT using pyodbc (2.1.11):

$ python
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49) 
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyodbc
>>> conn = pyodbc.connect('same connection string as before')
>>> cur = conn.cursor()
>>> cur.execute('select -1').fetchone()
(4294967295, )

That's 2^32-1.

There must be some incorrect signed vs unsigned conversion going on.

If it helps, if I do "select 2^32-1" directly I get a Decimal back instead of 
an integer like I do when I "select -1":

>>> cur.execute('select '+str(2**32-1)).fetchone()
(Decimal('4294967295'), )
>>> cur.execute('select '+str(-1)).fetchone()
(4294967295, )

Here's some more funky detail on the behavior I'm seeing:

>>> for i in range(32,0,-1): print(cur.execute('select -'+str(2**i)).fetchone())
... 
(Decimal('-4294967296'), )
(2147483648, )
(3221225472, )
(3758096384, )
(4026531840, )
(4160749568, )
(4227858432, )
(4261412864, )
(4278190080, )
(4286578688, )
(4290772992, )
(4292870144, )
(4293918720, )
(4294443008, )
(4294705152, )
(4294836224, )
(4294901760, )
(4294934528, )
(4294950912, )
(4294959104, )
(4294963200, )
(4294965248, )
(4294966272, )
(4294966784, )
(4294967040, )
(4294967168, )
(4294967232, )
(4294967264, )
(4294967280, )
(4294967288, )
(4294967292, )
(4294967294, )

Let me know if I can provide any more detail.

Original issue reported on code.google.com by ke...@keithdevens.com on 14 Oct 2011 at 8:53

GoogleCodeExporter commented 9 years ago

Original comment by mkleehammer on 16 Oct 2011 at 12:37

GoogleCodeExporter commented 9 years ago
Some more information: this also happens on freetds 0.82 on Linux. It's a 
longstanding bug and isn't OS or freetds-version-specific.

Original comment by ke...@keithdevens.com on 17 Oct 2011 at 9:27

GoogleCodeExporter commented 9 years ago
Fixed in 3.0.1

Original comment by mkleehammer on 3 Nov 2011 at 1:47