Skip to content

Commit f843e3a

Browse files
committed
Add support for date_bin (available in postgres >= 14)
1 parent 5ff8dc1 commit f843e3a

File tree

5 files changed

+58
-28
lines changed

5 files changed

+58
-28
lines changed

addons/joda-time/src/test/scala/com/github/tminglei/slickpg/PgDateSupportJodaSuite.scala

+9-1
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ class PgDateSupportJodaSuite extends AnyFunSuite with PostgresContainer {
145145
Datetimes.filter(_.id === 101L.bind).map(r => r.datetime.trunc("day")).result.head.map(
146146
r => assert(LocalDateTime.parse("2001-01-03T00:00:00") === r)
147147
),
148+
// dateBin
149+
DBIO.seq(Option.when(pgVersion.take(2).toInt >= 14)(Datetimes.filter(_.id === 101L.bind).map(r => r.datetime.dateBin("1 hour", LocalDateTime.parse("2001-01-03T18:35:17"))).result.head.map(
150+
r => assert(LocalDateTime.parse("2001-01-03T12:35:17") === r)
151+
)).toSeq:_*),
148152
// isFinite
149153
Datetimes.filter(_.id === 101L.bind).map(r => r.datetime.isFinite).result.head.map(
150154
r => assert(true === r)
@@ -204,7 +208,11 @@ class PgDateSupportJodaSuite extends AnyFunSuite with PostgresContainer {
204208
// trunc
205209
Datetimes.filter(_.id === 101L.bind).map(r => r.datetimetz.trunc("day")).result.head.map(
206210
r => assert(DateTime.parse("2001-01-03 00:00:00.000+08", jodaTzDateTimeFormatter) === r)
207-
)
211+
),
212+
// dateBin
213+
DBIO.seq(Option.when(pgVersion.take(2).toInt >= 14)(Datetimes.filter(_.id === 101L.bind).map(r => r.datetimetz.dateBin("1 hour", DateTime.parse("2001-01-02T18:35:17+08"))).result.head.map(
214+
r => assert(DateTime.parse("2001-01-03 12:35:17.000+08", jodaTzDateTimeFormatter) === r)
215+
)).toSeq:_*)
208216
),
209217
// update and check
210218
DBIO.seq(

core/src/main/scala/com/github/tminglei/slickpg/date/PgDateExtensions.scala

+4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ trait PgDateExtensions extends JdbcTypesComponent { driver: PostgresProfile =>
1818
val Age = new SqlFunction("age")
1919
val Part = new SqlFunction("date_part")
2020
val Trunc = new SqlFunction("date_trunc")
21+
val DateBin = new SqlFunction("date_bin")
2122
val IsFinite = new SqlFunction("isfinite")
2223

2324
val JustifyDays = new SqlFunction("justify_days")
@@ -65,6 +66,9 @@ trait PgDateExtensions extends JdbcTypesComponent { driver: PostgresProfile =>
6566
def trunc[R](field: Rep[String])(implicit om: o#to[TIMESTAMP, R]) = {
6667
om.column(DateLibrary.Trunc, field.toNode, n)
6768
}
69+
def dateBin[R](step: Rep[String], base: Rep[TIMESTAMP])(implicit om: o#to[TIMESTAMP, R]) = {
70+
om.column(DateLibrary.DateBin, step.toNode, n, base.toNode)
71+
}
6872
def isFinite[R](implicit om: o#to[Boolean, R]) = om.column(DateLibrary.IsFinite, n)
6973

7074
def atTimeZone[R](tz: Rep[String])(implicit om: o#to[TIMESTAMP_TZ, R]) =
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,29 @@
11
Supported Date/Time Oper/Functions
22
---------------------------------
33

4-
| Slick Oper/Function | PG Oper/Function | Description | Example | Result |
5-
| ------------------- | ---------------- | ----------------------- | ---------------------------------------------- | ------------------------ |
6-
| +++ | + | timestamp + interval | timestamp '2001-09-28 01:00' + interval '23 hours'|timestamp '2001-09-29 00:00:00'|
7-
| - | - | timestamp - timestamp | timestamp '2001-09-29 03:00' - timestamp '2001-09-27 12:00'|interval '1 day 15:00:00'|
8-
| -- | - | timestamp - time | timestamp '2001-09-29 03:00' - time '03:00' | timestamp '2001-09-29 00:00'|
9-
| --- | - | timestame - interval | timestamp '2001-09-28 23:00' - interval '23 hours'|timestamp '2001-09-28 00:00:00'|
10-
| age | age | age(timestamp[, timestamp])| age(timestamp '2001-04-10', timestamp '1957-06-13')|43 years 9 mons 27 days|
11-
| age | age | age(timestamp) | age(timestamp '1957-06-13') | 43 years 9 mons 27 days |
12-
| part | date_part/extract| date_part(text, timestamp) | date_part('hour', timestamp '2001-02-16 20:38:40') | 20 |
13-
| trunc | date_trunc | date_trunc(text, timestamp)| date_trunc('hour', timestamp '2001-02-16 20:38:40') | 2001-02-16 20:00:00 |
14-
| + | + | date + time | date '2001-09-28' + time '03:00' | timestamp '2001-09-28 03:00:00' |
15-
| ++ | + | date + int | date '2001-10-01' - integer '7' | date '2001-09-24' |
16-
| +++ | + | date + interval | date '2001-09-28' + interval '1 hour' | timestamp '2001-09-28 01:00:00' |
17-
| - | - | date - date | date '2001-10-01' - date '2001-09-28' | integer '3' (days) |
18-
| -- | - | date - int | date '2001-10-01' - integer '7' | date '2001-09-24' |
19-
| --- | - | date - interval | date '2001-09-28' - interval '1 hour' | timestamp '2001-09-27 23:00:00' |
20-
| + | + | time + date | time '03:00' + date '2001-09-28' | timestamp '2001-09-28 03:00:00' |
21-
| +++ | + | time + interval | time '05:00' - interval '2 hours' | time '03:00:00' |
22-
| - | - | time - time | time '05:00' - time '03:00' | interval '02:00:00' |
23-
| --- | - | time - interval | time '05:00' - interval '2 hours' | time '03:00:00' |
24-
| + | + | interval + interval | interval '1 day' + interval '1 hour' | interval '1 day 01:00:00' |
25-
| unary_- | - | - interval | - interval '23 hours' | interval '-23:00:00' |
26-
| - | - | interval - interval | interval '1 day' - interval '1 hour' | interval '1 day -01:00:00' |
27-
| * | * | interval * factor | double precision '3.5' * interval '1 hour'| interval '03:30:00' |
28-
| / | / | interval / factor | interval '1 hour' / double precision '1.5'| interval '00:40:00' |
4+
| Slick Oper/Function | PG Oper/Function | Description | Example | Result |
5+
|---------------------|-------------------|--------------------------------------|--------------------------------------------------------------------------------------|---------------------------------|
6+
| +++ | + | timestamp + interval | timestamp '2001-09-28 01:00' + interval '23 hours' | timestamp '2001-09-29 00:00:00' |
7+
| - | - | timestamp - timestamp | timestamp '2001-09-29 03:00' - timestamp '2001-09-27 12:00' | interval '1 day 15:00:00' |
8+
| -- | - | timestamp - time | timestamp '2001-09-29 03:00' - time '03:00' | timestamp '2001-09-29 00:00' |
9+
| --- | - | timestame - interval | timestamp '2001-09-28 23:00' - interval '23 hours' | timestamp '2001-09-28 00:00:00' |
10+
| age | age | age(timestamp[, timestamp]) | age(timestamp '2001-04-10', timestamp '1957-06-13') | 43 years 9 mons 27 days |
11+
| age | age | age(timestamp) | age(timestamp '1957-06-13') | 43 years 9 mons 27 days |
12+
| part | date_part/extract | date_part(text, timestamp) | date_part('hour', timestamp '2001-02-16 20:38:40') | 20 |
13+
| trunc | date_trunc | date_trunc(text, timestamp) | date_trunc('hour', timestamp '2001-02-16 20:38:40') | 2001-02-16 20:00:00 |
14+
| dateBin | date_bin | date_bin(text, timestamp, timestamp) | date_bin('1 hour', timestamp '2001-02-16 20:38:40', timestamp '2001-02-16 18:35:17') | 2001-02-16 20:35:17 |
15+
| + | + | date + time | date '2001-09-28' + time '03:00' | timestamp '2001-09-28 03:00:00' |
16+
| ++ | + | date + int | date '2001-10-01' - integer '7' | date '2001-09-24' |
17+
| +++ | + | date + interval | date '2001-09-28' + interval '1 hour' | timestamp '2001-09-28 01:00:00' |
18+
| - | - | date - date | date '2001-10-01' - date '2001-09-28' | integer '3' (days) |
19+
| -- | - | date - int | date '2001-10-01' - integer '7' | date '2001-09-24' |
20+
| --- | - | date - interval | date '2001-09-28' - interval '1 hour' | timestamp '2001-09-27 23:00:00' |
21+
| + | + | time + date | time '03:00' + date '2001-09-28' | timestamp '2001-09-28 03:00:00' |
22+
| +++ | + | time + interval | time '05:00' - interval '2 hours' | time '03:00:00' |
23+
| - | - | time - time | time '05:00' - time '03:00' | interval '02:00:00' |
24+
| --- | - | time - interval | time '05:00' - interval '2 hours' | time '03:00:00' |
25+
| + | + | interval + interval | interval '1 day' + interval '1 hour' | interval '1 day 01:00:00' |
26+
| unary_- | - | - interval | - interval '23 hours' | interval '-23:00:00' |
27+
| - | - | interval - interval | interval '1 day' - interval '1 hour' | interval '1 day -01:00:00' |
28+
| * | * | interval * factor | double precision '3.5' * interval '1 hour' | interval '03:30:00' |
29+
| / | / | interval / factor | interval '1 hour' / double precision '1.5' | interval '00:40:00' |

src/test/scala/com/github/tminglei/slickpg/PgDate2SupportSuite.scala

+9-1
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ class PgDate2SupportSuite extends AnyFunSuite with PostgresContainer {
162162
Datetimes.filter(_.id === 101L.bind).map(r => r.dateTime.trunc("day")).result.head.map(
163163
r => assert(LocalDateTime.parse("2001-01-03T00:00:00") === r)
164164
),
165+
// dateBin
166+
DBIO.seq(Option.when(pgVersion.take(2).toInt >= 14)(Datetimes.filter(_.id === 101L.bind).map(r => r.dateTime.dateBin("1 hour", LocalDateTime.parse("2001-01-03T18:35:17"))).result.head.map(
167+
r => assert(LocalDateTime.parse("2001-01-03T12:35:17") === r)
168+
)).toSeq:_*),
165169
// isFinite
166170
Datetimes.filter(_.id === 101L.bind).map(r => r.dateTime.isFinite).result.head.map(
167171
r => assert(true === r)
@@ -223,7 +227,11 @@ class PgDate2SupportSuite extends AnyFunSuite with PostgresContainer {
223227
),
224228
Datetimes.filter(_.id === 101L.bind).map(r => r.dateTimeTz.trunc("day")).result.head.map(
225229
r => assert(ZonedDateTime.parse("2001-01-03 00:00:00+08", date2TzDateTimeFormatter) === r)
226-
)
230+
),
231+
// dateBin
232+
DBIO.seq(Option.when(pgVersion.take(2).toInt >= 14)(Datetimes.filter(_.id === 101L.bind).map(r => r.dateTimeTz.dateBin("1 hour", ZonedDateTime.parse("2001-01-03 18:35:17+03", date2TzDateTimeFormatter))).result.head.map(
233+
r => assert(ZonedDateTime.parse("2001-01-03 12:35:17+08", date2TzDateTimeFormatter) === r)
234+
)).toSeq:_*)
227235
),
228236
// Timezones
229237
Datetimes.filter(_.id === 101L.bind).map(r => r.zone).result.head.map(

src/test/scala/com/github/tminglei/slickpg/PgDateSupportSuite.scala

+10-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import scala.concurrent.Await
1212
import scala.concurrent.duration._
1313

1414
class PgDateSupportSuite extends AnyFunSuite with PostgresContainer {
15+
1516
import MyPostgresProfile.api._
1617

1718
lazy val db = Database.forURL(url = container.jdbcUrl, driver = "org.postgresql.Driver")
@@ -143,6 +144,10 @@ class PgDateSupportSuite extends AnyFunSuite with PostgresContainer {
143144
Datetimes.filter(_.id === 101L.bind).map(r => r.timestamp.trunc("day")).result.head.map(
144145
r => assert(ts("2001-1-3 00:00:00.0").toLocalDateTime === r.toLocalDateTime)
145146
),
147+
// dateBin
148+
DBIO.seq(Option.when(pgVersion.take(2).toInt >= 14)(Datetimes.filter(_.id === 101L.bind).map(r => r.timestamp.dateBin("1 hour", ts("2001-1-3 18:35:17"))).result.head.map(
149+
r => assert(ts("2001-01-03 12:35:17").toLocalDateTime === r.toLocalDateTime)
150+
)).toSeq: _*),
146151
// isFinite
147152
Datetimes.filter(_.id === 101L.bind).map(r => r.timestamp.isFinite).result.head.map(
148153
r => assert(true === r)
@@ -202,7 +207,11 @@ class PgDateSupportSuite extends AnyFunSuite with PostgresContainer {
202207
// trunc
203208
Datetimes.filter(_.id === 101L.bind).map(r => r.timestamptz.trunc("day")).result.head.map(
204209
r => assert(tstz("2001-01-03T00:00:00+08:00").getTimeInMillis === r.getTimeInMillis)
205-
)
210+
),
211+
// dateBin
212+
DBIO.seq(Option.when(pgVersion.take(2).toInt >= 14)(Datetimes.filter(_.id === 101L.bind).map(r => r.timestamptz.dateBin("1 hour", tstz("2001-01-02T18:35:17+03"))).result.head.map(
213+
r => assert(tstz("2001-01-03T12:35:17+08").getTimeInMillis === r.getTimeInMillis)
214+
)).toSeq: _*)
206215
)
207216
)
208217
).andFinally(

0 commit comments

Comments
 (0)