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