{"record":{"id":"4181d6c3fd920864","repo":"bytebase/bytebase","slug":"failed-to-scan-ddl-row","errorCode":null,"errorMessage":"failed to scan DDL row","messagePattern":"failed to scan DDL row","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/plugin/db/hive/dump.go","lineNumber":184,"sourceCode":"\tobjectName = fmt.Sprintf(\"`%s`\", objectName)\n\n\t// 'SHOW CREATE TABLE' can also be used for dumping views\n\tstmt := fmt.Sprintf(\"SHOW CREATE %s %s\", objectType, objectName)\n\tif objectType == \"VIEW\" {\n\t\tstmt = fmt.Sprintf(\"SHOW CREATE TABLE %s\", objectName)\n\t}\n\n\trows, err := d.db.QueryContext(ctx, stmt)\n\tif err != nil {\n\t\treturn \"\", errors.Wrapf(err, \"failed to execute %s\", stmt)\n\t}\n\tdefer rows.Close()\n\n\tvar schemaDDL strings.Builder\n\tfor rows.Next() {\n\t\tvar ddlLine string\n\t\tif err := rows.Scan(&ddlLine); err != nil {\n\t\t\treturn \"\", errors.Wrap(err, \"failed to scan DDL row\")\n\t\t}\n\t\tschemaDDL.WriteString(ddlLine)\n\t\tschemaDDL.WriteString(\"\\n\")\n\t}\n\n\tif err := rows.Err(); err != nil {\n\t\treturn \"\", errors.Wrap(err, \"error reading DDL rows\")\n\t}\n\n\tif schemaDDL.Len() == 0 {\n\t\treturn \"\", errors.New(\"empty DDL result\")\n\t}\n\n\treturn fmt.Sprintf(schemaStmtFmt, objectType, objectName, schemaDDL.String()), nil\n}\n\nfunc genIndexDDL(opts *IndexDDLOptions) (string, error) {\n\tvar builder strings.Builder","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/plugin/db/hive/dump.go#L166-L202","documentation":"After running SHOW CREATE TABLE, showCreateDDL scans each result row into a string (one DDL line per row); a rows.Scan failure aborts with this error. It indicates the Hive result row could not be decoded into the expected single string column.","triggerScenarios":"rows.Scan(&ddlLine) failed because the driver returned a NULL value, multiple columns were expected, or the value type is not convertible to string (driver/type mismatch).","commonSituations":"Hive driver returning a different column layout than expected; NULL DDL lines from a broken object; driver version mismatch between gohive/hive client library and HiveServer2 version.","solutions":["Check the Hive driver version matches the HiveServer2 version in use","Handle NULLs — scan into sql.NullString and skip empty rows","Reproduce SHOW CREATE TABLE manually; if output is fine, the scan logic/driver is at fault","Upgrade or pin the Hive client library to a compatible release"],"exampleFix":"// before\nvar ddlLine string\nif err := rows.Scan(&ddlLine); err != nil {\n\treturn \"\", errors.Wrap(err, \"failed to scan DDL row\")\n}\n// after\nvar ddlLine sql.NullString\nif err := rows.Scan(&ddlLine); err != nil {\n\treturn \"\", errors.Wrap(err, \"failed to scan DDL row\")\n}\nif ddlLine.Valid {\n\tschemaDDL.WriteString(ddlLine.String)\n\tschemaDDL.WriteString(\"\\n\")\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func scanDDLRow(rows *sql.Rows) (string, bool) {\n\tvar s sql.NullString\n\tif err := rows.Scan(&s); err != nil || !s.Valid {\n\t\treturn \"\", false\n\t}\n\treturn s.String, true\n}","tryCatchPattern":"if err := Dump(ctx, out, dbName); err != nil {\n\tif strings.Contains(err.Error(), \"failed to scan DDL row\") {\n\t\t// driver/type mismatch — check driver version compatibility\n\t}\n}","preventionTips":["Pin Hive driver version to one compatible with your HiveServer2","Scan nullable columns with sql.NullString","Test SHOW CREATE TABLE output shape against your driver after upgrades"],"tags":["hive","sql","scan"],"backgroundTag":"unexpected-api-response-shape","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"}