简单的解决方案!添加“\n”。
SELECT encode(digest((x::text||E'\n')::bytea, 'sha1'), 'hex') FROM xtmp;
但真正的问题是获取原始文件而不剪切最后一个“\n”(最后一个 EOL)...让我们看看该函数我的旧测试套件 https://stackoverflow.com/q/48327289/287948:
INSERT INTO xtmp (x)
SELECT array_to_string(array_agg(x),E'\n')::xml FROM ttmp
;
这就是“错误”(解决之后COPY
不会将完整文件加载到一行一个字段中)。
The array_to_string()
不添加最后一个 EOL,因此通过连接|| E'\n'
修复了该错误。
NOTES
检查其他假设并为测试套件提供良好的解决方案。
POSIX 规则不是问题...
行尾 (EOL) 是 POSIX 文件系统(和非二进制模式)的义务,请参阅这个关于 EOL 的答案 https://stackoverflow.com/a/729795/287948。我们可以想象类似“字符串和文件表示因 EOL 不同而不同”之类的内容...我们可以检查吗?有什么不同吗?
我们可以通过终端来证明有no“细绳vsfile”问题,EOL没有奇怪的瘾:
printf "<root/>" > original1.xml
printf "<root/>\n" > original2.xml
sha1sum original*.xml
printf "<root/>" | openssl sha1
printf "<root/>\n" | openssl sha1
results
062c3db8ce3458fc3ccaf2f930bf663d8ce31d7d original1.xml
a05d91cbf0902b0fe341c979e9fc18fc69813f55 original2.xml
(stdin)= 062c3db8ce3458fc3ccaf2f930bf663d8ce31d7d
(stdin)= a05d91cbf0902b0fe341c979e9fc18fc69813f55
So sha1sum
没有使用额外的 EOL,字符串和文件就是一些。
现在在 SQL 上,同样的结论:
SELECT encode(digest('<root/>'::bytea, 'sha1'), 'hex') ;
SELECT encode(digest(E'<root/>\n'::bytea, 'sha1'), 'hex') ;
results
062c3db8ce3458fc3ccaf2f930bf663d8ce31d7d
a05d91cbf0902b0fe341c979e9fc18fc69813f55
更好的测试套件的解决方案
The COPY
这个简单的命令很难看加载/保存文本过程中,让我们使用直接的 getfile 函数来代替:
CREATE FUNCTION getfile(p_file text) RETURNS text AS $$
with open(args[0],"r") as content_file:
content = content_file.read()
return content
$$ LANGUAGE PLpythonU;
SELECT encode(digest( getfile('/tmp/original1.xml') ::bytea, 'sha1'), 'hex') ;
SELECT encode(digest( getfile('/tmp/original2.xml') ::bytea, 'sha1'), 'hex') ;
results
062c3db8ce3458fc3ccaf2f930bf663d8ce31d7d
a05d91cbf0902b0fe341c979e9fc18fc69813f55
完美(!),现在没有 EOL 问题。