*
* quote.c
* Functions for quoting identifiers and literals
*
* Portions Copyright (c) 2000-2012, PostgreSQL Global Development Group
*
*
* IDENTIFICATION
* src/backend/utils/adt/quote.c
*
* -------------------------------------------------------------------------
*/
#include "postgres.h"
#include "knl/knl_variable.h"
#include "mb/pg_wchar.h"
#include "utils/builtins.h"
* quote_ident -
* returns a properly quoted identifier
*/
Datum quote_ident(PG_FUNCTION_ARGS)
{
text* t = PG_GETARG_TEXT_PP(0);
const char* qstr = NULL;
char* str = NULL;
str = text_to_cstring(t);
qstr = quote_identifier(str);
PG_RETURN_TEXT_P(cstring_to_text(qstr));
}
* quote_literal_internal -
* helper function for quote_literal and quote_literal_cstr
*
* 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.
*/
static size_t quote_literal_internal(char* dst, const char* src, size_t len)
{
const char* s = NULL;
char* savedst = dst;
int charlen;
s = src;
while (s < src + len) {
if (*s == '\\') {
*dst++ = ESCAPE_STRING_SYNTAX;
break;
}
s += pg_mblen(s);
}
*dst++ = '\'';
while (len > 0) {
if (SQL_STR_DOUBLE(*src, true))
*dst++ = *src;
charlen = pg_mblen(src);
if (DB_IS_CMPT(B_FORMAT) && (size_t)charlen > len) {
ereport(ERROR,
(errmsg("Cannot convert string 0x%02x to %s",
(unsigned char)*src, GetDatabaseEncodingName())));
}
for (int i = 0; i < charlen; i++)
*dst++ = *src++;
len -= charlen;
}
*dst++ = '\'';
return dst - savedst;
}
* quote_literal -
* returns a properly quoted literal
*/
Datum quote_literal(PG_FUNCTION_ARGS)
{
text* t = PG_GETARG_TEXT_P(0);
text* result = NULL;
char* cp1 = NULL;
char* cp2 = NULL;
int len;
FUNC_CHECK_HUGE_POINTER(false, t, "quote_literal()");
len = VARSIZE(t) - VARHDRSZ;
if (unlikely(len < 0)) {
ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("The length should not be nagative: %d.\n", len)));
}
result = (text*)palloc(len * 2 + 3 + VARHDRSZ);
cp1 = VARDATA(t);
cp2 = VARDATA(result);
SET_VARSIZE(result, VARHDRSZ + quote_literal_internal(cp2, cp1, len));
PG_RETURN_TEXT_P(result);
}
* quote_literal_cstr -
* returns a properly quoted literal
*/
char* quote_literal_cstr(const char* rawstr)
{
char* result = NULL;
int len;
int newlen;
len = strlen(rawstr);
result = (char*)palloc(len * 2 + 3 + 1);
newlen = quote_literal_internal(result, rawstr, len);
result[newlen] = '\0';
return result;
}
* quote_nullable -
* Returns a properly quoted literal, with null values returned
* as the text string 'NULL'.
*/
Datum quote_nullable(PG_FUNCTION_ARGS)
{
if (PG_ARGISNULL(0))
PG_RETURN_TEXT_P(cstring_to_text("NULL"));
else
PG_RETURN_DATUM(DirectFunctionCall1(quote_literal, PG_GETARG_DATUM(0)));
}