{"record":{"id":"f686e11b36c2a8ff","repo":"vitessio/vitess","slug":"unknown-sql-type-q-at-s","errorCode":null,"errorMessage":"unknown SQL type %q at %s","messagePattern":"unknown SQL type %q at (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/sqltypes/parse_rows.go","lineNumber":87,"sourceCode":"\t\t\t}\n\t\tcase stInRow:\n\t\t\tswitch tok {\n\t\t\tcase ']':\n\t\t\t\tresult = append(result, row)\n\t\t\t\trow = nil\n\t\t\t\tnext = stBeginRow\n\t\t\tcase scanner.Ident:\n\t\t\t\tident := scan.TokenText()\n\n\t\t\t\tif ident == \"NULL\" {\n\t\t\t\t\trow = append(row, NULL)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tvar ok bool\n\t\t\t\tvtype, ok = querypb.Type_value[ident]\n\t\t\t\tif !ok {\n\t\t\t\t\treturn nil, fmt.Errorf(\"unknown SQL type %q at %s\", ident, scan.Position)\n\t\t\t\t}\n\t\t\t\tnext = stInValue0\n\t\t\t}\n\t\tcase stInValue0:\n\t\t\tif tok == '(' {\n\t\t\t\tnext = stInValue1\n\t\t\t}\n\t\tcase stInValue1:\n\t\t\tliteral := scan.TokenText()\n\t\t\tswitch tok {\n\t\t\tcase scanner.String:\n\t\t\t\tvar err error\n\t\t\t\tliteral, err = strconv.Unquote(literal)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"failed to parse literal string at %s: %w\", scan.Position, err)\n\t\t\t\t}\n\t\t\t\tfallthrough\n\t\t\tcase scanner.Int, scanner.Float:","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/sqltypes/parse_rows.go#L69-L105","documentation":"ParseRows parses a human-readable rows string where each value can carry a type annotation in parentheses. It throws when the annotation is not a recognized querypb.Type name, reporting the identifier and scan position.","triggerScenarios":"Calling ParseRows (directly or via RowsEqualsStr in tests) with a type annotation like (VARCHAR) or (INT) that is not an exact querypb.Type_value key — valid names include INT64, VARCHAR, VARBINARY, DATETIME, etc.","commonSituations":"Writing expected rows in unit tests with MySQL-style or made-up type names instead of Vitess/querypb enum names; typos in annotations; copying examples from an older version with different type names.","solutions":["Use exact querypb.Type_value names in annotations, e.g. (INT64), (VARCHAR), (VARBINARY)","Check go/vt/proto/query querypb.Type_value map for the valid identifier list","Fix the typo or outdated type name in the rows string"],"exampleFix":"// before\nrows := sqltypes.MakeTestRows(strings.NewReader(\"(VARCHAR 'abc')\"))\n// after\nrows := sqltypes.MakeTestRows(strings.NewReader(\"(VARCHAR 'abc')\")) // -> use querypb name:\n// (VARCHAR is valid only if in querypb.Type_value; otherwise use e.g. (VARBINARY 'abc'))","handlingStrategy":"validation","validationCode":"func validTypeName(ident string) bool {\n\t_, ok := querypb.Type_value[ident]\n\treturn ok\n}","typeGuard":"func isKnownSQLType(ident string) bool { _, ok := querypb.Type_value[ident]; return ok }","tryCatchPattern":"rows, err := sqltypes.ParseRows(input, cols)\nif err != nil {\n\treturn fmt.Errorf(\"bad test rows input at %v: %v\", err, input)\n}","preventionTips":["Use exact querypb.Type enum names (INT64, VARCHAR, VARBINARY...) in row strings","Copy type names from the querypb.Type_value map, not from MySQL docs","Keep a shared helper for building expected-row strings in tests"],"tags":["go","sql","parsing","test-helpers"],"backgroundTag":"unknown-sql-type","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}