|
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 | } |
|