Quantcast
Channel: Liquibase Forums
Viewing all articles
Browse latest Browse all 2993

Re : [LB1.9.3] Internal datatype conversion to target databases

$
0
0
Found this oldish thread after bumping into CORE-1033 / CORE-1285, which is to say I can't create TEXT and BLOB types on MySQL (or at least not without some clever use of modifySql).

A few thoughts:

It's problematic to have raw and abstract types specified in the same attribute, since, as here, you have a conflict when the names are the same. For systems that support user-defined types, you never really know what name conflicts might occur. And if you ever someday add a new abstract type, you risk breaking everyone who was using a raw type of the same name. Prefixing is just one way of cramming everything into a single "type" string, which starts to take on its own internal structure.

The whole point of having abstract types is to simplify portability. Actually, as it stands, DBMS-aware changelog parameters should be a sufficient mechanism for this purpose (or would be, if they could successfully specify raw types like TEXT). The added value of built-in abstract types, then, is just to concisely pre-package what most users will need.

When generating a changelog from a database, the foremost concern is to reproduce that schema faithfully. If I start with "MEDIUMINT UNSIGNED" in MySQL, the changelog should recreate a column of that exact same type. But there's no reason the generated changelog can't also support other database systems with reasonable equivalents. The obvious way to do this is to map each raw type with a changelog parameter, which would specify the original raw type for the original DBMS and some substitute type (say, BIGINT in this example) for others. If you get this far, it's nice to also somehow avoid the verbosity of listing the equivalents for each of fifteen different database systems.

A better idea, though, is to elevate type definitions to something explicit, distinguishing raw and abstract, like this:

<dataType name="TEXT" rawType="TEXT" dbms="mysql" />
<dataType name="MyWeirdNumber" rawType="MEDIUMINT UNSIGNED" dbms="mysql" />
<dataType name="MyWeirdNumber" type="BIGINT" dbms="!mysql" />
<dataType name="MyOtherNumber" type="MyWeirdNumber" />

<column name="a" type="MyWeirdNumber" />
<column name="b" rawType="BLOB" />


This accomplishes several things:
  • Backwards compatible. Existing changelogs that just use type will function the same. 
  • Users on a single DBMS who despise the whole abstract type system can just use rawType everywhere and be sure that TEXT will not turn into LONGTEXT. 
  • The user, or likewise the changelog generator, can define new abstract types (or redefine built-in ones). These may in turn leverage other abstract types, built-in or not.

Looking to the future, we may someday want to introduce a new built-in abstract type system, on an opt-in basis, and be able to opt out of the old one. So,

<dataTypes includeLegacy="false" />
    <include package="liquibase-standard" />
    <include package="liquibase-jdbc" />
</
dataTypes>

In this model, abstract types simply map a type name to a raw type in each DBMS. If more intelligence than that is really worthwhile, I would rather see parameters done in XML than develop a new string format. For example,

<dataType name="MyType" type="char" length="5000" padded="false" />


Viewing all articles
Browse latest Browse all 2993

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>