diff --git a/dialect/sql/builder_test.go b/dialect/sql/builder_test.go index 5600f4914..f2b58f401 100644 --- a/dialect/sql/builder_test.go +++ b/dialect/sql/builder_test.go @@ -1480,6 +1480,34 @@ func TestBuilder(t *testing.T) { wantQuery: `SELECT * FROM "test" WHERE nlevel("path") > $1`, wantArgs: []interface{}{1}, }, + { + input: Select("id").From(Table("users")).Where(ExprP("DATE(last_login_at) >= ?", "2022-05-03")), + wantQuery: "SELECT `id` FROM `users` WHERE DATE(last_login_at) >= ?", + wantArgs: []interface{}{"2022-05-03"}, + }, + { + input: Select("id"). + From(Table("users")). + Where(P(func(b *Builder) { + b.WriteString("DATE(").Ident("last_login_at").WriteString(") >= ").Arg("2022-05-03") + })), + wantQuery: "SELECT `id` FROM `users` WHERE DATE(`last_login_at`) >= ?", + wantArgs: []interface{}{"2022-05-03"}, + }, + { + input: Select("id").From(Table("events")).Where(ExprP("DATE_ADD(date, INTERVAL duration MINUTE) BETWEEN ? AND ?", "2022-05-03", "2022-05-04")), + wantQuery: "SELECT `id` FROM `events` WHERE DATE_ADD(date, INTERVAL duration MINUTE) BETWEEN ? AND ?", + wantArgs: []interface{}{"2022-05-03", "2022-05-04"}, + }, + { + input: Select("id"). + From(Table("events")). + Where(P(func(b *Builder) { + b.WriteString("DATE_ADD(date, INTERVAL duration MINUTE) BETWEEN ").Arg("2022-05-03").WriteString(" AND ").Arg("2022-05-04") + })), + wantQuery: "SELECT `id` FROM `events` WHERE DATE_ADD(date, INTERVAL duration MINUTE) BETWEEN ? AND ?", + wantArgs: []interface{}{"2022-05-03", "2022-05-04"}, + }, { input: func() Querier { t1, t2 := Table("users").Schema("s1"), Table("pets").Schema("s2") diff --git a/doc/md/predicates.md b/doc/md/predicates.md index 3fafbcd0e..74957b03e 100755 --- a/doc/md/predicates.md +++ b/doc/md/predicates.md @@ -89,6 +89,41 @@ client.Pet. Custom predicates can be useful if you want to write your own dialect-specific logic or to control the executed queries. +For example, in order to use built-in SQL functions such as `DATE()`, use one of the following options: + +1. Pass a dialect-aware predicate function using the `sql.P` option: + +```go +users := client.User.Query(). + Select(user.FieldID). + Where(sql.P(func(b *sql.Builder) { + b.WriteString("DATE(").Ident("last_login_at").WriteByte(')').WriteOp(OpGTE).Arg(value) + })). + AllX(ctx) +``` + +The above code will produce the following SQL query: + +```sql +SELECT `id` FROM `users` WHERE DATE(`last_login_at`) >= ? +``` + +2. Inline a predicate expression using the `ExprP()` option: + +```go +users := client.User.Query(). + Select(user.FieldID). + Where(func(s *sql.Selector) { + s.Where(sql.ExprP("DATE(last_login_at >= ?", value)) + }). + AllX(ctx) +``` + +The above code will produce the same SQL query: + +```sql +SELECT `id` FROM `users` WHERE DATE(`last_login_at`) >= ? +``` #### Get all pets of users 1, 2 and 3 ```go