Documentation
¶
Overview ¶
Package statement is a wrapper around the parser with some added functionality.
Index ¶
- Variables
- func ByName[T HasName](slice []T, name string) *T
- func DefaultCollationForCharset(name string) (cs, collation string, ok bool)
- func DiffCreateTables(table, wantCreate, gotCreate string, opts *DiffOptions) (string, error)
- func GetMissingSecondaryIndexes(sourceCreateTable, targetCreateTable, tableName string) (string, error)
- func ModifyColumnIsMetadataOnly(spec *ast.AlterTableSpec) bool
- func NormalizeCharsetName(cs string) string
- func RemoveSecondaryIndexes(createStmt string) (string, error)
- func RemoveSecondaryIndexesForComparison(createStmt string) (string, error)
- func SpecOnlyChangesComment(spec *ast.AlterTableSpec) bool
- type AbstractStatement
- func DeclarativeToImperative(current, desired []table.TableSchema, opts *DiffOptions) ([]*AbstractStatement, error)
- func MustNew(statement string) []*AbstractStatement
- func New(statement string) ([]*AbstractStatement, error)
- func NewWithOptions(statement string, opts Options) ([]*AbstractStatement, error)
- func (a *AbstractStatement) AlgorithmInplaceConsideredSafe() error
- func (a *AbstractStatement) AlterContainsAddUnique() error
- func (a *AbstractStatement) AlterContainsUnsupportedClause() error
- func (a *AbstractStatement) AlterWithRenamedConstraints(checkRenames, foreignKeyRenames map[string]string) (string, []string, error)
- func (a *AbstractStatement) AsAlterTable() (*ast.AlterTableStmt, bool)
- func (a *AbstractStatement) CheckConstraintsReferenced() []string
- func (a *AbstractStatement) ColumnCollationChange(column string, current, tableDefault CharsetCollation) (change ColumnCollationChange, determined bool, err error)
- func (a *AbstractStatement) ColumnRenameMap() map[string]string
- func (a *AbstractStatement) ForeignKeysDropped() []string
- func (a *AbstractStatement) GenericConstraintDrops() []string
- func (a *AbstractStatement) IsAlterTable() bool
- func (a *AbstractStatement) IsCreateTable() bool
- func (a *AbstractStatement) IsDropTable() bool
- func (a *AbstractStatement) IsRenameTable() bool
- func (a *AbstractStatement) ParseCreateTable() (*CreateTable, error)
- func (a *AbstractStatement) SetsAutoIncrement() bool
- func (a *AbstractStatement) StoredEnumSetMembers(colDef *ast.ColumnDef, tableDefault CharsetCollation) (members []string, determined bool, err error)
- func (a *AbstractStatement) TrimAlter() string
- type CharsetCollation
- type Classification
- type Column
- type ColumnCheck
- type ColumnCollationChange
- type Columns
- type Constraint
- type Constraints
- type CreateTable
- func (ct *CreateTable) Diff(target *CreateTable, opts *DiffOptions) ([]*AbstractStatement, error)
- func (ct *CreateTable) GetColumns() Columns
- func (ct *CreateTable) GetConstraints() Constraints
- func (ct *CreateTable) GetCreateTable() *CreateTable
- func (ct *CreateTable) GetIndexes() Indexes
- func (ct *CreateTable) GetPartition() *PartitionOptions
- func (ct *CreateTable) GetTableName() string
- func (ct *CreateTable) GetTableOptions() map[string]any
- func (ct *CreateTable) TableDefault() CharsetCollation
- func (ct *CreateTable) ToTableInfo(schemaName string) (*table.TableInfo, error)
- func (ct *CreateTable) ToTableSchema() (table.TableSchema, error)
- type DefaultKind
- type DefaultLiteral
- type DiffOptions
- type ForeignKeyReference
- type HasName
- type Index
- type IndexColumn
- type Indexes
- type Normalizer
- type Options
- type PartitionDefinition
- type PartitionOptions
- type PartitionStorage
- type PartitionValues
- type StatementType
- type SubPartitionDefinition
- type SubPartitionOptions
- type TableOptions
Constants ¶
This section is empty.
Variables ¶
var ( ErrNotSupportedStatement = errors.New("not a supported statement type") ErrNotAlterTable = errors.New("not an ALTER TABLE statement") ErrMultipleSchemas = errors.New("statement attempts to modify tables across multiple schemas") ErrNoStatements = errors.New("could not find any compatible statements to execute") ErrMixMatchMultiStatements = errors.New("when performing atomic schema changes, all statements must be of type ALTER TABLE") ErrUnsafeForInplace = errors.New("statement contains operations that are not safe for INPLACE algorithm") ErrAlterNoSpecs = errors.New("ALTER TABLE does not specify any changes to make") ErrMultipleAlterClauses = errors.New("ALTER contains multiple clauses. Combinations of INSTANT and INPLACE operations cannot be detected safely. Consider executing these as separate ALTER statements") ErrAlterContainsUnique = errors.New("ALTER contains adding a unique index") )
Functions ¶
func ByName ¶
ByName is a generic function that finds an element by name in any slice of types with Name field NOTE: This function assumes that names are unique within the slice! That will be true for "canonical" CREATE TABLE statements as returned by SHOW CREATE TABLE, but may not be true for arbitrary input.
func DefaultCollationForCharset ¶ added in v0.17.0
DefaultCollationForCharset returns the charset and the collation MySQL applies to it when no COLLATE is written, and whether cs names a charset the parser knows. Both are spelled the way EffectiveCharsetCollation spells them, so values from the two can be compared directly — callers that need to supply a default for DDL which declares no charset at all should come through here rather than reading the parser's registry themselves.
func DiffCreateTables ¶ added in v0.17.0
func DiffCreateTables(table, wantCreate, gotCreate string, opts *DiffOptions) (string, error)
DiffCreateTables compares two CREATE TABLE statements and returns a runnable ALTER TABLE statement describing how they differ, or an empty string if they are equivalent under opts.
The comparison is performed by parsing both statements and diffing the structured form via CreateTable.Diff, so it is insensitive to the textual noise two servers can put in SHOW CREATE TABLE output. What is and isn't compared is controlled by opts; with NewDiffOptions the comparison:
- ignores AUTO_INCREMENT counter values (instance-specific noise),
- ignores ENGINE and ROW_FORMAT cosmetic defaults,
- DOES compare column types, nullability, defaults, and per-column / per-table CHARACTER SET and COLLATE,
- DOES compare indexes (including the primary key) and constraints.
"want" is the schema treated as the source of truth; "got" is the schema being validated against it. The returned statement describes the transformation that would turn "got" into "want", which is what makes the message actionable. "table" is the real (logical) table name used to build the runnable "ALTER TABLE <table>" prefix, escaped so identifiers containing backticks remain valid — the two CREATE TABLE statements themselves may name tables on different instances, so their names are normalized away before the diff and never compared.
CreateTable.Diff deliberately splits some reconciliations across more than one ALTER — a partition-type change, or an option-only index change that MySQL would no-op if its DROP and ADD shared a statement. Those are emitted as separate semicolon-separated ALTERs, in order, rather than merged into one (which would produce SQL that silently does the wrong thing).
If opts is nil, NewDiffOptions() defaults are used.
func GetMissingSecondaryIndexes ¶ added in v0.10.1
func GetMissingSecondaryIndexes(sourceCreateTable, targetCreateTable, tableName string) (string, error)
GetMissingSecondaryIndexes compares two CREATE TABLE statements (source and target) and returns an ALTER TABLE statement that adds any missing secondary indexes. Returns an empty string if no indexes need to be added. Considers UNIQUE, FULLTEXT, SPATIAL, and regular INDEX types. PRIMARY KEY is excluded as it's fundamental to table structure.
func ModifyColumnIsMetadataOnly ¶ added in v0.16.0
func ModifyColumnIsMetadataOnly(spec *ast.AlterTableSpec) bool
ModifyColumnIsMetadataOnly returns true if a MODIFY/CHANGE COLUMN spec only changes metadata: a VARCHAR redeclaration that neither reorders the column nor declares NOT NULL. Both of those are accepted by MySQL under ALGORITHM=INPLACE but performed with a full table rebuild.
This is a statement-level judgement: without the current column definition we can't tell a VARCHAR length change from an INT-to-VARCHAR conversion, so a true result means "not provably a rebuild" rather than "provably not".
func NormalizeCharsetName ¶ added in v0.18.0
NormalizeCharsetName returns a charset name in the spelling EffectiveCharsetCollation uses: lower case, with the legacy "utf8" spelling of the 3-byte UTF-8 charset folded onto MySQL 8.0's "utf8mb3". The parser keeps the legacy spelling, so a column or table written CHARACTER SET utf8mb3 (or declared NCHAR/NVARCHAR) reports "utf8"; compare names through this function so the two spellings match.
func RemoveSecondaryIndexes ¶ added in v0.10.1
RemoveSecondaryIndexes takes a CREATE TABLE statement and returns a modified version without secondary indexes (regular INDEX only). PRIMARY KEY, UNIQUE, and FULLTEXT indexes are preserved, as is an index needed to support AUTO_INCREMENT.
func RemoveSecondaryIndexesForComparison ¶ added in v0.18.0
RemoveSecondaryIndexesForComparison removes every regular index, including AUTO_INCREMENT support. Its output is for schema comparison, not execution.
func SpecOnlyChangesComment ¶ added in v0.16.0
func SpecOnlyChangesComment(spec *ast.AlterTableSpec) bool
SpecOnlyChangesComment returns true if every table option in an AlterTableOption spec is a COMMENT change. A table comment change is in-place and metadata-only, but other table options (ENGINE=, ROW_FORMAT=, AUTO_INCREMENT=, ...) can force a table rebuild, so a spec that mixes any of them in is not safe for INPLACE.
Types ¶
type AbstractStatement ¶
type AbstractStatement struct {
Schema string // this will be empty unless the table name is fully qualified (ALTER TABLE test.t1 ...)
Table string // for statements that affect multiple tables (DROP TABLE t1, t2), only the first is set here!
Alter string // may be empty.
Statement string
StmtNode *ast.StmtNode
}
func DeclarativeToImperative ¶ added in v0.11.3
func DeclarativeToImperative(current, desired []table.TableSchema, opts *DiffOptions) ([]*AbstractStatement, error)
DeclarativeToImperative compares current and desired schemas and returns the imperative DDL statements (ALTER, CREATE, DROP) needed to transform current into desired.
This is the core of declarative schema management: given two sets of table definitions, compute the minimal set of changes. It is used by spirit's diff subcommand, strata, and GAP.
The returned statements are ordered as CREATE → ALTER → DROP. This ordering is a correctness property: it ensures the output is safe to execute sequentially (e.g. an ALTER that adds a foreign key referencing a newly-created table will run after the CREATE, and a table referenced by a FK won't be dropped before the referencing ALTER runs). Within the CREATE and DROP groups, tables follow their foreign keys: a table is created after the tables its foreign keys reference (MySQL error 1824 otherwise) and dropped before the tables that reference it (error 3730). Tables with no such dependency between them are sorted alphabetically, and ALTERs always are. A reference is matched by table name alone; a reference to a table outside the group, or a table's reference to itself, imposes no order. Two orders the output cannot satisfy are left to MySQL: a cycle of references among new tables (MySQL creates neither table without FOREIGN_KEY_CHECKS=0) and an ALTER that depends on another table's ALTER.
Tables are matched by name the way the target server compares them (see DiffOptions.LowerCaseTableNames). A schema that names the same table twice is refused rather than planned from one of its definitions: the caller's intent is ambiguous, and the definition left out would never be applied.
If opts is nil, NewDiffOptions() defaults are used for table diffs.
func MustNew ¶
func MustNew(statement string) []*AbstractStatement
MustNew is like New but panics if the statement cannot be parsed. It is used by tests.
func New ¶
func New(statement string) ([]*AbstractStatement, error)
func NewWithOptions ¶ added in v0.12.0
func NewWithOptions(statement string, opts Options) ([]*AbstractStatement, error)
func (*AbstractStatement) AlgorithmInplaceConsideredSafe ¶
func (a *AbstractStatement) AlgorithmInplaceConsideredSafe() error
AlgorithmInplaceConsideredSafe checks to see if all clauses of an ALTER statement are "safe". We consider an operation to be "safe" if it is "In Place" and "Only Modifies Metadata". See https://dev.mysql.com/doc/refman/8.0/en/innodb-online-ddl-operations.html for details. INPLACE DDL is not generally safe for online use in MySQL 8.0, because ADD INDEX can block replicas.
func (*AbstractStatement) AlterContainsAddUnique ¶
func (a *AbstractStatement) AlterContainsAddUnique() error
AlterContainsAddUnique checks to see if any clauses of an ALTER contains add UNIQUE index. We use this to customize the error returned from checksum fails.
func (*AbstractStatement) AlterContainsUnsupportedClause ¶
func (a *AbstractStatement) AlterContainsUnsupportedClause() error
AlterContainsUnsupportedClause checks to see if any clauses of an ALTER statement are unsupported by Spirit. These include clauses like ALGORITHM and LOCK, because they step on the toes of Spirit's own locking and algorithm selection.
func (*AbstractStatement) AlterWithRenamedConstraints ¶ added in v0.19.0
func (a *AbstractStatement) AlterWithRenamedConstraints(checkRenames, foreignKeyRenames map[string]string) (string, []string, error)
AlterWithRenamedConstraints returns this ALTER's clauses with its check constraint and foreign key symbols rewritten for a table other than the one the user named: the copy algorithm's _new table, which holds the same constraints under different names because check constraint and foreign key names are unique per schema rather than per table.
checkRenames maps a lower-cased check constraint name on the user's table to the name the same constraint has on the table the ALTER will be applied to. Names in DROP CHECK / DROP CONSTRAINT and ALTER CHECK clauses are translated through it. foreignKeyRenames does the same for the names in DROP FOREIGN KEY clauses. A name that is not in its map is left alone, so MySQL still reports it as missing rather than spirit guessing at what was meant.
A named check constraint being added by this same ALTER under a name it also drops (the "widen this constraint" idiom: DROP CHECK c, ADD CONSTRAINT c CHECK (...)) has its symbol removed, because the user's table still owns that name for as long as it exists, and adding it to a second table in the schema is an error. MySQL generates a name instead - the same outcome the copy algorithm already produces for every check constraint it copies, and the resolution recommended in issue #418. Those names are returned so the caller can report them.
func (*AbstractStatement) AsAlterTable ¶
func (a *AbstractStatement) AsAlterTable() (*ast.AlterTableStmt, bool)
AsAlterTable is a helper function that simply wraps the type case so the caller doesn't have to import the ast package and use the cast syntax
func (*AbstractStatement) CheckConstraintsReferenced ¶ added in v0.17.0
func (a *AbstractStatement) CheckConstraintsReferenced() []string
CheckConstraintsReferenced returns the check constraint names this ALTER refers to by name, i.e. the names in its DROP CHECK / DROP CONSTRAINT and ALTER CHECK clauses. It returns nil for a statement that is not an ALTER TABLE, or one that names no check constraints.
Note that MySQL's DROP CONSTRAINT is not specific to check constraints - it also drops a foreign key or a unique constraint of that name - so a name it contributes here is only a candidate. Callers match it against the check constraints that the table actually has.
func (*AbstractStatement) ColumnCollationChange ¶ added in v0.18.0
func (a *AbstractStatement) ColumnCollationChange(column string, current, tableDefault CharsetCollation) (change ColumnCollationChange, determined bool, err error)
ColumnCollationChange resolves the collation column compares under once the ALTER TABLE applies, following MySQL's rules:
- CONVERT TO CHARACTER SET re-collates every column that carries a charset once the statement applies, overriding a collation the same statement declares on the column.
- A MODIFY or CHANGE COLUMN resolves the redeclared definition the way a CREATE TABLE would, against the table's defaults as the statement leaves them. A redeclaration that omits COLLATE therefore drops a collation the column declared explicitly, and one that omits both CHARACTER SET and COLLATE picks up a default the same statement changes.
- Any other column keeps the collation it has.
current is what the column compares under now: the zero value for a column that carries no charset, and a charset without a collation when only the charset is known. A column whose charset is not known either cannot be described here, and a caller must not classify it. tableDefault is the table's current default, the zero value when it is not known.
determined is false when whether the collation changes depends on a default the inputs do not carry: CONVERT TO CHARACTER SET DEFAULT uses the schema's default, a redeclaration that inherits the table default needs tableDefault, and naming utf8mb4 without a collation takes the server's default for it — which decides nothing unless the column is under another charset now.
func (*AbstractStatement) ColumnRenameMap ¶ added in v0.13.0
func (a *AbstractStatement) ColumnRenameMap() map[string]string
ColumnRenameMap returns a mapping of old column name → new column name for any RENAME COLUMN or CHANGE COLUMN (with a different name) specs in this ALTER TABLE statement. Returns nil if there are no renames or if this is not an ALTER TABLE statement. MySQL column identifiers are case-insensitive, so a case-only change (e.g. foo → FOO) is not considered a rename: the data mapping is unaffected and case-insensitive identity matching handles it. The map keys and values keep the case as typed in the ALTER; consumers must match them against declared column names case-insensitively.
func (*AbstractStatement) ForeignKeysDropped ¶ added in v0.19.0
func (a *AbstractStatement) ForeignKeysDropped() []string
ForeignKeysDropped returns the names in this ALTER's DROP FOREIGN KEY clauses.
func (*AbstractStatement) GenericConstraintDrops ¶ added in v0.17.0
func (a *AbstractStatement) GenericConstraintDrops() []string
GenericConstraintDrops returns the names in this ALTER's DROP CONSTRAINT clauses - the subset of CheckConstraintsReferenced that does not say which kind of constraint it means. DROP CHECK and ALTER CHECK do say, so they are not returned.
MySQL resolves such a name against the table's CHECK, FOREIGN KEY, UNIQUE and PRIMARY KEY constraints, which are separate namespaces, and refuses the ALTER when more than one of them holds it: "Table has multiple constraints with the name 'x'. Please use constraint specific 'DROP' clause" (error 3939). A caller that resolves the name itself has to reproduce that rather than pick one.
func (*AbstractStatement) IsAlterTable ¶
func (a *AbstractStatement) IsAlterTable() bool
func (*AbstractStatement) IsCreateTable ¶
func (a *AbstractStatement) IsCreateTable() bool
func (*AbstractStatement) IsDropTable ¶ added in v0.11.1
func (a *AbstractStatement) IsDropTable() bool
func (*AbstractStatement) IsRenameTable ¶ added in v0.11.1
func (a *AbstractStatement) IsRenameTable() bool
func (*AbstractStatement) ParseCreateTable ¶
func (a *AbstractStatement) ParseCreateTable() (*CreateTable, error)
func (*AbstractStatement) SetsAutoIncrement ¶ added in v0.18.0
func (a *AbstractStatement) SetsAutoIncrement() bool
SetsAutoIncrement reports whether this ALTER TABLE sets the table's AUTO_INCREMENT counter explicitly (a table option such as AUTO_INCREMENT=N). It returns false for any statement that is not an ALTER TABLE.
func (*AbstractStatement) StoredEnumSetMembers ¶ added in v0.18.0
func (a *AbstractStatement) StoredEnumSetMembers(colDef *ast.ColumnDef, tableDefault CharsetCollation) (members []string, determined bool, err error)
StoredEnumSetMembers returns the members MySQL stores for an ENUM or SET column definition in this ALTER TABLE: as written when the column's charset resolves to binary, and with the trailing spaces of each stripped otherwise (see enumSetMemberSpacesNormalizer). The charset resolves the way ColumnCollationChange resolves it, with one difference MySQL makes: CONVERT TO CHARACTER SET does not convert a column that declares the binary charset, so its members keep their spaces.
tableDefault is the table's current default, the zero value when it is not known. determined is false when a member ends in a space and the column's charset is not decided: it inherits a table default that neither tableDefault nor the statement carries, or the statement converts the table with CONVERT TO CHARACTER SET DEFAULT, which takes the schema's default.
func (*AbstractStatement) TrimAlter ¶
func (a *AbstractStatement) TrimAlter() string
type CharsetCollation ¶ added in v0.18.0
type CharsetCollation struct {
Charset, Collation string
}
CharsetCollation is a charset and a collation of it. Collation is empty when only the charset is known: a definition that names utf8mb4 without a collation leaves it to the server's default_collation_for_utf8mb4.
type Classification ¶ added in v0.11.1
type Classification struct {
Type StatementType
Table string // First table referenced (empty for unparseable statements)
Schema string // Schema if fully qualified (e.g. "test" from "test.t1")
}
Classification holds the result of classifying a single SQL statement.
func Classify ¶ added in v0.11.1
func Classify(sql string) ([]Classification, error)
Classify parses one or more SQL statements and returns their classifications. Unlike New(), this accepts any statement type including DML and TRUNCATE.
type Column ¶
type Column struct {
Raw *ast.ColumnDef `json:"-"`
Name string `json:"name"`
Type string `json:"type"`
Length *int `json:"length,omitempty"` // nil = no width; 0 is a real width (varchar(0))
Precision *int `json:"precision,omitempty"`
Scale *int `json:"scale,omitempty"`
Unsigned *bool `json:"unsigned,omitempty"`
Zerofill *bool `json:"zerofill,omitempty"` // ZEROFILL display attribute (implies unsigned)
EnumValues []string `json:"enum_values,omitempty"` // Permitted values for ENUM type
SetValues []string `json:"set_values,omitempty"` // Permitted values for SET type
Nullable bool `json:"nullable"`
Default *string `json:"default,omitempty"`
DefaultIsExpr bool `json:"default_is_expr,omitempty"` // true when default is an expression (needs parens), e.g. DEFAULT (json_object())
DefaultKind DefaultKind `json:"default_kind,omitempty"` // the literal form the default was written as, read off the AST — see DefaultKind
OnUpdate *string `json:"on_update,omitempty"` // ON UPDATE expression for TIMESTAMP/DATETIME, e.g. "current_timestamp"
GeneratedExpr *string `json:"generated_expr,omitempty"` // Expression for GENERATED ALWAYS AS (...) columns
GeneratedStored bool `json:"generated_stored,omitempty"` // true = STORED, false = VIRTUAL (only meaningful when GeneratedExpr is set)
// DefaultAsWritten is the literal DEFAULT as the schema spelled it, kept
// for emission. Default holds the value MySQL stores for that literal, as
// the normalization rules read it (the text SHOW CREATE TABLE reports
// where that text is exact), and Diff compares it. The two can name
// different values: MySQL reports a float with six significant digits, so
// the live `float DEFAULT 1234567` reads back as '1234570', and a MODIFY
// that emitted that text would store 1234570. The written literal is the
// one MySQL reads itself, so emitting it stores exactly what a CREATE
// TABLE with it would have.
// Nil for an expression default, which is emitted from Default, and when a
// rule rewrites the emitted form on purpose (charUTF8MB4DefaultNormalizer).
// Not compared: see columnFieldsNotCompared.
DefaultAsWritten *DefaultLiteral `json:"default_as_written,omitempty"`
Checks []ColumnCheck `json:"checks,omitempty"` // Column-level CHECK constraints, in declaration order; hoisted into Constraints by columnCheckNormalizer
SRID *uint32 `json:"srid,omitempty"` // SRID attribute for spatial columns
Invisible bool `json:"invisible,omitempty"` // INVISIBLE (MySQL 8.0.23+); VISIBLE is the default and is not recorded
NotSecondary bool `json:"not_secondary,omitempty"` // NOT SECONDARY: excluded from the secondary engine
ColumnFormat *string `json:"column_format,omitempty"` // COLUMN_FORMAT FIXED|DYNAMIC; DEFAULT is not recorded
Storage *string `json:"storage,omitempty"` // STORAGE DISK|MEMORY; DEFAULT is not recorded
// SecondaryEngineAttribute is the SECONDARY_ENGINE_ATTRIBUTE JSON text as
// written. MySQL reports it re-serialized, so it is compared as JSON
// (engineAttributeEqual) and emitted as written.
SecondaryEngineAttribute *string `json:"secondary_engine_attribute,omitempty"`
AutoInc bool `json:"auto_increment"`
PrimaryKey bool `json:"primary_key"`
Unique bool `json:"unique"`
Comment *string `json:"comment,omitempty"`
Charset *string `json:"charset,omitempty"`
Collation *string `json:"collation,omitempty"`
Options map[string]string `json:"options,omitempty"`
}
Column represents a table column definition
func (*Column) CarriesCharset ¶ added in v0.17.0
CarriesCharset reports whether the column's type stores text, and therefore has a charset and collation that participate in comparisons. Numeric, date, binary, JSON and spatial types are excluded: they carry at most a synthetic "binary" charset that is identical for any two columns of the same type.
func (*Column) EffectiveCharsetCollation ¶ added in v0.17.0
func (c *Column) EffectiveCharsetCollation(table *CreateTable) (cs, collation string)
EffectiveCharsetCollation returns the charset and collation the column actually compares under, given the table that owns it. It resolves the column's own clauses against the table defaults exactly as MySQL does (see resolvedCharsetCollation), and then fills in the charset's *default* collation when no COLLATE was written anywhere. That last step matters because SHOW CREATE TABLE can omit COLLATE when it is the charset default, so a table spelled `DEFAULT CHARSET=latin1` means latin1_swedish_ci and must compare unequal to one that spells `COLLATE=latin1_bin`.
For utf8mb4 that default is an assumption. A server resolves utf8mb4 named without a collation to its default_collation_for_utf8mb4, which can be utf8mb4_general_ci, while this always answers utf8mb4_0900_ai_ci, MySQL 8.0's default. A caller that refuses a statement on the strength of the answer must not rely on that guess, and uses determinedCharsetCollation instead.
Either return value is "" when the statement does not determine it: a table with no DEFAULT CHARSET at all (only reachable from hand-written DDL, since SHOW CREATE TABLE always emits one) inherits the schema/server default, and a charset this parser does not know has no default collation to look up. Callers must treat "" as "unknown" rather than as a value that can differ.
Names are returned in MySQL 8.0's spelling: the legacy utf8/utf8_* forms are folded onto utf8mb3/utf8mb3_*, so the two spellings of the same charset compare equal.
The diff does not use this: it deliberately treats an unwritten collation as a match (see charsetCollationEqual) so it never emits a MODIFY it cannot prove converged. Only utf8mb4 reaches it that way: every other charset's default collation is fixed, and defaultCollationNormalizer writes it in at parse time. A linter has the opposite bias — it reports a difference it can prove, and stays silent otherwise.
type ColumnCheck ¶ added in v0.18.0
type ColumnCheck struct {
Name string `json:"name,omitempty"` // the CONSTRAINT name, or "" for MySQL to number it
Expression string `json:"expression"`
NotEnforced bool `json:"not_enforced,omitempty"`
}
ColumnCheck is a column-level CHECK constraint as written in a column definition: `c INT [CONSTRAINT name] CHECK (expr) [NOT ENFORCED]`. A column can carry any number of them. MySQL stores each as a table-level constraint, which is how SHOW CREATE TABLE reports them, so columnCheckNormalizer moves them to CreateTable.Constraints at parse time and the slice is empty on a parsed CreateTable.
type ColumnCollationChange ¶ added in v0.18.0
type ColumnCollationChange struct {
// Before is what the column compares under now, and After what it
// compares under once the statement applies. Either is the zero value
// when the column carries no charset at that point (numeric, temporal,
// binary string, ...), and either can know its charset but not its
// collation.
Before, After CharsetCollation
// DeclaredAs is the column's name as the statement spells it, or empty
// when the statement changes the column without naming it — a
// CONVERT TO CHARACTER SET re-collates every character column.
DeclaredAs string
}
ColumnCollationChange is how an ALTER TABLE changes the collation one existing column compares under.
func (ColumnCollationChange) Changed ¶ added in v0.18.0
func (c ColumnCollationChange) Changed() bool
Changed reports whether the column compares under a different collation once the statement applies, so the same values may sort, and compare equal, differently. Gaining or losing a collation counts: a change between a character type and a binary or non-string type is one. When either side's collation is not known, a change of charset still decides it, since no two charsets share a collation.
type Constraint ¶
type Constraint struct {
Raw *ast.Constraint `json:"-"`
Name string `json:"name"`
Type string `json:"type"` // CHECK, FOREIGN KEY, etc.
Columns []string `json:"columns,omitempty"`
Expression *string `json:"expression,omitempty"`
References *ForeignKeyReference `json:"references,omitempty"`
Definition *string `json:"definition,omitempty"` // Generated definition string for compatibility
NotEnforced bool `json:"not_enforced,omitempty"` // CHECK constraints only: true when NOT ENFORCED
Options map[string]any `json:"options,omitempty"`
}
Constraint represents a table constraint
func (Constraint) GetName ¶
func (c Constraint) GetName() string
type Constraints ¶
type Constraints []Constraint
func (Constraints) ByName ¶
func (constraints Constraints) ByName(name string) *Constraint
func (Constraints) HasForeignKeys ¶
func (constraints Constraints) HasForeignKeys() bool
type CreateTable ¶
type CreateTable struct {
Raw *ast.CreateTableStmt `json:"-"`
TableName string `json:"table_name"`
Temporary bool `json:"temporary"`
IfNotExists bool `json:"if_not_exists"`
Columns Columns `json:"columns"`
Indexes Indexes `json:"indexes"`
Constraints Constraints `json:"constraints"`
TableOptions *TableOptions `json:"table_options,omitempty"`
Partition *PartitionOptions `json:"partition,omitempty"`
}
CreateTable represents a parsed CREATE TABLE statement with structured data
func ParseCreateTable ¶
func ParseCreateTable(sql string) (*CreateTable, error)
ParseCreateTable parses a CREATE TABLE statement and returns an analyzer This function is particularly designed to be used with the output of SHOW CREATE TABLE, which we consider to be the "canonical" form of a CREATE TABLE statement.
Because there's so much variation in the ways a human might write a CREATE TABLE statement, from index names being auto-generated to column attributes being turned into table options, you should consider use of this function on non-canonical CREATE statements to be experimental at best.
Note also that this parser does not attempt to validate the SQL beyond what the underlying parser does. For example, it will not check that a PRIMARY KEY column is NOT NULL, or that column names are unique, or that indexed columns exist.
func (*CreateTable) Diff ¶ added in v0.11.0
func (ct *CreateTable) Diff(target *CreateTable, opts *DiffOptions) ([]*AbstractStatement, error)
Diff compares this CreateTable (source) with another CreateTable (target) and returns ALTER TABLE statements needed to transform source into target. Most changes produce a single statement, but some require multiple sequential statements: a spatial index dropped before the primary ALTER changes its column's SRID; an option-only index rebuild, a foreign key added back under the name the primary ALTER drops, or a partition clause that cannot share an ALTER after it. See pkg/statement/README.md, "Statement Planning". Returns nil if the tables are identical. Returns an error if either table declares a column, index, or constraint name more than once, if target has a primary key column that declares NULL, or if target changes primary key options MySQL would ignore in a combined DROP and ADD. If opts is nil, NewDiffOptions() defaults are used.
func (*CreateTable) GetColumns ¶
func (ct *CreateTable) GetColumns() Columns
func (*CreateTable) GetConstraints ¶
func (ct *CreateTable) GetConstraints() Constraints
func (*CreateTable) GetCreateTable ¶
func (ct *CreateTable) GetCreateTable() *CreateTable
func (*CreateTable) GetIndexes ¶
func (ct *CreateTable) GetIndexes() Indexes
func (*CreateTable) GetPartition ¶
func (ct *CreateTable) GetPartition() *PartitionOptions
func (*CreateTable) GetTableName ¶
func (ct *CreateTable) GetTableName() string
func (*CreateTable) GetTableOptions ¶
func (ct *CreateTable) GetTableOptions() map[string]any
func (*CreateTable) TableDefault ¶ added in v0.18.0
func (ct *CreateTable) TableDefault() CharsetCollation
TableDefault returns the charset and collation a column declared without either takes in this table. The collation is empty when the definition does not determine it — DEFAULT CHARSET=utf8mb4 alone takes the server's default for it — and both are empty when the definition declares no default at all, which leaves it to the schema. SHOW CREATE TABLE always spells both out.
func (*CreateTable) ToTableInfo ¶ added in v0.17.0
func (ct *CreateTable) ToTableInfo(schemaName string) (*table.TableInfo, error)
ToTableInfo builds a connection-less table.TableInfo from the parsed CREATE TABLE, carrying the column types, charsets and collations, the table's default charset and collation, and the primary key columns that Spirit's checks read from table metadata. schemaName names the schema the table lives in; it is only used for error messages and by checks that query MySQL, which cannot run against the returned TableInfo anyway (see table.NewTableInfoFromMeta).
This lets a caller holding a table's DDL — typically its SHOW CREATE TABLE — supply check.Resources.Change.Table without opening a connection.
func (*CreateTable) ToTableSchema ¶ added in v0.11.3
func (ct *CreateTable) ToTableSchema() (table.TableSchema, error)
ToTableSchema converts a parsed CreateTable back to a table.TableSchema by restoring the AST to SQL. This is useful when callers have already parsed schemas (e.g. for linting) but need to pass them to DeclarativeToImperative.
type DefaultKind ¶ added in v0.18.0
type DefaultKind uint8
DefaultKind is the literal form a column DEFAULT was written as, taken from the parsed AST rather than re-derived from the restored text.
The text alone cannot answer the question. `DEFAULT TRUE`, `DEFAULT 1` and `DEFAULT '1'` all restore to a numeric-looking string, and `DEFAULT b'1'` restores to text that reads like a quoted string but must be emitted bare. The AST distinguishes all of them — the boolean keyword carries mysql.IsBooleanFlag, a string literal is ast.KindString, a bit or hex literal is ast.KindBinaryLiteral — so the kind is recorded here at parse time and every later decision reads it instead of guessing from the characters.
Two things depend on it. Emission needs to know whether to quote (see formatColumnDefinition): a bit literal quoted as a string produces DDL MySQL rejects outright. And the keyword fold needs to know a default was written as the keyword rather than as the value MySQL stores, so it can rewrite it to that value in the form the column's type reports (see [booleanKeywordDefaultNormalizer]).
const ( // DefaultKindUnknown is a default whose literal form is not modelled here // — NULL, a function default such as CURRENT_TIMESTAMP, an expression. Emission falls back to the [needsQuotes] text heuristic, as // it did for every kind before this classification existed. DefaultKindUnknown DefaultKind = iota // DefaultKindNumber is a numeric literal: 0, -1, 1.5, a decimal. MySQL // reports these quoted in SHOW CREATE TABLE regardless of how they were // written, which is why quotedness carries no meaning on numeric types. DefaultKindNumber // DefaultKindKeywordBool is the bare TRUE or FALSE keyword. MySQL treats it // as an alias for 1/0 and never reports it back, so it only ever appears on // the declared side of a diff. DefaultKindKeywordBool // DefaultKindString is a quoted string literal. The stored value is the raw // unescaped text, so it is re-quoted and escaped exactly once on emission — // even when it looks like a keyword or a number, since 'TRUE' and '1' are // string values rather than the keyword or the integer. DefaultKindString // DefaultKindBitLiteral is a bit literal such as b'101'. MySQL reports it // in its minimal form (b'0101' comes back as b'101', independent of the // column's width), which is the form the parser restores, so the recorded // text is already canonical and must be emitted bare. DefaultKindBitLiteral // DefaultKindHexLiteral is a hex literal such as 0x1A or x'1a', which the // parser restores as x'1a'. MySQL converts it to whatever the column's // type stores (an integer column reports 0x1A as 26), and reports it back // as hex only on a binary, varbinary, char or varchar column whose value is // not valid utf8mb3. The normalization rules convert it to the reported // form on those types, on the integer types, on bit and on year (see // [binaryDefaultBytesNormalizer], [integerBinaryLiteralDefaultNormalizer], // [bitDefaultNormalizer], [charBinaryLiteralDefaultNormalizer], // [yearDefaultNormalizer]). On a // utf8mb4 char or varchar column the recorded text carries a _utf8mb4 // introducer, `_utf8mb4 x'f09f9880'`, whether the default was written as a // string or as hex (see [charUTF8MB4DefaultNormalizer]). It must be // emitted bare: quoted, it is the string "x'1a'" rather than the byte 0x1a. DefaultKindHexLiteral )
type DefaultLiteral ¶ added in v0.18.0
type DefaultLiteral struct {
Text string `json:"text"`
Kind DefaultKind `json:"kind"`
}
DefaultLiteral is a column DEFAULT literal as the schema spelled it: the text in the form the parse records for its kind (a string literal's raw value, any other literal's restored text) and the DefaultKind that tells emission how to write it back. Column.DefaultAsWritten keeps one so that an emitted DEFAULT is the literal the author wrote rather than the reading the normalization rules leave in Column.Default.
type DiffOptions ¶ added in v0.11.0
type DiffOptions struct {
// IgnoreAutoIncrement skips diffing the AUTO_INCREMENT table option
// (the table-level next-value counter, e.g. `AUTO_INCREMENT=100`).
// Default: true (via NewDiffOptions).
IgnoreAutoIncrement bool
// IgnoreColumnAutoIncrement skips diffing the column-level AUTO_INCREMENT
// attribute (whether a column carries the AUTO_INCREMENT flag). This is
// distinct from IgnoreAutoIncrement, which only covers the table-option
// counter. Default: false (via NewDiffOptions) — for general schema diffing
// a column gaining or losing AUTO_INCREMENT is a real change. It is enabled
// by consumers like the move-tables target-state check, where an unsharded
// source legitimately differs from a sharded target that drops
// AUTO_INCREMENT in favor of a Vitess sequence: the difference does not
// affect copy correctness and must not block the move.
IgnoreColumnAutoIncrement bool
// IgnoreNotNullRelaxation lets the schema being validated be STRICTER than
// its reference on nullability, and only stricter: a validated column
// declared NOT NULL where the reference permits NULL is accepted, while one
// that permits NULL where the reference is NOT NULL remains a real
// difference. The option therefore can never quietly accept a schema that
// lost a NOT NULL the reference had.
//
// Default: false (via NewDiffOptions) — for general schema diffing a column
// gaining or losing NOT NULL is a real change.
//
// It is enabled by the move-tables target checks (see
// check.TargetSchemaDiff), where the reference is the move's SOURCE and
// the validated schema is its physical TARGET. What that permits is a target
// column declared NOT NULL where the source still permits NULL — an
// unsharded source moving into a sharded target whose shard key must be
// NOT NULL, because a Vitess primary vindex cannot map NULL to a keyspace
// id.
//
// In terms of Diff's own arguments the reference is the parameter and the
// validated schema is the receiver, because DiffCreateTables diffs
// got->want. Stating the direction that way inverts it, which is why the
// wording above and TestDiff_IgnoreNotNullRelaxation both name the two
// schemas by role instead.
//
// That is safe for a move because nullability is metadata, not row bytes:
// the copy and the checksum compare values, and every column's NULL-ness is
// compared explicitly (see ColumnMapping.ChecksumExprs, which emits an
// ISNULL() digit per column). A tightened column whose source data holds no
// NULLs is therefore identical on both sides, and this option hides nothing
// about the rows themselves. One that does hold a NULL fails the move
// instead of being accepted, and fails before the checksum ever runs — see
// check.TargetSchemaDiff for where and why.
IgnoreNotNullRelaxation bool
// IgnoreEngine skips diffing the ENGINE table option.
// Default: true (via NewDiffOptions).
IgnoreEngine bool
// IgnoreCharsetCollation skips diffing CHARSET and COLLATION table options.
// Default: false (via NewDiffOptions).
IgnoreCharsetCollation bool
// IgnorePartitioning skips diffing partition options entirely.
// Default: false (via NewDiffOptions).
IgnorePartitioning bool
// IgnoreRowFormat skips diffing the ROW_FORMAT table option, and with it
// the table-level KEY_BLOCK_SIZE (the compressed page size, which implies
// ROW_FORMAT=COMPRESSED and is only valid with it).
// Default: true (via NewDiffOptions).
// ROW_FORMAT=DYNAMIC is the InnoDB default in MySQL 8.0+, so differences
// between an unspecified ROW_FORMAT and an explicit DYNAMIC are cosmetic.
//
// When false, a target that names no row format (or names
// ROW_FORMAT=DEFAULT, which MySQL stores as none) clears a row format the
// source has with ROW_FORMAT=DEFAULT, so the table returns to the engine
// default. That is a table rebuild, as every row format change is, and
// it fires once: the rebuilt table reports no row format either.
//
// A KEY_BLOCK_SIZE change on a table that stays compressed emits only
// the new size, and does not converge: MySQL keeps the old size on every
// existing index and reports it there. Compressed tables are out of
// scope (Spirit targets Aurora, which does not support them), so the
// diff does not re-create the indexes for it; re-creating the primary
// key would need a DROP PRIMARY KEY, which Spirit refuses.
// If the follow-up diff finds a primary key whose stored size differs
// from the target, it returns an unsupported-primary-key-options error
// and no statements, rather than planning a DROP and ADD MySQL ignores.
IgnoreRowFormat bool
// LowerCaseTableNames is the target server's @@lower_case_table_names.
// When it is nonzero the server compares table names case-insensitively,
// so DeclarativeToImperative does too: `Orders` in the desired schema is
// the same table as `orders` in the current one (diffed, not created and
// dropped), and a desired schema declaring both refuses. When it is 0,
// `orders` and `Orders` are different tables.
// Default: 0 (via NewDiffOptions), comparing names exactly.
LowerCaseTableNames int
}
DiffOptions controls the behavior of the Diff operation.
func NewDiffOptions ¶ added in v0.11.0
func NewDiffOptions() *DiffOptions
NewDiffOptions returns DiffOptions with sensible defaults. By default, AUTO_INCREMENT, ENGINE, and ROW_FORMAT differences are ignored.
type ForeignKeyReference ¶
type ForeignKeyReference struct {
Schema string `json:"schema,omitempty"`
Table string `json:"table"`
Columns []string `json:"columns"`
OnDelete *string `json:"on_delete,omitempty"`
OnUpdate *string `json:"on_update,omitempty"`
}
ForeignKeyReference represents a foreign key reference.
Schema is the referenced table's schema when the reference is qualified (REFERENCES db.parent) and empty when it is not. SHOW CREATE TABLE qualifies a reference only when the parent is in another schema, and a reference qualified with the table's own schema reads back unqualified, so an empty Schema means the table's own schema — which a parsed CREATE TABLE does not know. Two references therefore compare equal unless both are qualified and name different schemas (see constraintsEqualIgnoreNameAndEnforcement); a desired REFERENCES db2.parent is not told apart from a live REFERENCES parent, whichever schema that is.
type HasName ¶
type HasName interface {
GetName() string
}
HasName is a type constraint for types that have a Name field
type Index ¶
type Index struct {
Name string `json:"name"`
Type string `json:"type"` // PRIMARY KEY, UNIQUE, INDEX, FULLTEXT, SPATIAL
Columns []string `json:"columns"` // Deprecated: use ColumnList for full details
ColumnList []IndexColumn `json:"column_list,omitempty"` // Full column specifications including prefix/expression
Invisible *bool `json:"invisible,omitempty"`
Using *string `json:"using,omitempty"` // BTREE, HASH, RTREE
Comment *string `json:"comment,omitempty"`
// KeyBlockSize is the index's own KEY_BLOCK_SIZE; nil when none is set or
// it equals the table's, which SHOW CREATE TABLE omits
// (indexDefaultsNormalizer).
KeyBlockSize *uint64 `json:"key_block_size,omitempty"`
ParserName *string `json:"parser_name,omitempty"`
Options map[string]string `json:"options,omitempty"`
// SecondaryEngineAttribute is the index's SECONDARY_ENGINE_ATTRIBUTE JSON
// text as written; compared as JSON (engineAttributeEqual) because MySQL
// reports it re-serialized, and emitted as written.
SecondaryEngineAttribute *string `json:"secondary_engine_attribute,omitempty"`
// InlineDerived marks a UNIQUE index that indexNormalizer synthesized
// from an inline column-level UNIQUE (`c INT UNIQUE`). Its name is only a
// guess at the server-assigned one (the column name, suffixed on collision),
// so diffIndexes pairs it with an equivalent unique index on the other side
// by column set even when the names differ, and compares the pair under
// that side's name (see pairInlineUniqueNames) rather than emitting a
// spurious DROP+ADD. Not serialized: it is a diff-time hint, not part of
// the logical schema.
InlineDerived bool `json:"-"`
}
Index represents an index definition
type IndexColumn ¶ added in v0.11.0
type IndexColumn struct {
Name string `json:"name,omitempty"` // Column name (empty for expression indexes)
Expression *string `json:"expression,omitempty"` // Expression for functional indexes
Length *int `json:"length,omitempty"` // Prefix length for string columns
Desc bool `json:"desc,omitempty"` // Descending key part (MySQL 8.0+), e.g. KEY (a DESC)
}
IndexColumn represents a column or expression in an index
type Normalizer ¶ added in v0.16.0
type Normalizer interface {
// Name identifies the rule, for registry determinism and debugging.
Name() string
// Normalize returns ct rewritten to MySQL's canonical form for this rule.
Normalize(ct *CreateTable) *CreateTable
}
Normalizer applies a single MySQL canonicalization to a parsed CreateTable. A rule takes a CreateTable and returns the normalized CreateTable — it is free to mutate and return the same instance, or to return a new one. It is deliberately a standalone type rather than a method on CreateTable so rules live in their own files and compose as a pipeline.
type Options ¶ added in v0.12.0
type Options struct {
// AllowMixedStatementTypes permits multi-statement input containing different
// DDL types (e.g., CREATE TABLE + ALTER TABLE). By default, multi-statement
// input must be all ALTER TABLE statements (required for atomic schema changes).
// Enable this when using New() to split/parse schema files that may contain
// a mix of DDL statement types.
AllowMixedStatementTypes bool
}
Options configures the behavior of statement parsing.
type PartitionDefinition ¶
type PartitionDefinition struct {
Name string `json:"name"`
Values *PartitionValues `json:"values,omitempty"` // VALUES LESS THAN or VALUES IN
Comment *string `json:"comment,omitempty"`
Engine *string `json:"engine,omitempty"`
PartitionStorage
Options map[string]any `json:"options,omitempty"` // Options MySQL does not accept on a partition
SubPartitions []SubPartitionDefinition `json:"subpartitions,omitempty"`
}
PartitionDefinition represents a single partition definition
type PartitionOptions ¶
type PartitionOptions struct {
Type string `json:"type"` // RANGE, LIST, HASH, KEY
Expression *string `json:"expression,omitempty"` // For HASH, RANGE and LIST
Columns []string `json:"columns,omitempty"` // For KEY, RANGE COLUMNS, LIST COLUMNS
Linear bool `json:"linear,omitempty"` // For LINEAR HASH/KEY
KeyAlgorithm uint64 `json:"key_algorithm,omitempty"` // For KEY: ALGORITHM=1; 0 is MySQL's default (2)
Partitions uint64 `json:"partitions,omitempty"` // Number of partitions
Definitions []PartitionDefinition `json:"definitions,omitempty"` // Individual partition definitions
SubPartition *SubPartitionOptions `json:"subpartition,omitempty"` // Subpartitioning options
}
PartitionOptions represents table partitioning configuration
type PartitionStorage ¶ added in v0.18.0
type PartitionStorage struct {
DataDirectory *string `json:"data_directory,omitempty"`
IndexDirectory *string `json:"index_directory,omitempty"` // InnoDB rejects it (error 1031)
MaxRows *uint64 `json:"max_rows,omitempty"`
MinRows *uint64 `json:"min_rows,omitempty"`
Tablespace *string `json:"tablespace,omitempty"`
Nodegroup *uint64 `json:"nodegroup,omitempty"`
}
PartitionStorage holds the storage options of a partition or subpartition definition. A partition with named subpartitions holds none: MySQL stores them on each subpartition (see partitionOptionsNormalizer).
type PartitionValues ¶
type PartitionValues struct {
Type string `json:"type"` // "LESS_THAN", "IN", "MAXVALUE"
Values []any `json:"values"` // The actual values
}
PartitionValues represents the VALUES clause in partition definitions
type StatementType ¶ added in v0.11.1
type StatementType int
StatementType represents the type of a SQL statement.
const ( StatementUnknown StatementType = iota StatementAlterTable // ALTER TABLE ... StatementCreateTable // CREATE TABLE ... StatementDropTable // DROP TABLE ... StatementRenameTable // RENAME TABLE ... StatementTruncateTable // TRUNCATE TABLE ... StatementCreateIndex // CREATE INDEX ... StatementDropIndex // DROP INDEX ... StatementCreateView // CREATE VIEW ... StatementInsert // INSERT ... StatementUpdate // UPDATE ... StatementDelete // DELETE ... )
func (StatementType) IsDDL ¶ added in v0.11.1
func (t StatementType) IsDDL() bool
IsDDL returns true if this is a DDL statement type.
func (StatementType) IsDML ¶ added in v0.11.1
func (t StatementType) IsDML() bool
IsDML returns true if this is a DML statement type.
func (StatementType) String ¶ added in v0.11.1
func (t StatementType) String() string
String returns the human-readable name for a StatementType.
type SubPartitionDefinition ¶
type SubPartitionDefinition struct {
Name string `json:"name"`
Comment *string `json:"comment,omitempty"`
Engine *string `json:"engine,omitempty"`
PartitionStorage
Options map[string]any `json:"options,omitempty"` // Options MySQL does not accept on a subpartition
}
SubPartitionDefinition represents a single subpartition definition
type SubPartitionOptions ¶
type SubPartitionOptions struct {
Type string `json:"type"` // HASH, KEY
Expression *string `json:"expression,omitempty"` // For HASH
Columns []string `json:"columns,omitempty"` // For KEY
Linear bool `json:"linear,omitempty"` // For LINEAR HASH/KEY
KeyAlgorithm uint64 `json:"key_algorithm,omitempty"` // For KEY: ALGORITHM=1; 0 is MySQL's default (2)
Count uint64 `json:"count,omitempty"` // Number of subpartitions
}
SubPartitionOptions represents subpartitioning configuration
type TableOptions ¶
type TableOptions struct {
Engine *string `json:"engine,omitempty"`
Charset *string `json:"charset,omitempty"`
Collation *string `json:"collation,omitempty"`
Comment *string `json:"comment,omitempty"`
AutoIncrement *uint64 `json:"auto_increment,omitempty"`
RowFormat *string `json:"row_format,omitempty"`
// KeyBlockSize is the table-level KEY_BLOCK_SIZE, the compressed page
// size in KiB. It belongs with ROW_FORMAT (it implies COMPRESSED and
// InnoDB rejects it with any other row format), so Diff treats the two
// together under DiffOptions.IgnoreRowFormat. 0 means unset.
KeyBlockSize *uint64 `json:"key_block_size,omitempty"`
// AutoextendSize is AUTOEXTEND_SIZE in bytes. MySQL accepts it with a
// K/M/G suffix (4M) and reports it in bytes (4194304). 0 means unset.
AutoextendSize *uint64 `json:"autoextend_size,omitempty"`
// The following are reported by SHOW CREATE TABLE only when set; each
// has a value MySQL treats as "unset" that Diff emits to clear it.
StatsPersistent *bool `json:"stats_persistent,omitempty"` // STATS_PERSISTENT=0|1; DEFAULT is not recorded
StatsAutoRecalc *bool `json:"stats_auto_recalc,omitempty"` // STATS_AUTO_RECALC=0|1; DEFAULT is not recorded
StatsSamplePages *uint64 `json:"stats_sample_pages,omitempty"` // STATS_SAMPLE_PAGES=n; 0 and DEFAULT are not recorded
PackKeys *bool `json:"pack_keys,omitempty"` // PACK_KEYS=0|1; DEFAULT is not recorded
Checksum bool `json:"checksum,omitempty"` // CHECKSUM=1
DelayKeyWrite bool `json:"delay_key_write,omitempty"` // DELAY_KEY_WRITE=1
AvgRowLength *uint64 `json:"avg_row_length,omitempty"` // 0 is not recorded
MinRows *uint64 `json:"min_rows,omitempty"` // 0 is not recorded
MaxRows *uint64 `json:"max_rows,omitempty"` // 0 is not recorded
// SecondaryEngineAttribute is the table's SECONDARY_ENGINE_ATTRIBUTE JSON
// text as written; compared as JSON (engineAttributeEqual) because MySQL
// reports it re-serialized, and emitted as written. ” is not recorded.
SecondaryEngineAttribute *string `json:"secondary_engine_attribute,omitempty"`
}
TableOptions represents table-level options
Source Files
¶
- charset.go
- classify.go
- column_collation.go
- create_table.go
- declarative.go
- default_kind.go
- diff.go
- duplicate_names.go
- equality.go
- format.go
- normalize.go
- normalize_auto_increment_not_null.go
- normalize_binary_attribute.go
- normalize_binary_charset.go
- normalize_binary_default_bytes.go
- normalize_bit_default.go
- normalize_boolean_keyword_default.go
- normalize_char_binary_literal_default.go
- normalize_char_default_spaces.go
- normalize_char_utf8mb4_default.go
- normalize_charsetless_types.go
- normalize_column_checks.go
- normalize_column_reference_case.go
- normalize_decimal_zero_precision.go
- normalize_default_collation.go
- normalize_enum_set_default.go
- normalize_enum_set_member_spaces.go
- normalize_expression_parens.go
- normalize_function_aliases.go
- normalize_index_defaults.go
- normalize_index_names.go
- normalize_integer_binary_literal_default.go
- normalize_integer_display_width.go
- normalize_numeric_default.go
- normalize_partition_bound_constants.go
- normalize_partition_comment.go
- normalize_partition_key_algorithm.go
- normalize_partition_list_value_order.go
- normalize_partition_options.go
- normalize_primary_key.go
- normalize_primary_key_not_null.go
- normalize_temporal_default.go
- normalize_text_blob_length.go
- normalize_timestamp_fsp_zero.go
- normalize_vector_dimension.go
- normalize_year_default.go
- normalize_year_display_width.go
- normalize_zerofill_default.go
- parse_helpers.go
- schema_compare.go
- secondary_indexes.go
- statement.go
- utils.go