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

📄 like.c

📁 postgresql8.3.4源码,开源数据库
💻 C
字号:
/*------------------------------------------------------------------------- * * like.c *	  like expression handling code. * *	 NOTES *		A big hack of the regexp.c code!! Contributed by *		Keith Parks <emkxp01@mtcc.demon.co.uk> (7/95). * * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION *	$PostgreSQL: pgsql/src/backend/utils/adt/like.c,v 1.73 2008/01/01 19:45:52 momjian Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include <ctype.h>#include "mb/pg_wchar.h"#include "utils/builtins.h"#define LIKE_TRUE						1#define LIKE_FALSE						0#define LIKE_ABORT						(-1)static int	SB_MatchText(char *t, int tlen, char *p, int plen);static text *SB_do_like_escape(text *, text *);static int	MB_MatchText(char *t, int tlen, char *p, int plen);static text *MB_do_like_escape(text *, text *);static int	UTF8_MatchText(char *t, int tlen, char *p, int plen);static int	SB_IMatchText(char *t, int tlen, char *p, int plen);static int	GenericMatchText(char *s, int slen, char *p, int plen);static int	Generic_Text_IC_like(text *str, text *pat);/*-------------------- * Support routine for MatchText. Compares given multibyte streams * as wide characters. If they match, returns 1 otherwise returns 0. *-------------------- */static inline intwchareq(char *p1, char *p2){	int			p1_len;	/* Optimization:  quickly compare the first byte. */	if (*p1 != *p2)		return 0;	p1_len = pg_mblen(p1);	if (pg_mblen(p2) != p1_len)		return 0;	/* They are the same length */	while (p1_len--)	{		if (*p1++ != *p2++)			return 0;	}	return 1;}/* * Formerly we had a routine iwchareq() here that tried to do case-insensitive * comparison of multibyte characters.	It did not work at all, however, * because it relied on tolower() which has a single-byte API ... and * towlower() wouldn't be much better since we have no suitably cheap way * of getting a single character transformed to the system's wchar_t format. * So now, we just downcase the strings using lower() and apply regular LIKE * comparison.	This should be revisited when we install better locale support. */#define NextByte(p, plen)	((p)++, (plen)--)/* Set up to compile like_match.c for multibyte characters */#define CHAREQ(p1, p2) wchareq((p1), (p2))#define NextChar(p, plen) \	do { int __l = pg_mblen(p); (p) +=__l; (plen) -=__l; } while (0)#define CopyAdvChar(dst, src, srclen) \	do { int __l = pg_mblen(src); \		 (srclen) -= __l; \		 while (__l-- > 0) \			 *(dst)++ = *(src)++; \	   } while (0)#define MatchText	MB_MatchText#define do_like_escape	MB_do_like_escape#include "like_match.c"/* Set up to compile like_match.c for single-byte characters */#define CHAREQ(p1, p2) (*(p1) == *(p2))#define NextChar(p, plen) NextByte((p), (plen))#define CopyAdvChar(dst, src, srclen) (*(dst)++ = *(src)++, (srclen)--)#define MatchText	SB_MatchText#define do_like_escape	SB_do_like_escape#include "like_match.c"/* setup to compile like_match.c for single byte case insensitive matches */#define MATCH_LOWER#define NextChar(p, plen) NextByte((p), (plen))#define MatchText SB_IMatchText#include "like_match.c"/* setup to compile like_match.c for UTF8 encoding, using fast NextChar */#define NextChar(p, plen) \	do { (p)++; (plen)--; } while ((plen) > 0 && (*(p) & 0xC0) == 0x80 )#define MatchText	UTF8_MatchText#include "like_match.c"static inline intGenericMatchText(char *s, int slen, char *p, int plen){	if (pg_database_encoding_max_length() == 1)		return SB_MatchText(s, slen, p, plen);	else if (GetDatabaseEncoding() == PG_UTF8)		return UTF8_MatchText(s, slen, p, plen);	else		return MB_MatchText(s, slen, p, plen);}static inline intGeneric_Text_IC_like(text *str, text *pat){	char	   *s,			   *p;	int			slen,				plen;	/*	 * For efficiency reasons, in the single byte case we don't call lower()	 * on the pattern and text, but instead call to_lower on each character.	 * In the multi-byte case we don't have much choice :-(	 */	if (pg_database_encoding_max_length() > 1)	{		/* lower's result is never packed, so OK to use old macros here */		pat = DatumGetTextP(DirectFunctionCall1(lower, PointerGetDatum(pat)));		p = VARDATA(pat);		plen = (VARSIZE(pat) - VARHDRSZ);		str = DatumGetTextP(DirectFunctionCall1(lower, PointerGetDatum(str)));		s = VARDATA(str);		slen = (VARSIZE(str) - VARHDRSZ);		if (GetDatabaseEncoding() == PG_UTF8)			return UTF8_MatchText(s, slen, p, plen);		else			return MB_MatchText(s, slen, p, plen);	}	else	{		p = VARDATA_ANY(pat);		plen = VARSIZE_ANY_EXHDR(pat);		s = VARDATA_ANY(str);		slen = VARSIZE_ANY_EXHDR(str);		return SB_IMatchText(s, slen, p, plen);	}}/* *	interface routines called by the function manager */Datumnamelike(PG_FUNCTION_ARGS){	Name		str = PG_GETARG_NAME(0);	text	   *pat = PG_GETARG_TEXT_PP(1);	bool		result;	char	   *s,			   *p;	int			slen,				plen;	s = NameStr(*str);	slen = strlen(s);	p = VARDATA_ANY(pat);	plen = VARSIZE_ANY_EXHDR(pat);	result = (GenericMatchText(s, slen, p, plen) == LIKE_TRUE);	PG_RETURN_BOOL(result);}Datumnamenlike(PG_FUNCTION_ARGS){	Name		str = PG_GETARG_NAME(0);	text	   *pat = PG_GETARG_TEXT_PP(1);	bool		result;	char	   *s,			   *p;	int			slen,				plen;	s = NameStr(*str);	slen = strlen(s);	p = VARDATA_ANY(pat);	plen = VARSIZE_ANY_EXHDR(pat);	result = (GenericMatchText(s, slen, p, plen) != LIKE_TRUE);	PG_RETURN_BOOL(result);}Datumtextlike(PG_FUNCTION_ARGS){	text	   *str = PG_GETARG_TEXT_PP(0);	text	   *pat = PG_GETARG_TEXT_PP(1);	bool		result;	char	   *s,			   *p;	int			slen,				plen;	s = VARDATA_ANY(str);	slen = VARSIZE_ANY_EXHDR(str);	p = VARDATA_ANY(pat);	plen = VARSIZE_ANY_EXHDR(pat);	result = (GenericMatchText(s, slen, p, plen) == LIKE_TRUE);	PG_RETURN_BOOL(result);}Datumtextnlike(PG_FUNCTION_ARGS){	text	   *str = PG_GETARG_TEXT_PP(0);	text	   *pat = PG_GETARG_TEXT_PP(1);	bool		result;	char	   *s,			   *p;	int			slen,				plen;	s = VARDATA_ANY(str);	slen = VARSIZE_ANY_EXHDR(str);	p = VARDATA_ANY(pat);	plen = VARSIZE_ANY_EXHDR(pat);	result = (GenericMatchText(s, slen, p, plen) != LIKE_TRUE);	PG_RETURN_BOOL(result);}Datumbytealike(PG_FUNCTION_ARGS){	bytea	   *str = PG_GETARG_BYTEA_PP(0);	bytea	   *pat = PG_GETARG_BYTEA_PP(1);	bool		result;	char	   *s,			   *p;	int			slen,				plen;	s = VARDATA_ANY(str);	slen = VARSIZE_ANY_EXHDR(str);	p = VARDATA_ANY(pat);	plen = VARSIZE_ANY_EXHDR(pat);	result = (SB_MatchText(s, slen, p, plen) == LIKE_TRUE);	PG_RETURN_BOOL(result);}Datumbyteanlike(PG_FUNCTION_ARGS){	bytea	   *str = PG_GETARG_BYTEA_PP(0);	bytea	   *pat = PG_GETARG_BYTEA_PP(1);	bool		result;	char	   *s,			   *p;	int			slen,				plen;	s = VARDATA_ANY(str);	slen = VARSIZE_ANY_EXHDR(str);	p = VARDATA_ANY(pat);	plen = VARSIZE_ANY_EXHDR(pat);	result = (SB_MatchText(s, slen, p, plen) != LIKE_TRUE);	PG_RETURN_BOOL(result);}/* * Case-insensitive versions */Datumnameiclike(PG_FUNCTION_ARGS){	Name		str = PG_GETARG_NAME(0);	text	   *pat = PG_GETARG_TEXT_PP(1);	bool		result;	text	   *strtext;	strtext = DatumGetTextP(DirectFunctionCall1(name_text,												NameGetDatum(str)));	result = (Generic_Text_IC_like(strtext, pat) == LIKE_TRUE);	PG_RETURN_BOOL(result);}Datumnameicnlike(PG_FUNCTION_ARGS){	Name		str = PG_GETARG_NAME(0);	text	   *pat = PG_GETARG_TEXT_PP(1);	bool		result;	text	   *strtext;	strtext = DatumGetTextP(DirectFunctionCall1(name_text,												NameGetDatum(str)));	result = (Generic_Text_IC_like(strtext, pat) != LIKE_TRUE);	PG_RETURN_BOOL(result);}Datumtexticlike(PG_FUNCTION_ARGS){	text	   *str = PG_GETARG_TEXT_PP(0);	text	   *pat = PG_GETARG_TEXT_PP(1);	bool		result;	result = (Generic_Text_IC_like(str, pat) == LIKE_TRUE);	PG_RETURN_BOOL(result);}Datumtexticnlike(PG_FUNCTION_ARGS){	text	   *str = PG_GETARG_TEXT_PP(0);	text	   *pat = PG_GETARG_TEXT_PP(1);	bool		result;	result = (Generic_Text_IC_like(str, pat) != LIKE_TRUE);	PG_RETURN_BOOL(result);}/* * like_escape() --- given a pattern and an ESCAPE string, * convert the pattern to use Postgres' standard backslash escape convention. */Datumlike_escape(PG_FUNCTION_ARGS){	text	   *pat = PG_GETARG_TEXT_PP(0);	text	   *esc = PG_GETARG_TEXT_PP(1);	text	   *result;	if (pg_database_encoding_max_length() == 1)		result = SB_do_like_escape(pat, esc);	else		result = MB_do_like_escape(pat, esc);	PG_RETURN_TEXT_P(result);}/* * like_escape_bytea() --- given a pattern and an ESCAPE string, * convert the pattern to use Postgres' standard backslash escape convention. */Datumlike_escape_bytea(PG_FUNCTION_ARGS){	bytea	   *pat = PG_GETARG_BYTEA_PP(0);	bytea	   *esc = PG_GETARG_BYTEA_PP(1);	bytea	   *result = SB_do_like_escape((text *) pat, (text *) esc);	PG_RETURN_BYTEA_P((bytea *) result);}

⌨️ 快捷键说明

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