NAME
DBIO::MySQL::Diff::Column - Diff operations for MySQL/MariaDB columns
VERSION
version 0.900004
DESCRIPTION
Represents a column-level diff operation in MySQL/MariaDB. Unlike SQLite, MySQL has full ALTER TABLE support so all of ADD COLUMN, DROP COLUMN, and MODIFY COLUMN are emitted directly.
Brand-new tables get their columns inline via DBIO::MySQL::Diff::Table -- this module only sees columns of tables that exist in both source and target.
ATTRIBUTES
lossy_pairs
my %pairs = %DBIO::MySQL::Diff::Column::LOSSLESS_PAIRS;
The changes of data_type that MySQL and MariaDB carry out without loss, as the old->new keys "column_change_lossy" in DBIO::Diff::Compare reads: the integer types to a wider one (tinyint < smallint < mediumint < int < bigint), the text types and the blob types to a larger one, char to varchar, char and varchar to text, mediumtext and longtext (tinytext holds 255 bytes, fewer than a varchar(255)), binary to varbinary, varbinary to the blobs from blob up, and date to datetime. Every other pair of types is lossy, in doubt it is: float to double alters the decimal reading of a value, datetime to timestamp narrows the range, a number to a string rewrites it.
METHODS
diff
my @ops = DBIO::MySQL::Diff::Column->diff(
$source_cols, $target_cols,
$source_tables, $target_tables,
);
Compares column lists for tables that exist in both source and target. Detects added columns, dropped columns, and modified columns (data type, NOT NULL, default value or ON UPDATE changes). Returns a list of DBIO::MySQL::Diff::Column objects. ON UPDATE (on_update in the model) is compared when the target carries the key, as the introspection does for every column, and MODIFY COLUMN, ADD COLUMN and the CREATE TABLE of DBIO::MySQL::Diff::Table write it; a column whose target has none loses it, and a target from target_from_compiled, which has no such key, leaves it alone. A column that gains or loses AUTO_INCREMENT is modified too, and a MODIFY COLUMN of a column that is AUTO_INCREMENT in the target keeps the attribute. A column that is AUTO_INCREMENT without being the primary key has to have a key; the statement that takes the attribute from it stands before the DROP INDEX of that key, see DBIO::MySQL::Diff. The columns a table gains are added in the order the target declares them, not in the order of their names.
The MySQL column shape carries extras beyond the canonical model (column_type, character_set, collation, numeric_precision, numeric_scale, datetime_precision, values, comment) so we use "changed_fields" in DBIO::Diff::Compare with a MySQL-specific field spec instead of the canonical changed_column_fields.
A column with a character set or collation of its own, off the default of its table, has them written by MODIFY COLUMN and ADD COLUMN ("collation_sql"); one on the default is written without.
lossy
True for a modify that can alter or lose stored values, so that "apply" in DBIO::Deploy::Base runs it only with allow_destructive. The answer is "column_change_lossy" in DBIO::Diff::Compare over the types and sizes of the two columns, with the pairs of "lossy_pairs", and four things the generic comparison does not see:
unsignedgained or lost -- negative values go, or large ones do not fit;another
character_set-- text of one may not be representable in the other;an
enumorsetwhose values are not the old ones with more behind them;a type without a size of its own (
float,double,json, ...) whosecolumn_typeis another string.
A change of NOT NULL, the default, the comment, ON UPDATE, the collation within one character set and AUTO_INCREMENT keeps every value and is not lossy (NOT NULL over a NULL is refused by "_refuse_unfillable" in DBIO::MySQL::Deploy). The integer display width (int(11)) is no size. Other actions are not lossy.
collation_sql
my $sql = DBIO::MySQL::Diff::Column::collation_sql($column_info, $table_collation);
The CHARACTER SET and COLLATE of a column, with a leading blank, where they differ from the default of its table, and the empty string where they do not. A column on the default is written without, as the server gives it the default of the table; one off it needs them in every MODIFY COLUMN, ADD COLUMN and CREATE TABLE, or the statement resets it and the next diff finds it again. Compared as the introspection reports them: case aside, the character set of the table taken from the prefix of its collation. A table whose default is not known (a target from target_from_compiled) gets what the column says; a column that says nothing gets nothing.
as_sql
The ALTER TABLE statement. The names of the table and the column are quoted with "quote_ident" in DBIO::MySQL::Identifier.
add_clause
my $clause = $op->add_clause; # ADD COLUMN `c` int(11) NOT NULL
my $clause = $op->add_clause(1); # ... NOT NULL AUTO_INCREMENT
The ADD COLUMN clause of an add operation, without the ALTER TABLE. AUTO_INCREMENT is written only when asked for: the server refuses it on a column that is no key, so DBIO::MySQL::Diff::PrimaryKey takes the clause of a column that is its key into the statement that adds the key.
summary
AUTHOR
DBIO & DBIx::Class Authors
COPYRIGHT AND LICENSE
Copyright (C) 2026 DBIO Authors Portions Copyright (C) 2005-2025 DBIx::Class Authors Based on DBIx::Class, heavily modified.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.