mirror of
https://github.com/dimitri/pgloader.git
synced 2025-08-08 07:16:58 +02:00
Implement per-column MySQL CAST rules.
This commit is contained in:
parent
8ce0288b63
commit
b31ccded6f
@ -136,10 +136,6 @@ Some notes about what I intend to be working on next.
|
||||
- error reporting (done)
|
||||
- add input line number to log file?
|
||||
|
||||
### transformation and casts
|
||||
|
||||
- add per-column support for cast rules in the system
|
||||
|
||||
### data output
|
||||
|
||||
- PostgreSQL COPY Text format output for any supported input
|
||||
|
@ -860,9 +860,16 @@ The `database` command accepts the following clauses and options:
|
||||
The cast clause allows to specify custom casting rules, either to
|
||||
overload the default casting rules or to amend them with special cases.
|
||||
|
||||
A casting rule is expected to follow the form:
|
||||
A casting rule is expected to follow one of the forms:
|
||||
|
||||
type <mysql-type-name> [ <guard> ... ] to <pgsql-type-name> [ <option> ... ]
|
||||
column <table-name>.<column-name> [ <guards> ] to ...
|
||||
|
||||
It's possible for a *casting rule* to either match against a MySQL data
|
||||
type or against a given *column name* in a given *table name*. That
|
||||
flexibility allows to cope with cases where the type `tinyint` might
|
||||
have been used as a `boolean` in some cases but as a `smallint` in
|
||||
others.
|
||||
|
||||
The supported guards are:
|
||||
|
||||
|
@ -604,26 +604,39 @@
|
||||
(alexandria:alist-plist guards)))
|
||||
|
||||
;; at the moment we only know about extra auto_increment
|
||||
(defrule cast-source-extra (and ignore-whitespace
|
||||
kw-with kw-extra kw-auto-increment)
|
||||
(defrule cast-source-extra (and kw-with kw-extra kw-auto-increment)
|
||||
(:constant (list :auto-increment t)))
|
||||
|
||||
(defrule cast-source (and (or kw-column kw-type)
|
||||
trimmed-name
|
||||
(defrule cast-source-type (and kw-type trimmed-name)
|
||||
(:destructure (kw name) (declare (ignore kw)) (list :type name)))
|
||||
|
||||
(defrule table-column-name (and namestring "." namestring)
|
||||
(:destructure (table-name dot column-name)
|
||||
(declare (ignore dot))
|
||||
(list :column (cons (text table-name) (text column-name)))))
|
||||
|
||||
(defrule cast-source-column (and kw-column table-column-name)
|
||||
;; well, we want namestring . namestring
|
||||
(:destructure (kw name) (declare (ignore kw)) name))
|
||||
|
||||
(defrule cast-source (and (or cast-source-type cast-source-column)
|
||||
(? cast-source-extra)
|
||||
(? cast-source-guards)
|
||||
ignore-whitespace)
|
||||
(:lambda (source)
|
||||
(destructuring-bind (kw name opts guards ws) source
|
||||
(destructuring-bind (name-and-type opts guards ws) source
|
||||
(declare (ignore ws))
|
||||
(destructuring-bind (&key (default nil d-s-p)
|
||||
(typemod nil t-s-p)
|
||||
&allow-other-keys) guards
|
||||
(destructuring-bind (&key auto-increment &allow-other-keys) opts
|
||||
`(,kw ,name
|
||||
&allow-other-keys)
|
||||
guards
|
||||
(destructuring-bind (&key (auto-increment nil ai-s-p)
|
||||
&allow-other-keys)
|
||||
opts
|
||||
`(,@name-and-type
|
||||
,@(when t-s-p (list :typemod typemod))
|
||||
,@(when d-s-p (list :default default))
|
||||
:auto-increment ,auto-increment))))))
|
||||
,@(when ai-s-p (list :auto-increment auto-increment))))))))
|
||||
|
||||
(defrule cast-type-name (and (alpha-char-p character)
|
||||
(* (or (alpha-char-p character)
|
||||
|
@ -181,11 +181,15 @@
|
||||
using)
|
||||
rule
|
||||
(destructuring-bind
|
||||
;; it's either :type or :column, just cope with both thanks to
|
||||
;; &allow-other-keys
|
||||
(&key ((:type rule-source-type) nil t-s-p)
|
||||
((:column rule-source-column) nil c-s-p)
|
||||
((:typemod typemod-expr) nil tm-s-p)
|
||||
((:default rule-source-default) nil d-s-p)
|
||||
((:not-null rule-source-not-null) nil n-s-p)
|
||||
((:auto-increment rule-source-auto-increment) nil ai-s-p))
|
||||
((:auto-increment rule-source-auto-increment) nil ai-s-p)
|
||||
&allow-other-keys)
|
||||
rule-source
|
||||
(destructuring-bind (&key table-name
|
||||
column-name
|
||||
@ -196,10 +200,13 @@
|
||||
not-null
|
||||
auto-increment)
|
||||
source
|
||||
(declare (ignore table-name column-name ctype))
|
||||
(declare (ignore ctype))
|
||||
(when
|
||||
(and
|
||||
(string= type rule-source-type)
|
||||
(or (and t-s-p (string= type rule-source-type))
|
||||
(and c-s-p
|
||||
(string-equal table-name (car rule-source-column))
|
||||
(string-equal column-name (cdr rule-source-column))))
|
||||
(or (null tm-s-p) (typemod-expr-matches-p typemod-expr typemod))
|
||||
(or (null d-s-p) (string= default rule-source-default))
|
||||
(or (null n-s-p) (eq not-null rule-source-not-null))
|
||||
|
@ -6,7 +6,7 @@ LOAD DATABASE
|
||||
|
||||
CAST type datetime to timestamptz drop default drop not null using zero-dates-to-null,
|
||||
type date drop not null drop default using zero-dates-to-null,
|
||||
type tinyint to boolean drop typemod using tinyint-to-boolean,
|
||||
column bools.a to boolean drop typemod using tinyint-to-boolean,
|
||||
type char when (= precision 1) to char keep typemod,
|
||||
type year to integer,
|
||||
type timestamp to timestamptz drop not null using zero-dates-to-null
|
||||
|
Loading…
Reference in New Issue
Block a user