Токен "(" - недопустимая ошибка при вызове функции, которая присваивается пользовательскому типу, содержащему тип json - PullRequest
0 голосов
/ 02 мая 2018

Я декодирую JWT с Postgresql. Функция test - это упрощенная версия того, что она на самом деле делает. Здесь он показывает сообщение об ошибке, которое я тоже получаю.

CREATE TYPE parts AS (header json, payload json, valid boolean);

CREATE OR REPLACE FUNCTION verify(token text, secret text, algorithm text DEFAULT 'HS256')
RETURNS parts AS $$
  SELECT
    '{"alg": "HS256","typ": "JWT"}'::json AS header,
    '{"id": 1, "exp": 1524683318}'::json AS payload,
    TRUE AS valid;
$$ LANGUAGE sql;

CREATE OR REPLACE FUNCTION test(token text)
RETURNS parts AS $$
  DECLARE
    jwt_parts parts;
  BEGIN
    SELECT verify(test.token, 'secret')
    INTO jwt_parts;

    RETURN jwt_parts;
  END
$$ LANGUAGE plpgsql;

После запуска SELECT test('xx') я получаю сообщение об ошибке (на Postgres v10.1):

ОШИБКА: неверный синтаксис ввода для типа json
ДЕТАЛИ: токен "(" недействителен.
КОНТЕКСТ: данные JSON, строка 1: (...
Строка 5 функционального теста PL / pgSQL в операторе SQL

Я бы хотел SELECT ... INTO мой пользовательский тип parts. Я перепробовал много способов перефразировать, но подозреваю, что это можно сделать гораздо проще, чем то, что я пробовал до сих пор.

PS: реальная функция test(token text), которую я использую, больше и нуждается в языке plpgsql. PS2: Просто чтобы убедиться, что ответы на данный вопрос имеют смысл для людей, посещающих этот вопрос. Оригинальная версия моего вопроса имела такую ​​функцию теста:

CREATE OR REPLACE FUNCTION test(token text)
RETURNS parts AS $$
  DECLARE
    jwt_parts parts;
  BEGIN
    SELECT ('{"alg": "HS256","typ": "JWT"}', '{"id": 1, "exp": 1524683318}', TRUE)
    INTO jwt_parts;

    RETURN jwt_parts;
  END
$$ LANGUAGE plpgsql;

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

Скобки заставляют вас выбрать один столбец (типа строка), где вам фактически нужно три столбца. Например:

select (1,2,3)
>>
   row
--------
 (1,2,3)
(1 row)

Опустите скобки после select:

SELECT ('{"alg": "HS256","typ": "JWT"}', '{"id": 1, "exp": 1524683318}', TRUE)
      ^^^                                                                   ^^^

В ответ на ваш комментарий появляется ошибка в вашем новом запросе:

SELECT verify('xxx', 'yyy')
INTO jwt_parts;

Это снова пытается присвоить один столбец типу с тремя столбцами. Вместо этого вы можете использовать:

SELECT * FROM verify('xxx', 'yyy')
INTO jwt_parts;
0 голосов
/ 02 мая 2018

Вы должны выбрать не кортеж, а обычную строку (убрать скобки):

SELECT '{"alg": "HS256","typ": "JWT"}', '{"id": 1, "exp": 1524683318}', TRUE
...