mirror of
https://github.com/dimitri/pgloader.git
synced 2025-08-08 07:16:58 +02:00
Implement support for MySQL bitstrings.
We migrate bit(xx) to the same PostgreSQL datatype bit(xx) where in Postgres we can use bitstring as documented at the following URL. In particular the COPY syntax accepts the notation Xabcd for the values, which is quite nice when MySQL sends the data to us a a byte vector: https://www.postgresql.org/docs/current/datatype-bit.html Fixes #943.
This commit is contained in:
parent
a9133256a7
commit
513455f552
@ -36,10 +36,16 @@
|
|||||||
:target (:type "boolean" :drop-typemod t)
|
:target (:type "boolean" :drop-typemod t)
|
||||||
:using pgloader.transforms::tinyint-to-boolean)
|
:using pgloader.transforms::tinyint-to-boolean)
|
||||||
|
|
||||||
|
;; bit(1) is most often used as a boolean too
|
||||||
(:source (:type "bit" :typemod (= 1 precision))
|
(:source (:type "bit" :typemod (= 1 precision))
|
||||||
:target (:type "boolean" :drop-typemod t)
|
:target (:type "boolean" :drop-typemod t)
|
||||||
:using pgloader.transforms::bits-to-boolean)
|
:using pgloader.transforms::bits-to-boolean)
|
||||||
|
|
||||||
|
;; bit(X) might be flags or another use case for bitstrings
|
||||||
|
(:source (:type "bit")
|
||||||
|
:target (:type "bit" :drop-typemod nil)
|
||||||
|
:using pgloader.transforms::bits-to-hex-bitstring)
|
||||||
|
|
||||||
;; bigint(20) unsigned (or not, actually) does not fit into PostgreSQL
|
;; bigint(20) unsigned (or not, actually) does not fit into PostgreSQL
|
||||||
;; bigint (-9223372036854775808 to +9223372036854775807):
|
;; bigint (-9223372036854775808 to +9223372036854775807):
|
||||||
(:source (:type "bigint" :typemod (< 19 precision))
|
(:source (:type "bigint" :typemod (< 19 precision))
|
||||||
|
@ -82,6 +82,7 @@
|
|||||||
time-with-no-separator
|
time-with-no-separator
|
||||||
tinyint-to-boolean
|
tinyint-to-boolean
|
||||||
bits-to-boolean
|
bits-to-boolean
|
||||||
|
bits-to-hex-bitstring
|
||||||
int-to-ip
|
int-to-ip
|
||||||
ip-range
|
ip-range
|
||||||
convert-mysql-point
|
convert-mysql-point
|
||||||
@ -180,6 +181,29 @@
|
|||||||
(fixnum (if (= 0 bit) "f" "t"))
|
(fixnum (if (= 0 bit) "f" "t"))
|
||||||
(character (if (= 0 (char-code bit)) "f" "t"))))))
|
(character (if (= 0 (char-code bit)) "f" "t"))))))
|
||||||
|
|
||||||
|
(defun bits-to-hex-bitstring (bit-vector-or-string)
|
||||||
|
"Transform bit(XX) from MySQL to bit(XX) in PostgreSQL."
|
||||||
|
(etypecase bit-vector-or-string
|
||||||
|
(null nil)
|
||||||
|
;; default value as string looks like "b'0'", skip b' and then closing '
|
||||||
|
(string (let ((default bit-vector-or-string)
|
||||||
|
(size (length bit-vector-or-string)))
|
||||||
|
(subseq default 2 (+ -1 size))))
|
||||||
|
(array (let* ((bytes bit-vector-or-string)
|
||||||
|
(size (length bit-vector-or-string))
|
||||||
|
(digits "0123456789abcdef")
|
||||||
|
(hexstr
|
||||||
|
(make-array (+ 1 (* size 2)) :element-type 'character)))
|
||||||
|
;; use Postgres hex bitstring support: x0ff
|
||||||
|
(setf (aref hexstr 0) #\X)
|
||||||
|
(loop :for pos :from 1 :by 2
|
||||||
|
:for byte :across bytes
|
||||||
|
:do (let ((high (ldb (byte 4 4) byte))
|
||||||
|
(low (ldb (byte 4 0) byte)))
|
||||||
|
(setf (aref hexstr pos) (aref digits high))
|
||||||
|
(setf (aref hexstr (+ pos 1)) (aref digits low))))
|
||||||
|
hexstr))))
|
||||||
|
|
||||||
(defun int-to-ip (int)
|
(defun int-to-ip (int)
|
||||||
"Transform an IP as integer into its dotted notation, optimised code from
|
"Transform an IP as integer into its dotted notation, optimised code from
|
||||||
stassats."
|
stassats."
|
||||||
|
21
test/mysql/my.sql
vendored
21
test/mysql/my.sql
vendored
@ -155,6 +155,27 @@ create table `CamelCase` (
|
|||||||
`validSizes` varchar(12)
|
`validSizes` varchar(12)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* https://github.com/dimitri/pgloader/issues/943
|
||||||
|
*/
|
||||||
|
CREATE TABLE `countdata_template`
|
||||||
|
(
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`data` int(11) DEFAULT NULL,
|
||||||
|
`date_time` datetime DEFAULT NULL,
|
||||||
|
`gmt_offset` smallint(6) NOT NULL DEFAULT '0' COMMENT 'Offset GMT en minute',
|
||||||
|
`measurement_id` int(11) NOT NULL,
|
||||||
|
`flags` bit(16) NOT NULL DEFAULT b'0' COMMENT 'mot binaire : b1000=validé, b10000000=supprimé',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `ak_countdata_idx` (`measurement_id`,`date_time`,`gmt_offset`)
|
||||||
|
)
|
||||||
|
ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='données de comptage';
|
||||||
|
|
||||||
|
INSERT INTO `countdata_template`(`date_time`, `measurement_id`, `flags`)
|
||||||
|
VALUES (now(), 1, b'1000'),
|
||||||
|
(now(), 2, b'10000000');
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE `fcm_batches` (
|
CREATE TABLE `fcm_batches` (
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
`raw_payload` mediumtext COLLATE utf8_unicode_ci,
|
`raw_payload` mediumtext COLLATE utf8_unicode_ci,
|
||||||
|
Loading…
Reference in New Issue
Block a user