{"record":{"id":"1ec27d3a1cc39c18","repo":"geektutu/7days-golang","slug":"invalid-sql-type-s-s-1ec27d","errorCode":null,"errorMessage":"invalid sql type %s (%s)","messagePattern":"invalid sql type (.+?) \\((.+?)\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gee-orm/day4-chain-operation/dialect/sqlite3.go","lineNumber":38,"sourceCode":"\tcase reflect.Bool:\n\t\treturn \"bool\"\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32,\n\t\treflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uintptr:\n\t\treturn \"integer\"\n\tcase reflect.Int64, reflect.Uint64:\n\t\treturn \"bigint\"\n\tcase reflect.Float32, reflect.Float64:\n\t\treturn \"real\"\n\tcase reflect.String:\n\t\treturn \"text\"\n\tcase reflect.Array, reflect.Slice:\n\t\treturn \"blob\"\n\tcase reflect.Struct:\n\t\tif _, ok := typ.Interface().(time.Time); ok {\n\t\t\treturn \"datetime\"\n\t\t}\n\t}\n\tpanic(fmt.Sprintf(\"invalid sql type %s (%s)\", typ.Type().Name(), typ.Kind()))\n}\n\n// TableExistSQL returns SQL that judge whether the table exists in database\nfunc (s *sqlite3) TableExistSQL(tableName string) (string, []interface{}) {\n\targs := []interface{}{tableName}\n\treturn \"SELECT name FROM sqlite_master WHERE type='table' and name = ?\", args\n}\n","sourceCodeStart":20,"sourceCodeEnd":46,"githubUrl":"https://github.com/geektutu/7days-golang/blob/cf3644382101dc13e7fd92e8f5c66cabc51bcd3b/gee-orm/day4-chain-operation/dialect/sqlite3.go#L20-L46","documentation":"Same 'invalid sql type' panic as errors 103/104, in the day4-chain-operation stage of gee-orm. The sqlite3 dialect cannot map the reflect.Type of a schema field to a column type and fails fast during schema parsing.","triggerScenarios":" geeorm.Open or table creation against a struct containing an unsupported field kind; chained query building that first parses the schema triggers it.","commonSituations":"Evolving models with nested structs or slices; using custom numeric types (e.g. type Money struct) in model fields.","solutions":["Map the field to a supported primitive or []byte/string serialized form","Extend the dialect's DataTypeOf switch with the needed kind","Exclude the field from persistence"],"exampleFix":"// before\ntype Account struct {\n    Balance Money // custom struct type\n}\n// after\ntype Account struct {\n    BalanceCents int64\n}","handlingStrategy":"validation","validationCode":"if err := checkSchemaTypes(&MyModel{}); err != nil {\n    log.Fatalf(\"model not persistable: %v\", err)\n}\n_ = geeorm.Open(db, \"sqlite3\", \"...\" )","typeGuard":"func isSQLiteMappable(t reflect.Type) bool {\n    if t == reflect.TypeOf(time.Time{}) { return true }\n    switch t.Kind() {\n    case reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,\n        reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,\n        reflect.Float32, reflect.Float64, reflect.String, reflect.Slice:\n        return true\n    }\n    return false\n}","tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        if s, ok := r.(string); ok && strings.Contains(s, \"invalid sql type\") {\n            err = fmt.Errorf(\"bad model schema: %s\", s)\n        } else { panic(r) }\n    }\n}()","preventionTips":["Restrict model fields to SQL-mappable primitives","Convert custom value types to primitive columns (e.g. int64 cents)","Test schema parsing whenever a model changes"],"tags":["go","panic","sqlite","orm","schema"],"backgroundTag":"unsupported-field-type","analyzedSha":"cf3644382101dc13e7fd92e8f5c66cabc51bcd3b","analyzedAt":"2026-09-03T18:31:24.087Z","contentChangedAt":"2026-09-03T18:31:24.087Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}