varlena-avoid-detoast.patch
text/plain
Filename: varlena-avoid-detoast.patch
Type: text/plain
Part: 0
Message:
texteq/byteaeq: avoid detoast
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: context
| File | + | − |
|---|---|---|
| src/backend/utils/adt/varlena.c | 48 | 0 |
*** a/src/backend/utils/adt/varlena.c
--- b/src/backend/utils/adt/varlena.c
***************
*** 1451,1472 **** text_cmp(text *arg1, text *arg2)
Datum
texteq(PG_FUNCTION_ARGS)
{
! text *arg1 = PG_GETARG_TEXT_PP(0);
! text *arg2 = PG_GETARG_TEXT_PP(1);
bool result;
! /*
! * Since we only care about equality or not-equality, we can avoid all the
! * expense of strcoll() here, and just do bitwise comparison.
! */
! if (VARSIZE_ANY_EXHDR(arg1) != VARSIZE_ANY_EXHDR(arg2))
result = false;
else
! result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2),
! VARSIZE_ANY_EXHDR(arg1)) == 0);
!
! PG_FREE_IF_COPY(arg1, 0);
! PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(result);
}
--- 1451,1475 ----
Datum
texteq(PG_FUNCTION_ARGS)
{
! Size len1 = toast_raw_datum_size(PG_GETARG_DATUM(0)) - VARHDRSZ;
! Size len2 = toast_raw_datum_size(PG_GETARG_DATUM(1)) - VARHDRSZ;
bool result;
! /* Fast path for different-length inputs: possibly skip detoast. */
! if (len1 != len2)
result = false;
else
! {
! text *arg1 = PG_GETARG_TEXT_PP(0);
! text *arg2 = PG_GETARG_TEXT_PP(1);
! /*
! * Since we only care about equality or not-equality, we can avoid all the
! * expense of strcoll() here, and just do bitwise comparison.
! */
! result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) == 0);
! PG_FREE_IF_COPY(arg1, 0);
! PG_FREE_IF_COPY(arg2, 1);
! }
PG_RETURN_BOOL(result);
}
***************
*** 1474,1495 **** texteq(PG_FUNCTION_ARGS)
Datum
textne(PG_FUNCTION_ARGS)
{
! text *arg1 = PG_GETARG_TEXT_PP(0);
! text *arg2 = PG_GETARG_TEXT_PP(1);
bool result;
! /*
! * Since we only care about equality or not-equality, we can avoid all the
! * expense of strcoll() here, and just do bitwise comparison.
! */
! if (VARSIZE_ANY_EXHDR(arg1) != VARSIZE_ANY_EXHDR(arg2))
result = true;
else
! result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2),
! VARSIZE_ANY_EXHDR(arg1)) != 0);
!
! PG_FREE_IF_COPY(arg1, 0);
! PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(result);
}
--- 1477,1501 ----
Datum
textne(PG_FUNCTION_ARGS)
{
! Size len1 = toast_raw_datum_size(PG_GETARG_DATUM(0)) - VARHDRSZ;
! Size len2 = toast_raw_datum_size(PG_GETARG_DATUM(1)) - VARHDRSZ;
bool result;
! /* Fast path for different-length inputs: possibly skip detoast. */
! if (len1 != len2)
result = true;
else
! {
! text *arg1 = PG_GETARG_TEXT_PP(0);
! text *arg2 = PG_GETARG_TEXT_PP(1);
! /*
! * Since we only care about equality or not-equality, we can avoid all the
! * expense of strcoll() here, and just do bitwise comparison.
! */
! result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) != 0);
! PG_FREE_IF_COPY(arg1, 0);
! PG_FREE_IF_COPY(arg2, 1);
! }
PG_RETURN_BOOL(result);
}
***************
*** 2358,2380 **** SplitIdentifierString(char *rawstring, char separator,
Datum
byteaeq(PG_FUNCTION_ARGS)
{
! bytea *arg1 = PG_GETARG_BYTEA_PP(0);
! bytea *arg2 = PG_GETARG_BYTEA_PP(1);
! int len1,
! len2;
bool result;
! len1 = VARSIZE_ANY_EXHDR(arg1);
! len2 = VARSIZE_ANY_EXHDR(arg2);
!
! /* fast path for different-length inputs */
if (len1 != len2)
result = false;
else
result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) == 0);
!
! PG_FREE_IF_COPY(arg1, 0);
! PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(result);
}
--- 2364,2384 ----
Datum
byteaeq(PG_FUNCTION_ARGS)
{
! Size len1 = toast_raw_datum_size(PG_GETARG_DATUM(0)) - VARHDRSZ;
! Size len2 = toast_raw_datum_size(PG_GETARG_DATUM(1)) - VARHDRSZ;
bool result;
! /* Fast path for different-length inputs: possibly skip detoast. */
if (len1 != len2)
result = false;
else
+ {
+ bytea *arg1 = PG_GETARG_BYTEA_PP(0);
+ bytea *arg2 = PG_GETARG_BYTEA_PP(1);
result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) == 0);
! PG_FREE_IF_COPY(arg1, 0);
! PG_FREE_IF_COPY(arg2, 1);
! }
PG_RETURN_BOOL(result);
}
***************
*** 2382,2404 **** byteaeq(PG_FUNCTION_ARGS)
Datum
byteane(PG_FUNCTION_ARGS)
{
! bytea *arg1 = PG_GETARG_BYTEA_PP(0);
! bytea *arg2 = PG_GETARG_BYTEA_PP(1);
! int len1,
! len2;
bool result;
! len1 = VARSIZE_ANY_EXHDR(arg1);
! len2 = VARSIZE_ANY_EXHDR(arg2);
!
! /* fast path for different-length inputs */
if (len1 != len2)
result = true;
else
result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) != 0);
!
! PG_FREE_IF_COPY(arg1, 0);
! PG_FREE_IF_COPY(arg2, 1);
PG_RETURN_BOOL(result);
}
--- 2386,2406 ----
Datum
byteane(PG_FUNCTION_ARGS)
{
! Size len1 = toast_raw_datum_size(PG_GETARG_DATUM(0)) - VARHDRSZ;
! Size len2 = toast_raw_datum_size(PG_GETARG_DATUM(1)) - VARHDRSZ;
bool result;
! /* Fast path for different-length inputs: possibly skip detoast. */
if (len1 != len2)
result = true;
else
+ {
+ bytea *arg1 = PG_GETARG_BYTEA_PP(0);
+ bytea *arg2 = PG_GETARG_BYTEA_PP(1);
result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) != 0);
! PG_FREE_IF_COPY(arg1, 0);
! PG_FREE_IF_COPY(arg2, 1);
! }
PG_RETURN_BOOL(result);
}