mirror of
https://github.com/dimitri/pgloader.git
synced 2025-08-08 15:27:00 +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)
|
- error reporting (done)
|
||||||
- add input line number to log file?
|
- add input line number to log file?
|
||||||
|
|
||||||
### transformation and casts
|
|
||||||
|
|
||||||
- add per-column support for cast rules in the system
|
|
||||||
|
|
||||||
### data output
|
### data output
|
||||||
|
|
||||||
- PostgreSQL COPY Text format output for any supported input
|
- 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
|
The cast clause allows to specify custom casting rules, either to
|
||||||
overload the default casting rules or to amend them with special cases.
|
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> ... ]
|
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:
|
The supported guards are:
|
||||||
|
|
||||||
|
@ -604,26 +604,39 @@
|
|||||||
(alexandria:alist-plist guards)))
|
(alexandria:alist-plist guards)))
|
||||||
|
|
||||||
;; at the moment we only know about extra auto_increment
|
;; at the moment we only know about extra auto_increment
|
||||||
(defrule cast-source-extra (and ignore-whitespace
|
(defrule cast-source-extra (and kw-with kw-extra kw-auto-increment)
|
||||||
kw-with kw-extra kw-auto-increment)
|
|
||||||
(:constant (list :auto-increment t)))
|
(:constant (list :auto-increment t)))
|
||||||
|
|
||||||
(defrule cast-source (and (or kw-column kw-type)
|
(defrule cast-source-type (and kw-type trimmed-name)
|
||||||
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-extra)
|
||||||
(? cast-source-guards)
|
(? cast-source-guards)
|
||||||
ignore-whitespace)
|
ignore-whitespace)
|
||||||
(:lambda (source)
|
(:lambda (source)
|
||||||
(destructuring-bind (kw name opts guards ws) source
|
(destructuring-bind (name-and-type opts guards ws) source
|
||||||
(declare (ignore ws))
|
(declare (ignore ws))
|
||||||
(destructuring-bind (&key (default nil d-s-p)
|
(destructuring-bind (&key (default nil d-s-p)
|
||||||
(typemod nil t-s-p)
|
(typemod nil t-s-p)
|
||||||
&allow-other-keys) guards
|
&allow-other-keys)
|
||||||
(destructuring-bind (&key auto-increment &allow-other-keys) opts
|
guards
|
||||||
`(,kw ,name
|
(destructuring-bind (&key (auto-increment nil ai-s-p)
|
||||||
|
&allow-other-keys)
|
||||||
|
opts
|
||||||
|
`(,@name-and-type
|
||||||
,@(when t-s-p (list :typemod typemod))
|
,@(when t-s-p (list :typemod typemod))
|
||||||
,@(when d-s-p (list :default default))
|
,@(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)
|
(defrule cast-type-name (and (alpha-char-p character)
|
||||||
(* (or (alpha-char-p character)
|
(* (or (alpha-char-p character)
|
||||||
|
@ -181,11 +181,15 @@
|
|||||||
using)
|
using)
|
||||||
rule
|
rule
|
||||||
(destructuring-bind
|
(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)
|
(&key ((:type rule-source-type) nil t-s-p)
|
||||||
|
((:column rule-source-column) nil c-s-p)
|
||||||
((:typemod typemod-expr) nil tm-s-p)
|
((:typemod typemod-expr) nil tm-s-p)
|
||||||
((:default rule-source-default) nil d-s-p)
|
((:default rule-source-default) nil d-s-p)
|
||||||
((:not-null rule-source-not-null) nil n-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
|
rule-source
|
||||||
(destructuring-bind (&key table-name
|
(destructuring-bind (&key table-name
|
||||||
column-name
|
column-name
|
||||||
@ -196,10 +200,13 @@
|
|||||||
not-null
|
not-null
|
||||||
auto-increment)
|
auto-increment)
|
||||||
source
|
source
|
||||||
(declare (ignore table-name column-name ctype))
|
(declare (ignore ctype))
|
||||||
(when
|
(when
|
||||||
(and
|
(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 tm-s-p) (typemod-expr-matches-p typemod-expr typemod))
|
||||||
(or (null d-s-p) (string= default rule-source-default))
|
(or (null d-s-p) (string= default rule-source-default))
|
||||||
(or (null n-s-p) (eq not-null rule-source-not-null))
|
(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,
|
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 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 char when (= precision 1) to char keep typemod,
|
||||||
type year to integer,
|
type year to integer,
|
||||||
type timestamp to timestamptz drop not null using zero-dates-to-null
|
type timestamp to timestamptz drop not null using zero-dates-to-null
|
||||||
|
Loading…
Reference in New Issue
Block a user