[DB-SIG] Help w/ bugs in dbiDate win32

kinquiry at kennedytech.com kinquiry at kennedytech.com
Fri Jan 30 02:55:36 EST 2004


Not sure if I'm posting to the right group.

Below describes situations with dbiDate and odbc modules under win32 that 
will crash python.

>From all that I have been able to gather, the win32all odbc.py module uses 
the dbi.dbiDate object whenever a result column in SQL references an ODBC 
timestamp type field.

I've played with this object on various win32 machines, with various 
versions of python 2.X , and have experienced the following (which I think 
is due to unimplemented or incorrectly implemented python base object 
functions in the underlying C++ code in odbc.cpp and dbi.cpp):

When instantiating the dbiDate with a float in the constructor (which I 
think is how it's supposed to be used), everything works OK.....

$ python
ActivePython 2.2.2 Build 224 (ActiveState Corp.) based on
Python 2.2.2 (#37, Nov 26 2002, 10:24:37) [MSC 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import dbi
>>> import time
>>> x = dbi.dbiDate(time.time())
>>> x
<DbiDate object at 0x007A8100>
>>> float(x)
1075446574.7260001
>>> str(x)
'Fri Jan 30 02:09:34 2004'
>>> long(x)
1075446574L
>>> int(x)
1075446574
>>> x <> 0
1
>>> x == 0
0
>>> x == None
0
>>>

However, the dbiDate object will let you instantiate it with something 
other than a float in the constructor (like None).  I wouldn't do this in 
my code, but I think there might be some cases when odbc.pyd does this, or 
something similar.  For example:

$ python
ActivePython 2.2.2 Build 224 (ActiveState Corp.) based on
Python 2.2.2 (#37, Nov 26 2002, 10:24:37) [MSC 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import dbi
>>> x = dbi.dbiDate(None)
>>> float(x)

WILL CRASH PYTHON.

I might be barking up the wrong tree, but I suspect that the above 
condition is similar to what happens in the following REAL WORLD code 
snippet:

$ python
ActivePython 2.2.2 Build 224 (ActiveState Corp.) based on
Python 2.2.2 (#37, Nov 26 2002, 10:24:37) [MSC 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import odbc
>>> cur = odbc.odbc('beaulieu').cursor() # MySQL database on win32
>>> cur.execute('use newbeaulieu')
0
>>> cur.execute("""
...   select date_format(PRDOB8,'%M %D %Y') , PRDOB8
...   from cvt_1_prpmss where import_sequence = 342056
...   """
... )
0
>>> res = cur.fetchall()
>>> res
[('November 23rd 1985', <DbiDate object at 0x007A6F40>)]
>>> testDate = res[0][1]
>>>
>>> cur.execute("""
...   create table test_table ( dt datetime )
...   """
... )
0
>>> cur.execute('insert into test_table ( dt ) values ( ? )', ( testDate , 
) )
1
>>> cur.execute("""
...   select date_format(PRDOB8,'%M %D %Y') , PRDOB8
...   from cvt_1_prpmss where import_sequence = 1
...   """
... )
0
>>> res = cur.fetchall()
>>> res
[('April 19th 1954', <DbiDate object at 0x007A5648>)]
>>> testDate = res[0][1]
>>>
>>> cur.execute('insert into test_table ( dt ) values ( ? )', (testDate, ) 
)

The last line crashed python with an invalid memory access error.  I think 
it's because the date was before the epoch, which probably isn't supported 
by the C libraries that dbiDate uses.  This seems a logical conclusion, 
since the code for the 2nd 'insert' was exactly the same as the first, but 
it used an older date as a parameter.  From what I can gather, once an old 
date is put into a dbiDate instance, many of the methods on the dbiDate 
overwrite memory and will eventually crash python. 

I'm at a standstill with this now, because I'm not a good C programmer, 
and I don't have visual studio.  There doesn't seem to be too much code 
involved in the two .cpp modules that underly the dbi and odbc python 
modules in win32all. 

Ideally, the odbc module should be given a function or a flag to check 
that would cause it to pass the date value back as a float ( or whatever 
the underlying odbc API returns ) so that application programmers can deal 
with it.  Or, even better, dbiDate could be replaced with an object that 
works for dates older than 1970.

Does anyone have any ideas?  Any help would be greatly appreciated.

Best Regards,
John Kennedy

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/db-sig/attachments/20040130/8560c4b1/attachment.html


More information about the DB-SIG mailing list