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);
  }