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

📄 oracle_compat.c

📁 PostgreSQL7.4.6 for Linux
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * oracle_compat.c *	Oracle compatible functions. * * Copyright (c) 1996-2003, PostgreSQL Global Development Group * *	Author: Edmund Mergl <E.Mergl@bawue.de> *	Multibyte enhancement: Tatsuo Ishii <ishii@postgresql.org> * * * IDENTIFICATION *	$Header: /cvsroot/pgsql/src/backend/utils/adt/oracle_compat.c,v 1.48 2003/08/08 21:42:06 momjian Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include <ctype.h>#include "utils/builtins.h"#include "mb/pg_wchar.h"static text *dotrim(const char *string, int stringlen,	   const char *set, int setlen,	   bool doltrim, bool dortrim);/******************************************************************** * * lower * * Syntax: * *	 text lower(text string) * * Purpose: * *	 Returns string, with all letters forced to lowercase. * ********************************************************************/Datumlower(PG_FUNCTION_ARGS){	text	   *string = PG_GETARG_TEXT_P_COPY(0);	char	   *ptr;	int			m;	/* Since we copied the string, we can scribble directly on the value */	ptr = VARDATA(string);	m = VARSIZE(string) - VARHDRSZ;	while (m-- > 0)	{		*ptr = tolower((unsigned char) *ptr);		ptr++;	}	PG_RETURN_TEXT_P(string);}/******************************************************************** * * upper * * Syntax: * *	 text upper(text string) * * Purpose: * *	 Returns string, with all letters forced to uppercase. * ********************************************************************/Datumupper(PG_FUNCTION_ARGS){	text	   *string = PG_GETARG_TEXT_P_COPY(0);	char	   *ptr;	int			m;	/* Since we copied the string, we can scribble directly on the value */	ptr = VARDATA(string);	m = VARSIZE(string) - VARHDRSZ;	while (m-- > 0)	{		*ptr = toupper((unsigned char) *ptr);		ptr++;	}	PG_RETURN_TEXT_P(string);}/******************************************************************** * * initcap * * Syntax: * *	 text initcap(text string) * * Purpose: * *	 Returns string, with first letter of each word in uppercase, *	 all other letters in lowercase. A word is delimited by white *	 space. * ********************************************************************/Datuminitcap(PG_FUNCTION_ARGS){	text	   *string = PG_GETARG_TEXT_P_COPY(0);	char	   *ptr;	int			m;	/* Since we copied the string, we can scribble directly on the value */	ptr = VARDATA(string);	m = VARSIZE(string) - VARHDRSZ;	if (m > 0)	{		*ptr = toupper((unsigned char) *ptr);		ptr++;		m--;	}	while (m-- > 0)	{		/* Oracle capitalizes after all non-alphanumeric */		if (!isalnum((unsigned char) ptr[-1]))			*ptr = toupper((unsigned char) *ptr);		else			*ptr = tolower((unsigned char) *ptr);		ptr++;	}	PG_RETURN_TEXT_P(string);}/******************************************************************** * * lpad * * Syntax: * *	 text lpad(text string1, int4 len, text string2) * * Purpose: * *	 Returns string1, left-padded to length len with the sequence of *	 characters in string2.  If len is less than the length of string1, *	 instead truncate (on the right) to len. * ********************************************************************/Datumlpad(PG_FUNCTION_ARGS){	text	   *string1 = PG_GETARG_TEXT_P(0);	int32		len = PG_GETARG_INT32(1);	text	   *string2 = PG_GETARG_TEXT_P(2);	text	   *ret;	char	   *ptr1,			   *ptr2,			   *ptr2end,			   *ptr_ret;	int			m,				s1len,				s2len;	int			bytelen;	/* Negative len is silently taken as zero */	if (len < 0)		len = 0;	s1len = VARSIZE(string1) - VARHDRSZ;	if (s1len < 0)		s1len = 0;				/* shouldn't happen */	s2len = VARSIZE(string2) - VARHDRSZ;	if (s2len < 0)		s2len = 0;				/* shouldn't happen */	s1len = pg_mbstrlen_with_len(VARDATA(string1), s1len);	if (s1len > len)		s1len = len;			/* truncate string1 to len chars */	if (s2len <= 0)		len = s1len;			/* nothing to pad with, so don't pad */	bytelen = pg_database_encoding_max_length() * len;	/* check for integer overflow */	if (len != 0 && bytelen / pg_database_encoding_max_length() != len)		ereport(ERROR,				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),				 errmsg("requested length too large")));	ret = (text *) palloc(VARHDRSZ + bytelen);	m = len - s1len;	ptr2 = VARDATA(string2);	ptr2end = ptr2 + s2len;	ptr_ret = VARDATA(ret);	while (m--)	{		int			mlen = pg_mblen(ptr2);		memcpy(ptr_ret, ptr2, mlen);		ptr_ret += mlen;		ptr2 += mlen;		if (ptr2 == ptr2end)	/* wrap around at end of s2 */			ptr2 = VARDATA(string2);	}	ptr1 = VARDATA(string1);	while (s1len--)	{		int			mlen = pg_mblen(ptr1);		memcpy(ptr_ret, ptr1, mlen);		ptr_ret += mlen;		ptr1 += mlen;	}	VARATT_SIZEP(ret) = ptr_ret - (char *) ret;	PG_RETURN_TEXT_P(ret);}/******************************************************************** * * rpad * * Syntax: * *	 text rpad(text string1, int4 len, text string2) * * Purpose: * *	 Returns string1, right-padded to length len with the sequence of *	 characters in string2.  If len is less than the length of string1, *	 instead truncate (on the right) to len. * ********************************************************************/Datumrpad(PG_FUNCTION_ARGS){	text	   *string1 = PG_GETARG_TEXT_P(0);	int32		len = PG_GETARG_INT32(1);	text	   *string2 = PG_GETARG_TEXT_P(2);	text	   *ret;	char	   *ptr1,			   *ptr2,			   *ptr2end,			   *ptr_ret;	int			m,				s1len,				s2len;	int			bytelen;	/* Negative len is silently taken as zero */	if (len < 0)		len = 0;	s1len = VARSIZE(string1) - VARHDRSZ;	if (s1len < 0)		s1len = 0;				/* shouldn't happen */	s2len = VARSIZE(string2) - VARHDRSZ;	if (s2len < 0)		s2len = 0;				/* shouldn't happen */	s1len = pg_mbstrlen_with_len(VARDATA(string1), s1len);	if (s1len > len)		s1len = len;			/* truncate string1 to len chars */	if (s2len <= 0)		len = s1len;			/* nothing to pad with, so don't pad */	bytelen = pg_database_encoding_max_length() * len;	/* Check for integer overflow */	if (len != 0 && bytelen / pg_database_encoding_max_length() != len)		ereport(ERROR,				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),				 errmsg("requested length too large")));	ret = (text *) palloc(VARHDRSZ + bytelen);	m = len - s1len;	ptr1 = VARDATA(string1);	ptr_ret = VARDATA(ret);	while (s1len--)	{		int			mlen = pg_mblen(ptr1);		memcpy(ptr_ret, ptr1, mlen);		ptr_ret += mlen;		ptr1 += mlen;	}	ptr2 = VARDATA(string2);	ptr2end = ptr2 + s2len;	while (m--)	{		int			mlen = pg_mblen(ptr2);		memcpy(ptr_ret, ptr2, mlen);		ptr_ret += mlen;		ptr2 += mlen;		if (ptr2 == ptr2end)	/* wrap around at end of s2 */			ptr2 = VARDATA(string2);	}	VARATT_SIZEP(ret) = ptr_ret - (char *) ret;	PG_RETURN_TEXT_P(ret);}/******************************************************************** * * btrim * * Syntax: * *	 text btrim(text string, text set) * * Purpose: * *	 Returns string with characters removed from the front and back *	 up to the first character not in set. * ********************************************************************/Datumbtrim(PG_FUNCTION_ARGS){	text	   *string = PG_GETARG_TEXT_P(0);	text	   *set = PG_GETARG_TEXT_P(1);	text	   *ret;	ret = dotrim(VARDATA(string), VARSIZE(string) - VARHDRSZ,				 VARDATA(set), VARSIZE(set) - VARHDRSZ,				 true, true);	PG_RETURN_TEXT_P(ret);}/******************************************************************** * * btrim1 --- btrim with set fixed as ' ' * ********************************************************************/Datumbtrim1(PG_FUNCTION_ARGS){	text	   *string = PG_GETARG_TEXT_P(0);	text	   *ret;	ret = dotrim(VARDATA(string), VARSIZE(string) - VARHDRSZ,				 " ", 1,				 true, true);	PG_RETURN_TEXT_P(ret);}/* * Common implementation for btrim, ltrim, rtrim */static text *dotrim(const char *string, int stringlen,	   const char *set, int setlen,	   bool doltrim, bool dortrim){	text	   *result;	int			i;	/* Nothing to do if either string or set is empty */	if (stringlen > 0 && setlen > 0)	{		if (pg_database_encoding_max_length() > 1)		{			/*			 * In the multibyte-encoding case, build arrays of pointers to			 * character starts, so that we can avoid inefficient checks			 * in the inner loops.			 */			const char **stringchars;			const char **setchars;			int		   *stringmblen;			int		   *setmblen;			int			stringnchars;			int			setnchars;			int			resultndx;			int			resultnchars;			const char *p;			int			len;			int			mblen;			const char *str_pos;			int			str_len;			stringchars = (const char **) palloc(stringlen * sizeof(char *));			stringmblen = (int *) palloc(stringlen * sizeof(int));			stringnchars = 0;			p = string;			len = stringlen;			while (len > 0)			{				stringchars[stringnchars] = p;				stringmblen[stringnchars] = mblen = pg_mblen(p);				stringnchars++;				p += mblen;				len -= mblen;			}			setchars = (const char **) palloc(setlen * sizeof(char *));			setmblen = (int *) palloc(setlen * sizeof(int));			setnchars = 0;			p = set;			len = setlen;			while (len > 0)			{				setchars[setnchars] = p;				setmblen[setnchars] = mblen = pg_mblen(p);				setnchars++;				p += mblen;				len -= mblen;			}			resultndx = 0;		/* index in stringchars[] */			resultnchars = stringnchars;			if (doltrim)			{				while (resultnchars > 0)				{					str_pos = stringchars[resultndx];					str_len = stringmblen[resultndx];					for (i = 0; i < setnchars; i++)					{						if (str_len == setmblen[i] &&							memcmp(str_pos, setchars[i], str_len) == 0)							break;					}					if (i >= setnchars)						break;	/* no match here */					string += str_len;					stringlen -= str_len;					resultndx++;					resultnchars--;

⌨️ 快捷键说明

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