Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

weird numeric issue, not sure which side its on but did not occur in cx_oracle 5.x #77

Closed
zzzeek opened this issue Sep 1, 2017 · 3 comments
Labels

Comments

@zzzeek
Copy link

zzzeek commented Sep 1, 2017

the test program below works without issue on all the 5.x cx_Oracle series, like 5.3, etc. When I run it on 6.0.2, I get random behavior, all seemingly related to the value "5748E+15". With outconverter set, I get just failures like:

AssertionError: set([Decimal('400000000'), Decimal('5749300000000000000'), Decimal('1521000000000000'), Decimal('100000000000')]) != set([Decimal('4E+8'), Decimal('5.748E+18'), Decimal('1E+11'), Decimal('1.521E+15')])

noting above, the exponent display is different, but that part is normal, the issue is the 5.748E value isn't coming back correctly - in my own test suites, sometimes it comes back as None also as though the outputtypehandler is getting skipped.

however more weirdly, if I use cursor.var(decimal.Decimal, ...) as cx_Oracle 6.0.x supports, then I get different errors each time, of the form:

decimal.InvalidOperation: Invalid literal for Decimal: '574A900000000000000'
decimal.InvalidOperation: Invalid literal for Decimal: '574?700000000000000'
decimal.InvalidOperation: Invalid literal for Decimal: '574:200000000000000'
decimal.InvalidOperation: Invalid literal for Decimal: '574:900000000000000'

if I remove the "5748E+15" value, then everything works without failing.

this is Oracle 11.2 express. I'm not sure if this is some weird known Oracle thing but if I use cx_Oracle 5.x, it goes away. This may well be within the realm of, "this won't work anymore on Oracle express on a laptop" but looking to see if you have some idea of what changed and what could cause this.

import cx_Oracle
import decimal

conn = cx_Oracle.connect(
    user="scott",
    password="tiger",
    dsn=cx_Oracle.makedsn(
        "172.17.0.3", 1521, sid="xe",
    )
)

cursor = conn.cursor()

cursor.execute("""
CREATE TABLE t (
    x NUMERIC(27, 4)
)
""")
try:
    values = set([
        decimal.Decimal('4E+8'),
        decimal.Decimal("5748E+15"),  # <--- this number is causing the problem
        decimal.Decimal('1.521E+15'),
        decimal.Decimal('00000000000000.1E+12')
    ])

    cursor.executemany(
        "INSERT INTO t (x) VALUES (:x)",
        [{"x": value} for value in values]
    )

    def output_type_handler(cursor, name, defaultType,
                            size, precision, scale):
        return cursor.var(
            # using decimal.Decimal here on cx_Oracle 6.0.2 still breaks
            cx_Oracle.STRING,
            255,
            outconverter=decimal.Decimal,
            arraysize=cursor.arraysize)
    cursor.outputtypehandler = output_type_handler
    cursor.execute("SELECT x FROM t")

    received = set([
        row[0] for row in cursor.fetchall()
    ])

    print "cx_Oracle version: %r" % cx_Oracle.__version__
    print "Sent: %r   Received: %r" % (values, received)

    assert received == values, "%r != %r" % (received, values)


finally:
    cursor.execute("DROP TABLE t")

@anthony-tuininga
Copy link
Member

Interesting! I'll take a look.

@anthony-tuininga
Copy link
Member

Thanks for catching that. It was an intermittent issue due to the use of uninitialised data (only relevant with some numbers and only in some circumstances). I have corrected this in both ODPI-C and cx_Oracle.

@zzzeek
Copy link
Author

zzzeek commented Sep 4, 2017

awesome!! only some numbers as I observed :). great

@cjbj cjbj added the bug label Sep 4, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants