Skip to content

Commit db86f29

Browse files
committed
Marginal hack to save a little bit of time in bpcharin() when typmod is -1,
which is a common case.
1 parent 7cac502 commit db86f29

File tree

1 file changed

+50
-48
lines changed

1 file changed

+50
-48
lines changed

src/backend/utils/adt/varchar.c

Lines changed: 50 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/varchar.c,v 1.109 2005/04/12 04:26:26 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/varchar.c,v 1.110 2005/05/29 20:15:59 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -36,8 +36,8 @@
3636
* length also. (eg. in INSERTs, we have the tupleDescriptor which contains
3737
* the length of the attributes and hence the exact length of the char() or
3838
* varchar(). We pass this to bpcharin() or varcharin().) In the case where
39-
* we cannot determine the length, we pass in -1 instead and the input string
40-
* must be null-terminated.
39+
* we cannot determine the length, we pass in -1 instead and the input
40+
* converter does not enforce any length check.
4141
*
4242
* We actually implement this as a varlena so that we don't have to pass in
4343
* the length for the comparison functions. (The difference between these
@@ -72,63 +72,62 @@ bpcharin(PG_FUNCTION_ARGS)
7272
char *r;
7373
size_t len,
7474
maxlen;
75-
int i;
76-
int charlen; /* number of charcters in the input string */
7775

7876
/* verify encoding */
7977
len = strlen(s);
8078
pg_verifymbstr(s, len, false);
8179

82-
charlen = pg_mbstrlen(s);
83-
8480
/* If typmod is -1 (or invalid), use the actual string length */
8581
if (atttypmod < (int32) VARHDRSZ)
86-
maxlen = charlen;
82+
maxlen = len;
8783
else
88-
maxlen = atttypmod - VARHDRSZ;
89-
90-
if (charlen > maxlen)
9184
{
92-
/* Verify that extra characters are spaces, and clip them off */
93-
size_t mbmaxlen = pg_mbcharcliplen(s, len, maxlen);
85+
size_t charlen; /* number of CHARACTERS in the input */
9486

95-
/*
96-
* at this point, len is the actual BYTE length of the input
97-
* string, maxlen is the max number of CHARACTERS allowed for this
98-
* bpchar type.
99-
*/
100-
if (strspn(s + mbmaxlen, " ") == len - mbmaxlen)
101-
len = mbmaxlen;
87+
maxlen = atttypmod - VARHDRSZ;
88+
charlen = pg_mbstrlen(s);
89+
if (charlen > maxlen)
90+
{
91+
/* Verify that extra characters are spaces, and clip them off */
92+
size_t mbmaxlen = pg_mbcharcliplen(s, len, maxlen);
93+
94+
/*
95+
* at this point, len is the actual BYTE length of the input
96+
* string, maxlen is the max number of CHARACTERS allowed for this
97+
* bpchar type.
98+
*/
99+
if (strspn(s + mbmaxlen, " ") == len - mbmaxlen)
100+
len = mbmaxlen;
101+
else
102+
ereport(ERROR,
103+
(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
104+
errmsg("value too long for type character(%d)",
105+
(int) maxlen)));
106+
107+
/*
108+
* Now we set maxlen to the necessary byte length, not
109+
* the number of CHARACTERS!
110+
*/
111+
maxlen = len;
112+
}
102113
else
103-
ereport(ERROR,
104-
(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
105-
errmsg("value too long for type character(%d)",
106-
(int) maxlen)));
107-
108-
/*
109-
* XXX: at this point, maxlen is the necessary byte length, not
110-
* the number of CHARACTERS!
111-
*/
112-
maxlen = len;
113-
}
114-
else
115-
{
116-
/*
117-
* XXX: at this point, maxlen is the necessary byte length, not
118-
* the number of CHARACTERS!
119-
*/
120-
maxlen = len + (maxlen - charlen);
114+
{
115+
/*
116+
* Now we set maxlen to the necessary byte length, not
117+
* the number of CHARACTERS!
118+
*/
119+
maxlen = len + (maxlen - charlen);
120+
}
121121
}
122122

123123
result = palloc(maxlen + VARHDRSZ);
124124
VARATT_SIZEP(result) = maxlen + VARHDRSZ;
125125
r = VARDATA(result);
126-
for (i = 0; i < len; i++)
127-
*r++ = *s++;
126+
memcpy(r, s, len);
128127

129128
/* blank pad the string if necessary */
130-
for (; i < maxlen; i++)
131-
*r++ = ' ';
129+
if (maxlen > len)
130+
memset(r + len, ' ', maxlen - len);
132131

133132
PG_RETURN_BPCHAR_P(result);
134133
}
@@ -200,12 +199,16 @@ bpchar(PG_FUNCTION_ARGS)
200199
int charlen; /* number of charcters in the input string
201200
* + VARHDRSZ */
202201

202+
/* No work if typmod is invalid */
203+
if (maxlen < (int32) VARHDRSZ)
204+
PG_RETURN_BPCHAR_P(source);
205+
203206
len = VARSIZE(source);
204207

205208
charlen = pg_mbstrlen_with_len(VARDATA(source), len - VARHDRSZ) + VARHDRSZ;
206209

207-
/* No work if typmod is invalid or supplied data matches it already */
208-
if (maxlen < (int32) VARHDRSZ || charlen == maxlen)
210+
/* No work if supplied data matches typmod already */
211+
if (charlen == maxlen)
209212
PG_RETURN_BPCHAR_P(source);
210213

211214
if (charlen > maxlen)
@@ -249,12 +252,11 @@ bpchar(PG_FUNCTION_ARGS)
249252
VARATT_SIZEP(result) = maxlen;
250253
r = VARDATA(result);
251254

252-
for (i = 0; i < len - VARHDRSZ; i++)
253-
*r++ = *s++;
255+
memcpy(r, s, len - VARHDRSZ);
254256

255257
/* blank pad the string if necessary */
256-
for (; i < maxlen - VARHDRSZ; i++)
257-
*r++ = ' ';
258+
if (maxlen > len)
259+
memset(r + len - VARHDRSZ, ' ', maxlen - len);
258260

259261
PG_RETURN_BPCHAR_P(result);
260262
}

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