Skip to content

Commit daf1e3a

Browse files
Jan WieckJan Wieck
authored andcommitted
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
1 parent d7f1e11 commit daf1e3a

File tree

4 files changed

+304
-4
lines changed

4 files changed

+304
-4
lines changed

src/backend/utils/adt/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#
22
# Makefile for utils/adt
33
#
4-
# $Header: /cvsroot/pgsql/src/backend/utils/adt/Makefile,v 1.45 2000/08/31 16:10:45 petere Exp $
4+
# $Header: /cvsroot/pgsql/src/backend/utils/adt/Makefile,v 1.46 2000/09/05 20:25:12 wieck Exp $
55
#
66

77
subdir = src/backend/utils/adt
@@ -24,7 +24,7 @@ OBJS = acl.o arrayfuncs.o arrayutils.o bool.o cash.o char.o \
2424
tid.o timestamp.o varbit.o varchar.o varlena.o version.o \
2525
network.o mac.o inet_net_ntop.o inet_net_pton.o \
2626
ri_triggers.o pg_lzcompress.o pg_locale.o formatting.o \
27-
ascii.o
27+
ascii.o quote.o
2828

2929
all: SUBSYS.o
3030

src/backend/utils/adt/quote.c

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* quote.c
4+
* Functions for quoting identifiers and literals
5+
*
6+
* Portions Copyright (c) 2000, PostgreSQL, Inc
7+
*
8+
*
9+
* IDENTIFICATION
10+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/quote.c,v 1.1 2000/09/05 20:25:13 wieck Exp $
11+
*
12+
*-------------------------------------------------------------------------
13+
*/
14+
#include <ctype.h>
15+
16+
#include "postgres.h"
17+
18+
#include "mb/pg_wchar.h"
19+
#include "utils/builtins.h"
20+
21+
22+
static bool quote_ident_required(text *iptr);
23+
static text *do_quote_ident(text *iptr);
24+
static text *do_quote_literal(text *iptr);
25+
26+
27+
/*
28+
* quote_ident -
29+
* returns a properly quoted identifier
30+
*/
31+
Datum
32+
quote_ident(PG_FUNCTION_ARGS)
33+
{
34+
text *t = PG_GETARG_TEXT_P(0);
35+
text *result;
36+
37+
if (quote_ident_required(t))
38+
{
39+
result = do_quote_ident(t);
40+
}
41+
else
42+
{
43+
result = (text *)palloc(VARSIZE(t));
44+
memcpy(result, t, VARSIZE(t));
45+
}
46+
47+
PG_FREE_IF_COPY(t, 0);
48+
49+
return result;
50+
}
51+
52+
/*
53+
* quote_literal -
54+
* returns a properly quoted literal
55+
*/
56+
Datum
57+
quote_literal(PG_FUNCTION_ARGS)
58+
{
59+
text *t = PG_GETARG_TEXT_P(0);
60+
text *result;
61+
62+
result = do_quote_literal(t);
63+
64+
PG_FREE_IF_COPY(t, 0);
65+
66+
return result;
67+
}
68+
69+
70+
/*
71+
* MULTIBYTE dependant internal functions follow
72+
*
73+
*/
74+
75+
76+
#ifndef MULTIBYTE
77+
78+
/* Check if a given identifier needs quoting */
79+
static bool
80+
quote_ident_required(text *iptr)
81+
{
82+
char *cp;
83+
char *ep;
84+
85+
cp = VARDATA(iptr);
86+
ep = VARDATA(iptr) + VARSIZE(iptr) - VARHDRSZ;
87+
88+
if (cp >= ep)
89+
return true;
90+
91+
if (!(*cp == '_' || (*cp >= 'a' && *cp <= 'z')))
92+
return true;
93+
94+
while((++cp) < ep)
95+
{
96+
if (*cp >= 'a' && *cp <= 'z') continue;
97+
if (*cp >= '0' && *cp <= '9') continue;
98+
if (*cp == '_') continue;
99+
100+
return true;
101+
}
102+
103+
return false;
104+
}
105+
106+
/* Return a properly quoted identifier */
107+
static text *
108+
do_quote_ident(text *iptr)
109+
{
110+
text *result;
111+
char *cp1;
112+
char *cp2;
113+
int len;
114+
115+
len = VARSIZE(iptr) - VARHDRSZ;
116+
result = (text *)palloc(len * 2 + VARHDRSZ + 2);
117+
118+
cp1 = VARDATA(iptr);
119+
cp2 = VARDATA(result);
120+
121+
*cp2++ = '"';
122+
while(len-- > 0)
123+
{
124+
if (*cp1 == '"')
125+
*cp2++ = '"';
126+
if (*cp1 == '\\')
127+
*cp2++ = '\\';
128+
*cp2++ = *cp1++;
129+
}
130+
*cp2++ = '"';
131+
132+
VARATT_SIZEP(result) = cp2 - ((char *)result);
133+
134+
return result;
135+
}
136+
137+
/* Return a properly quoted literal value */
138+
static text *
139+
do_quote_literal(text *lptr)
140+
{
141+
text *result;
142+
char *cp1;
143+
char *cp2;
144+
int len;
145+
146+
len = VARSIZE(lptr) - VARHDRSZ;
147+
result = (text *)palloc(len * 2 + VARHDRSZ + 2);
148+
149+
cp1 = VARDATA(lptr);
150+
cp2 = VARDATA(result);
151+
152+
*cp2++ = '\'';
153+
while(len-- > 0)
154+
{
155+
if (*cp1 == '\'')
156+
*cp2++ = '\'';
157+
if (*cp1 == '\\')
158+
*cp2++ = '\\';
159+
*cp2++ = *cp1++;
160+
}
161+
*cp2++ = '\'';
162+
163+
VARATT_SIZEP(result) = cp2 - ((char *)result);
164+
165+
return result;
166+
}
167+
168+
#else
169+
170+
/* Check if a given identifier needs quoting (MULTIBYTE version) */
171+
static bool
172+
quote_ident_required(text *iptr)
173+
{
174+
char *cp;
175+
char *ep;
176+
177+
cp = VARDATA(iptr);
178+
ep = VARDATA(iptr) + VARSIZE(iptr) - VARHDRSZ;
179+
180+
if (cp >= ep)
181+
return true;
182+
183+
if(pg_mblen(cp) != 1)
184+
return true;
185+
if (!(*cp == '_' || (*cp >= 'a' && *cp <= 'z')))
186+
return true;
187+
188+
while((++cp) < ep)
189+
{
190+
if (pg_mblen(cp) != 1)
191+
return true;
192+
193+
if (*cp >= 'a' && *cp <= 'z') continue;
194+
if (*cp >= '0' && *cp <= '9') continue;
195+
if (*cp == '_') continue;
196+
197+
return true;
198+
}
199+
200+
return false;
201+
}
202+
203+
/* Return a properly quoted identifier (MULTIBYTE version) */
204+
static text *
205+
do_quote_ident(text *iptr)
206+
{
207+
text *result;
208+
char *cp1;
209+
char *cp2;
210+
int len;
211+
int wl;
212+
213+
len = VARSIZE(iptr) - VARHDRSZ;
214+
result = (text *)palloc(len * 2 + VARHDRSZ + 2);
215+
216+
cp1 = VARDATA(iptr);
217+
cp2 = VARDATA(result);
218+
219+
*cp2++ = '"';
220+
while(len > 0)
221+
{
222+
if ((wl = pg_mblen(cp1)) != 1)
223+
{
224+
len -= wl;
225+
226+
while(wl-- > 0)
227+
*cp2++ = *cp1++;
228+
continue;
229+
}
230+
231+
if (*cp1 == '"')
232+
*cp2++ = '"';
233+
if (*cp1 == '\\')
234+
*cp2++ = '\\';
235+
*cp2++ = *cp1++;
236+
237+
len--;
238+
}
239+
*cp2++ = '"';
240+
241+
VARATT_SIZEP(result) = cp2 - ((char *)result);
242+
243+
return result;
244+
}
245+
246+
/* Return a properly quoted literal value (MULTIBYTE version) */
247+
static text *
248+
do_quote_literal(text *lptr)
249+
{
250+
text *result;
251+
char *cp1;
252+
char *cp2;
253+
int len;
254+
int wl;
255+
256+
len = VARSIZE(lptr) - VARHDRSZ;
257+
result = (text *)palloc(len * 2 + VARHDRSZ + 2);
258+
259+
cp1 = VARDATA(lptr);
260+
cp2 = VARDATA(result);
261+
262+
*cp2++ = '\'';
263+
while(len > 0)
264+
{
265+
if ((wl = pg_mblen(cp1)) != 1)
266+
{
267+
len -= wl;
268+
269+
while(wl-- > 0)
270+
*cp2++ = *cp1++;
271+
continue;
272+
}
273+
274+
if (*cp1 == '\'')
275+
*cp2++ = '\'';
276+
if (*cp1 == '\\')
277+
*cp2++ = '\\';
278+
*cp2++ = *cp1++;
279+
280+
len--;
281+
}
282+
*cp2++ = '\'';
283+
284+
VARATT_SIZEP(result) = cp2 - ((char *)result);
285+
286+
return result;
287+
}
288+
289+
#endif
290+
291+

src/include/catalog/pg_proc.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: pg_proc.h,v 1.164 2000/08/24 03:29:08 tgl Exp $
10+
* $Id: pg_proc.h,v 1.165 2000/09/05 20:25:13 wieck Exp $
1111
*
1212
* NOTES
1313
* The script catalog/genbki.sh reads this file and generates .bki
@@ -2409,6 +2409,11 @@ DESCR("convert text to timestamp");
24092409
DATA(insert OID = 1780 ( to_date PGUID 12 f t f t 2 f 1082 "25 25" 100 0 0 100 to_date - ));
24102410
DESCR("convert text to date");
24112411

2412+
DATA(insert OID = 1282 ( quote_ident PGUID 12 f t t t 1 f 25 "25" 100 0 0 100 quote_ident - ));
2413+
DESCR("quote an identifier for usage in a querystring");
2414+
DATA(insert OID = 1283 ( quote_literal PGUID 12 f t t t 1 f 25 "25" 100 0 0 100 quote_literal - ));
2415+
DESCR("quote a literal for usage in a querystring");
2416+
24122417
DATA(insert OID = 1798 ( oidin PGUID 12 f t t t 1 f 26 "0" 100 0 0 100 oidin - ));
24132418
DESCR("(internal)");
24142419
DATA(insert OID = 1799 ( oidout PGUID 12 f t t t 1 f 23 "0" 100 0 0 100 oidout - ));

src/include/utils/builtins.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: builtins.h,v 1.135 2000/08/25 18:05:53 tgl Exp $
10+
* $Id: builtins.h,v 1.136 2000/09/05 20:25:14 wieck Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -585,4 +585,8 @@ extern Datum format_type(PG_FUNCTION_ARGS);
585585
extern Datum oidvectortypes(PG_FUNCTION_ARGS);
586586
extern int32 type_maximum_size(Oid type_oid, int32 typemod);
587587

588+
/* quote.c */
589+
extern Datum quote_ident(PG_FUNCTION_ARGS);
590+
extern Datum quote_literal(PG_FUNCTION_ARGS);
591+
588592
#endif /* BUILTINS_H */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy