{"record":{"id":"94ac5fdddd342f2b","repo":"bytebase/bytebase","slug":"failed-to-get-sql-mode","errorCode":null,"errorMessage":"failed to get SQL mode","messagePattern":"failed to get SQL mode","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/plugin/schema/tidb/get_database_metadata.go","lineNumber":33,"sourceCode":"\t// Register pingcap parser driver.\n\t_ \"github.com/pingcap/tidb/pkg/types/parser_driver\"\n\n\tstorepb \"github.com/bytebase/bytebase/backend/generated-go/store\"\n\t\"github.com/bytebase/bytebase/backend/plugin/schema\"\n)\n\nfunc init() {\n\tschema.RegisterGetDatabaseMetadata(storepb.Engine_TIDB, GetDatabaseMetadata)\n}\n\n// GetDatabaseMetadata parses the database schema text and returns the metadata using TiDB's parser.\nfunc GetDatabaseMetadata(schemaText string) (*storepb.DatabaseSchemaMetadata, error) {\n\t// Use TiDB's parser to parse the SQL\n\tp := parser.New()\n\tp.EnableWindowFunc(true)\n\tmode, err := mysql.GetSQLMode(mysql.DefaultSQLMode)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed to get SQL mode\")\n\t}\n\tmode = mysql.DelSQLMode(mode, mysql.ModeNoZeroDate)\n\tmode = mysql.DelSQLMode(mode, mysql.ModeNoZeroInDate)\n\tp.SetSQLMode(mode)\n\n\tstmts, _, err := p.Parse(schemaText, \"\", \"\")\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed to parse schema\")\n\t}\n\n\textractor := &metadataExtractor{\n\t\tschemas: make(map[string]*storepb.SchemaMetadata),\n\t\ttables:  make(map[tableKey]*storepb.TableMetadata),\n\t\tviews:   make(map[viewKey]*storepb.ViewMetadata),\n\t\tresult: &storepb.DatabaseSchemaMetadata{\n\t\t\tName: \"\",\n\t\t},\n\t}","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/plugin/schema/tidb/get_database_metadata.go#L15-L51","documentation":"GetDatabaseMetadata for TiDB configures the parser's SQL mode by calling mysql.GetSQLMode(mysql.DefaultSQLMode). If that call fails (it essentially never does with the built-in default mode string), the error is wrapped with this message. It is a defensive wrap during parser initialization, before any user SQL is parsed.","triggerScenarios":"Calling schema.tidb.GetDatabaseMetadata(schemaText) when mysql.GetSQLMode fails on mysql.DefaultSQLMode — practically only if the DefaultSQLMode constant is malformed or a custom/pinned parser version has a broken mode parser.","commonSituations":"Dependency upgrades of pingcap/tidb/parser changing SQL-mode parsing behavior; forked parser builds with a modified DefaultSQLMode; this is nearly always an upstream library issue, not user input.","solutions":["Check the wrapped inner error for which SQL mode token failed to parse","Verify the pingcap/tidb/parser dependency version and try upgrading/downgrading it","Pin a known-good parser version in go.mod","If reproducible, replace DefaultSQLMode with an explicit mode string known to parse"],"exampleFix":"// before\nmode, err := mysql.GetSQLMode(mysql.DefaultSQLMode)\nif err != nil {\n    return nil, errors.Wrap(err, \"failed to get SQL mode\")\n}\n// after\nmode, err := mysql.GetSQLMode(mysql.DefaultSQLMode)\nif err != nil {\n    mode, err = mysql.GetSQLMode(\"STRICT_TRANS_TABLES\") // fallback mode\n    if err != nil {\n        return nil, errors.Wrap(err, \"failed to get SQL mode\")\n    }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"meta, err := tidb.GetDatabaseMetadata(schemaText)\nif err != nil && strings.Contains(err.Error(), \"failed to get SQL mode\") {\n    return fmt.Errorf(\"parser initialization failed (likely parser dependency issue): %w\", err)\n}","preventionTips":["Pin the pingcap/tidb/parser version and test parser init in CI on dependency upgrades","Treat this error as an environment/dependency problem, not user-input problem","Keep DefaultSQLMode untouched; pass custom modes through explicit, tested strings"],"tags":["go","tidb","parser","sql-mode"],"backgroundTag":"sql-mode-resolution-failed","analyzedSha":"1870550677fe08f0d2a78c07acd27541464eb945","analyzedAt":"2026-09-06T21:16:13.665Z","contentChangedAt":"2026-09-06T21:16:13.665Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}