Postgres 中的 SHA256 函数行为

SHA256 function behavior in Postgres

当我在 Postgres 中调用 sha256('abc') 函数时,它 returns 传递值的散列作为 bytea 作为该函数的结果。

SELECT sha256('abc'); -- Works as expected

但是,当我有一个自定义函数接受 text 作为输入参数并在该函数中执行完全相同的操作时:

CREATE OR REPLACE FUNCTION hash_text(input text) RETURNS bytea
LANGUAGE plpgsql
AS
$$
DECLARE
  res bytea;
BEGIN
  SELECT sha256(input) INTO res;
  RETURN res;
END
$$

-- Executing the function above
SELECT hash_text('abc');

我遇到以下异常:

SQL Error [42883]: ERROR: function sha256(text) does not exist Hint: No function matches the given name and argument types. You might need to add explicit type casts. Where: PL/pgSQL function hash_text(text) line 5 at SQL statement

我查看了官方 docs,似乎 sha256 正在接受 bytea 作为输入参数。令我困惑的是,当我直接传递 'abc' 值时它有效,但当该值通过函数参数传递时它不起作用?让我感到困惑的第二件事是,当我在该函数中转换 input::bytea 时,为什么会产生不同的结果?我在这里错过了什么?

我是 Postgres 的新手,所以我可能遗漏了一些明显的东西。

您需要输入强制转换

CREATE OR REPLACE FUNCTION hash_text(input text) RETURNS text
LANGUAGE plpgsql
AS
$$
DECLARE
  res text;
BEGIN
  SELECT encode(sha256(input::bytea),  'escape') INTO res;
  RETURN res;
END
$$

-- Executing the function above
SELECT hash_text('abc');
| hash_text                                                                        |
| :------------------------------------------------------------------------------- |
| 2x7772AA@6]6"#0a36z447a2[=13=]05 |
SELECT encode(sha256('abc'),  'escape')
| encode                                                                           |
| :------------------------------------------------------------------------------- |
| 2x7772AA@6]6"#0a36z447a2[=13=]05 |

db<>fiddle here

我不确定是否有更简单的方法,但这种格式将其转换为 bytea 我想看到的结果。感谢@nbk 引导我找到这个解决方案。

CREATE OR REPLACE FUNCTION hash_text(input text) RETURNS bytea
LANGUAGE plpgsql
AS
$$
DECLARE
  res bytea;
BEGIN
  SELECT encode(sha256(input::bytea), 'escape')::bytea INTO res;
  RETURN res;
END
$$

What confuses me is the fact it works when I pass 'abc' value directly, but doesn't work when that value is coming through the function parameter?

文字 'abc' 是未知类型。所以它着眼于它是如何被用来决定它到底是什么类型的。因为它知道 sha256 接受 bytea 作为输入,所以它将 'abc' 视为 bytea 类型。

就您的函数而言,它不是未知类型。它被明确声明为文本类型。它不会隐式地将文本转换为 bytea。

The second thing that confuses me is why does it yield different result when I convert input::bytea in that function?

它会产生什么不同的结果?在我的手中,你的带有显式转换的函数给出了与直接调用时 sha256 相同的答案。