mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-05 19:09:58 +08:00
Added functions
quote_ident(text) returns text quote_literal(text) returns text These are handy to build up properly quoted query strings for the new PL/pgSQL EXECUTE functionality to submit dynamic DDL statements. Jan
This commit is contained in:
parent
d7f1e11026
commit
daf1e3a702
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Makefile for utils/adt
|
||||
#
|
||||
# $Header: /cvsroot/pgsql/src/backend/utils/adt/Makefile,v 1.45 2000/08/31 16:10:45 petere Exp $
|
||||
# $Header: /cvsroot/pgsql/src/backend/utils/adt/Makefile,v 1.46 2000/09/05 20:25:12 wieck Exp $
|
||||
#
|
||||
|
||||
subdir = src/backend/utils/adt
|
||||
@ -24,7 +24,7 @@ OBJS = acl.o arrayfuncs.o arrayutils.o bool.o cash.o char.o \
|
||||
tid.o timestamp.o varbit.o varchar.o varlena.o version.o \
|
||||
network.o mac.o inet_net_ntop.o inet_net_pton.o \
|
||||
ri_triggers.o pg_lzcompress.o pg_locale.o formatting.o \
|
||||
ascii.o
|
||||
ascii.o quote.o
|
||||
|
||||
all: SUBSYS.o
|
||||
|
||||
|
291
src/backend/utils/adt/quote.c
Normal file
291
src/backend/utils/adt/quote.c
Normal file
@ -0,0 +1,291 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* quote.c
|
||||
* Functions for quoting identifiers and literals
|
||||
*
|
||||
* Portions Copyright (c) 2000, PostgreSQL, Inc
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/quote.c,v 1.1 2000/09/05 20:25:13 wieck Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include <ctype.h>
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "mb/pg_wchar.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 -
|
||||
* returns a properly quoted identifier
|
||||
*/
|
||||
Datum
|
||||
quote_ident(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *t = PG_GETARG_TEXT_P(0);
|
||||
text *result;
|
||||
|
||||
if (quote_ident_required(t))
|
||||
{
|
||||
result = do_quote_ident(t);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = (text *)palloc(VARSIZE(t));
|
||||
memcpy(result, t, VARSIZE(t));
|
||||
}
|
||||
|
||||
PG_FREE_IF_COPY(t, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* quote_literal -
|
||||
* returns a properly quoted literal
|
||||
*/
|
||||
Datum
|
||||
quote_literal(PG_FUNCTION_ARGS)
|
||||
{
|
||||
text *t = PG_GETARG_TEXT_P(0);
|
||||
text *result;
|
||||
|
||||
result = do_quote_literal(t);
|
||||
|
||||
PG_FREE_IF_COPY(t, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* MULTIBYTE dependant internal functions follow
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MULTIBYTE
|
||||
|
||||
/* 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 (!(*cp == '_' || (*cp >= 'a' && *cp <= 'z')))
|
||||
return true;
|
||||
|
||||
while((++cp) < ep)
|
||||
{
|
||||
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;
|
||||
|
||||
len = VARSIZE(iptr) - VARHDRSZ;
|
||||
result = (text *)palloc(len * 2 + VARHDRSZ + 2);
|
||||
|
||||
cp1 = VARDATA(iptr);
|
||||
cp2 = VARDATA(result);
|
||||
|
||||
*cp2++ = '"';
|
||||
while(len-- > 0)
|
||||
{
|
||||
if (*cp1 == '"')
|
||||
*cp2++ = '"';
|
||||
if (*cp1 == '\\')
|
||||
*cp2++ = '\\';
|
||||
*cp2++ = *cp1++;
|
||||
}
|
||||
*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;
|
||||
|
||||
len = VARSIZE(lptr) - VARHDRSZ;
|
||||
result = (text *)palloc(len * 2 + VARHDRSZ + 2);
|
||||
|
||||
cp1 = VARDATA(lptr);
|
||||
cp2 = VARDATA(result);
|
||||
|
||||
*cp2++ = '\'';
|
||||
while(len-- > 0)
|
||||
{
|
||||
if (*cp1 == '\'')
|
||||
*cp2++ = '\'';
|
||||
if (*cp1 == '\\')
|
||||
*cp2++ = '\\';
|
||||
*cp2++ = *cp1++;
|
||||
}
|
||||
*cp2++ = '\'';
|
||||
|
||||
VARATT_SIZEP(result) = cp2 - ((char *)result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* Check if a given identifier needs quoting (MULTIBYTE version) */
|
||||
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 (MULTIBYTE version) */
|
||||
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++ = '"';
|
||||
if (*cp1 == '\\')
|
||||
*cp2++ = '\\';
|
||||
*cp2++ = *cp1++;
|
||||
|
||||
len--;
|
||||
}
|
||||
*cp2++ = '"';
|
||||
|
||||
VARATT_SIZEP(result) = cp2 - ((char *)result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Return a properly quoted literal value (MULTIBYTE version) */
|
||||
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;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: pg_proc.h,v 1.164 2000/08/24 03:29:08 tgl Exp $
|
||||
* $Id: pg_proc.h,v 1.165 2000/09/05 20:25:13 wieck Exp $
|
||||
*
|
||||
* NOTES
|
||||
* The script catalog/genbki.sh reads this file and generates .bki
|
||||
@ -2409,6 +2409,11 @@ DESCR("convert text to timestamp");
|
||||
DATA(insert OID = 1780 ( to_date PGUID 12 f t f t 2 f 1082 "25 25" 100 0 0 100 to_date - ));
|
||||
DESCR("convert text to date");
|
||||
|
||||
DATA(insert OID = 1282 ( quote_ident PGUID 12 f t t t 1 f 25 "25" 100 0 0 100 quote_ident - ));
|
||||
DESCR("quote an identifier for usage in a querystring");
|
||||
DATA(insert OID = 1283 ( quote_literal PGUID 12 f t t t 1 f 25 "25" 100 0 0 100 quote_literal - ));
|
||||
DESCR("quote a literal for usage in a querystring");
|
||||
|
||||
DATA(insert OID = 1798 ( oidin PGUID 12 f t t t 1 f 26 "0" 100 0 0 100 oidin - ));
|
||||
DESCR("(internal)");
|
||||
DATA(insert OID = 1799 ( oidout PGUID 12 f t t t 1 f 23 "0" 100 0 0 100 oidout - ));
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: builtins.h,v 1.135 2000/08/25 18:05:53 tgl Exp $
|
||||
* $Id: builtins.h,v 1.136 2000/09/05 20:25:14 wieck Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -585,4 +585,8 @@ extern Datum format_type(PG_FUNCTION_ARGS);
|
||||
extern Datum oidvectortypes(PG_FUNCTION_ARGS);
|
||||
extern int32 type_maximum_size(Oid type_oid, int32 typemod);
|
||||
|
||||
/* quote.c */
|
||||
extern Datum quote_ident(PG_FUNCTION_ARGS);
|
||||
extern Datum quote_literal(PG_FUNCTION_ARGS);
|
||||
|
||||
#endif /* BUILTINS_H */
|
||||
|
Loading…
Reference in New Issue
Block a user