2016-07-25 4 views
0

После изменения таблицы для использования timestamptz для всех столбцов времени я вижу очень странное поведение, когда выбираю в зависимости от временного диапазона. Когда часовой пояс пользователя - это UTC, он работает, результат правильный. Когда часовой пояс пользователя не является UTC, результат равен нулю. Я ожидаю, что результат не должен зависеть от часового пояса пользователя.Столб postgres timestamptz и часовой пояс пользователя

set timezone = 'UTC'; 

select count(*) 
from table1 
where modified >= timestamp '2016-07-25 08:00' at time zone 'GB' 
    and modified < timestamp '2016-07-25 09:00' at time zone 'GB' 
; 

set timezone = 'GB'; 

select count(*) 
from table1 
where modified >= timestamp '2016-07-25 08:00' at time zone 'GB' 
    and modified < timestamp '2016-07-25 09:00' at time zone 'GB' 
; 

В пояснении запроса я вижу, что константы преобразования Postgres корректно. В первом случае (UTC) она показывает

'2016-07-25 07:00:00+00'::timestamp with timezone 
'2016-07-25 08:00:00+00'::timestamp with timezone 

Второй случай (GB) показывает

'2016-07-25 08:00:00+01'::timestamp with timezone 
'2016-07-25 09:00:00+01'::timestamp with timezone 

Что еще более странно, он не работает полностью только тогда, когда разница во времени один час. При фильтрации в течение двух часов с 8:00 до 10:00 запрос возвращает ненулевой результат. Он работает следующим образом

count(*) from 08:00 to 09:00 - zero 
count(*) from 09:00 to 10:00 - zero 
count(*) from 08:00 to 10:00 = actual count from 09:00 to 10:00 

Похоже, что есть ошибка в конверсиях диапазона. Время начала конвертируется, но время окончания - нет.

Интересно, видел ли кто-нибудь этот вопрос раньше. Postgres - 9.3.4, работающий на Ubuntu.

Определение modified колонки

... 
modified timestamp with time zone NOT NULL DEFAULT now(), 
... 

EXPLAIN

Aggregate (cost=374.84..374.85 rows=1 width=0) 
    Output: count(*) 
    -> Index Only Scan using modified_idx on public.table1 (cost=0.56..362.14 rows=5079 width=0) 
     Output: modified 
     Index Cond: ((table1.modified >= '2016-07-25 08:00:00+01'::timestamp with time zone) AND (table1.modified < '2016-07-25 09:00:00+01'::timestamp with time zone)) 
+0

Просьба показать определение 'table1'. Если column 'modified' имеет тип' timestamp', его значение изменится при изменении часового пояса. –

+0

@LaurenzAlbe Я исправил вопрос с определением столбца – Alsin

+0

Это выглядит невозможно. Можете ли вы разместить вывод 'EXPLAIN (VERBOSE)'? –

ответ

0

Это кажется невозможным, и единственное объяснение, которое приходит на ум, что индекс поврежден.

REINDEX INDEX modified_idx; 

будет перестраивать индекс, надеюсь, это устранит проблему.

Смежные вопросы