Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit e3f5bc3

Browse files
committed
Fix type_maximum_size() to give the right answer in MULTIBYTE cases.
Avoid use of prototype-less function pointers in MB code.
1 parent 39dc8ff commit e3f5bc3

File tree

4 files changed

+76
-38
lines changed

4 files changed

+76
-38
lines changed

src/backend/utils/adt/format_type.c

+15-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.14 2001/08/09 18:28:18 petere Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.15 2001/09/21 15:27:38 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -22,6 +22,10 @@
2222
#include "utils/builtins.h"
2323
#include "utils/numeric.h"
2424
#include "utils/syscache.h"
25+
#ifdef MULTIBYTE
26+
#include "mb/pg_wchar.h"
27+
#endif
28+
2529

2630
#define MAX_INT32_LEN 11
2731
#define _textin(str) DirectFunctionCall1(textin, CStringGetDatum(str))
@@ -249,9 +253,9 @@ format_type_internal(Oid type_oid, int32 typemod, bool allow_invalid)
249253

250254

251255
/*
252-
* type_maximum_size --- determine maximum length of a varlena column
256+
* type_maximum_size --- determine maximum width of a varlena column
253257
*
254-
* If the max length is indeterminate, return -1. In particular, we return
258+
* If the max width is indeterminate, return -1. In particular, we return
255259
* -1 for any type not known to this routine. We assume the caller has
256260
* already determined that the type is a varlena type, so it's not
257261
* necessary to look up the type's pg_type tuple here.
@@ -271,7 +275,14 @@ type_maximum_size(Oid type_oid, int32 typemod)
271275
case BPCHAROID:
272276
case VARCHAROID:
273277
/* typemod includes varlena header */
278+
#ifdef MULTIBYTE
279+
/* typemod is in characters not bytes */
280+
return (typemod - VARHDRSZ) *
281+
pg_encoding_max_length(GetDatabaseEncoding())
282+
+ VARHDRSZ;
283+
#else
274284
return typemod;
285+
#endif
275286

276287
case NUMERICOID:
277288
/* precision (ie, max # of digits) is in upper bits of typmod */
@@ -291,7 +302,7 @@ type_maximum_size(Oid type_oid, int32 typemod)
291302
+ 2 * sizeof(int32);
292303
}
293304

294-
/* Unknown type, or unlimited-length type such as 'text' */
305+
/* Unknown type, or unlimited-width type such as 'text' */
295306
return -1;
296307
}
297308

src/backend/utils/mb/mbutils.c

+19-13
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* client encoding and server internal encoding.
44
* (currently mule internal code (mic) is used)
55
* Tatsuo Ishii
6-
* $Id: mbutils.c,v 1.22 2001/09/09 01:15:11 ishii Exp $
6+
* $Id: mbutils.c,v 1.23 2001/09/21 15:27:38 tgl Exp $
77
*/
88
#include "postgres.h"
99

@@ -24,10 +24,10 @@
2424
static pg_enc2name *ClientEncoding = &pg_enc2name_tbl[ PG_SQL_ASCII ];
2525
static pg_enc2name *DatabaseEncoding = &pg_enc2name_tbl[ PG_SQL_ASCII ];
2626

27-
static void (*client_to_mic) (); /* something to MIC */
28-
static void (*client_from_mic) (); /* MIC to something */
29-
static void (*server_to_mic) (); /* something to MIC */
30-
static void (*server_from_mic) (); /* MIC to something */
27+
static to_mic_converter client_to_mic; /* something to MIC */
28+
static from_mic_converter client_from_mic; /* MIC to something */
29+
static to_mic_converter server_to_mic; /* something to MIC */
30+
static from_mic_converter server_from_mic; /* MIC to something */
3131

3232
/*
3333
* find encoding table entry by encoding
@@ -60,7 +60,9 @@ pg_get_enconv_by_encoding(int encoding)
6060
* appropriate function found, set to 0.
6161
*/
6262
int
63-
pg_find_encoding_converters(int src, int dest, void (**src_to_mic)(), void (**dest_from_mic)())
63+
pg_find_encoding_converters(int src, int dest,
64+
to_mic_converter *src_to_mic,
65+
from_mic_converter *dest_from_mic)
6466
{
6567
if (src == dest)
6668
{ /* src == dest? */
@@ -132,7 +134,7 @@ pg_set_client_encoding(int encoding)
132134
* returns the current client encoding
133135
*/
134136
int
135-
pg_get_client_encoding()
137+
pg_get_client_encoding(void)
136138
{
137139
Assert(ClientEncoding);
138140
return (ClientEncoding->encoding);
@@ -142,7 +144,7 @@ pg_get_client_encoding()
142144
* returns the current client encoding name
143145
*/
144146
const char *
145-
pg_get_client_encoding_name()
147+
pg_get_client_encoding_name(void)
146148
{
147149
Assert(ClientEncoding);
148150
return (ClientEncoding->name);
@@ -176,7 +178,9 @@ pg_get_client_encoding_name()
176178
* in the length of the string --- is this enough? */
177179

178180
unsigned char *
179-
pg_do_encoding_conversion(unsigned char *src, int len, void (*src_to_mic)(), void (*dest_from_mic)())
181+
pg_do_encoding_conversion(unsigned char *src, int len,
182+
to_mic_converter src_to_mic,
183+
from_mic_converter dest_from_mic)
180184
{
181185
unsigned char *result = src;
182186
unsigned char *buf;
@@ -212,7 +216,8 @@ pg_convert(PG_FUNCTION_ARGS)
212216
Name s = PG_GETARG_NAME(1);
213217
int encoding = pg_char_to_encoding(NameStr(*s));
214218
int db_encoding = DatabaseEncoding->encoding;
215-
void (*src)(), (*dest)();
219+
to_mic_converter src;
220+
from_mic_converter dest;
216221
unsigned char *result;
217222
text *retval;
218223

@@ -253,7 +258,8 @@ pg_convert2(PG_FUNCTION_ARGS)
253258
int src_encoding = pg_char_to_encoding(src_encoding_name);
254259
char *dest_encoding_name = NameStr(*PG_GETARG_NAME(2));
255260
int dest_encoding = pg_char_to_encoding(dest_encoding_name);
256-
void (*src)(), (*dest)();
261+
to_mic_converter src;
262+
from_mic_converter dest;
257263
unsigned char *result;
258264
text *retval;
259265

@@ -446,14 +452,14 @@ SetDatabaseEncoding(int encoding)
446452
}
447453

448454
int
449-
GetDatabaseEncoding()
455+
GetDatabaseEncoding(void)
450456
{
451457
Assert(DatabaseEncoding);
452458
return (DatabaseEncoding->encoding);
453459
}
454460

455461
const char *
456-
GetDatabaseEncodingName()
462+
GetDatabaseEncodingName(void)
457463
{
458464
Assert(DatabaseEncoding);
459465
return (DatabaseEncoding->name);

src/backend/utils/mb/wchar.c

+18-7
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
/*
22
* conversion functions between pg_wchar and multi-byte streams.
33
* Tatsuo Ishii
4-
* $Id: wchar.c,v 1.20 2001/09/11 04:50:36 ishii Exp $
4+
* $Id: wchar.c,v 1.21 2001/09/21 15:27:38 tgl Exp $
55
*
66
* WIN1250 client encoding updated by Pavel Behal
77
*
88
*/
99
/* can be used in either frontend or backend */
10-
#include "postgres_fe.h"
11-
#include "mb/pg_wchar.h"
12-
1310
#ifdef FRONTEND
14-
#define Assert(condition)
11+
#include "postgres_fe.h"
12+
#define Assert(condition)
1513
#else
16-
#include "postgres.h"
14+
#include "postgres.h"
1715
#endif
1816

17+
#include "mb/pg_wchar.h"
18+
1919

2020
/*
2121
* conversion to pg_wchar is done by "table driven."
@@ -499,6 +499,17 @@ pg_encoding_mblen(int encoding, const unsigned char *mbstr)
499499
((*pg_wchar_table[PG_SQL_ASCII].mblen) (mbstr)));
500500
}
501501

502+
/*
503+
* fetch maximum length of a char encoding
504+
*/
505+
int
506+
pg_encoding_max_length(int encoding)
507+
{
508+
Assert(PG_VALID_ENCODING(encoding));
509+
510+
return pg_wchar_table[encoding].maxmblen;
511+
}
512+
502513
#ifndef FRONTEND
503514
/*
504515
* Verify mbstr to make sure that it has a valid character sequence.
@@ -517,7 +528,7 @@ pg_verifymbstr(const unsigned char *mbstr, int len)
517528
int slen = 0;
518529

519530
/* we do not check single byte encodings */
520-
if (pg_wchar_table[GetDatabaseEncoding()].maxmblen <= 1)
531+
if (pg_encoding_max_length(GetDatabaseEncoding()) <= 1)
521532
return NULL;
522533

523534
while (len > 0 && *mbstr)

src/include/mb/pg_wchar.h

+24-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $Id: pg_wchar.h,v 1.30 2001/09/11 04:50:36 ishii Exp $ */
1+
/* $Id: pg_wchar.h,v 1.31 2001/09/21 15:27:38 tgl Exp $ */
22

33
#ifndef PG_WCHAR_H
44
#define PG_WCHAR_H
@@ -17,7 +17,6 @@
1717
*/
1818
#ifdef MULTIBYTE
1919
typedef unsigned int pg_wchar;
20-
2120
#else
2221
#define pg_wchar char
2322
#endif
@@ -152,6 +151,9 @@ extern pg_encname *pg_char_to_encname_struct(const char *name);
152151
extern int pg_char_to_encoding(const char *s);
153152
extern const char *pg_encoding_to_char(int encoding);
154153

154+
typedef void (*to_mic_converter) (unsigned char *l, unsigned char *p, int len);
155+
typedef void (*from_mic_converter) (unsigned char *mic, unsigned char *p, int len);
156+
155157
/*
156158
* The backend encoding conversion routines
157159
* Careful:
@@ -162,11 +164,11 @@ extern const char *pg_encoding_to_char(int encoding);
162164
#ifndef FRONTEND
163165
typedef struct pg_enconv
164166
{
165-
pg_enc encoding; /* encoding identificator */
166-
void (*to_mic) (); /* client encoding to MIC */
167-
void (*from_mic) (); /* MIC to client encoding */
168-
void (*to_unicode) (); /* client encoding to UTF-8 */
169-
void (*from_unicode) (); /* UTF-8 to client encoding */
167+
pg_enc encoding; /* encoding identifier */
168+
to_mic_converter to_mic; /* client encoding to MIC */
169+
from_mic_converter from_mic; /* MIC to client encoding */
170+
to_mic_converter to_unicode; /* client encoding to UTF-8 */
171+
from_mic_converter from_unicode; /* UTF-8 to client encoding */
170172
} pg_enconv;
171173

172174
extern pg_enconv pg_enconv_tbl[];
@@ -177,13 +179,16 @@ extern pg_enconv *pg_get_enconv_by_encoding(int encoding);
177179
/*
178180
* pg_wchar stuff
179181
*/
182+
typedef int (*mb2wchar_with_len_converter) (const unsigned char *from,
183+
pg_wchar *to,
184+
int len);
185+
typedef int (*mblen_converter) (const unsigned char *mbstr);
186+
180187
typedef struct
181188
{
182-
int (*mb2wchar_with_len) (); /* convert a multi-byte
183-
* string to a wchar */
184-
int (*mblen) (); /* returns the length of a multi-byte word */
185-
int maxmblen; /* max bytes for a letter in this charset */
186-
189+
mb2wchar_with_len_converter mb2wchar_with_len; /* convert a multi-byte string to a wchar */
190+
mblen_converter mblen; /* returns the length of a multi-byte char */
191+
int maxmblen; /* max bytes for a char in this charset */
187192
} pg_wchar_tbl;
188193

189194
extern pg_wchar_tbl pg_wchar_table[];
@@ -220,6 +225,7 @@ extern int pg_mbstrlen(const unsigned char *);
220225
extern int pg_mbstrlen_with_len(const unsigned char *, int);
221226
extern int pg_mbcliplen(const unsigned char *, int, int);
222227
extern int pg_mbcharcliplen(const unsigned char *, int, int);
228+
extern int pg_encoding_max_length(int);
223229

224230
extern int pg_set_client_encoding(int);
225231
extern int pg_get_client_encoding(void);
@@ -233,8 +239,12 @@ extern int pg_valid_client_encoding(const char *name);
233239
extern int pg_valid_server_encoding(const char *name);
234240

235241
extern int pg_utf_mblen(const unsigned char *);
236-
extern int pg_find_encoding_converters(int, int, void (**)(), void (**)());
237-
extern unsigned char *pg_do_encoding_conversion(unsigned char *, int, void (*)(), void (*)());
242+
extern int pg_find_encoding_converters(int src, int dest,
243+
to_mic_converter *src_to_mic,
244+
from_mic_converter *dest_from_mic);
245+
extern unsigned char *pg_do_encoding_conversion(unsigned char *src, int len,
246+
to_mic_converter src_to_mic,
247+
from_mic_converter dest_from_mic);
238248

239249
extern unsigned char *pg_client_to_server(unsigned char *, int);
240250
extern unsigned char *pg_server_to_client(unsigned char *, int);

0 commit comments

Comments
 (0)