[pg-cvs] CVS update: pg/parsers.lisp pg/pg-tests.lisp pg/CREDITS
Eric Marsden
emarsden at common-lisp.net
Tue Sep 7 12:52:20 UTC 2004
Update of /project/pg/cvsroot/pg
In directory common-lisp.net:/tmp/cvs-serv10481
Modified Files:
parsers.lisp pg-tests.lisp CREDITS
Log Message:
Add support for the SQL NUMERIC type, thanks to Risto Sakari Laakso.
Was previously being parsed as an integer, but is in fact a fix-precision
floating-point number.
Date: Tue Sep 7 14:52:19 2004
Author: emarsden
Index: pg/parsers.lisp
diff -u pg/parsers.lisp:1.5 pg/parsers.lisp:1.6
--- pg/parsers.lisp:1.5 Fri Aug 13 18:45:07 2004
+++ pg/parsers.lisp Tue Sep 7 14:52:19 2004
@@ -72,7 +72,7 @@
("char16" . ,'text-parser)
("text" . ,'text-parser)
("varchar" . ,'text-parser)
- ("numeric" . ,'integer-parser)
+ ("numeric" . ,'numeric-parser)
("int2" . ,'integer-parser)
("int4" . ,'integer-parser)
("int8" . ,'integer-parser)
@@ -96,7 +96,34 @@
;; see `man pgbuiltin' for details on PostgreSQL builtin types
(defun integer-parser (str) (parse-integer str))
-;; FIXME switch to a specialized float parser
+;; from Risto Sakari Laakso <rlaakso at cc.hut.fi>
+;;
+;; http://www.postgresql.org/docs/7.4/static/datatype.html#DATATYPE-NUMERIC-DECIMAL
+;;
+;; NUMERIC(precision, scale)
+;;
+;; The scale of a numeric is the count of decimal digits in the
+;; fractional part, to the right of the decimal point. The precision of a
+;; numeric is the total count of significant digits in the whole number, that
+;; is, the number of digits to both sides of the decimal point.
+(defun numeric-parser (str)
+ (let ((dot-pos (position #\. str))
+ integer-part
+ (decimal-part 0))
+ ;; parse up to #\., or whole string if #\. not present
+ (setq integer-part (parse-integer (subseq str 0 dot-pos)))
+ ;; if #\. present ..
+ (when dot-pos
+ (let* ((decimal-str (subseq str (1+ dot-pos)))
+ (dec-str-len (length decimal-str)))
+
+ ;; if has at least one digit after #\.
+ (when (> dec-str-len 0)
+ ;; parse integer after #\. and divide by 10^(digits), i.e. ".023" => 23/1000
+ (setq decimal-part (/ (parse-integer decimal-str) (expt 10 dec-str-len))))))
+ (+ integer-part decimal-part)))
+
+;; FIXME switch to a specialized float parser that conses less
(defun float-parser (str)
(declare (type simple-string str))
(let ((*read-eval* nil))
Index: pg/pg-tests.lisp
diff -u pg/pg-tests.lisp:1.8 pg/pg-tests.lisp:1.9
--- pg/pg-tests.lisp:1.8 Fri Aug 13 18:50:37 2004
+++ pg/pg-tests.lisp Tue Sep 7 14:52:19 2004
@@ -82,6 +82,32 @@
(when created
(pg-exec conn "DROP TABLE count_test_float")))))))
+(defun test-insert/numeric ()
+ (format *debug-io* "Testing INSERT & SELECT on NUMERIC ...~%")
+ (with-test-connection (conn)
+ (let ((res nil)
+ (sum 0)
+ (created nil))
+ (unwind-protect
+ (progn
+ (pg-exec conn "CREATE TABLE count_test_numeric(key int, val numeric(10,2))")
+ (setq created t)
+ (loop :for i :from 1 :to 1000
+ :for sql = (format nil "INSERT INTO count_test_numeric VALUES(~d, ~f)"
+ i i)
+ :do (pg-exec conn sql))
+ (setq res (pg-exec conn "SELECT count(val) FROM count_test_numeric"))
+ (assert (eql 1000 (first (pg-result res :tuple 0))))
+ (setq res (pg-exec conn "SELECT sum(key) FROM count_test_numeric"))
+ (assert (eql 500500 (first (pg-result res :tuple 0))))
+ ;; this iterator does the equivalent of the sum(key) SQL statement
+ ;; above, but on the client side.
+ (pg-for-each conn "SELECT val FROM count_test_numeric"
+ (lambda (tuple) (incf sum (first tuple))))
+ (assert (eql 500500 sum)))
+ (when created
+ (pg-exec conn "DROP TABLE count_test_numeric"))))))
+
(defun test-date ()
(format *debug-io* "Testing DATE and TIMESTAMP parsing ...~%")
(with-test-connection (conn)
@@ -355,7 +381,7 @@
(pg-exec conn "DROP TABLE foo")))
(defun test ()
- (let ((*pg-client-encoding* "UNICODE"))
+ (let (#+nil (*pg-client-encoding* "UNICODE"))
(with-test-connection (conn)
(format t "Running pg.lisp tests against backend ~a~%" (pg-backend-version conn))
;; client encoding supported since PostgreSQL v7.1
@@ -373,6 +399,7 @@
(test-simple)
(test-insert)
(test-insert/float)
+ (test-insert/numeric)
(test-date)
(test-booleans)
(test-integrity)
Index: pg/CREDITS
diff -u pg/CREDITS:1.3 pg/CREDITS:1.4
--- pg/CREDITS:1.3 Wed Aug 11 15:26:41 2004
+++ pg/CREDITS Tue Sep 7 14:52:19 2004
@@ -28,4 +28,5 @@
Brian Mastenbrook:
Implemented MD5 authentication support
-
+Risto Sakari Laakso:
+ Provided a parser for the NUMERIC type
More information about the Pg-cvs
mailing list