{"record":{"id":"f424d03437ec57ff","repo":"geektutu/7days-golang","slug":"invalid-sql-type-s-s-f424d0","errorCode":null,"errorMessage":"invalid sql type %s (%s)","messagePattern":"invalid sql type (.+?) \\((.+?)\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gee-orm/day5-hooks/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/day5-hooks/dialect/sqlite3.go#L20-L46","documentation":"Same 'invalid sql type' panic in the day5-hooks stage of gee-orm: DataTypeOf for the sqlite3 dialect panics on any reflect.Type outside its supported switch (bool/int kinds, float, string, []byte, time.Time struct). Triggered while parsing the schema for Open or query building.","triggerScenarios":"Opening a session against a model with an unmappable field type (map, slice of structs, custom struct kind, interface field).","commonSituations":"Persisting struct fields added by hooks/feature work; modeling JSON documents inline; interface-typed fields.","solutions":["Change the field type to one of the supported kinds","Pre-serialize complex values into string/[]byte columns","Add explicit dialect support for the kind"],"exampleFix":"// before\ntype Session struct {\n    Data map[string]interface{}\n}\n// after\ntype Session struct {\n    Data string // JSON encoded\n}","handlingStrategy":"validation","validationCode":"for _, f := range reflect.VisibleFields(reflect.TypeOf(Model{})) {\n    if !isSQLiteMappable(f.Type) {\n        log.Fatalf(\"field %s of type %s is not sqlite-mappable\", f.Name, f.Type)\n    }\n}","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.HasPrefix(s, \"invalid sql type\") {\n            err = fmt.Errorf(\"unsupported schema field: %s\", s)\n        } else { panic(r) }\n    }\n}()","preventionTips":["Keep hooks/models free of complex field types","Serialize structured data into text/blob columns","Cover every model with a Parse/DataTypeOf smoke test"],"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"}