diff --git a/dialect/sql/builder.go b/dialect/sql/builder.go index 6a9df6433..4875abc2a 100644 --- a/dialect/sql/builder.go +++ b/dialect/sql/builder.go @@ -897,21 +897,6 @@ func (p *Predicate) EQ(col string, arg interface{}) *Predicate { }) } -// JSONHasKey calls Predicate.JSONHasKey. -func JSONHasKey(col string, path string) *Predicate { - return P().JSONHasKey(col, path) -} - -// JSONHasKey return a predicate for checking that a JSON key exists and not NULL. -// -// P().JSONHasKey("column", "a.b[2].c") -// -func (p *Predicate) JSONHasKey(col string, path string) *Predicate { - return p.Append(func(b *Builder) { - b.JSONPath(col, DotPath(path)).WriteOp(OpNotNull) - }) -} - // NEQ returns a "<>" predicate. func NEQ(col string, value interface{}) *Predicate { return P().NEQ(col, value) @@ -982,6 +967,37 @@ func (p *Predicate) GTE(col string, arg interface{}) *Predicate { }) } +// JSONHasKey calls Predicate.JSONHasKey. +func JSONHasKey(col, path string) *Predicate { + return P().JSONHasKey(col, path) +} + +// JSONHasKey return a predicate for checking that a JSON key exists and not NULL. +// +// P().JSONHasKey("column", "a.b[2].c") +// +func (p *Predicate) JSONHasKey(col, path string) *Predicate { + return p.Append(func(b *Builder) { + b.JSONPath(col, DotPath(path)).WriteOp(OpNotNull) + }) +} + +// JSONValueEQ calls Predicate.JSONValueEQ. +func JSONValueEQ(col, path string, arg interface{}) *Predicate { + return P().JSONValueEQ(col, path, arg) +} + +// JSONValueEQ return a predicate for checking that a JSON +// value (returned by the path) is equal to the given argument. +// +// P().JSONValueEQ("column", "a.b[2].c", arg) +// +func (p *Predicate) JSONValueEQ(col, path string, arg interface{}) *Predicate { + return p.Append(func(b *Builder) { + b.JSONPath(col, DotPath(path)).WriteOp(OpEQ).Arg(arg) + }) +} + // NotNull returns the `IS NOT NULL` predicate. func NotNull(col string) *Predicate { return P().NotNull(col) diff --git a/dialect/sql/builder_test.go b/dialect/sql/builder_test.go index 9f986c436..341d899a6 100644 --- a/dialect/sql/builder_test.go +++ b/dialect/sql/builder_test.go @@ -1269,26 +1269,6 @@ WHERE wantQuery: `SELECT * FROM "test" WHERE nlevel("path") > $1`, wantArgs: []interface{}{1}, }, - { - input: Select("*"). - From(Table("test")). - Where(JSONHasKey("j", "a.*.c")), - wantQuery: "SELECT * FROM `test` WHERE JSON_EXTRACT(`j`, \"$.a.*.c\") IS NOT NULL", - }, - { - input: Dialect(dialect.Postgres). - Select("*"). - From(Table("test")). - Where(JSONHasKey("j", "a.b.c")), - wantQuery: `SELECT * FROM "test" WHERE "j"->'a'->'b'->'c' IS NOT NULL`, - }, - { - input: Dialect(dialect.Postgres). - Select("*"). - From(Table("test")). - Where(JSONHasKey("j", "a.b.c")), - wantQuery: `SELECT * FROM "test" WHERE "j"->'a'->'b'->'c' IS NOT NULL`, - }, { input: Dialect(dialect.Postgres). Select("*"). @@ -1325,6 +1305,33 @@ WHERE wantQuery: "SELECT * FROM `users` WHERE JSON_EXTRACT(`a`, \"$.b.\"c[1]\".d[1][2].e\") = ?", wantArgs: []interface{}{"a"}, }, + { + input: Select("*"). + From(Table("test")). + Where(JSONHasKey("j", "a.*.c")), + wantQuery: "SELECT * FROM `test` WHERE JSON_EXTRACT(`j`, \"$.a.*.c\") IS NOT NULL", + }, + { + input: Dialect(dialect.Postgres). + Select("*"). + From(Table("test")). + Where(JSONHasKey("j", "a.b.c")), + wantQuery: `SELECT * FROM "test" WHERE "j"->'a'->'b'->'c' IS NOT NULL`, + }, + { + input: Dialect(dialect.Postgres). + Select("*"). + From(Table("test")). + Where(JSONHasKey("j", "a.b.c")), + wantQuery: `SELECT * FROM "test" WHERE "j"->'a'->'b'->'c' IS NOT NULL`, + }, + { + input: Select("*"). + From(Table("test")). + Where(JSONValueEQ("j", "a.b.c", 1)), + wantQuery: "SELECT * FROM `test` WHERE JSON_EXTRACT(`j`, \"$.a.b.c\") = ?", + wantArgs: []interface{}{1}, + }, } for i, tt := range tests { t.Run(strconv.Itoa(i), func(t *testing.T) {