bytebase/bytebase · error
failed to parse schema DDL
Error message
failed to parse schema DDL
What it means
After initializing the catalog, GetDatabaseMetadataOmni executes the whole schema DDL text through the embedded omni MySQL catalog with ContinueOnError. If the batch itself fails (e.g. the SQL cannot be parsed at all), the error is wrapped as 'failed to parse schema DDL'. This indicates the input is not valid MySQL DDL for the embedded parser.
Source
Thrown at backend/plugin/schema/mysql/get_database_metadata_omni.go:34
}
// GetDatabaseMetadataOmni parses MySQL schema DDL text and returns database metadata
// using the omni catalog. This replaces the ANTLR-based GetDatabaseMetadata.
func GetDatabaseMetadataOmni(schemaText string) (*storepb.DatabaseSchemaMetadata, error) {
if schemaText == "" {
return &storepb.DatabaseSchemaMetadata{}, nil
}
const dbName = "tmp"
c := catalog.New()
initSQL := fmt.Sprintf("SET foreign_key_checks = 0;\nCREATE DATABASE IF NOT EXISTS `%s`;\nUSE `%s`;", dbName, dbName)
if _, err := c.Exec(initSQL, nil); err != nil {
return nil, errors.Wrap(err, "failed to initialize catalog")
}
results, err := c.Exec(schemaText, &catalog.ExecOptions{ContinueOnError: true})
if err != nil {
return nil, errors.Wrap(err, "failed to parse schema DDL")
}
// Check for hard errors (not per-statement errors).
for _, r := range results {
if r.Error != nil {
return nil, errors.Wrapf(r.Error, "failed to execute schema DDL")
}
}
proto := catalogToProto(c, dbName)
return proto, nil
}
View on GitHub (pinned to 1870550677)
Solutions
- Unwrap the error to find the offending statement and parser message.
- Validate the schemaText with mysql client or lint it as MySQL DDL before passing it in.
- Fix or regenerate the DDL so it is standard MySQL CREATE TABLE/VIEW/etc. syntax.
- If specific statements legitimately fail, rely on the per-statement results path (ContinueOnError) rather than the batch error and inspect results for r.Error.
Example fix
// before
proto, err := GetDatabaseMetadataOmni(ctx, rawDDL) // rawDDL contains dialect-specific syntax
// after
validated, err := lintAndNormalizeMySQLDDL(rawDDL)
if err != nil {
return nil, err
}
proto, err := GetDatabaseMetadataOmni(ctx, validated) Defensive patterns
Strategy: validation
Validate before calling
if err := validateMySQLDDL(schemaText); err != nil {
return nil, fmt.Errorf("schemaText is not valid MySQL DDL: %w", err)
} Try / catch
if err != nil && strings.Contains(err.Error(), "failed to parse schema DDL") {
return nil, fmt.Errorf("input schema rejected by parser: %w", err)
} Prevention
- Generate schema text only from tools emitting standard MySQL DDL
- Lint the DDL (mysql --force dry run or a parser) before calling GetDatabaseMetadataOmni
- Watch for dialect drift when the DDL producer and the omni parser versions diverge
When it happens
Trigger: Calling GetDatabaseMetadataOmni with schemaText containing syntax the omni parser rejects, non-DDL statements, or malformed multi-statement input.
Common situations: Schema text produced by another tool with MySQL-incompatible syntax; dialect drift between the generator and the omni parser; truncated or concatenated DDL files.
Understand the failure class
Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- failed to execute schema DDL
- failed to extract tables
- failed to initialize catalog
- parse expr %q: empty result
- parse expr %q: expected SelectStmt, got %T
AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06).
Data as JSON: /api/errors/ad690ecbdd994404.
Report an issue: GitHub.