提交 f8afec06 编写于 作者: I Ivan Leskin 提交者: Ashwin Agrawal

Fix ZSTD compression error "dst buffer too small"

When ZSTD compression is used for AO CO tables, insertion of data may cause an
error "Destination buffer is too small". This happens when compressed data is
larger than uncompressed input data.

This commit adds handling of this situation: do not change output buffer and
return size used equal to source size. The caller (e.g.,
'cdbappendonlystoragewrite.c') is able to handle such output; in this case, it
copies data from input to output itself.
上级 e90a3bdd
......@@ -13158,7 +13158,7 @@ fi
fi
# Check for zstd.h
# Check for zstd.h and zstd_errors.h
if test "$with_zstd" = yes; then
ac_fn_c_check_header_mongrel "$LINENO" "zstd.h" "ac_cv_header_zstd_h" "$ac_includes_default"
if test "x$ac_cv_header_zstd_h" = xyes; then :
......@@ -13168,6 +13168,14 @@ else
fi
ac_fn_c_check_header_mongrel "$LINENO" "zstd_errors.h" "ac_cv_header_zstd_errors_h" "$ac_includes_default"
if test "x$ac_cv_header_zstd_errors_h" = xyes; then :
else
as_fn_error $? "header file <zstd_errors.h> is required for zstd support" "$LINENO" 5
fi
fi
if test "$with_gssapi" = yes ; then
......
......@@ -1542,6 +1542,7 @@ fi
# Check for zstd.h
if test "$with_zstd" = yes; then
AC_CHECK_HEADER(zstd.h, [], [AC_MSG_ERROR([header file <zstd.h> is required for zstd support])])
AC_CHECK_HEADER(zstd_errors.h, [], [AC_MSG_ERROR([header file <zstd_errors.h> is required for zstd support])])
fi
if test "$with_gssapi" = yes ; then
......@@ -1648,7 +1649,7 @@ fi
if test "$PORTNAME" = "win32" ; then
AC_CHECK_HEADERS(crtdefs.h)
fi
fi
# OpenBSD requires libexecinfo from ports for backtrace() as it's a glibc addition
if test "$PORTNAME" = "openbsd"; then
......
......@@ -16,6 +16,7 @@
#include "utils/builtins.h"
#include <zstd.h>
#include <zstd_errors.h>
Datum zstd_constructor(PG_FUNCTION_ARGS);
Datum zstd_destructor(PG_FUNCTION_ARGS);
......@@ -83,6 +84,12 @@ zstd_destructor(PG_FUNCTION_ARGS)
PG_RETURN_VOID();
}
/*
* zstd compression implementation
*
* Note that when compression fails due to algorithm inefficiency,
* dst_used is set so src_sz, but the output buffer contents are left unchanged
*/
Datum
zstd_compress(PG_FUNCTION_ARGS)
{
......@@ -104,7 +111,16 @@ zstd_compress(PG_FUNCTION_ARGS)
if (ZSTD_isError(dst_length_used))
{
elog(ERROR, "%s", ZSTD_getErrorName(dst_length_used));
if (ZSTD_getErrorCode(dst_length_used) == ZSTD_error_dstSize_tooSmall) {
/*
* This error is returned when "compressed" output is bigger than
* uncompressed input.
* The caller can detect this by checking dst_used >= src_size
*/
dst_length_used = src_sz;
}
else
elog(ERROR, "%s", ZSTD_getErrorName(dst_length_used));
}
*dst_used = (int32) dst_length_used;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册