From 3624e09e56a4d6b317a71af0821bd0debfc439de Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 17 Jul 2025 14:25:55 -0700 Subject: [PATCH] Fix bug when json with a real SQLType in the tag --- tags/parser.go | 12 ++++++++---- tags/parser_test.go | 38 ++++++++++++++++++++++++++++++++++++++ tags/tag.go | 14 +++++++++++--- 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/tags/parser.go b/tags/parser.go index 53ef0c10..cb14b6fc 100644 --- a/tags/parser.go +++ b/tags/parser.go @@ -250,10 +250,14 @@ func (parser *Parser) parseFieldWithTags(table *schemas.Table, fieldIndex int, f } if col.SQLType.Name == "" { - var err error - col.SQLType, err = parser.getSQLTypeByType(field.Type) - if err != nil { - return nil, err + if col.IsJSON { + col.SQLType = schemas.SQLType{Name: schemas.Text} + } else { + var err error + col.SQLType, err = parser.getSQLTypeByType(field.Type) + if err != nil { + return nil, err + } } } if ctx.isUnsigned && col.SQLType.IsNumeric() && !strings.HasPrefix(col.SQLType.Name, "UNSIGNED") { diff --git a/tags/parser_test.go b/tags/parser_test.go index 434cfc07..839da3b0 100644 --- a/tags/parser_test.go +++ b/tags/parser_test.go @@ -617,3 +617,41 @@ func TestParseWithSQLType(t *testing.T) { assert.EqualValues(t, "DATETIME", table.Columns()[3].SQLType.Name) assert.EqualValues(t, "UUID", table.Columns()[4].SQLType.Name) } + +func TestParseWithJSONLongText(t *testing.T) { + parser := NewParser( + "db", + dialects.QueryDialect("mysql"), + names.GonicMapper{ + "JSON": true, + }, + names.GonicMapper{ + "JSON": true, + }, + caches.NewManager(), + ) + + type StructWithJSONLongText struct { + Col1 string `db:"LongText json"` + } + + table, err := parser.Parse(reflect.ValueOf(new(StructWithJSONLongText))) + assert.NoError(t, err) + assert.EqualValues(t, "struct_with_json_long_text", table.Name) + assert.EqualValues(t, 1, len(table.Columns())) + assert.EqualValues(t, "col1", table.Columns()[0].Name) + assert.EqualValues(t, "LONGTEXT", table.Columns()[0].SQLType.Name) + assert.EqualValues(t, true, table.Columns()[0].IsJSON) + + type StructWithJSONLongText2 struct { + Col1 string `db:"json"` + } + + table, err = parser.Parse(reflect.ValueOf(new(StructWithJSONLongText2))) + assert.NoError(t, err) + assert.EqualValues(t, "struct_with_json_long_text2", table.Name) + assert.EqualValues(t, 1, len(table.Columns())) + assert.EqualValues(t, "col1", table.Columns()[0].Name) + assert.EqualValues(t, "TEXT", table.Columns()[0].SQLType.Name) + assert.EqualValues(t, true, table.Columns()[0].IsJSON) +} diff --git a/tags/tag.go b/tags/tag.go index 55f0b7c7..dfb66a7e 100644 --- a/tags/tag.go +++ b/tags/tag.go @@ -124,10 +124,16 @@ var defaultTagHandlers = map[string]Handler{ "EXTENDS": ExtendsTagHandler, "UNSIGNED": UnsignedTagHandler, "COLLATE": CollateTagHandler, + "JSON": JSONTagHandler, + "JSONB": JSONTagHandler, } func init() { for k := range schemas.SqlTypes { + // don't override default tag handlers + if _, ok := defaultTagHandlers[k]; ok { + continue + } defaultTagHandlers[k] = SQLTypeTagHandler } } @@ -293,12 +299,14 @@ func CollateTagHandler(ctx *Context) error { return nil } +func JSONTagHandler(ctx *Context) error { + ctx.col.IsJSON = true + return nil +} + // SQLTypeTagHandler describes SQL Type tag handler func SQLTypeTagHandler(ctx *Context) error { ctx.col.SQLType = schemas.SQLType{Name: ctx.tagUname} - if ctx.tagUname == "JSON" || ctx.tagUname == "JSONB" { - ctx.col.IsJSON = true - } if len(ctx.params) == 0 { return nil }