dialct/sql/sqljson: fix HasKey implementation for SQLite (#2887)

This commit is contained in:
Ariel Mashraki
2022-08-29 23:37:30 +03:00
committed by GitHub
parent 1cf4fc88c7
commit bedbea6665
4 changed files with 68 additions and 17 deletions

View File

@@ -22,18 +22,11 @@ func HasKey(column string, opts ...Option) *sql.Predicate {
return sql.P(func(b *sql.Builder) {
switch b.Dialect() {
case dialect.SQLite:
b.Nested(func(b *sql.Builder) {
b.Join(
sql.Or(
// The result is NULL for JSON null.
sql.P(func(b *sql.Builder) {
ValuePath(b, column, opts...)
b.WriteOp(sql.OpNotNull)
}),
ValueIsNull(column, opts...),
),
)
})
// JSON_TYPE returns NULL in case the path selects an element
// that does not exist. See: https://sqlite.org/json1.html#jtype.
path := identPath(column, opts...)
path.mysqlFunc("JSON_TYPE", b)
b.WriteOp(sql.OpNotNull)
default:
ValuePath(b, column, opts...)
b.WriteOp(sql.OpNotNull)

View File

@@ -61,14 +61,14 @@ func TestWritePath(t *testing.T) {
Select("*").
From(sql.Table("test")).
Where(sqljson.HasKey("j", sqljson.DotPath("attributes[1].body"))),
wantQuery: "SELECT * FROM `test` WHERE (JSON_EXTRACT(`j`, \"$.attributes[1].body\") IS NOT NULL OR JSON_TYPE(`j`, \"$.attributes[1].body\") = 'null')",
wantQuery: "SELECT * FROM `test` WHERE JSON_TYPE(`j`, \"$.attributes[1].body\") IS NOT NULL",
},
{
input: sql.Dialect(dialect.SQLite).
Select("*").
From(sql.Table("test")).
Where(sqljson.HasKey("j", sqljson.DotPath("a.*.c"))),
wantQuery: "SELECT * FROM `test` WHERE (JSON_EXTRACT(`j`, \"$.a.*.c\") IS NOT NULL OR JSON_TYPE(`j`, \"$.a.*.c\") = 'null')",
wantQuery: "SELECT * FROM `test` WHERE JSON_TYPE(`j`, \"$.a.*.c\") IS NOT NULL",
},
{
input: sql.Dialect(dialect.SQLite).
@@ -81,7 +81,7 @@ func TestWritePath(t *testing.T) {
sql.EQ("active", true),
),
),
wantQuery: "SELECT * FROM `test` WHERE `id` > ? AND (JSON_EXTRACT(`j`, \"$.a.*.c\") IS NOT NULL OR JSON_TYPE(`j`, \"$.a.*.c\") = 'null') AND `active`",
wantQuery: "SELECT * FROM `test` WHERE `id` > ? AND JSON_TYPE(`j`, \"$.a.*.c\") IS NOT NULL AND `active`",
wantArgs: []any{100},
},
{