varlena.c

来自「PostgreSQL7.4.6 for Linux」· C语言 代码 · 共 2,310 行 · 第 1/4 页

C
2,310
字号
		if (*nextp == separator)		{			nextp++;			while (isspace((unsigned char) *nextp))				nextp++;		/* skip leading whitespace for next */			/* we expect another name, so done remains false */		}		else if (*nextp == '\0')			done = true;		else			return false;		/* invalid syntax */		/* Now safe to overwrite separator with a null */		*endp = '\0';		/* Truncate name if it's overlength */		truncate_identifier(curname, strlen(curname), false);		/*		 * Finished isolating current name --- add it to list		 */		*namelist = lappend(*namelist, curname);		/* Loop back if we didn't reach end of string */	} while (!done);	return true;}/***************************************************************************** *	Comparison Functions used for bytea * * Note: btree indexes need these routines not to leak memory; therefore, * be careful to free working copies of toasted datums.  Most places don't * need to be so careful. *****************************************************************************/Datumbyteaeq(PG_FUNCTION_ARGS){	bytea	   *arg1 = PG_GETARG_BYTEA_P(0);	bytea	   *arg2 = PG_GETARG_BYTEA_P(1);	int			len1,				len2;	bool		result;	len1 = VARSIZE(arg1) - VARHDRSZ;	len2 = VARSIZE(arg2) - VARHDRSZ;	/* fast path for different-length inputs */	if (len1 != len2)		result = false;	else		result = (memcmp(VARDATA(arg1), VARDATA(arg2), len1) == 0);	PG_FREE_IF_COPY(arg1, 0);	PG_FREE_IF_COPY(arg2, 1);	PG_RETURN_BOOL(result);}Datumbyteane(PG_FUNCTION_ARGS){	bytea	   *arg1 = PG_GETARG_BYTEA_P(0);	bytea	   *arg2 = PG_GETARG_BYTEA_P(1);	int			len1,				len2;	bool		result;	len1 = VARSIZE(arg1) - VARHDRSZ;	len2 = VARSIZE(arg2) - VARHDRSZ;	/* fast path for different-length inputs */	if (len1 != len2)		result = true;	else		result = (memcmp(VARDATA(arg1), VARDATA(arg2), len1) != 0);	PG_FREE_IF_COPY(arg1, 0);	PG_FREE_IF_COPY(arg2, 1);	PG_RETURN_BOOL(result);}Datumbytealt(PG_FUNCTION_ARGS){	bytea	   *arg1 = PG_GETARG_BYTEA_P(0);	bytea	   *arg2 = PG_GETARG_BYTEA_P(1);	int			len1,				len2;	int			cmp;	len1 = VARSIZE(arg1) - VARHDRSZ;	len2 = VARSIZE(arg2) - VARHDRSZ;	cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));	PG_FREE_IF_COPY(arg1, 0);	PG_FREE_IF_COPY(arg2, 1);	PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 < len2)));}Datumbyteale(PG_FUNCTION_ARGS){	bytea	   *arg1 = PG_GETARG_BYTEA_P(0);	bytea	   *arg2 = PG_GETARG_BYTEA_P(1);	int			len1,				len2;	int			cmp;	len1 = VARSIZE(arg1) - VARHDRSZ;	len2 = VARSIZE(arg2) - VARHDRSZ;	cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));	PG_FREE_IF_COPY(arg1, 0);	PG_FREE_IF_COPY(arg2, 1);	PG_RETURN_BOOL((cmp < 0) || ((cmp == 0) && (len1 <= len2)));}Datumbyteagt(PG_FUNCTION_ARGS){	bytea	   *arg1 = PG_GETARG_BYTEA_P(0);	bytea	   *arg2 = PG_GETARG_BYTEA_P(1);	int			len1,				len2;	int			cmp;	len1 = VARSIZE(arg1) - VARHDRSZ;	len2 = VARSIZE(arg2) - VARHDRSZ;	cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));	PG_FREE_IF_COPY(arg1, 0);	PG_FREE_IF_COPY(arg2, 1);	PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 > len2)));}Datumbyteage(PG_FUNCTION_ARGS){	bytea	   *arg1 = PG_GETARG_BYTEA_P(0);	bytea	   *arg2 = PG_GETARG_BYTEA_P(1);	int			len1,				len2;	int			cmp;	len1 = VARSIZE(arg1) - VARHDRSZ;	len2 = VARSIZE(arg2) - VARHDRSZ;	cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));	PG_FREE_IF_COPY(arg1, 0);	PG_FREE_IF_COPY(arg2, 1);	PG_RETURN_BOOL((cmp > 0) || ((cmp == 0) && (len1 >= len2)));}Datumbyteacmp(PG_FUNCTION_ARGS){	bytea	   *arg1 = PG_GETARG_BYTEA_P(0);	bytea	   *arg2 = PG_GETARG_BYTEA_P(1);	int			len1,				len2;	int			cmp;	len1 = VARSIZE(arg1) - VARHDRSZ;	len2 = VARSIZE(arg2) - VARHDRSZ;	cmp = memcmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));	if ((cmp == 0) && (len1 != len2))		cmp = (len1 < len2) ? -1 : 1;	PG_FREE_IF_COPY(arg1, 0);	PG_FREE_IF_COPY(arg2, 1);	PG_RETURN_INT32(cmp);}/* * replace_text * replace all occurrences of 'old_sub_str' in 'orig_str' * with 'new_sub_str' to form 'new_str' * * returns 'orig_str' if 'old_sub_str' == '' or 'orig_str' == '' * otherwise returns 'new_str' */Datumreplace_text(PG_FUNCTION_ARGS){	text	   *left_text;	text	   *right_text;	text	   *buf_text;	text	   *ret_text;	int			curr_posn;	text	   *src_text = PG_GETARG_TEXT_P(0);	int			src_text_len = TEXTLEN(src_text);	text	   *from_sub_text = PG_GETARG_TEXT_P(1);	int			from_sub_text_len = TEXTLEN(from_sub_text);	text	   *to_sub_text = PG_GETARG_TEXT_P(2);	char	   *to_sub_str = PG_TEXT_GET_STR(to_sub_text);	StringInfo	str = makeStringInfo();	if (src_text_len == 0 || from_sub_text_len == 0)		PG_RETURN_TEXT_P(src_text);	buf_text = TEXTDUP(src_text);	curr_posn = TEXTPOS(buf_text, from_sub_text);	while (curr_posn > 0)	{		left_text = LEFT(buf_text, from_sub_text);		right_text = RIGHT(buf_text, from_sub_text, from_sub_text_len);		appendStringInfoString(str, PG_TEXT_GET_STR(left_text));		appendStringInfoString(str, to_sub_str);		pfree(buf_text);		pfree(left_text);		buf_text = right_text;		curr_posn = TEXTPOS(buf_text, from_sub_text);	}	appendStringInfoString(str, PG_TEXT_GET_STR(buf_text));	pfree(buf_text);	ret_text = PG_STR_GET_TEXT(str->data);	pfree(str->data);	pfree(str);	PG_RETURN_TEXT_P(ret_text);}/* * split_text * parse input string * return ord item (1 based) * based on provided field separator */Datumsplit_text(PG_FUNCTION_ARGS){	text	   *inputstring = PG_GETARG_TEXT_P(0);	int			inputstring_len = TEXTLEN(inputstring);	text	   *fldsep = PG_GETARG_TEXT_P(1);	int			fldsep_len = TEXTLEN(fldsep);	int			fldnum = PG_GETARG_INT32(2);	int			start_posn = 0;	int			end_posn = 0;	text	   *result_text;	/* return empty string for empty input string */	if (inputstring_len < 1)		PG_RETURN_TEXT_P(PG_STR_GET_TEXT(""));	/* empty field separator */	if (fldsep_len < 1)	{		if (fldnum == 1)		/* first field - just return the input								 * string */			PG_RETURN_TEXT_P(inputstring);		else/* otherwise return an empty string */			PG_RETURN_TEXT_P(PG_STR_GET_TEXT(""));	}	/* field number is 1 based */	if (fldnum < 1)		ereport(ERROR,				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),				 errmsg("field position must be greater than zero")));	start_posn = text_position(PointerGetDatum(inputstring),							   PointerGetDatum(fldsep),							   fldnum - 1);	end_posn = text_position(PointerGetDatum(inputstring),							 PointerGetDatum(fldsep),							 fldnum);	if ((start_posn == 0) && (end_posn == 0))	/* fldsep not found */	{		if (fldnum == 1)		/* first field - just return the input								 * string */			PG_RETURN_TEXT_P(inputstring);		else/* otherwise return an empty string */			PG_RETURN_TEXT_P(PG_STR_GET_TEXT(""));	}	else if ((start_posn != 0) && (end_posn == 0))	{		/* last field requested */		result_text = text_substring(PointerGetDatum(inputstring), start_posn + fldsep_len, -1, true);		PG_RETURN_TEXT_P(result_text);	}	else if ((start_posn == 0) && (end_posn != 0))	{		/* first field requested */		result_text = LEFT(inputstring, fldsep);		PG_RETURN_TEXT_P(result_text);	}	else	{		/* prior to last field requested */		result_text = text_substring(PointerGetDatum(inputstring), start_posn + fldsep_len, end_posn - start_posn - fldsep_len, false);		PG_RETURN_TEXT_P(result_text);	}}/* * text_to_array * parse input string * return text array of elements * based on provided field separator */Datumtext_to_array(PG_FUNCTION_ARGS){	text	   *inputstring = PG_GETARG_TEXT_P(0);	int			inputstring_len = TEXTLEN(inputstring);	text	   *fldsep = PG_GETARG_TEXT_P(1);	int			fldsep_len = TEXTLEN(fldsep);	int			fldnum;	int			start_posn = 0;	int			end_posn = 0;	text	   *result_text = NULL;	ArrayBuildState *astate = NULL;	MemoryContext oldcontext = CurrentMemoryContext;	/* return NULL for empty input string */	if (inputstring_len < 1)		PG_RETURN_NULL();	/*	 * empty field separator return one element, 1D, array using the input	 * string	 */	if (fldsep_len < 1)		PG_RETURN_ARRAYTYPE_P(create_singleton_array(fcinfo, TEXTOID,									   CStringGetDatum(inputstring), 1));	/* start with end position holding the initial start position */	end_posn = 0;	for (fldnum = 1;; fldnum++) /* field number is 1 based */	{		Datum		dvalue;		bool		disnull = false;		start_posn = end_posn;		end_posn = text_position(PointerGetDatum(inputstring),								 PointerGetDatum(fldsep),								 fldnum);		if ((start_posn == 0) && (end_posn == 0))		/* fldsep not found */		{			if (fldnum == 1)			{				/*				 * first element return one element, 1D, array using the				 * input string				 */				PG_RETURN_ARRAYTYPE_P(create_singleton_array(fcinfo, TEXTOID,									   CStringGetDatum(inputstring), 1));			}			else			{				/* otherwise create array and exit */				PG_RETURN_ARRAYTYPE_P(makeArrayResult(astate, oldcontext));			}		}		else if ((start_posn != 0) && (end_posn == 0))		{			/* last field requested */			result_text = text_substring(PointerGetDatum(inputstring), start_posn + fldsep_len, -1, true);		}		else if ((start_posn == 0) && (end_posn != 0))		{			/* first field requested */			result_text = LEFT(inputstring, fldsep);		}		else		{			/* prior to last field requested */			result_text = text_substring(PointerGetDatum(inputstring), start_posn + fldsep_len, end_posn - start_posn - fldsep_len, false);		}		/* stash away current value */		dvalue = PointerGetDatum(result_text);		astate = accumArrayResult(astate, dvalue,								  disnull, TEXTOID, oldcontext);	}	/* never reached -- keep compiler quiet */	PG_RETURN_NULL();}/* * array_to_text * concatenate Cstring representation of input array elements * using provided field separator */Datumarray_to_text(PG_FUNCTION_ARGS){	ArrayType  *v = PG_GETARG_ARRAYTYPE_P(0);	char	   *fldsep = PG_TEXTARG_GET_STR(1);	int			nitems,			   *dims,				ndims;	char	   *p;	Oid			element_type;	int			typlen;	bool		typbyval;	char		typalign;	Oid			typelem;	StringInfo	result_str = makeStringInfo();	int			i;	ArrayMetaState *my_extra;	p = ARR_DATA_PTR(v);	ndims = ARR_NDIM(v);	dims = ARR_DIMS(v);	nitems = ArrayGetNItems(ndims, dims);	/* if there are no elements, return an empty string */	if (nitems == 0)		PG_RETURN_TEXT_P(PG_STR_GET_TEXT(""));	element_type = ARR_ELEMTYPE(v);	/*	 * We arrange to look up info about element type, including its output	 * conversion proc, only once per series of calls, assuming the	 * element type doesn't change underneath us.	 */	my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;	if (my_extra == NULL)	{		fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,												 sizeof(ArrayMetaState));		my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;		my_extra->element_type = InvalidOid;	}	if (my_extra->element_type != element_type)	{		/*		 * Get info about element type, including its output conversion		 * proc		 */		get_type_io_data(element_type, IOFunc_output,						 &my_extra->typlen, &my_extra->typbyval,						 &my_extra->typalign, &my_extra->typdelim,						 &my_extra->typelem, &my_extra->typiofunc);		fmgr_info_cxt(my_extra->typiofunc, &my_extra->proc,					  fcinfo->flinfo->fn_mcxt);		my_extra->element_type = element_type;	}	typlen = my_extra->typlen;	typbyval = my_extra->typbyval;	typalign = my_extra->typalign;	typelem = my_extra->typelem;	for (i = 0; i < nitems; i++)	{		Datum		itemvalue;		char	   *value;		itemvalue = fetch_att(p, typbyval, typlen);		value = DatumGetCString(FunctionCall3(&my_extra->proc,											  itemvalue,											  ObjectIdGetDatum(typelem),											  Int32GetDatum(-1)));		if (i > 0)			appendStringInfo(result_str, "%s%s", fldsep, value);		else			appendStringInfo(result_str, "%s", value);		p = att_addlength(p, typlen, PointerGetDatum(p));		p = (char *) att_align(p, typalign);	}	PG_RETURN_TEXT_P(PG_STR_GET_TEXT(result_str->data));}#define HEXBASE 16/* * Convert a int32 to a string containing a base 16 (hex) representation of * the number. */Datumto_hex32(PG_FUNCTION_ARGS){	uint32		value = (uint32) PG_GETARG_INT32(0);	text	   *result_text;	char	   *ptr;	const char *digits = "0123456789abcdef";	char		buf[32];		/* bigger than needed, but reasonable */	ptr = buf + sizeof(buf) - 1;	*ptr = '\0';	do	{		*--ptr = digits[value % HEXBASE];		value /= HEXBASE;	} while (ptr > buf && value);	result_text = PG_STR_GET_TEXT(ptr);	PG_RETURN_TEXT_P(result_text);}/* * Convert a int64 to a string containing a base 16 (hex) representation of * the number. */Datumto_hex64(PG_FUNCTION_ARGS){	uint64		value = (uint64) PG_GETARG_INT64(0);	text	   *result_text;	char	   *ptr;	const char *digits = "0123456789abcdef";	char		buf[32];		/* bigger than needed, but reasonable */	ptr = buf + sizeof(buf) - 1;	*ptr = '\0';	do	{		*--ptr = digits[value % HEXBASE];		value /= HEXBASE;	} while (ptr > buf && value);	result_text = PG_STR_GET_TEXT(ptr);	PG_RETURN_TEXT_P(result_text);}/* * Create an md5 hash of a text string and return it as hex * * md5 produces a 16 byte (128 bit) hash; double it for hex */#define MD5_HASH_LEN  32Datummd5_text(PG_FUNCTION_ARGS){	char	   *buff = PG_TEXT_GET_STR(PG_GETARG_TEXT_P(0));	size_t		len = strlen(buff);	char	   *hexsum;	text	   *result_text;	/* leave room for the terminating '\0' */	hexsum = (char *) palloc(MD5_HASH_LEN + 1);	/* get the hash result */	md5_hash((void *) buff, len, hexsum);	/* convert to text and return it */	result_text = PG_STR_GET_TEXT(hexsum);	PG_RETURN_TEXT_P(result_text);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?