From 53a7e47058e793a94f0cc22d216410c806c0914b Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Thu, 3 Jul 2014 11:47:59 +0200 Subject: [PATCH] New MySQL default Cast Rule for bit(1) to boolean, fix #93. We need a new transformation function that work with a vector of integers as input. --- src/sources/mysql-cast-rules.lisp | 4 ++++ src/transforms.lisp | 9 ++++++++- test/parse/hans.goeuro.load | 4 ++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/sources/mysql-cast-rules.lisp b/src/sources/mysql-cast-rules.lisp index c10bbc2..bf90820 100644 --- a/src/sources/mysql-cast-rules.lisp +++ b/src/sources/mysql-cast-rules.lisp @@ -66,6 +66,10 @@ :target (:type "boolean" :drop-typemod t) :using pgloader.transforms::tinyint-to-boolean) + (:source (:type "bit" :typemod (= 1 precision)) + :target (:type "boolean" :drop-typemod t) + :using pgloader.transforms::bits-to-boolean) + ;; we need the following to benefit from :drop-typemod (:source (:type "tinyint") :target (:type "smallint" :drop-typemod t)) (:source (:type "smallint") :target (:type "smallint" :drop-typemod t)) diff --git a/src/transforms.lisp b/src/transforms.lisp index 881825b..040e476 100644 --- a/src/transforms.lisp +++ b/src/transforms.lisp @@ -16,6 +16,7 @@ date-with-no-separator time-with-no-separator tinyint-to-boolean + bits-to-boolean int-to-ip ip-range convert-mysql-point @@ -98,7 +99,13 @@ tinyiny that are either 0 (false) or 1 (true). Of course PostgreSQL wants 'f' and 't', respectively." (when integer-string - (if (string= "0" integer-string) "f" "t"))) + (if (string= "0" integer-string) "f" "t"))) + +(defun bits-to-boolean (bit-vector) + "When using MySQL, strange things will happen, like encoding booleans into + bit(1). Of course PostgreSQL wants 'f' and 't'." + (when (and bit-vector (= 1 (length bit-vector))) + (if (= 0 (aref bit-vector 0)) "f" "t"))) (defun int-to-ip (int) "Transform an IP as integer into its dotted notation, optimised code from diff --git a/test/parse/hans.goeuro.load b/test/parse/hans.goeuro.load index cb02698..a0db939 100644 --- a/test/parse/hans.goeuro.load +++ b/test/parse/hans.goeuro.load @@ -16,6 +16,10 @@ LOAD DATABASE -- override char(1) to varchar(1), just use char(1) here. type char when (= precision 1) to char keep typemod, + -- bit(1) is a boolean too! + -- it's a default setting, just shows how to type it in + type bit when (= precision 1) to boolean drop typemod using bits-to-boolean, + column ascii.s using byte-vector-to-bytea, column enumerate.foo using empty-string-to-null