> From: Christoph Zwerschke <[email protected]>
> Am 16.07.2011 15:29 schrieb Maxim Yegorushkin:
> > This patch extends float handling by supporting nan and inf values along
> > with a new unit test. It basically always quotes floats to avoid isinf()
> > and isnan() checks for each and every float value.
>
> Hm, this may work with older Postgres versions, but it's a bit unclean
> since it puts quotes arounds normal floats where they do not belong, and
> since it relies on the string representation of NaN and Inf in Python
> which may differ for different Python versions and is definitely
> different from their official representation in Postgres (e.g. 'inf'
> instead of 'Infinity' and 'nan' instead of 'NaN').
Fair enough. The reason I did it that way was to avoid calling isinf()
and isnan() for every float value and since every float gets converted
to a string anyway I thought I'd convert it earlier, premature
optimization if you wish. Too bad python doesn't have C99 fpclassify()
that checks for nan and inf in one call.
> Newer Postgres
> versions may not be so sloppy concerning the input, and indeed Postgres
> 9.0 does not allow writing 'inf' insted of 'Infinity'. We should better
> produce the proper SQL, i.e. the official names with proper case even
> though Postgres currently is case-insensitive on input, and we should
> not put quotes around numbers.
I see now, I overlooked the fact that there are official Postgres
names for special float values. Would it make sense to do this
instead:
===================================================================
--- pgdb.py (revision 429)
+++ pgdb.py (working copy)
@@ -64,7 +64,7 @@
"""
from _pg import *
-import time, sys
+import time, sys, math
try:
frozenset
except NameError: # Python < 2.4
@@ -201,8 +201,13 @@
val = "E'%s'" % self._cnx.escape_bytea(val)
else:
val = "'%s'" % self._cnx.escape_string(val)
- elif isinstance(val, (int, long, float)):
+ elif isinstance(val, (int, long)):
pass
+ elif isinstance(val, float):
+ if math.isnan(val):
+ val = "'NaN'"
+ elif math.isinf(val):
+ val = "'Infinity'" if val > 0 else "'-Infinity'"
elif val is None:
val = 'NULL'
elif isinstance(val, (list, tuple)):
It relies on the fact that python can handle "Infinity" and
"-Infinity" as well as "inf" and "-inf". I can't double check that in
python documentation right now since python.org does not respond at
present.
Another thing worth mentioning is that it would break user code that
uses float formatting in sql strings, like "%.2f" instead of simple
"%s". Are float formats allowed in sql strings according to dbapi
spec?
> > With regards to date support, I am thinking of handling date and
> > datetime similar to decimal, that is, to convert strings to date and
> > datetime when reading rowsets, so that user code does not have to
> > convert strings to dates. Does it make sense?
>
> This is http://trac.vex.net:8000/pgtracker/ticket/28
>
> But I think we should make it configurable so that old code will not be
> broken. The default could be strings in 4.x, and then dates in 5.x.
Sure, we don't want to break existing working code.
-- Maxim
_______________________________________________
PyGreSQL mailing list
[email protected]
http://mailman.vex.net/mailman/listinfo/pygresql