From 327745110a11ae12311c701506e8486d69d39102 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Mon, 18 Jan 2016 21:55:01 +0100 Subject: [PATCH] MySQL bytea default value can be "". Fix 291. Thanks to a reproducable test case we can see that MySQL default for a varbinary column is an empty string, so tweak the transform function byte-vector-to-bytea in order to cope with that. --- src/utils/transforms.lisp | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/utils/transforms.lisp b/src/utils/transforms.lisp index 743a9fc..4e33e66 100644 --- a/src/utils/transforms.lisp +++ b/src/utils/transforms.lisp @@ -223,25 +223,28 @@ http://www.postgresql.org/docs/9.3/interactive/datatype-binary.html Note that we choose here the bytea Hex Format." - (declare (type (or null (simple-array (unsigned-byte 8) (*))) vector)) - (when vector - (let ((hex-digits "0123456789abcdef") - (bytea (make-array (+ 2 (* 2 (length vector))) - :initial-element #\0 - :element-type 'standard-char))) + (declare (type (or null string (simple-array (unsigned-byte 8) (*))) vector)) + (etypecase vector + (null nil) + (string (assert (string= "" vector)) nil) + (simple-array + (let ((hex-digits "0123456789abcdef") + (bytea (make-array (+ 2 (* 2 (length vector))) + :initial-element #\0 + :element-type 'standard-char))) - ;; The entire string is preceded by the sequence \x (to distinguish it - ;; from the escape format). - (setf (aref bytea 0) #\\) - (setf (aref bytea 1) #\x) + ;; The entire string is preceded by the sequence \x (to distinguish it + ;; from the escape format). + (setf (aref bytea 0) #\\) + (setf (aref bytea 1) #\x) - (loop for pos from 2 by 2 - for byte across vector - do (let ((high (ldb (byte 4 4) byte)) - (low (ldb (byte 4 0) byte))) - (setf (aref bytea pos) (aref hex-digits high)) - (setf (aref bytea (+ pos 1)) (aref hex-digits low))) - finally (return bytea))))) + (loop for pos from 2 by 2 + for byte across vector + do (let ((high (ldb (byte 4 4) byte)) + (low (ldb (byte 4 0) byte))) + (setf (aref bytea pos) (aref hex-digits high)) + (setf (aref bytea (+ pos 1)) (aref hex-digits low))) + finally (return bytea)))))) (defun ensure-parse-integer (string-or-integer) "Return an integer value if string-or-integer is an integer or a string