mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Fix varlena.c routines to allow 1-byte-header text values. This is now
demonstrably necessary for text_substring() since regexp_split functions may pass it such a value; and we might as well convert the whole file at once. Per buildfarm results (though I wonder why most machines aren't showing a failure).
This commit is contained in:
		@@ -8,7 +8,7 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * IDENTIFICATION
 | 
					 * IDENTIFICATION
 | 
				
			||||||
 *	  $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.157 2007/07/19 20:34:20 tgl Exp $
 | 
					 *	  $PostgreSQL: pgsql/src/backend/utils/adt/varlena.c,v 1.158 2007/09/22 00:36:38 tgl Exp $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *-------------------------------------------------------------------------
 | 
					 *-------------------------------------------------------------------------
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -689,7 +689,7 @@ text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
 | 
				
			|||||||
			slice = (text *) DatumGetPointer(str);
 | 
								slice = (text *) DatumGetPointer(str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* see if we got back an empty string */
 | 
							/* see if we got back an empty string */
 | 
				
			||||||
		if ((VARSIZE(slice) - VARHDRSZ) == 0)
 | 
							if (VARSIZE_ANY_EXHDR(slice) == 0)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (slice != (text *) DatumGetPointer(str))
 | 
								if (slice != (text *) DatumGetPointer(str))
 | 
				
			||||||
				pfree(slice);
 | 
									pfree(slice);
 | 
				
			||||||
@@ -697,7 +697,8 @@ text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Now we can get the actual length of the slice in MB characters */
 | 
							/* Now we can get the actual length of the slice in MB characters */
 | 
				
			||||||
		slice_strlen = pg_mbstrlen_with_len(VARDATA(slice), VARSIZE(slice) - VARHDRSZ);
 | 
							slice_strlen = pg_mbstrlen_with_len(VARDATA_ANY(slice),
 | 
				
			||||||
 | 
																VARSIZE_ANY_EXHDR(slice));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * Check that the start position wasn't > slice_strlen. If so, SQL99
 | 
							 * Check that the start position wasn't > slice_strlen. If so, SQL99
 | 
				
			||||||
@@ -722,7 +723,7 @@ text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
 | 
				
			|||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * Find the start position in the slice; remember S1 is not zero based
 | 
							 * Find the start position in the slice; remember S1 is not zero based
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		p = VARDATA(slice);
 | 
							p = VARDATA_ANY(slice);
 | 
				
			||||||
		for (i = 0; i < S1 - 1; i++)
 | 
							for (i = 0; i < S1 - 1; i++)
 | 
				
			||||||
			p += pg_mblen(p);
 | 
								p += pg_mblen(p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -762,8 +763,8 @@ text_substring(Datum str, int32 start, int32 length, bool length_not_specified)
 | 
				
			|||||||
Datum
 | 
					Datum
 | 
				
			||||||
textpos(PG_FUNCTION_ARGS)
 | 
					textpos(PG_FUNCTION_ARGS)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	text	   *str = PG_GETARG_TEXT_P(0);
 | 
						text	   *str = PG_GETARG_TEXT_PP(0);
 | 
				
			||||||
	text	   *search_str = PG_GETARG_TEXT_P(1);
 | 
						text	   *search_str = PG_GETARG_TEXT_PP(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	PG_RETURN_INT32((int32) text_position(str, search_str));
 | 
						PG_RETURN_INT32((int32) text_position(str, search_str));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -808,15 +809,15 @@ text_position(text *t1, text *t2)
 | 
				
			|||||||
static void
 | 
					static void
 | 
				
			||||||
text_position_setup(text *t1, text *t2, TextPositionState *state)
 | 
					text_position_setup(text *t1, text *t2, TextPositionState *state)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int			len1 = VARSIZE(t1) - VARHDRSZ;
 | 
						int			len1 = VARSIZE_ANY_EXHDR(t1);
 | 
				
			||||||
	int			len2 = VARSIZE(t2) - VARHDRSZ;
 | 
						int			len2 = VARSIZE_ANY_EXHDR(t2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pg_database_encoding_max_length() == 1)
 | 
						if (pg_database_encoding_max_length() == 1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* simple case - single byte encoding */
 | 
							/* simple case - single byte encoding */
 | 
				
			||||||
		state->use_wchar = false;
 | 
							state->use_wchar = false;
 | 
				
			||||||
		state->str1 = VARDATA(t1);
 | 
							state->str1 = VARDATA_ANY(t1);
 | 
				
			||||||
		state->str2 = VARDATA(t2);
 | 
							state->str2 = VARDATA_ANY(t2);
 | 
				
			||||||
		state->len1 = len1;
 | 
							state->len1 = len1;
 | 
				
			||||||
		state->len2 = len2;
 | 
							state->len2 = len2;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -827,9 +828,9 @@ text_position_setup(text *t1, text *t2, TextPositionState *state)
 | 
				
			|||||||
				   *p2;
 | 
									   *p2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		p1 = (pg_wchar *) palloc((len1 + 1) * sizeof(pg_wchar));
 | 
							p1 = (pg_wchar *) palloc((len1 + 1) * sizeof(pg_wchar));
 | 
				
			||||||
		len1 = pg_mb2wchar_with_len(VARDATA(t1), p1, len1);
 | 
							len1 = pg_mb2wchar_with_len(VARDATA_ANY(t1), p1, len1);
 | 
				
			||||||
		p2 = (pg_wchar *) palloc((len2 + 1) * sizeof(pg_wchar));
 | 
							p2 = (pg_wchar *) palloc((len2 + 1) * sizeof(pg_wchar));
 | 
				
			||||||
		len2 = pg_mb2wchar_with_len(VARDATA(t2), p2, len2);
 | 
							len2 = pg_mb2wchar_with_len(VARDATA_ANY(t2), p2, len2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		state->use_wchar = true;
 | 
							state->use_wchar = true;
 | 
				
			||||||
		state->wstr1 = p1;
 | 
							state->wstr1 = p1;
 | 
				
			||||||
@@ -2094,7 +2095,7 @@ byteacmp(PG_FUNCTION_ARGS)
 | 
				
			|||||||
static void
 | 
					static void
 | 
				
			||||||
appendStringInfoText(StringInfo str, const text *t)
 | 
					appendStringInfoText(StringInfo str, const text *t)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	appendBinaryStringInfo(str, VARDATA(t), VARSIZE(t) - VARHDRSZ);
 | 
						appendBinaryStringInfo(str, VARDATA_ANY(t), VARSIZE_ANY_EXHDR(t));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
@@ -2108,9 +2109,9 @@ appendStringInfoText(StringInfo str, const text *t)
 | 
				
			|||||||
Datum
 | 
					Datum
 | 
				
			||||||
replace_text(PG_FUNCTION_ARGS)
 | 
					replace_text(PG_FUNCTION_ARGS)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	text	   *src_text = PG_GETARG_TEXT_P(0);
 | 
						text	   *src_text = PG_GETARG_TEXT_PP(0);
 | 
				
			||||||
	text	   *from_sub_text = PG_GETARG_TEXT_P(1);
 | 
						text	   *from_sub_text = PG_GETARG_TEXT_PP(1);
 | 
				
			||||||
	text	   *to_sub_text = PG_GETARG_TEXT_P(2);
 | 
						text	   *to_sub_text = PG_GETARG_TEXT_PP(2);
 | 
				
			||||||
	int			src_text_len;
 | 
						int			src_text_len;
 | 
				
			||||||
	int			from_sub_text_len;
 | 
						int			from_sub_text_len;
 | 
				
			||||||
	TextPositionState state;
 | 
						TextPositionState state;
 | 
				
			||||||
@@ -2148,7 +2149,7 @@ replace_text(PG_FUNCTION_ARGS)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* start_ptr points to the start_posn'th character of src_text */
 | 
						/* start_ptr points to the start_posn'th character of src_text */
 | 
				
			||||||
	start_ptr = (char *) VARDATA(src_text);
 | 
						start_ptr = VARDATA_ANY(src_text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	initStringInfo(&str);
 | 
						initStringInfo(&str);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2172,7 +2173,7 @@ replace_text(PG_FUNCTION_ARGS)
 | 
				
			|||||||
	while (curr_posn > 0);
 | 
						while (curr_posn > 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* copy trailing data */
 | 
						/* copy trailing data */
 | 
				
			||||||
	chunk_len = ((char *) src_text + VARSIZE(src_text)) - start_ptr;
 | 
						chunk_len = ((char *) src_text + VARSIZE_ANY(src_text)) - start_ptr;
 | 
				
			||||||
	appendBinaryStringInfo(&str, start_ptr, chunk_len);
 | 
						appendBinaryStringInfo(&str, start_ptr, chunk_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	text_position_cleanup(&state);
 | 
						text_position_cleanup(&state);
 | 
				
			||||||
@@ -2191,8 +2192,8 @@ replace_text(PG_FUNCTION_ARGS)
 | 
				
			|||||||
static bool
 | 
					static bool
 | 
				
			||||||
check_replace_text_has_escape_char(const text *replace_text)
 | 
					check_replace_text_has_escape_char(const text *replace_text)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *p = VARDATA(replace_text);
 | 
						const char *p = VARDATA_ANY(replace_text);
 | 
				
			||||||
	const char *p_end = p + (VARSIZE(replace_text) - VARHDRSZ);
 | 
						const char *p_end = p + VARSIZE_ANY_EXHDR(replace_text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pg_database_encoding_max_length() == 1)
 | 
						if (pg_database_encoding_max_length() == 1)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -2226,8 +2227,8 @@ appendStringInfoRegexpSubstr(StringInfo str, text *replace_text,
 | 
				
			|||||||
							 regmatch_t *pmatch,
 | 
												 regmatch_t *pmatch,
 | 
				
			||||||
							 char *start_ptr, int data_pos)
 | 
												 char *start_ptr, int data_pos)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *p = VARDATA(replace_text);
 | 
						const char *p = VARDATA_ANY(replace_text);
 | 
				
			||||||
	const char *p_end = p + (VARSIZE(replace_text) - VARHDRSZ);
 | 
						const char *p_end = p + VARSIZE_ANY_EXHDR(replace_text);
 | 
				
			||||||
	int			eml = pg_database_encoding_max_length();
 | 
						int			eml = pg_database_encoding_max_length();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (;;)
 | 
						for (;;)
 | 
				
			||||||
@@ -2332,7 +2333,7 @@ replace_text_regexp(text *src_text, void *regexp,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	text	   *ret_text;
 | 
						text	   *ret_text;
 | 
				
			||||||
	regex_t    *re = (regex_t *) regexp;
 | 
						regex_t    *re = (regex_t *) regexp;
 | 
				
			||||||
	int			src_text_len = VARSIZE(src_text) - VARHDRSZ;
 | 
						int			src_text_len = VARSIZE_ANY_EXHDR(src_text);
 | 
				
			||||||
	StringInfoData buf;
 | 
						StringInfoData buf;
 | 
				
			||||||
	regmatch_t	pmatch[REGEXP_REPLACE_BACKREF_CNT];
 | 
						regmatch_t	pmatch[REGEXP_REPLACE_BACKREF_CNT];
 | 
				
			||||||
	pg_wchar   *data;
 | 
						pg_wchar   *data;
 | 
				
			||||||
@@ -2346,13 +2347,13 @@ replace_text_regexp(text *src_text, void *regexp,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/* Convert data string to wide characters. */
 | 
						/* Convert data string to wide characters. */
 | 
				
			||||||
	data = (pg_wchar *) palloc((src_text_len + 1) * sizeof(pg_wchar));
 | 
						data = (pg_wchar *) palloc((src_text_len + 1) * sizeof(pg_wchar));
 | 
				
			||||||
	data_len = pg_mb2wchar_with_len(VARDATA(src_text), data, src_text_len);
 | 
						data_len = pg_mb2wchar_with_len(VARDATA_ANY(src_text), data, src_text_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Check whether replace_text has escape char. */
 | 
						/* Check whether replace_text has escape char. */
 | 
				
			||||||
	have_escape = check_replace_text_has_escape_char(replace_text);
 | 
						have_escape = check_replace_text_has_escape_char(replace_text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* start_ptr points to the data_pos'th character of src_text */
 | 
						/* start_ptr points to the data_pos'th character of src_text */
 | 
				
			||||||
	start_ptr = (char *) VARDATA(src_text);
 | 
						start_ptr = (char *) VARDATA_ANY(src_text);
 | 
				
			||||||
	data_pos = 0;
 | 
						data_pos = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	search_start = 0;
 | 
						search_start = 0;
 | 
				
			||||||
@@ -2439,7 +2440,7 @@ replace_text_regexp(text *src_text, void *regexp,
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		int			chunk_len;
 | 
							int			chunk_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		chunk_len = ((char *) src_text + VARSIZE(src_text)) - start_ptr;
 | 
							chunk_len = ((char *) src_text + VARSIZE_ANY(src_text)) - start_ptr;
 | 
				
			||||||
		appendBinaryStringInfo(&buf, start_ptr, chunk_len);
 | 
							appendBinaryStringInfo(&buf, start_ptr, chunk_len);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2459,8 +2460,8 @@ replace_text_regexp(text *src_text, void *regexp,
 | 
				
			|||||||
Datum
 | 
					Datum
 | 
				
			||||||
split_text(PG_FUNCTION_ARGS)
 | 
					split_text(PG_FUNCTION_ARGS)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	text	   *inputstring = PG_GETARG_TEXT_P(0);
 | 
						text	   *inputstring = PG_GETARG_TEXT_PP(0);
 | 
				
			||||||
	text	   *fldsep = PG_GETARG_TEXT_P(1);
 | 
						text	   *fldsep = PG_GETARG_TEXT_PP(1);
 | 
				
			||||||
	int			fldnum = PG_GETARG_INT32(2);
 | 
						int			fldnum = PG_GETARG_INT32(2);
 | 
				
			||||||
	int			inputstring_len;
 | 
						int			inputstring_len;
 | 
				
			||||||
	int			fldsep_len;
 | 
						int			fldsep_len;
 | 
				
			||||||
@@ -2559,8 +2560,8 @@ split_text(PG_FUNCTION_ARGS)
 | 
				
			|||||||
Datum
 | 
					Datum
 | 
				
			||||||
text_to_array(PG_FUNCTION_ARGS)
 | 
					text_to_array(PG_FUNCTION_ARGS)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	text	   *inputstring = PG_GETARG_TEXT_P(0);
 | 
						text	   *inputstring = PG_GETARG_TEXT_PP(0);
 | 
				
			||||||
	text	   *fldsep = PG_GETARG_TEXT_P(1);
 | 
						text	   *fldsep = PG_GETARG_TEXT_PP(1);
 | 
				
			||||||
	int			inputstring_len;
 | 
						int			inputstring_len;
 | 
				
			||||||
	int			fldsep_len;
 | 
						int			fldsep_len;
 | 
				
			||||||
	TextPositionState state;
 | 
						TextPositionState state;
 | 
				
			||||||
@@ -2601,7 +2602,7 @@ text_to_array(PG_FUNCTION_ARGS)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	start_posn = 1;
 | 
						start_posn = 1;
 | 
				
			||||||
	/* start_ptr points to the start_posn'th character of inputstring */
 | 
						/* start_ptr points to the start_posn'th character of inputstring */
 | 
				
			||||||
	start_ptr = (char *) VARDATA(inputstring);
 | 
						start_ptr = VARDATA_ANY(inputstring);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (fldnum = 1;; fldnum++) /* field number is 1 based */
 | 
						for (fldnum = 1;; fldnum++) /* field number is 1 based */
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -2612,7 +2613,7 @@ text_to_array(PG_FUNCTION_ARGS)
 | 
				
			|||||||
		if (end_posn == 0)
 | 
							if (end_posn == 0)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			/* fetch last field */
 | 
								/* fetch last field */
 | 
				
			||||||
			chunk_len = ((char *) inputstring + VARSIZE(inputstring)) - start_ptr;
 | 
								chunk_len = ((char *) inputstring + VARSIZE_ANY(inputstring)) - start_ptr;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user