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