|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * 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 $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
|
36 | 36 | * length also. (eg. in INSERTs, we have the tupleDescriptor which contains
|
37 | 37 | * the length of the attributes and hence the exact length of the char() or
|
38 | 38 | * 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. |
41 | 41 | *
|
42 | 42 | * We actually implement this as a varlena so that we don't have to pass in
|
43 | 43 | * the length for the comparison functions. (The difference between these
|
@@ -72,63 +72,62 @@ bpcharin(PG_FUNCTION_ARGS)
|
72 | 72 | char*r;
|
73 | 73 | size_tlen,
|
74 | 74 | maxlen;
|
75 |
| -inti; |
76 |
| -intcharlen;/* number of charcters in the input string */ |
77 | 75 |
|
78 | 76 | /* verify encoding */
|
79 | 77 | len=strlen(s);
|
80 | 78 | pg_verifymbstr(s,len, false);
|
81 | 79 |
|
82 |
| -charlen=pg_mbstrlen(s); |
83 |
| - |
84 | 80 | /* If typmod is -1 (or invalid), use the actual string length */
|
85 | 81 | if (atttypmod< (int32)VARHDRSZ)
|
86 |
| -maxlen=charlen; |
| 82 | +maxlen=len; |
87 | 83 | else
|
88 |
| -maxlen=atttypmod-VARHDRSZ; |
89 |
| - |
90 |
| -if (charlen>maxlen) |
91 | 84 | {
|
92 |
| -/* Verify that extra characters are spaces, and clip them off */ |
93 |
| -size_tmbmaxlen=pg_mbcharcliplen(s,len,maxlen); |
| 85 | +size_tcharlen;/* number of CHARACTERS in the input */ |
94 | 86 |
|
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_tmbmaxlen=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 | +} |
102 | 113 | 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 | +} |
121 | 121 | }
|
122 | 122 |
|
123 | 123 | result=palloc(maxlen+VARHDRSZ);
|
124 | 124 | VARATT_SIZEP(result)=maxlen+VARHDRSZ;
|
125 | 125 | r=VARDATA(result);
|
126 |
| -for (i=0;i<len;i++) |
127 |
| -*r++=*s++; |
| 126 | +memcpy(r,s,len); |
128 | 127 |
|
129 | 128 | /* blank pad the string if necessary */
|
130 |
| -for (;i<maxlen;i++) |
131 |
| -*r++=' '; |
| 129 | +if (maxlen>len) |
| 130 | +memset(r+len,' ',maxlen-len); |
132 | 131 |
|
133 | 132 | PG_RETURN_BPCHAR_P(result);
|
134 | 133 | }
|
@@ -200,12 +199,16 @@ bpchar(PG_FUNCTION_ARGS)
|
200 | 199 | intcharlen;/* number of charcters in the input string
|
201 | 200 | * + VARHDRSZ */
|
202 | 201 |
|
| 202 | +/* No work if typmod is invalid */ |
| 203 | +if (maxlen< (int32)VARHDRSZ) |
| 204 | +PG_RETURN_BPCHAR_P(source); |
| 205 | + |
203 | 206 | len=VARSIZE(source);
|
204 | 207 |
|
205 | 208 | charlen=pg_mbstrlen_with_len(VARDATA(source),len-VARHDRSZ)+VARHDRSZ;
|
206 | 209 |
|
207 |
| -/* No work iftypmod is invalid orsupplied data matchesit already */ |
208 |
| -if (maxlen< (int32)VARHDRSZ||charlen==maxlen) |
| 210 | +/* No work if supplied data matchestypmod already */ |
| 211 | +if (charlen==maxlen) |
209 | 212 | PG_RETURN_BPCHAR_P(source);
|
210 | 213 |
|
211 | 214 | if (charlen>maxlen)
|
@@ -249,12 +252,11 @@ bpchar(PG_FUNCTION_ARGS)
|
249 | 252 | VARATT_SIZEP(result)=maxlen;
|
250 | 253 | r=VARDATA(result);
|
251 | 254 |
|
252 |
| -for (i=0;i<len-VARHDRSZ;i++) |
253 |
| -*r++=*s++; |
| 255 | +memcpy(r,s,len-VARHDRSZ); |
254 | 256 |
|
255 | 257 | /* 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); |
258 | 260 |
|
259 | 261 | PG_RETURN_BPCHAR_P(result);
|
260 | 262 | }
|
|