Простое решение! Добавьте "\n".
SELECT encode(digest((x::text||E'\n')::bytea, 'sha1'), 'hex') FROM xtmp;
Но реальная проблема заключается в том, чтобы получить исходный файл без вырезания последнего "\n" (последний EOL)... Давайте посмотрим на функцию в my старый тестовый набор:
INSERT INTO xtmp (x)
SELECT array_to_string(array_agg(x),E'\n')::xml FROM ttmp
;
Именно здесь "ошибка" (после обхода COPY
, который не загружает полный файл в одну строку одного поля).
array_to_string()
не добавляет последний EOL, поэтому объединение с помощью || E'\n'
устранило ошибку.
ЗАМЕТКИ
Проверка другой гипотезы и предложение хорошего решения для тестового набора.
Правило POSIX не проблема...
Конец строки (EOL) является обязательным для файловых систем POSIX (и недвоичного режима), см. этот ответ о EOL а>. Мы можем представить что-то вроде «представления строк и файлов различаются на EOL»… Мы можем проверить? отличается?
С помощью терминала мы можем продемонстрировать, что нет проблемы "строка vs файл", нет странной зависимости от EOL:
printf "<root/>" > original1.xml
printf "<root/>\n" > original2.xml
sha1sum original*.xml
printf "<root/>" | openssl sha1
printf "<root/>\n" | openssl sha1
полученные результаты
062c3db8ce3458fc3ccaf2f930bf663d8ce31d7d original1.xml
a05d91cbf0902b0fe341c979e9fc18fc69813f55 original2.xml
(stdin)= 062c3db8ce3458fc3ccaf2f930bf663d8ce31d7d
(stdin)= a05d91cbf0902b0fe341c979e9fc18fc69813f55
Таким образом, sha1sum
не использует дополнительный EOL, строка и файл - это некоторые.
Теперь по SQL те же выводы:
SELECT encode(digest('<root/>'::bytea, 'sha1'), 'hex') ;
SELECT encode(digest(E'<root/>\n'::bytea, 'sha1'), 'hex') ;
полученные результаты
062c3db8ce3458fc3ccaf2f930bf663d8ce31d7d
a05d91cbf0902b0fe341c979e9fc18fc69813f55
Решение для лучшего тестового набора
Команда 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') ;
полученные результаты
062c3db8ce3458fc3ccaf2f930bf663d8ce31d7d
a05d91cbf0902b0fe341c979e9fc18fc69813f55
Отлично (!), теперь нет проблем с EOL.
person
Community
schedule
28.01.2018