2000-09-05 22:25:14 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* quote.c
|
|
|
|
* Functions for quoting identifiers and literals
|
|
|
|
*
|
2008-01-01 20:46:01 +01:00
|
|
|
* Portions Copyright (c) 2000-2008, PostgreSQL Global Development Group
|
2000-09-05 22:25:14 +02:00
|
|
|
*
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
2008-01-01 20:46:01 +01:00
|
|
|
* $PostgreSQL: pgsql/src/backend/utils/adt/quote.c,v 1.23 2008/01/01 19:45:52 momjian Exp $
|
2000-09-05 22:25:14 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
|
|
|
|
|
|
#include "utils/builtins.h"
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* quote_ident -
|
|
|
|
* returns a properly quoted identifier
|
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
quote_ident(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
text *t = PG_GETARG_TEXT_P(0);
|
|
|
|
text *result;
|
2005-03-21 17:29:20 +01:00
|
|
|
const char *qstr;
|
|
|
|
char *str;
|
|
|
|
int len;
|
2000-09-05 22:25:14 +02:00
|
|
|
|
2005-03-21 17:29:20 +01:00
|
|
|
/* 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';
|
2000-09-05 22:25:14 +02:00
|
|
|
|
2005-03-21 17:29:20 +01:00
|
|
|
qstr = quote_identifier(str);
|
|
|
|
|
|
|
|
len = strlen(qstr);
|
|
|
|
result = (text *) palloc(len + VARHDRSZ);
|
2007-02-28 00:48:10 +01:00
|
|
|
SET_VARSIZE(result, len + VARHDRSZ);
|
2005-03-21 17:29:20 +01:00
|
|
|
memcpy(VARDATA(result), qstr, len);
|
2000-09-05 22:25:14 +02:00
|
|
|
|
2000-09-12 21:39:42 +02:00
|
|
|
PG_RETURN_TEXT_P(result);
|
2000-09-05 22:25:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* quote_literal -
|
|
|
|
* returns a properly quoted literal
|
2006-05-28 23:13:54 +02:00
|
|
|
*
|
|
|
|
* NOTE: think not to make this function's behavior change with
|
|
|
|
* standard_conforming_strings. We don't know where the result
|
|
|
|
* literal will be used, and so we must generate a result that
|
|
|
|
* will work with either setting. Take a look at what dblink
|
|
|
|
* uses this for before thinking you know better.
|
2000-09-05 22:25:14 +02:00
|
|
|
*/
|
|
|
|
Datum
|
|
|
|
quote_literal(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
text *t = PG_GETARG_TEXT_P(0);
|
|
|
|
text *result;
|
2001-03-22 05:01:46 +01:00
|
|
|
char *cp1;
|
|
|
|
char *cp2;
|
|
|
|
int len;
|
2000-09-05 22:25:14 +02:00
|
|
|
|
2005-03-21 17:29:20 +01:00
|
|
|
len = VARSIZE(t) - VARHDRSZ;
|
|
|
|
/* We make a worst-case result area; wasting a little space is OK */
|
2005-07-02 19:01:59 +02:00
|
|
|
result = (text *) palloc(len * 2 + 3 + VARHDRSZ);
|
2000-09-05 22:25:14 +02:00
|
|
|
|
2005-03-21 17:29:20 +01:00
|
|
|
cp1 = VARDATA(t);
|
2000-09-05 22:25:14 +02:00
|
|
|
cp2 = VARDATA(result);
|
|
|
|
|
2006-05-28 23:13:54 +02:00
|
|
|
for (; len-- > 0; cp1++)
|
|
|
|
{
|
|
|
|
if (*cp1 == '\\')
|
|
|
|
{
|
|
|
|
*cp2++ = ESCAPE_STRING_SYNTAX;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2005-07-02 19:01:59 +02:00
|
|
|
len = VARSIZE(t) - VARHDRSZ;
|
|
|
|
cp1 = VARDATA(t);
|
2006-05-28 23:13:54 +02:00
|
|
|
|
2000-09-05 22:25:14 +02:00
|
|
|
*cp2++ = '\'';
|
2005-03-21 17:29:20 +01:00
|
|
|
while (len-- > 0)
|
2000-09-05 22:25:14 +02:00
|
|
|
{
|
2006-05-28 23:13:54 +02:00
|
|
|
if (SQL_STR_DOUBLE(*cp1, true))
|
2005-07-02 19:01:59 +02:00
|
|
|
*cp2++ = *cp1;
|
2005-03-21 17:29:20 +01:00
|
|
|
*cp2++ = *cp1++;
|
2000-09-05 22:25:14 +02:00
|
|
|
}
|
|
|
|
*cp2++ = '\'';
|
|
|
|
|
2007-02-28 00:48:10 +01:00
|
|
|
SET_VARSIZE(result, cp2 - ((char *) result));
|
2000-09-05 22:25:14 +02:00
|
|
|
|
2005-03-21 17:29:20 +01:00
|
|
|
PG_RETURN_TEXT_P(result);
|
2000-09-05 22:25:14 +02:00
|
|
|
}
|