mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04:00 
			
		
		
		
	Fix quote_ident to use quote_identifier rather than its own, not quite
up-to-speed logic; in particular this will cause it to quote names that match keywords. Remove unnecessary multibyte cruft from quote_literal (all backend-internal encodings are 8-bit-safe).
This commit is contained in:
		
							parent
							
								
									6a8eb1a7b6
								
							
						
					
					
						commit
						775d28302c
					
				| @ -7,23 +7,15 @@ | ||||
|  * | ||||
|  * | ||||
|  * IDENTIFICATION | ||||
|  *	  $PostgreSQL: pgsql/src/backend/utils/adt/quote.c,v 1.14 2005/01/01 05:43:07 momjian Exp $ | ||||
|  *	  $PostgreSQL: pgsql/src/backend/utils/adt/quote.c,v 1.15 2005/03/21 16:29:20 tgl Exp $ | ||||
|  * | ||||
|  *------------------------------------------------------------------------- | ||||
|  */ | ||||
| #include "postgres.h" | ||||
| 
 | ||||
| #include <ctype.h> | ||||
| 
 | ||||
| #include "mb/pg_wchar.h" | ||||
| #include "utils/builtins.h" | ||||
| 
 | ||||
| 
 | ||||
| static bool quote_ident_required(text *iptr); | ||||
| static text *do_quote_ident(text *iptr); | ||||
| static text *do_quote_literal(text *iptr); | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  * quote_ident - | ||||
|  *	  returns a properly quoted identifier | ||||
| @ -33,16 +25,22 @@ quote_ident(PG_FUNCTION_ARGS) | ||||
| { | ||||
| 	text	   *t = PG_GETARG_TEXT_P(0); | ||||
| 	text	   *result; | ||||
| 	const char *qstr; | ||||
| 	char	   *str; | ||||
| 	int			len; | ||||
| 
 | ||||
| 	if (quote_ident_required(t)) | ||||
| 		result = do_quote_ident(t); | ||||
| 	else | ||||
| 	{ | ||||
| 		result = (text *) palloc(VARSIZE(t)); | ||||
| 		memcpy(result, t, VARSIZE(t)); | ||||
| 	} | ||||
| 	/* We have to convert to a C string to use quote_identifier */ | ||||
| 	len = VARSIZE(t) - VARHDRSZ; | ||||
| 	str = (char *) palloc(len + 1); | ||||
| 	memcpy(str, VARDATA(t), len); | ||||
| 	str[len] = '\0'; | ||||
| 
 | ||||
| 	PG_FREE_IF_COPY(t, 0); | ||||
| 	qstr = quote_identifier(str); | ||||
| 
 | ||||
| 	len = strlen(qstr); | ||||
| 	result = (text *) palloc(len + VARHDRSZ); | ||||
| 	VARATT_SIZEP(result) = len + VARHDRSZ; | ||||
| 	memcpy(VARDATA(result), qstr, len); | ||||
| 
 | ||||
| 	PG_RETURN_TEXT_P(result); | ||||
| } | ||||
| @ -56,136 +54,30 @@ quote_literal(PG_FUNCTION_ARGS) | ||||
| { | ||||
| 	text	   *t = PG_GETARG_TEXT_P(0); | ||||
| 	text	   *result; | ||||
| 	char	   *cp1; | ||||
| 	char	   *cp2; | ||||
| 	int			len; | ||||
| 
 | ||||
| 	result = do_quote_literal(t); | ||||
| 	len = VARSIZE(t) - VARHDRSZ; | ||||
| 	/* We make a worst-case result area; wasting a little space is OK */ | ||||
| 	result = (text *) palloc(len * 2 + 2 + VARHDRSZ); | ||||
| 
 | ||||
| 	PG_FREE_IF_COPY(t, 0); | ||||
| 	cp1 = VARDATA(t); | ||||
| 	cp2 = VARDATA(result); | ||||
| 
 | ||||
| 	*cp2++ = '\''; | ||||
| 	while (len-- > 0) | ||||
| 	{ | ||||
| 		if (*cp1 == '\'') | ||||
| 			*cp2++ = '\''; | ||||
| 		else if (*cp1 == '\\') | ||||
| 			*cp2++ = '\\'; | ||||
| 
 | ||||
| 		*cp2++ = *cp1++; | ||||
| 	} | ||||
| 	*cp2++ = '\''; | ||||
| 
 | ||||
| 	VARATT_SIZEP(result) = cp2 - ((char *) result); | ||||
| 
 | ||||
| 	PG_RETURN_TEXT_P(result); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Check if a given identifier needs quoting | ||||
|  */ | ||||
| static bool | ||||
| quote_ident_required(text *iptr) | ||||
| { | ||||
| 	char	   *cp; | ||||
| 	char	   *ep; | ||||
| 
 | ||||
| 	cp = VARDATA(iptr); | ||||
| 	ep = VARDATA(iptr) + VARSIZE(iptr) - VARHDRSZ; | ||||
| 
 | ||||
| 	if (cp >= ep) | ||||
| 		return true; | ||||
| 
 | ||||
| 	if (pg_mblen(cp) != 1) | ||||
| 		return true; | ||||
| 	if (!(*cp == '_' || (*cp >= 'a' && *cp <= 'z'))) | ||||
| 		return true; | ||||
| 
 | ||||
| 	while ((++cp) < ep) | ||||
| 	{ | ||||
| 		if (pg_mblen(cp) != 1) | ||||
| 			return true; | ||||
| 
 | ||||
| 		if (*cp >= 'a' && *cp <= 'z') | ||||
| 			continue; | ||||
| 		if (*cp >= '0' && *cp <= '9') | ||||
| 			continue; | ||||
| 		if (*cp == '_') | ||||
| 			continue; | ||||
| 
 | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Return a properly quoted identifier | ||||
|  */ | ||||
| static text * | ||||
| do_quote_ident(text *iptr) | ||||
| { | ||||
| 	text	   *result; | ||||
| 	char	   *cp1; | ||||
| 	char	   *cp2; | ||||
| 	int			len; | ||||
| 	int			wl; | ||||
| 
 | ||||
| 	len = VARSIZE(iptr) - VARHDRSZ; | ||||
| 	result = (text *) palloc(len * 2 + VARHDRSZ + 2); | ||||
| 
 | ||||
| 	cp1 = VARDATA(iptr); | ||||
| 	cp2 = VARDATA(result); | ||||
| 
 | ||||
| 	*cp2++ = '"'; | ||||
| 	while (len > 0) | ||||
| 	{ | ||||
| 		if ((wl = pg_mblen(cp1)) != 1) | ||||
| 		{ | ||||
| 			len -= wl; | ||||
| 
 | ||||
| 			while (wl-- > 0) | ||||
| 				*cp2++ = *cp1++; | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		if (*cp1 == '"') | ||||
| 			*cp2++ = '"'; | ||||
| 		*cp2++ = *cp1++; | ||||
| 
 | ||||
| 		len--; | ||||
| 	} | ||||
| 	*cp2++ = '"'; | ||||
| 
 | ||||
| 	VARATT_SIZEP(result) = cp2 - ((char *) result); | ||||
| 
 | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Return a properly quoted literal value | ||||
|  */ | ||||
| static text * | ||||
| do_quote_literal(text *lptr) | ||||
| { | ||||
| 	text	   *result; | ||||
| 	char	   *cp1; | ||||
| 	char	   *cp2; | ||||
| 	int			len; | ||||
| 	int			wl; | ||||
| 
 | ||||
| 	len = VARSIZE(lptr) - VARHDRSZ; | ||||
| 	result = (text *) palloc(len * 2 + VARHDRSZ + 2); | ||||
| 
 | ||||
| 	cp1 = VARDATA(lptr); | ||||
| 	cp2 = VARDATA(result); | ||||
| 
 | ||||
| 	*cp2++ = '\''; | ||||
| 	while (len > 0) | ||||
| 	{ | ||||
| 		if ((wl = pg_mblen(cp1)) != 1) | ||||
| 		{ | ||||
| 			len -= wl; | ||||
| 
 | ||||
| 			while (wl-- > 0) | ||||
| 				*cp2++ = *cp1++; | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		if (*cp1 == '\'') | ||||
| 			*cp2++ = '\''; | ||||
| 		if (*cp1 == '\\') | ||||
| 			*cp2++ = '\\'; | ||||
| 		*cp2++ = *cp1++; | ||||
| 
 | ||||
| 		len--; | ||||
| 	} | ||||
| 	*cp2++ = '\''; | ||||
| 
 | ||||
| 	VARATT_SIZEP(result) = cp2 - ((char *) result); | ||||
| 
 | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user