8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.80 2001/06/09 23:21:55 petere Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.81 2001/07/15 11:07:37 ishii Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -73,33 +73,65 @@ bpcharin(PG_FUNCTION_ARGS)
73
73
char * r ;
74
74
size_t len , maxlen ;
75
75
int i ;
76
+ #ifdef MULTIBYTE
77
+ int charlen ; /* number of charcters in the input string */
78
+ #endif
76
79
77
80
len = strlen (s );
81
+ #ifdef MULTIBYTE
82
+ charlen = pg_mbstrlen (s );
83
+ #endif
78
84
79
85
/* If typmod is -1 (or invalid), use the actual string length */
80
86
if (atttypmod < (int32 ) VARHDRSZ )
87
+ #ifdef MULTIBYTE
88
+ maxlen = charlen ;
89
+ #else
81
90
maxlen = len ;
91
+ #endif
82
92
else
83
93
maxlen = atttypmod - VARHDRSZ ;
84
94
95
+ #ifdef MULTIBYTE
96
+ if (charlen > maxlen )
97
+ #else
85
98
if (len > maxlen )
99
+ #endif
86
100
{
87
101
/* Verify that extra characters are spaces, and clip them off */
88
102
#ifdef MULTIBYTE
89
- size_t mbmaxlen = pg_mbcliplen (s , len , maxlen );
90
-
103
+ size_t mbmaxlen = pg_mbcharcliplen (s , len , maxlen );
104
+ /*
105
+ * at this point, len is the actual BYTE length of the
106
+ * input string, maxlen is the max number of
107
+ * CHARACTERS allowed for this bpchar type.
108
+ */
91
109
if (strspn (s + mbmaxlen , " " ) == len - mbmaxlen )
92
110
len = mbmaxlen ;
93
111
else
94
112
elog (ERROR , "value too long for type character(%d)" , maxlen );
95
- Assert (len <= maxlen );
113
+ /*
114
+ * XXX: at this point, maxlen is the necessary byte
115
+ * length, not the number of CHARACTERS!
116
+ */
117
+ maxlen = len ;
96
118
#else
97
119
if (strspn (s + maxlen , " " ) == len - maxlen )
98
120
len = maxlen ;
99
121
else
100
122
elog (ERROR , "value too long for type character(%d)" , maxlen );
101
123
#endif
102
124
}
125
+ #ifdef MULTIBYTE
126
+ else
127
+ {
128
+ /*
129
+ * XXX: at this point, maxlen is the necessary byte
130
+ * length, not the number of CHARACTERS!
131
+ */
132
+ maxlen = len + (maxlen - charlen );
133
+ }
134
+ #endif
103
135
104
136
result = palloc (maxlen + VARHDRSZ );
105
137
VARATT_SIZEP (result ) = maxlen + VARHDRSZ ;
@@ -158,19 +190,29 @@ bpchar(PG_FUNCTION_ARGS)
158
190
char * r ;
159
191
char * s ;
160
192
int i ;
193
+ #ifdef MULTIBYTE
194
+ int charlen ; /* number of charcters in the input string
195
+ + VARHDRSZ*/
196
+ #endif
161
197
162
198
len = VARSIZE (source );
199
+ #ifdef MULTIBYTE
200
+ charlen = pg_mbstrlen_with_len (VARDATA (source ), len - VARHDRSZ ) + VARHDRSZ ;
201
+ #endif
163
202
/* No work if typmod is invalid or supplied data matches it already */
164
203
if (maxlen < (int32 ) VARHDRSZ || len == maxlen )
165
204
PG_RETURN_BPCHAR_P (source );
166
-
205
+ #ifdef MULTIBYTE
206
+ if (charlen > maxlen )
207
+ #else
167
208
if (len > maxlen )
209
+ #endif
168
210
{
169
211
/* Verify that extra characters are spaces, and clip them off */
170
212
#ifdef MULTIBYTE
171
213
size_t maxmblen ;
172
214
173
- maxmblen = pg_mbcliplen (VARDATA (source ), len - VARHDRSZ ,
215
+ maxmblen = pg_mbcharcliplen (VARDATA (source ), len - VARHDRSZ ,
174
216
maxlen - VARHDRSZ ) + VARHDRSZ ;
175
217
176
218
for (i = maxmblen - VARHDRSZ ; i < len - VARHDRSZ ; i ++ )
@@ -179,7 +221,11 @@ bpchar(PG_FUNCTION_ARGS)
179
221
maxlen - VARHDRSZ );
180
222
181
223
len = maxmblen ;
182
- Assert (len <= maxlen );
224
+ /*
225
+ * XXX: at this point, maxlen is the necessary byte
226
+ * length+VARHDRSZ, not the number of CHARACTERS!
227
+ */
228
+ maxlen = len ;
183
229
#else
184
230
for (i = maxlen - VARHDRSZ ; i < len - VARHDRSZ ; i ++ )
185
231
if (* (VARDATA (source ) + i ) != ' ' )
@@ -189,6 +235,16 @@ bpchar(PG_FUNCTION_ARGS)
189
235
len = maxlen ;
190
236
#endif
191
237
}
238
+ #ifdef MULTIBYTE
239
+ else
240
+ {
241
+ /*
242
+ * XXX: at this point, maxlen is the necessary byte
243
+ * length+VARHDRSZ, not the number of CHARACTERS!
244
+ */
245
+ maxlen = len + (maxlen - charlen );
246
+ }
247
+ #endif
192
248
193
249
s = VARDATA (source );
194
250
@@ -333,9 +389,12 @@ name_bpchar(PG_FUNCTION_ARGS)
333
389
* Convert a C string to VARCHAR internal representation. atttypmod
334
390
* is the declared length of the type plus VARHDRSZ.
335
391
*
336
- * If the C string is too long, raise an error, unless the extra
337
- * characters are spaces, in which case they're truncated. (per SQL)
338
- */
392
+ * Note that if MULTIBYTE is enabled, atttypmod is regarded as the
393
+ * number of characters, rather than number of bytes.
394
+ *
395
+ * If the C string is too long,
396
+ * raise an error, unless the extra characters are spaces, in which
397
+ * case they're truncated. (per SQL) */
339
398
Datum
340
399
varcharin (PG_FUNCTION_ARGS )
341
400
{
@@ -354,7 +413,7 @@ varcharin(PG_FUNCTION_ARGS)
354
413
{
355
414
/* Verify that extra characters are spaces, and clip them off */
356
415
#ifdef MULTIBYTE
357
- size_t mbmaxlen = pg_mbcliplen (s , len , maxlen );
416
+ size_t mbmaxlen = pg_mbcharcliplen (s , len , maxlen );
358
417
359
418
if (strspn (s + mbmaxlen , " " ) == len - mbmaxlen )
360
419
len = mbmaxlen ;
@@ -428,7 +487,7 @@ varchar(PG_FUNCTION_ARGS)
428
487
size_t maxmblen ;
429
488
430
489
/* truncate multi-byte string preserving multi-byte boundary */
431
- maxmblen = pg_mbcliplen (VARDATA (source ), len - VARHDRSZ ,
490
+ maxmblen = pg_mbcharcliplen (VARDATA (source ), len - VARHDRSZ ,
432
491
maxlen - VARHDRSZ ) + VARHDRSZ ;
433
492
434
493
for (i = maxmblen - VARHDRSZ ; i < len - VARHDRSZ ; i ++ )
@@ -515,22 +574,9 @@ bpcharlen(PG_FUNCTION_ARGS)
515
574
BpChar * arg = PG_GETARG_BPCHAR_P (0 );
516
575
517
576
#ifdef MULTIBYTE
518
- unsigned char * s ;
519
- int len ,
520
- l ,
521
- wl ;
522
-
523
- l = VARSIZE (arg ) - VARHDRSZ ;
524
- len = 0 ;
525
- s = VARDATA (arg );
526
- while (l > 0 )
527
- {
528
- wl = pg_mblen (s );
529
- l -= wl ;
530
- s += wl ;
531
- len ++ ;
532
- }
533
- PG_RETURN_INT32 (len );
577
+ PG_RETURN_INT32 (
578
+ pg_mbstrlen_with_len (VARDATA (arg ), VARSIZE (arg ) - VARHDRSZ )
579
+ );
534
580
#else
535
581
PG_RETURN_INT32 (VARSIZE (arg ) - VARHDRSZ );
536
582
#endif
@@ -736,22 +782,9 @@ varcharlen(PG_FUNCTION_ARGS)
736
782
VarChar * arg = PG_GETARG_VARCHAR_P (0 );
737
783
738
784
#ifdef MULTIBYTE
739
- unsigned char * s ;
740
- int len ,
741
- l ,
742
- wl ;
743
-
744
- len = 0 ;
745
- s = VARDATA (arg );
746
- l = VARSIZE (arg ) - VARHDRSZ ;
747
- while (l > 0 )
748
- {
749
- wl = pg_mblen (s );
750
- l -= wl ;
751
- s += wl ;
752
- len ++ ;
753
- }
754
- PG_RETURN_INT32 (len );
785
+ PG_RETURN_INT32 (
786
+ pg_mbstrlen_with_len (VARDATA (arg ), VARSIZE (arg ) - VARHDRSZ )
787
+ );
755
788
#else
756
789
PG_RETURN_INT32 (VARSIZE (arg ) - VARHDRSZ );
757
790
#endif
0 commit comments