[pg-cvs] CVS update: pg/parsers.lisp
Eric Marsden
emarsden at common-lisp.net
Wed Apr 21 19:23:18 UTC 2004
Update of /project/pg/cvsroot/pg
In directory common-lisp.net:/tmp/cvs-serv13664
Modified Files:
parsers.lisp
Log Message:
>From Sven Van Caekenberghe:
- fix to PARSE-TIMESTAMP when no milliseconds are present
- make use of :start and :end arguments to PARSE-INTEGER to reduce consing
Date: Wed Apr 21 15:23:18 2004
Author: emarsden
Index: pg/parsers.lisp
diff -u pg/parsers.lisp:1.2 pg/parsers.lisp:1.3
--- pg/parsers.lisp:1.2 Mon Mar 8 09:37:36 2004
+++ pg/parsers.lisp Wed Apr 21 15:23:18 2004
@@ -1,7 +1,6 @@
;;; parsers.lisp -- type coercion support
;;;
;;; Author: Eric Marsden <emarsden at laas.fr>
-;;; Time-stamp: <2004-03-05 emarsden>
;;
;;
;; When returning data from a SELECT statement, PostgreSQL starts by
@@ -100,11 +99,15 @@
;; FIXME switch to a specialized float parser
(defun float-parser (str)
(declare (type simple-string str))
-
(let ((*read-eval* nil))
(read-from-string str)))
-;; FIXME this may need support for charset decoding
+;; here we are assuming that the value of *PG-CLIENT-ENCODING* is
+;; compatible with the encoding that the CL implementation uses for
+;; strings. The backend should convert all values belonging to one of
+;; the text data types from the table's internal representation to
+;; that requested by the client, so here we don't need to do any
+;; conversion.
(defun text-parser (str) str)
(defun bool-parser (str)
@@ -116,18 +119,20 @@
(defun parse-timestamp (str)
(declare (type simple-string str))
- (let* ((year (parse-integer (subseq str 0 4)))
- (month (parse-integer (subseq str 5 7)))
- (day (parse-integer (subseq str 8 10)))
- (hours (parse-integer (subseq str 11 13)))
- (minutes (parse-integer (subseq str 14 16)))
- (seconds (parse-integer (subseq str 17 19)))
- (start-tz (if (eql #\+ (char str (- (length str) 3)))
- (- (length str) 3)))
+ (let* ((year (parse-integer str :start 0 :end 4))
+ (month (parse-integer str :start 5 :end 7))
+ (day (parse-integer str :start 8 :end 10))
+ (hours (parse-integer str :start 11 :end 13))
+ (minutes (parse-integer str :start 14 :end 16))
+ (seconds (parse-integer str :start 17 :end 19))
+ (length (length str))
+ (start-tz (if (eql #\+ (char str (- length 3)))
+ (- length 3)))
(tz (when start-tz
- (parse-integer (subseq str start-tz))))
- (milliseconds (if (eql (char str 19) #\.)
- (parse-integer (subseq str 20 start-tz)) 0)))
+ (parse-integer str :start start-tz)))
+ (milliseconds (if (and (< 19 length) (eql (char str 19) #\.))
+ (parse-integer str :start 20 :end start-tz)
+ 0)))
(values year month day hours minutes seconds milliseconds tz)))
;; format for abstime/timestamp etc with ISO output syntax is
@@ -151,10 +156,10 @@
;; An interval is what you get when you subtract two timestamps. We
;; convert to a number of seconds.
(defun interval-parser (str)
- (let* ((hours (parse-integer (subseq str 0 2)))
- (minutes (parse-integer (subseq str 3 5)))
- (seconds (parse-integer (subseq str 6 8)))
- (milliseconds (parse-integer (subseq str 9))))
+ (let* ((hours (parse-integer str :start 0 :end 2))
+ (minutes (parse-integer str :start 3 :end 5))
+ (seconds (parse-integer str :start 6 :end 8))
+ (milliseconds (parse-integer str :start 9)))
(+ (/ milliseconds (expt 10.0 (- (length str) 9)))
seconds
(* 60 minutes)
@@ -165,22 +170,22 @@
;;; "1999-01-02 00:00:00+01"
;; which we convert to a CL universal time
(defun isodate-parser (str)
- (let ((year (parse-integer (subseq str 0 4)))
- (month (parse-integer (subseq str 5 7)))
- (day (parse-integer (subseq str 8 10)))
- (hours (parse-integer (subseq str 11 13)))
- (minutes (parse-integer (subseq str 14 16)))
- (seconds (parse-integer (subseq str 17 19)))
- (tz (parse-integer (subseq str 19 22))))
+ (let ((year (parse-integer str :start 0 :end 4))
+ (month (parse-integer str :start 5 :end 7))
+ (day (parse-integer str :start 8 :end 10))
+ (hours (parse-integer str :start 11 :end 13))
+ (minutes (parse-integer str :start 14 :end 16))
+ (seconds (parse-integer str :start 17 :end 19))
+ (tz (parse-integer str :start 19 :end 22)))
(encode-universal-time seconds minutes hours day month year tz)))
;; format for date with ISO output syntax is
;;; "1999-01-02"
;; which we convert to a CL universal time
(defun date-parser (str)
- (let ((year (parse-integer (subseq str 0 4)))
- (month (parse-integer (subseq str 5 7)))
- (day (parse-integer (subseq str 8 10))))
+ (let ((year (parse-integer str :start 0 :end 4))
+ (month (parse-integer str :start 5 :end 7))
+ (day (parse-integer str :start 8 :end 10)))
(encode-universal-time 0 0 0 day month year)))
(defun initialize-parsers (connection)
@@ -204,6 +209,8 @@
oid)))))
tuples)))
+;; FIXME should perhaps resignal parse errors as a condition derived
+;; from POSTGRESQL-ERROR
(defun parse (str oid)
(declare (type simple-string str))
(let ((parser (assoc oid *parsers* :test #'eql)))
More information about the Pg-cvs
mailing list