Использование Gapfill Timescale DB с аргументом throw в JOOQ: start не может быть NULL - PullRequest
4 голосов
/ 25 марта 2020

У меня работает Timescale DB, и я использую JOOQ для доступа к данным.

Я использую gapfill() для

dslContext
        .select(Routines.timeBucketGapfill5(
                Routines.createInterval(DURATION), table.TIME, null, null).as(FieldName.TIME_BUCKET),
                ifnull(count(table.STATUS), 0).as(FieldName.STATUS))
        .from(table)
        .where(table.ID.in(ids)
                .and(table.TIME.ge(Timestamp.from(Instant.now().minus(Duration.ofSeconds(DURATION)))))
                .and(table.TIME.le(Timestamp.from(Instant.now())))
                .and(table.STATUS.eq(status)))
        .groupBy(field(FieldName.TIME_BUCKET))
        .fetch()

Иногда я получаю

org.postgresql.util.PSQLException: ERROR: invalid time_bucket_gapfill argument: start cannot be NULL
  Hinweis: You can either pass start and finish as arguments or in the WHERE clause

Как может start быть НЕДЕЙСТВИТЕЛЬНЫМ, если у меня всегда есть предложение where с moreEquals и lessEquals?

Мне удалось зарегистрировать оператор SQL. Если я запускаю этот запрос непосредственно в БД, он работает нормально.

select "public"."time_bucket_gapfill"("bucket_width" := cast("public"."create_interval"("seconds" := 43200) as "pg_catalog"."interval"), "ts" := cast("public"."device_health"."time" as timestamp), "start" := cast(null as timestamp), "finish" := cast(null as timestamp)) as "time_bucket", coalesce(count("public"."device_health"."health"), 0) as "health" from "public"."device_health" where ("public"."device_health"."device" in ('700004', '700009', '700008', '700005', '700007', '700000', '700003', '700001', '700002', '700006') and "public"."device_health"."time" >= timestamp '2020-03-11 13:59:20.0564238' and "public"."device_health"."time" <= timestamp '2020-03-25 13:59:20.0564238' and "public"."device_health"."health" = 'OK') group by time_bucket

Ответы [ 2 ]

2 голосов
/ 25 марта 2020

Вы видите ту же ошибку, если передаете те же аргументы, что и необязательные аргументы start и finish в вызове gapfill? Можете ли вы захватить фактический SQL, который синтезирует JOOQ?

(Если не считать дополнительной справки, вы можете найти slack.timescale.com полезным.)

1 голос
/ 26 марта 2020

Чтобы исправить проблему, я теперь передаю start и finish как JOOQ DSL.val() в виде Field<Timestamp> и удаляю часть start / fini sh из предложения where.

I Понятия не имею, что именно вызывает ошибку, но это исправляет ее.

Вот рабочий код:


var now = Instant.now();
Timestamp startTimestamp = Timestamp.from(now.minus(Duration.ofSeconds(DURATION)));
Timestamp finishTimestamp = Timestamp.from(now);

dslContext
        .select(Routines.timeBucketGapfill5(
                        Routines.createInterval(DURATION),
                        table.TIME,
                        DSL.val(startTimestamp),
                        DSL.val(finishTimestamp))
                                .as(FieldName.TIME_BUCKET),
                        table.HEALTH,
                        ifnull(count(table.STATUS), 0).as(FieldName.STATUS))
                .from(table)
                .where(table.ID.in(ids))
                .groupBy(field(FieldName.TIME_BUCKET))
                .fetch();
...