Hi all,

The small demo script below makes ADO calls to a Microsoft Access (Jet)
database via win32com. But it fails in a potentially dangerous way;
"SELECT int * int;" can return None with no warning if the result is
large enough. This can also occur if one or both of the operands is a
column reference.

The same SQL run as a Query inside the Access GUI works as expected.
Manually changing one of the ints to a Single by appending ".0" works as
expected.

Any ideas about where I need to look next to find the cause of, and then
fix, this behavior?
 

Robert Brewer
System Architect
Amor Ministries
[EMAIL PROTECTED]



# demo_access_overflow.py

import os
import win32com.client

adOpenForwardOnly = 0
adLockReadOnly = 1

dbname = "test.mdb"

def create_db():
    cat = win32com.client.Dispatch(r'ADOX.Catalog')
    cat.Create("PROVIDER=MICROSOFT.JET.OLEDB.4.0;DATA SOURCE=%s;" %
dbname)
    cat.ActiveConnection.Close()

def fetch(query, conn):
    try:
        # Call conn.Open(query) directly, skipping win32com overhead.
        res = win32com.client.Dispatch(r'ADODB.Recordset')
        res.Open(query, conn, adOpenForwardOnly, adLockReadOnly)
        data = res.GetRows()
    finally:
        res.Close()
    
    return data


if __name__ == '__main__':
    try:
        create_db()
        conn = win32com.client.Dispatch(r'ADODB.Connection')
        try:
            conn.Open("PROVIDER=MICROSOFT.JET.OLEDB.4.0;DATA SOURCE=%s;"
% dbname)
            
            # This works fine.
            assert fetch("SELECT 86400;", conn) == ((86400,),)
            
            # This fails because data is ((None,),)
            data = fetch("SELECT 62647 * 86400;", conn)
            assert (data == ((62647 * 86400,),)), data
            
        finally:
            conn.Close()
    finally:
        if os.path.exists(dbname):
            os.remove(dbname)
_______________________________________________
Python-win32 mailing list
Python-win32@python.org
http://mail.python.org/mailman/listinfo/python-win32

Reply via email to