unsigned 64 bit integers patch
Aaron Burrow <[email protected]> Mon, 6 Jan 2014 23:49:17 -0500
| Newsgroups | gmane.lisp.clsql.general |
|---|---|
| Message-ID | <CADExsvFhQA9KxBbU4apuwSckK4w7Zr43gDnZFBRDRbMYUf=VEA@mail.gmail.com> |
I do not believe unsigned 64 bit integers behave properly.
CL-USER> (setf d (clsql:connect '("127.0.0.1" "dt0" "root" "letmein" 3306)
:database-type :mysql
:if-exists :new
:make-default nil))
<snip>
#<CLSQL-MYSQL:MYSQL-DATABASE 127.0.0.1:3306/dt0/root OPEN {10068A59C3}>
CL-USER> (clsql:query "create table tt (x bigint unsigned)" :database d)
NIL
NIL
CL-USER> (clsql:query "select * from tt" :database d)
NIL
("x")
CL-USER> (clsql:query (format nil "insert into tt values (~A), (~A), (~A)"
(expt 2 64) (1- (expt 2 64)) (expt 2 63))
:database d)
NIL
NIL
CL-USER> (clsql:query "select * from tt" :database d)
((-1) (-1) (-9223372036854775808))
("x")
The issue seemed to stem from indiscriminately using
make-64-bit-integer(...) which was treating everything like it was signed.
My patch uses strtoull and strtoll in an attempt to match the style seen
nearby. Why do you not use parse-integer(...) ?
patch:
diff --git a/uffi/clsql-uffi.lisp b/uffi/clsql-uffi.lisp
index 79d423f..942c69d 100644
--- a/uffi/clsql-uffi.lisp
+++ b/uffi/clsql-uffi.lisp
@@ -71,6 +71,18 @@
(radix :int))
:returning :unsigned-long)
+(uffi:def-function ("strtoull" c-strtoull)
+ ((str (* :unsigned-char))
+ (endptr (* :unsigned-char))
+ (radix :int))
+ :returning :unsigned-long-long)
+
+(uffi:def-function ("strtoll" c-strtoll)
+ ((str (* :unsigned-char))
+ (endptr (* :unsigned-char))
+ (radix :int))
+ :returning :unsigned-long-long)
+
(uffi:def-function "atol"
((str (* :unsigned-char)))
:returning :long)
@@ -108,6 +120,16 @@
(type char-ptr-def char-ptr))
(c-strtoul char-ptr uffi:+null-cstring-pointer+ 10))
+(defun strtoull (char-ptr)
+ (declare (optimize (speed 3) (safety 0) (space 0))
+ (type char-ptr-def char-ptr))
+ (c-strtoull char-ptr uffi:+null-cstring-pointer+ 10))
+
+(defun strtoll (char-ptr)
+ (declare (optimize (speed 3) (safety 0) (space 0))
+ (type char-ptr-def char-ptr))
+ (c-strtoll char-ptr uffi:+null-cstring-pointer+ 10))
+
(defun convert-raw-field (char-ptr type &key length encoding)
(declare (optimize (speed 3) (safety 0) (space 0))
(type char-ptr-def char-ptr))
@@ -122,17 +144,14 @@
(atol char-ptr))
(:int32
(atoi char-ptr))
+ (:int64
+ (strtoll char-ptr))
(:uint32
(strtoul char-ptr))
(:uint
(strtoul char-ptr))
- ((:int64 :uint64)
- (uffi:with-foreign-object (high32-ptr :unsigned-int)
- (let ((low32 (atol64 char-ptr high32-ptr))
- (high32 (uffi:deref-pointer high32-ptr :unsigned-int)))
- (if (zerop high32)
- low32
- (make-64-bit-integer high32 low32)))))
+ (:uint64
+ (strtoull char-ptr))
(:blob
(if length
(uffi:convert-from-foreign-usb8 char-ptr length)
_______________________________________________
CLSQL mailing list
[email protected]
http://lists.b9.com/cgi-bin/mailman/listinfo/clsql