Re: unsigned 64 bit integers patch
Russ Tyndall <[email protected]> Tue, 07 Jan 2014 13:16:04 -0500
| Newsgroups | gmane.lisp.clsql.general |
|---|---|
| Message-ID | <[email protected]> |
There is an outstanding request to merge a patch that attempts to make
fixes around this behavior. I don't believe it actually addresses the
signed/unsigned issue you brought up. It does try to be cross
compatible with windows though. I will attempt to merge both at the
same time.
https://github.com/UnwashedMeme/clsql/pull/2
Thanks much for your input and patch!
Cheers,
Russ Tyndall
Acceleration.net
On 1/6/2014 11:49 PM, Aaron Burrow wrote:
> 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
> <http://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
_______________________________________________
CLSQL mailing list
[email protected]
http://lists.b9.com/cgi-bin/mailman/listinfo/clsql