⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 varchar.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
 * * If the input string is too long, raise an error, unless the extra * characters are spaces, in which case they're truncated.  (per SQL) */static VarChar *varchar_input(const char *s, size_t len, int32 atttypmod){	VarChar    *result;	size_t		maxlen;	maxlen = atttypmod - VARHDRSZ;	if (atttypmod >= (int32) VARHDRSZ && len > maxlen)	{		/* Verify that extra characters are spaces, and clip them off */		size_t		mbmaxlen = pg_mbcharcliplen(s, len, maxlen);		size_t		j;		for (j = mbmaxlen; j < len; j++)		{			if (s[j] != ' ')				ereport(ERROR,						(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),					  errmsg("value too long for type character varying(%d)",							 (int) maxlen)));		}		len = mbmaxlen;	}	result = (VarChar *) palloc(len + VARHDRSZ);	SET_VARSIZE(result, len + VARHDRSZ);	memcpy(VARDATA(result), s, len);	return result;}/* * Convert a C string to VARCHAR internal representation.  atttypmod * is the declared length of the type plus VARHDRSZ. */Datumvarcharin(PG_FUNCTION_ARGS){	char	   *s = PG_GETARG_CSTRING(0);#ifdef NOT_USED	Oid			typelem = PG_GETARG_OID(1);#endif	int32		atttypmod = PG_GETARG_INT32(2);	VarChar    *result;	result = varchar_input(s, strlen(s), atttypmod);	PG_RETURN_VARCHAR_P(result);}/* * Convert a VARCHAR value to a C string. */Datumvarcharout(PG_FUNCTION_ARGS){	VarChar    *s = PG_GETARG_VARCHAR_PP(0);	char	   *result;	int32		len;	/* copy and add null term */	len = VARSIZE_ANY_EXHDR(s);	result = palloc(len + 1);	memcpy(result, VARDATA_ANY(s), len);	result[len] = '\0';	PG_RETURN_CSTRING(result);}/* *		varcharrecv			- converts external binary format to varchar */Datumvarcharrecv(PG_FUNCTION_ARGS){	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);#ifdef NOT_USED	Oid			typelem = PG_GETARG_OID(1);#endif	int32		atttypmod = PG_GETARG_INT32(2);	VarChar    *result;	char	   *str;	int			nbytes;	str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);	result = varchar_input(str, nbytes, atttypmod);	pfree(str);	PG_RETURN_VARCHAR_P(result);}/* *		varcharsend			- converts varchar to binary format */Datumvarcharsend(PG_FUNCTION_ARGS){	/* Exactly the same as textsend, so share code */	return textsend(fcinfo);}/* * Converts a VARCHAR type to the specified size. * * maxlen is the typmod, ie, declared length plus VARHDRSZ bytes. * isExplicit is true if this is for an explicit cast to varchar(N). * * Truncation rules: for an explicit cast, silently truncate to the given * length; for an implicit cast, raise error unless extra characters are * all spaces.	(This is sort-of per SQL: the spec would actually have us * raise a "completion condition" for the explicit cast case, but Postgres * hasn't got such a concept.) */Datumvarchar(PG_FUNCTION_ARGS){	VarChar    *source = PG_GETARG_VARCHAR_PP(0);	int32		typmod = PG_GETARG_INT32(1);	bool		isExplicit = PG_GETARG_BOOL(2);	VarChar    *result;	int32		len,				maxlen;	size_t		maxmblen;	int			i;	char	   *s_data;	len = VARSIZE_ANY_EXHDR(source);	s_data = VARDATA_ANY(source);	maxlen = typmod - VARHDRSZ;	/* No work if typmod is invalid or supplied data fits it already */	if (maxlen < 0 || len <= maxlen)		PG_RETURN_VARCHAR_P(source);	/* only reach here if string is too long... */	/* truncate multibyte string preserving multibyte boundary */	maxmblen = pg_mbcharcliplen(s_data, len, maxlen);	if (!isExplicit)	{		for (i = maxmblen; i < len; i++)			if (s_data[i] != ' ')				ereport(ERROR,						(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),					  errmsg("value too long for type character varying(%d)",							 maxlen)));	}	result = palloc(maxmblen + VARHDRSZ);	SET_VARSIZE(result, maxmblen + VARHDRSZ);	memcpy(VARDATA(result), s_data, maxmblen);	PG_RETURN_VARCHAR_P(result);}Datumvarchartypmodin(PG_FUNCTION_ARGS){	ArrayType  *ta = PG_GETARG_ARRAYTYPE_P(0);	PG_RETURN_INT32(anychar_typmodin(ta, "varchar"));}Datumvarchartypmodout(PG_FUNCTION_ARGS){	int32		typmod = PG_GETARG_INT32(0);	PG_RETURN_CSTRING(anychar_typmodout(typmod));}/***************************************************************************** * Exported functions *****************************************************************************//* "True" length (not counting trailing blanks) of a BpChar */static intbcTruelen(BpChar *arg){	char	   *s = VARDATA_ANY(arg);	int			i;	int			len;	len = VARSIZE_ANY_EXHDR(arg);	for (i = len - 1; i >= 0; i--)	{		if (s[i] != ' ')			break;	}	return i + 1;}Datumbpcharlen(PG_FUNCTION_ARGS){	BpChar	   *arg = PG_GETARG_BPCHAR_PP(0);	int			len;	/* get number of bytes, ignoring trailing spaces */	len = bcTruelen(arg);	/* in multibyte encoding, convert to number of characters */	if (pg_database_encoding_max_length() != 1)		len = pg_mbstrlen_with_len(VARDATA_ANY(arg), len);	PG_RETURN_INT32(len);}Datumbpcharoctetlen(PG_FUNCTION_ARGS){	Datum		arg = PG_GETARG_DATUM(0);	/* We need not detoast the input at all */	PG_RETURN_INT32(toast_raw_datum_size(arg) - VARHDRSZ);}/***************************************************************************** *	Comparison Functions used for bpchar * * 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. *****************************************************************************/Datumbpchareq(PG_FUNCTION_ARGS){	BpChar	   *arg1 = PG_GETARG_BPCHAR_PP(0);	BpChar	   *arg2 = PG_GETARG_BPCHAR_PP(1);	int			len1,				len2;	bool		result;	len1 = bcTruelen(arg1);	len2 = bcTruelen(arg2);	/*	 * Since we only care about equality or not-equality, we can avoid all the	 * expense of strcoll() here, and just do bitwise comparison.	 */	if (len1 != len2)		result = false;	else		result = (strncmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) == 0);	PG_FREE_IF_COPY(arg1, 0);	PG_FREE_IF_COPY(arg2, 1);	PG_RETURN_BOOL(result);}Datumbpcharne(PG_FUNCTION_ARGS){	BpChar	   *arg1 = PG_GETARG_BPCHAR_PP(0);	BpChar	   *arg2 = PG_GETARG_BPCHAR_PP(1);	int			len1,				len2;	bool		result;	len1 = bcTruelen(arg1);	len2 = bcTruelen(arg2);	/*	 * Since we only care about equality or not-equality, we can avoid all the	 * expense of strcoll() here, and just do bitwise comparison.	 */	if (len1 != len2)		result = true;	else		result = (strncmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) != 0);	PG_FREE_IF_COPY(arg1, 0);	PG_FREE_IF_COPY(arg2, 1);	PG_RETURN_BOOL(result);}Datumbpcharlt(PG_FUNCTION_ARGS){	BpChar	   *arg1 = PG_GETARG_BPCHAR_PP(0);	BpChar	   *arg2 = PG_GETARG_BPCHAR_PP(1);	int			len1,				len2;	int			cmp;	len1 = bcTruelen(arg1);	len2 = bcTruelen(arg2);	cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2);	PG_FREE_IF_COPY(arg1, 0);	PG_FREE_IF_COPY(arg2, 1);	PG_RETURN_BOOL(cmp < 0);}Datumbpcharle(PG_FUNCTION_ARGS){	BpChar	   *arg1 = PG_GETARG_BPCHAR_PP(0);	BpChar	   *arg2 = PG_GETARG_BPCHAR_PP(1);	int			len1,				len2;	int			cmp;	len1 = bcTruelen(arg1);	len2 = bcTruelen(arg2);	cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2);	PG_FREE_IF_COPY(arg1, 0);	PG_FREE_IF_COPY(arg2, 1);	PG_RETURN_BOOL(cmp <= 0);}Datumbpchargt(PG_FUNCTION_ARGS){	BpChar	   *arg1 = PG_GETARG_BPCHAR_PP(0);	BpChar	   *arg2 = PG_GETARG_BPCHAR_PP(1);	int			len1,				len2;	int			cmp;	len1 = bcTruelen(arg1);	len2 = bcTruelen(arg2);	cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2);	PG_FREE_IF_COPY(arg1, 0);	PG_FREE_IF_COPY(arg2, 1);	PG_RETURN_BOOL(cmp > 0);}Datumbpcharge(PG_FUNCTION_ARGS){	BpChar	   *arg1 = PG_GETARG_BPCHAR_PP(0);	BpChar	   *arg2 = PG_GETARG_BPCHAR_PP(1);	int			len1,				len2;	int			cmp;	len1 = bcTruelen(arg1);	len2 = bcTruelen(arg2);	cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2);	PG_FREE_IF_COPY(arg1, 0);	PG_FREE_IF_COPY(arg2, 1);	PG_RETURN_BOOL(cmp >= 0);}Datumbpcharcmp(PG_FUNCTION_ARGS){	BpChar	   *arg1 = PG_GETARG_BPCHAR_PP(0);	BpChar	   *arg2 = PG_GETARG_BPCHAR_PP(1);	int			len1,				len2;	int			cmp;	len1 = bcTruelen(arg1);	len2 = bcTruelen(arg2);	cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2);	PG_FREE_IF_COPY(arg1, 0);	PG_FREE_IF_COPY(arg2, 1);	PG_RETURN_INT32(cmp);}Datumbpchar_larger(PG_FUNCTION_ARGS){	BpChar	   *arg1 = PG_GETARG_BPCHAR_PP(0);	BpChar	   *arg2 = PG_GETARG_BPCHAR_PP(1);	int			len1,				len2;	int			cmp;	len1 = bcTruelen(arg1);	len2 = bcTruelen(arg2);	cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2);	PG_RETURN_BPCHAR_P((cmp >= 0) ? arg1 : arg2);}Datumbpchar_smaller(PG_FUNCTION_ARGS){	BpChar	   *arg1 = PG_GETARG_BPCHAR_PP(0);	BpChar	   *arg2 = PG_GETARG_BPCHAR_PP(1);	int			len1,				len2;	int			cmp;	len1 = bcTruelen(arg1);	len2 = bcTruelen(arg2);	cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2);	PG_RETURN_BPCHAR_P((cmp <= 0) ? arg1 : arg2);}/* * bpchar needs a specialized hash function because we want to ignore * trailing blanks in comparisons. * * Note: currently there is no need for locale-specific behavior here, * but if we ever change the semantics of bpchar comparison to trust * strcoll() completely, we'd need to do something different in non-C locales. */Datumhashbpchar(PG_FUNCTION_ARGS){	BpChar	   *key = PG_GETARG_BPCHAR_PP(0);	char	   *keydata;	int			keylen;	Datum		result;	keydata = VARDATA_ANY(key);	keylen = bcTruelen(key);	result = hash_any((unsigned char *) keydata, keylen);	/* Avoid leaking memory for toasted inputs */	PG_FREE_IF_COPY(key, 0);	return result;}

⌨️ 快捷键说明

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