mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-30 00:04:49 -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 |  * 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 "postgres.h" | ||||||
| 
 | 
 | ||||||
| #include <ctype.h> |  | ||||||
| 
 |  | ||||||
| #include "mb/pg_wchar.h" |  | ||||||
| #include "utils/builtins.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 - |  * quote_ident - | ||||||
|  *	  returns a properly quoted identifier |  *	  returns a properly quoted identifier | ||||||
| @ -33,16 +25,22 @@ quote_ident(PG_FUNCTION_ARGS) | |||||||
| { | { | ||||||
| 	text	   *t = PG_GETARG_TEXT_P(0); | 	text	   *t = PG_GETARG_TEXT_P(0); | ||||||
| 	text	   *result; | 	text	   *result; | ||||||
|  | 	const char *qstr; | ||||||
|  | 	char	   *str; | ||||||
|  | 	int			len; | ||||||
| 
 | 
 | ||||||
| 	if (quote_ident_required(t)) | 	/* We have to convert to a C string to use quote_identifier */ | ||||||
| 		result = do_quote_ident(t); | 	len = VARSIZE(t) - VARHDRSZ; | ||||||
| 	else | 	str = (char *) palloc(len + 1); | ||||||
| 	{ | 	memcpy(str, VARDATA(t), len); | ||||||
| 		result = (text *) palloc(VARSIZE(t)); | 	str[len] = '\0'; | ||||||
| 		memcpy(result, t, VARSIZE(t)); |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	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); | 	PG_RETURN_TEXT_P(result); | ||||||
| } | } | ||||||
| @ -56,136 +54,30 @@ quote_literal(PG_FUNCTION_ARGS) | |||||||
| { | { | ||||||
| 	text	   *t = PG_GETARG_TEXT_P(0); | 	text	   *t = PG_GETARG_TEXT_P(0); | ||||||
| 	text	   *result; | 	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); | 	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