Attached is a small patch to $SUBJECT.

In master, only single-byte characters are allowed as an escape. Of
course, with the patch it must still be a single character, but it may
be multi-byte.

Regards,
        Jeff Davis

*** a/src/backend/utils/adt/regexp.c
--- b/src/backend/utils/adt/regexp.c
***************
*** 688,698 **** similar_escape(PG_FUNCTION_ARGS)
  		elen = VARSIZE_ANY_EXHDR(esc_text);
  		if (elen == 0)
  			e = NULL;			/* no escape character */
! 		else if (elen != 1)
! 			ereport(ERROR,
! 					(errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE),
! 					 errmsg("invalid escape string"),
! 				  errhint("Escape string must be empty or one character.")));
  	}
  
  	/*----------
--- 688,704 ----
  		elen = VARSIZE_ANY_EXHDR(esc_text);
  		if (elen == 0)
  			e = NULL;			/* no escape character */
! 		else
! 		{
! 			int escape_mblen = pg_verify_mbstr_len(GetDatabaseEncoding(), e,
! 												   elen, false);
! 
! 			if (escape_mblen > 1)
! 				ereport(ERROR,
! 						(errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE),
! 						 errmsg("invalid escape string"),
! 						 errhint("Escape string must be empty or one character.")));
! 		}
  	}
  
  	/*----------
***************
*** 722,781 **** similar_escape(PG_FUNCTION_ARGS)
  
  	while (plen > 0)
  	{
! 		char		pchar = *p;
  
! 		if (afterescape)
  		{
! 			if (pchar == '"' && !incharclass)	/* for SUBSTRING patterns */
! 				*r++ = ((nquotes++ % 2) == 0) ? '(' : ')';
! 			else
  			{
  				*r++ = '\\';
  				*r++ = pchar;
  			}
! 			afterescape = false;
! 		}
! 		else if (e && pchar == *e)
! 		{
! 			/* SQL99 escape character; do not send to output */
! 			afterescape = true;
  		}
! 		else if (incharclass)
  		{
! 			if (pchar == '\\')
  				*r++ = '\\';
! 			*r++ = pchar;
! 			if (pchar == ']')
! 				incharclass = false;
! 		}
! 		else if (pchar == '[')
! 		{
! 			*r++ = pchar;
! 			incharclass = true;
! 		}
! 		else if (pchar == '%')
! 		{
! 			*r++ = '.';
! 			*r++ = '*';
! 		}
! 		else if (pchar == '_')
! 			*r++ = '.';
! 		else if (pchar == '(')
! 		{
! 			/* convert to non-capturing parenthesis */
! 			*r++ = '(';
! 			*r++ = '?';
! 			*r++ = ':';
! 		}
! 		else if (pchar == '\\' || pchar == '.' ||
! 				 pchar == '^' || pchar == '$')
! 		{
! 			*r++ = '\\';
! 			*r++ = pchar;
  		}
- 		else
- 			*r++ = pchar;
- 		p++, plen--;
  	}
  
  	*r++ = ')';
--- 728,816 ----
  
  	while (plen > 0)
  	{
! 		char	pchar = *p;
! 		int		mblen = pg_encoding_verifymb(GetDatabaseEncoding(), p, plen);
! 
! 		Assert(mblen > 0);
  
! 		if (mblen == 1)
  		{
! 			if (afterescape)
! 			{
! 				if (pchar == '"' && !incharclass)	/* for SUBSTRING patterns */
! 					*r++ = ((nquotes++ % 2) == 0) ? '(' : ')';
! 				else
! 				{
! 					*r++ = '\\';
! 					*r++ = pchar;
! 				}
! 				afterescape = false;
! 			}
! 			else if (e && pchar == *e)
! 			{
! 				/* SQL99 escape character; do not send to output */
! 				afterescape = true;
! 			}
! 			else if (incharclass)
! 			{
! 				if (pchar == '\\')
! 					*r++ = '\\';
! 				*r++ = pchar;
! 				if (pchar == ']')
! 					incharclass = false;
! 			}
! 			else if (pchar == '[')
! 			{
! 				*r++ = pchar;
! 				incharclass = true;
! 			}
! 			else if (pchar == '%')
! 			{
! 				*r++ = '.';
! 				*r++ = '*';
! 			}
! 			else if (pchar == '_')
! 				*r++ = '.';
! 			else if (pchar == '(')
! 			{
! 				/* convert to non-capturing parenthesis */
! 				*r++ = '(';
! 				*r++ = '?';
! 				*r++ = ':';
! 			}
! 			else if (pchar == '\\' || pchar == '.' ||
! 					 pchar == '^' || pchar == '$')
  			{
  				*r++ = '\\';
  				*r++ = pchar;
  			}
! 			else
! 				*r++ = pchar;
! 			p++, plen--;
  		}
! 		else
  		{
! 			if (afterescape)
! 			{
  				*r++ = '\\';
! 				memcpy(r, p, mblen);
! 				r += mblen;
! 				afterescape = false;
! 			}
! 			else if (e && elen == mblen && memcmp(e, p, mblen) == 0)
! 			{
! 				/* SQL99 escape character; do not send to output */
! 				afterescape = true;
! 			}
! 			else
! 			{
! 				memcpy(r, p, mblen);
! 				r += mblen;
! 			}
! 
! 			p += mblen;
! 			plen -= mblen;
  		}
  	}
  
  	*r++ = ')';
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to