Estou enfrentando um problema absolutamente estranho que parece mais um bug do Postgres do que um problema de algoritmo.
Eu tenho esta função:
CREATE FUNCTION sp_connect(mail character varying, passwd character varying, role character varying)
RETURNS json LANGUAGE plpgsql STABLE AS
$$
DECLARE
user_info record;
BEGIN
IF role = 'Role1' THEN
SELECT u.id, r.name INTO user_info
FROM users u
INNER JOIN users_roles ur ON ur.user_id = u.id
INNER JOIN roles r ON ur.role_id = r.id
WHERE u.email = mail
AND u.password = encode(digest(CONCAT(passwd, u.password_salt), 'sha512'), 'hex')
AND r.name = 'Role1';
ELSIF role = 'Role2' THEN
SELECT h.id, 'Role1' AS name INTO user_info
FROM history h
WHERE h.email = mail
AND h.password = encode(digest(CONCAT(passwd, h.password_salt), 'sha512'), 'hex');
ELSE
RAISE 'USER_NOT_FOUND';
END IF;
IF NOT FOUND THEN
RAISE 'USER_NOT_FOUND';
ELSE
RETURN row_to_json(row) FROM (SELECT user_info.id AS id, user_info.name AS role) row;
END IF;
END;
$$;
O problema que estou enfrentando é quando uso essa função para fazer login com um usuário Role1 e, quando a uso com um usuário Role2, recebo esta mensagem de erro:
type of parameter 7 (character varying) does not match that when preparing the plan (unknown)
O que é... bem, eu só não entendo de onde isso vem. Se você limpar o banco de dados e alterar a ordem de login (ou seja, Role2 e depois Role1), desta vez, Role1 receberá o erro.
Problema estranho, soluções estranhas ... Se eu apenas usar, ALTER FUNCTION sp_connect
mas sem modificar nada dentro da função, então magicamente, as duas funções podem fazer login sem nenhum problema. Eu também tentei esta solução:
IF NOT FOUND THEN
RAISE 'USER_NOT_FOUND';
ELSE
IF role = 'Seeker'
THEN
RETURN row_to_json(row) FROM (SELECT user_info.id AS id, user_info.name AS role) row;
ELSE
RETURN row_to_json(row) FROM (SELECT user_info.id AS id, user_info.name AS role) row;
END IF;
E adicionando um IF
e ELSE
isso é absolutamente inútil e usa a mesma cláusula RETURN, isso não aciona nenhum erro.
Eu sei que o DBA StackExchange não é para desenvolvedores, mas esse tipo de problema parece ser mais um problema de cache ou algo assim. Alguém pode me dizer se estou fazendo algo errado com as funções do PostgreSQL? Ou onde posso obter ajuda com esse problema estranho?