Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7c0c9b3

Browse files
committed
New improved version of bpcharin() may have got the truncation case
right, but it failed to get the padding case right.This was obscured by subsequent application of bpchar() in all but oneregression test case, and that one didn't fail in an obvious way ---trailing blanks are hard to see. Add another test case to make itmore obvious if it breaks again.
1 parent597ca67 commit7c0c9b3

File tree

3 files changed

+36
-29
lines changed

3 files changed

+36
-29
lines changed

‎src/backend/utils/adt/varchar.c

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.78 2001/05/21 16:54:46 petere Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.79 2001/06/01 17:49:16 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -65,10 +65,8 @@ Datum
6565
bpcharin(PG_FUNCTION_ARGS)
6666
{
6767
char*s=PG_GETARG_CSTRING(0);
68-
6968
#ifdefNOT_USED
7069
Oidtypelem=PG_GETARG_OID(1);
71-
7270
#endif
7371
int32atttypmod=PG_GETARG_INT32(2);
7472
BpChar*result;
@@ -77,45 +75,46 @@ bpcharin(PG_FUNCTION_ARGS)
7775
inti;
7876

7977
len=strlen(s);
80-
maxlen=atttypmod-VARHDRSZ;
8178

82-
if (atttypmod >= (int32)VARHDRSZ&&len>maxlen)
79+
/* If typmod is -1 (or invalid), use the actual string length */
80+
if (atttypmod< (int32)VARHDRSZ)
81+
maxlen=len;
82+
else
83+
maxlen=atttypmod-VARHDRSZ;
84+
85+
if (len>maxlen)
8386
{
87+
/* Verify that extra characters are spaces, and clip them off */
8488
#ifdefMULTIBYTE
8589
size_tmbmaxlen=pg_mbcliplen(s,len,maxlen);
8690

8791
if (strspn(s+mbmaxlen," ")==len-mbmaxlen)
8892
len=mbmaxlen;
93+
else
94+
elog(ERROR,"value too long for type character(%d)",maxlen);
95+
Assert(len <=maxlen);
8996
#else
9097
if (strspn(s+maxlen," ")==len-maxlen)
91-
/* clip extra spaces */
9298
len=maxlen;
93-
#endif
9499
else
95100
elog(ERROR,"value too long for type character(%d)",maxlen);
101+
#endif
96102
}
97-
else
98-
/* If typmod is -1 (or invalid), use the actual string length */
99-
maxlen=len;
100103

101104
result=palloc(maxlen+VARHDRSZ);
102105
VARATT_SIZEP(result)=maxlen+VARHDRSZ;
103106
r=VARDATA(result);
104-
for (i=0;i<len;i++,r++,s++)
105-
{
106-
*r=*s;
107-
if (*r=='\0')
108-
break;
109-
}
110-
111-
#ifdefCYR_RECODE
112-
convertstr(VARDATA(result),len,0);
113-
#endif
107+
for (i=0;i<len;i++)
108+
*r++=*s++;
114109

115110
/* blank pad the string if necessary */
116111
for (;i<maxlen;i++)
117112
*r++=' ';
118113

114+
#ifdefCYR_RECODE
115+
convertstr(VARDATA(result),len,0);
116+
#endif
117+
119118
PG_RETURN_BPCHAR_P(result);
120119
}
121120

@@ -162,11 +161,12 @@ bpchar(PG_FUNCTION_ARGS)
162161

163162
len=VARSIZE(source);
164163
/* No work if typmod is invalid or supplied data matches it already */
165-
if (len< (int32)VARHDRSZ||len==maxlen)
164+
if (maxlen< (int32)VARHDRSZ||len==maxlen)
166165
PG_RETURN_BPCHAR_P(source);
167166

168167
if (len>maxlen)
169168
{
169+
/* Verify that extra characters are spaces, and clip them off */
170170
#ifdefMULTIBYTE
171171
size_tmaxmblen;
172172

@@ -179,13 +179,13 @@ bpchar(PG_FUNCTION_ARGS)
179179
maxlen-VARHDRSZ);
180180

181181
len=maxmblen;
182+
Assert(len <=maxlen);
182183
#else
183184
for (i=maxlen-VARHDRSZ;i<len-VARHDRSZ;i++)
184185
if (*(VARDATA(source)+i)!=' ')
185186
elog(ERROR,"value too long for type character(%d)",
186187
maxlen-VARHDRSZ);
187188

188-
/* clip extra spaces */
189189
len=maxlen;
190190
#endif
191191
}
@@ -196,7 +196,7 @@ bpchar(PG_FUNCTION_ARGS)
196196
VARATT_SIZEP(result)=maxlen;
197197
r=VARDATA(result);
198198

199-
for (i=0;(i<maxlen-VARHDRSZ)&& (i<len-VARHDRSZ);i++)
199+
for (i=0;i<len-VARHDRSZ;i++)
200200
*r++=*s++;
201201

202202
/* blank pad the string if necessary */
@@ -340,10 +340,8 @@ Datum
340340
varcharin(PG_FUNCTION_ARGS)
341341
{
342342
char*s=PG_GETARG_CSTRING(0);
343-
344343
#ifdefNOT_USED
345344
Oidtypelem=PG_GETARG_OID(1);
346-
347345
#endif
348346
int32atttypmod=PG_GETARG_INT32(2);
349347
VarChar*result;
@@ -354,14 +352,14 @@ varcharin(PG_FUNCTION_ARGS)
354352

355353
if (atttypmod >= (int32)VARHDRSZ&&len>maxlen)
356354
{
355+
/* Verify that extra characters are spaces, and clip them off */
357356
#ifdefMULTIBYTE
358357
size_tmbmaxlen=pg_mbcliplen(s,len,maxlen);
359358

360359
if (strspn(s+mbmaxlen," ")==len-mbmaxlen)
361360
len=mbmaxlen;
362361
#else
363362
if (strspn(s+maxlen," ")==len-maxlen)
364-
/* clip extra spaces */
365363
len=maxlen;
366364
#endif
367365
else
@@ -419,6 +417,7 @@ varchar(PG_FUNCTION_ARGS)
419417
inti;
420418

421419
len=VARSIZE(source);
420+
/* No work if typmod is invalid or supplied data fits it already */
422421
if (maxlen< (int32)VARHDRSZ||len <=maxlen)
423422
PG_RETURN_VARCHAR_P(source);
424423

‎src/test/regress/expected/strings.out

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -481,10 +481,16 @@ SELECT text 'text' || ' and unknown' AS "Concat text to unknown type";
481481
text and unknown
482482
(1 row)
483483

484+
SELECT char(20) 'characters' || 'and text' AS "Concat char to unknown type";
485+
Concat char to unknown type
486+
------------------------------
487+
characters and text
488+
(1 row)
489+
484490
SELECT text 'text' || char(20) ' and characters' AS "Concat text to char";
485-
Concat text to char
486-
---------------------
487-
text and characters
491+
Concat text to char
492+
--------------------------
493+
text and characters
488494
(1 row)
489495

490496
SELECT text 'text' || varchar ' and varchar' AS "Concat text to varchar";

‎src/test/regress/sql/strings.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ SELECT 'unknown' || ' and unknown' AS "Concat unknown types";
160160

161161
SELECTtext'text'||' and unknown'AS"Concat text to unknown type";
162162

163+
SELECTchar(20)'characters'||'and text'AS"Concat char to unknown type";
164+
163165
SELECTtext'text'||char(20)' and characters'AS"Concat text to char";
164166

165167
SELECTtext'text'||varchar' and varchar'AS"Concat text to varchar";

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp