Неправильная вставка bigint в столбец JSONB при использовании pgAdmin 4 - PullRequest
0 голосов
/ 03 апреля 2019

Я наблюдаю странное поведение при вставке значений jsonb, имеющих поле bigint. В соответствии с doc jsonb поддерживает числовой тип данных, поэтому это не должно быть проблемой.

Таблица:

CREATE TABLE document_wrapper
(
    id integer NOT NULL,
    document jsonb NOT NULL,
    CONSTRAINT document_pkey PRIMARY KEY (id)
)
WITH (
    OIDS = FALSE
)
TABLESPACE pg_default;

Образец вставки:

insert into document_wrapper(id, document) values(-8, '{"id":101861191707868275}');

Теперь при запросе документа:

SELECT document FROM document_wrapper;

дает результат (примечание 0 в конце):

{ "id": 101861191707868270 }

Но когда я выбираю из него фактическое значение идентификатора, оно корректно в каждом из этих случаев:

SELECT
    (document->'id')::text, 
    jsonb_extract_path_text(d.document, 'id') , 
    (document #>> '{id}')::bigint, 
    (document->>'id')::numeric, 
    (document->'id')::bigint
FROM document_wrapper d 
WHERE id = -8 ;

Результат равен 101861191707868275 в каждом случае.

Почему значение, видимое в json, отличается от того, которое было вставлено туда изначально? Это вызывает проблемы при отправке json в бэкэнд-приложение, которое получает неправильное значение.

Версия Posgres: PostgreSQL 11.2 для x86_64-pc-linux-gnu, скомпилированный gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36), 64-битный

Обновление: код работает правильно с помощью инструмента psql. Проблема возникает в pgAdmin и приложении (драйвер https://mvnrepository.com/artifact/org.postgresql/postgresql версия 42.2.5)

1 Ответ

0 голосов
/ 03 апреля 2019

Так что проблема на самом деле была в Java-скрипте.Проблема проявляется только в веб-приложениях (webapp pg_admin, внешний интерфейс приложения).Переданный номер расширенный js-es Number.MAX_SAFE_INTEGER, в результате чего число было округлено.Глупо с моей стороны полагать, что бэкэнд возвращает неверные данные, основываясь на поиске ответа в браузере (который уже был округлен).

В качестве обходного пути я изменил число на строку

...