1
0
mirror of https://github.com/postgres/postgres.git synced 2025-04-29 13:56:47 +03:00
Noah Misch 3a0d473192 Use wrappers of PG_DETOAST_DATUM_PACKED() more.
This makes almost all core code follow the policy introduced in the
previous commit.  Specific decisions:

- Text search support functions with char* and length arguments, such as
  prsstart and lexize, may receive unaligned strings.  I doubt
  maintainers of non-core text search code will notice.

- Use plain VARDATA() on values detoasted or synthesized earlier in the
  same function.  Use VARDATA_ANY() on varlenas sourced outside the
  function, even if they happen to always have four-byte headers.  As an
  exception, retain the universal practice of using VARDATA() on return
  values of SendFunctionCall().

- Retain PG_GETARG_BYTEA_P() in pageinspect.  (Page images are too large
  for a one-byte header, so this misses no optimization.)  Sites that do
  not call get_page_from_raw() typically need the four-byte alignment.

- For now, do not change btree_gist.  Its use of four-byte headers in
  memory is partly entangled with storage of 4-byte headers inside
  GBT_VARKEY, on disk.

- For now, do not change gtrgm_consistent() or gtrgm_distance().  They
  incorporate the varlena header into a cache, and there are multiple
  credible implementation strategies to consider.
2017-03-12 19:35:34 -04:00

132 lines
2.6 KiB
C

/*-------------------------------------------------------------------------
*
* quote.c
* Functions for quoting identifiers and literals
*
* Portions Copyright (c) 2000-2017, PostgreSQL Global Development Group
*
*
* IDENTIFICATION
* src/backend/utils/adt/quote.c
*
*-------------------------------------------------------------------------
*/
#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_PP(0);
const char *qstr;
char *str;
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;
char *savedst = dst;
for (s = src; s < src + len; s++)
{
if (*s == '\\')
{
*dst++ = ESCAPE_STRING_SYNTAX;
break;
}
}
*dst++ = '\'';
while (len-- > 0)
{
if (SQL_STR_DOUBLE(*src, true))
*dst++ = *src;
*dst++ = *src++;
}
*dst++ = '\'';
return dst - savedst;
}
/*
* quote_literal -
* returns a properly quoted literal
*/
Datum
quote_literal(PG_FUNCTION_ARGS)
{
text *t = PG_GETARG_TEXT_PP(0);
text *result;
char *cp1;
char *cp2;
int len;
len = VARSIZE_ANY_EXHDR(t);
/* We make a worst-case result area; wasting a little space is OK */
result = (text *) palloc(len * 2 + 3 + VARHDRSZ);
cp1 = VARDATA_ANY(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;
int len;
int newlen;
len = strlen(rawstr);
/* We make a worst-case result area; wasting a little space is OK */
result = 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)));
}