Commit e3f5bc34 authored by Tom Lane's avatar Tom Lane

Fix type_maximum_size() to give the right answer in MULTIBYTE cases.

Avoid use of prototype-less function pointers in MB code.
parent 39dc8ff6
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.14 2001/08/09 18:28:18 petere Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/format_type.c,v 1.15 2001/09/21 15:27:38 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -22,6 +22,10 @@ ...@@ -22,6 +22,10 @@
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/numeric.h" #include "utils/numeric.h"
#include "utils/syscache.h" #include "utils/syscache.h"
#ifdef MULTIBYTE
#include "mb/pg_wchar.h"
#endif
#define MAX_INT32_LEN 11 #define MAX_INT32_LEN 11
#define _textin(str) DirectFunctionCall1(textin, CStringGetDatum(str)) #define _textin(str) DirectFunctionCall1(textin, CStringGetDatum(str))
...@@ -249,9 +253,9 @@ format_type_internal(Oid type_oid, int32 typemod, bool allow_invalid) ...@@ -249,9 +253,9 @@ format_type_internal(Oid type_oid, int32 typemod, bool allow_invalid)
/* /*
* type_maximum_size --- determine maximum length of a varlena column * type_maximum_size --- determine maximum width of a varlena column
* *
* If the max length is indeterminate, return -1. In particular, we return * If the max width is indeterminate, return -1. In particular, we return
* -1 for any type not known to this routine. We assume the caller has * -1 for any type not known to this routine. We assume the caller has
* already determined that the type is a varlena type, so it's not * already determined that the type is a varlena type, so it's not
* necessary to look up the type's pg_type tuple here. * necessary to look up the type's pg_type tuple here.
...@@ -271,7 +275,14 @@ type_maximum_size(Oid type_oid, int32 typemod) ...@@ -271,7 +275,14 @@ type_maximum_size(Oid type_oid, int32 typemod)
case BPCHAROID: case BPCHAROID:
case VARCHAROID: case VARCHAROID:
/* typemod includes varlena header */ /* typemod includes varlena header */
#ifdef MULTIBYTE
/* typemod is in characters not bytes */
return (typemod - VARHDRSZ) *
pg_encoding_max_length(GetDatabaseEncoding())
+ VARHDRSZ;
#else
return typemod; return typemod;
#endif
case NUMERICOID: case NUMERICOID:
/* precision (ie, max # of digits) is in upper bits of typmod */ /* precision (ie, max # of digits) is in upper bits of typmod */
...@@ -291,7 +302,7 @@ type_maximum_size(Oid type_oid, int32 typemod) ...@@ -291,7 +302,7 @@ type_maximum_size(Oid type_oid, int32 typemod)
+ 2 * sizeof(int32); + 2 * sizeof(int32);
} }
/* Unknown type, or unlimited-length type such as 'text' */ /* Unknown type, or unlimited-width type such as 'text' */
return -1; return -1;
} }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* client encoding and server internal encoding. * client encoding and server internal encoding.
* (currently mule internal code (mic) is used) * (currently mule internal code (mic) is used)
* Tatsuo Ishii * Tatsuo Ishii
* $Id: mbutils.c,v 1.22 2001/09/09 01:15:11 ishii Exp $ * $Id: mbutils.c,v 1.23 2001/09/21 15:27:38 tgl Exp $
*/ */
#include "postgres.h" #include "postgres.h"
...@@ -24,10 +24,10 @@ ...@@ -24,10 +24,10 @@
static pg_enc2name *ClientEncoding = &pg_enc2name_tbl[ PG_SQL_ASCII ]; static pg_enc2name *ClientEncoding = &pg_enc2name_tbl[ PG_SQL_ASCII ];
static pg_enc2name *DatabaseEncoding = &pg_enc2name_tbl[ PG_SQL_ASCII ]; static pg_enc2name *DatabaseEncoding = &pg_enc2name_tbl[ PG_SQL_ASCII ];
static void (*client_to_mic) (); /* something to MIC */ static to_mic_converter client_to_mic; /* something to MIC */
static void (*client_from_mic) (); /* MIC to something */ static from_mic_converter client_from_mic; /* MIC to something */
static void (*server_to_mic) (); /* something to MIC */ static to_mic_converter server_to_mic; /* something to MIC */
static void (*server_from_mic) (); /* MIC to something */ static from_mic_converter server_from_mic; /* MIC to something */
/* /*
* find encoding table entry by encoding * find encoding table entry by encoding
...@@ -60,7 +60,9 @@ pg_get_enconv_by_encoding(int encoding) ...@@ -60,7 +60,9 @@ pg_get_enconv_by_encoding(int encoding)
* appropriate function found, set to 0. * appropriate function found, set to 0.
*/ */
int int
pg_find_encoding_converters(int src, int dest, void (**src_to_mic)(), void (**dest_from_mic)()) pg_find_encoding_converters(int src, int dest,
to_mic_converter *src_to_mic,
from_mic_converter *dest_from_mic)
{ {
if (src == dest) if (src == dest)
{ /* src == dest? */ { /* src == dest? */
...@@ -132,7 +134,7 @@ pg_set_client_encoding(int encoding) ...@@ -132,7 +134,7 @@ pg_set_client_encoding(int encoding)
* returns the current client encoding * returns the current client encoding
*/ */
int int
pg_get_client_encoding() pg_get_client_encoding(void)
{ {
Assert(ClientEncoding); Assert(ClientEncoding);
return (ClientEncoding->encoding); return (ClientEncoding->encoding);
...@@ -142,7 +144,7 @@ pg_get_client_encoding() ...@@ -142,7 +144,7 @@ pg_get_client_encoding()
* returns the current client encoding name * returns the current client encoding name
*/ */
const char * const char *
pg_get_client_encoding_name() pg_get_client_encoding_name(void)
{ {
Assert(ClientEncoding); Assert(ClientEncoding);
return (ClientEncoding->name); return (ClientEncoding->name);
...@@ -176,7 +178,9 @@ pg_get_client_encoding_name() ...@@ -176,7 +178,9 @@ pg_get_client_encoding_name()
* in the length of the string --- is this enough? */ * in the length of the string --- is this enough? */
unsigned char * unsigned char *
pg_do_encoding_conversion(unsigned char *src, int len, void (*src_to_mic)(), void (*dest_from_mic)()) pg_do_encoding_conversion(unsigned char *src, int len,
to_mic_converter src_to_mic,
from_mic_converter dest_from_mic)
{ {
unsigned char *result = src; unsigned char *result = src;
unsigned char *buf; unsigned char *buf;
...@@ -212,7 +216,8 @@ pg_convert(PG_FUNCTION_ARGS) ...@@ -212,7 +216,8 @@ pg_convert(PG_FUNCTION_ARGS)
Name s = PG_GETARG_NAME(1); Name s = PG_GETARG_NAME(1);
int encoding = pg_char_to_encoding(NameStr(*s)); int encoding = pg_char_to_encoding(NameStr(*s));
int db_encoding = DatabaseEncoding->encoding; int db_encoding = DatabaseEncoding->encoding;
void (*src)(), (*dest)(); to_mic_converter src;
from_mic_converter dest;
unsigned char *result; unsigned char *result;
text *retval; text *retval;
...@@ -253,7 +258,8 @@ pg_convert2(PG_FUNCTION_ARGS) ...@@ -253,7 +258,8 @@ pg_convert2(PG_FUNCTION_ARGS)
int src_encoding = pg_char_to_encoding(src_encoding_name); int src_encoding = pg_char_to_encoding(src_encoding_name);
char *dest_encoding_name = NameStr(*PG_GETARG_NAME(2)); char *dest_encoding_name = NameStr(*PG_GETARG_NAME(2));
int dest_encoding = pg_char_to_encoding(dest_encoding_name); int dest_encoding = pg_char_to_encoding(dest_encoding_name);
void (*src)(), (*dest)(); to_mic_converter src;
from_mic_converter dest;
unsigned char *result; unsigned char *result;
text *retval; text *retval;
...@@ -446,14 +452,14 @@ SetDatabaseEncoding(int encoding) ...@@ -446,14 +452,14 @@ SetDatabaseEncoding(int encoding)
} }
int int
GetDatabaseEncoding() GetDatabaseEncoding(void)
{ {
Assert(DatabaseEncoding); Assert(DatabaseEncoding);
return (DatabaseEncoding->encoding); return (DatabaseEncoding->encoding);
} }
const char * const char *
GetDatabaseEncodingName() GetDatabaseEncodingName(void)
{ {
Assert(DatabaseEncoding); Assert(DatabaseEncoding);
return (DatabaseEncoding->name); return (DatabaseEncoding->name);
......
/* /*
* conversion functions between pg_wchar and multi-byte streams. * conversion functions between pg_wchar and multi-byte streams.
* Tatsuo Ishii * Tatsuo Ishii
* $Id: wchar.c,v 1.20 2001/09/11 04:50:36 ishii Exp $ * $Id: wchar.c,v 1.21 2001/09/21 15:27:38 tgl Exp $
* *
* WIN1250 client encoding updated by Pavel Behal * WIN1250 client encoding updated by Pavel Behal
* *
*/ */
/* can be used in either frontend or backend */ /* can be used in either frontend or backend */
#include "postgres_fe.h"
#include "mb/pg_wchar.h"
#ifdef FRONTEND #ifdef FRONTEND
#define Assert(condition) #include "postgres_fe.h"
#define Assert(condition)
#else #else
#include "postgres.h" #include "postgres.h"
#endif #endif
#include "mb/pg_wchar.h"
/* /*
* conversion to pg_wchar is done by "table driven." * conversion to pg_wchar is done by "table driven."
...@@ -499,6 +499,17 @@ pg_encoding_mblen(int encoding, const unsigned char *mbstr) ...@@ -499,6 +499,17 @@ pg_encoding_mblen(int encoding, const unsigned char *mbstr)
((*pg_wchar_table[PG_SQL_ASCII].mblen) (mbstr))); ((*pg_wchar_table[PG_SQL_ASCII].mblen) (mbstr)));
} }
/*
* fetch maximum length of a char encoding
*/
int
pg_encoding_max_length(int encoding)
{
Assert(PG_VALID_ENCODING(encoding));
return pg_wchar_table[encoding].maxmblen;
}
#ifndef FRONTEND #ifndef FRONTEND
/* /*
* Verify mbstr to make sure that it has a valid character sequence. * Verify mbstr to make sure that it has a valid character sequence.
...@@ -517,7 +528,7 @@ pg_verifymbstr(const unsigned char *mbstr, int len) ...@@ -517,7 +528,7 @@ pg_verifymbstr(const unsigned char *mbstr, int len)
int slen = 0; int slen = 0;
/* we do not check single byte encodings */ /* we do not check single byte encodings */
if (pg_wchar_table[GetDatabaseEncoding()].maxmblen <= 1) if (pg_encoding_max_length(GetDatabaseEncoding()) <= 1)
return NULL; return NULL;
while (len > 0 && *mbstr) while (len > 0 && *mbstr)
......
/* $Id: pg_wchar.h,v 1.30 2001/09/11 04:50:36 ishii Exp $ */ /* $Id: pg_wchar.h,v 1.31 2001/09/21 15:27:38 tgl Exp $ */
#ifndef PG_WCHAR_H #ifndef PG_WCHAR_H
#define PG_WCHAR_H #define PG_WCHAR_H
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
*/ */
#ifdef MULTIBYTE #ifdef MULTIBYTE
typedef unsigned int pg_wchar; typedef unsigned int pg_wchar;
#else #else
#define pg_wchar char #define pg_wchar char
#endif #endif
...@@ -152,6 +151,9 @@ extern pg_encname *pg_char_to_encname_struct(const char *name); ...@@ -152,6 +151,9 @@ extern pg_encname *pg_char_to_encname_struct(const char *name);
extern int pg_char_to_encoding(const char *s); extern int pg_char_to_encoding(const char *s);
extern const char *pg_encoding_to_char(int encoding); extern const char *pg_encoding_to_char(int encoding);
typedef void (*to_mic_converter) (unsigned char *l, unsigned char *p, int len);
typedef void (*from_mic_converter) (unsigned char *mic, unsigned char *p, int len);
/* /*
* The backend encoding conversion routines * The backend encoding conversion routines
* Careful: * Careful:
...@@ -162,11 +164,11 @@ extern const char *pg_encoding_to_char(int encoding); ...@@ -162,11 +164,11 @@ extern const char *pg_encoding_to_char(int encoding);
#ifndef FRONTEND #ifndef FRONTEND
typedef struct pg_enconv typedef struct pg_enconv
{ {
pg_enc encoding; /* encoding identificator */ pg_enc encoding; /* encoding identifier */
void (*to_mic) (); /* client encoding to MIC */ to_mic_converter to_mic; /* client encoding to MIC */
void (*from_mic) (); /* MIC to client encoding */ from_mic_converter from_mic; /* MIC to client encoding */
void (*to_unicode) (); /* client encoding to UTF-8 */ to_mic_converter to_unicode; /* client encoding to UTF-8 */
void (*from_unicode) (); /* UTF-8 to client encoding */ from_mic_converter from_unicode; /* UTF-8 to client encoding */
} pg_enconv; } pg_enconv;
extern pg_enconv pg_enconv_tbl[]; extern pg_enconv pg_enconv_tbl[];
...@@ -177,13 +179,16 @@ extern pg_enconv *pg_get_enconv_by_encoding(int encoding); ...@@ -177,13 +179,16 @@ extern pg_enconv *pg_get_enconv_by_encoding(int encoding);
/* /*
* pg_wchar stuff * pg_wchar stuff
*/ */
typedef int (*mb2wchar_with_len_converter) (const unsigned char *from,
pg_wchar *to,
int len);
typedef int (*mblen_converter) (const unsigned char *mbstr);
typedef struct typedef struct
{ {
int (*mb2wchar_with_len) (); /* convert a multi-byte mb2wchar_with_len_converter mb2wchar_with_len; /* convert a multi-byte string to a wchar */
* string to a wchar */ mblen_converter mblen; /* returns the length of a multi-byte char */
int (*mblen) (); /* returns the length of a multi-byte word */ int maxmblen; /* max bytes for a char in this charset */
int maxmblen; /* max bytes for a letter in this charset */
} pg_wchar_tbl; } pg_wchar_tbl;
extern pg_wchar_tbl pg_wchar_table[]; extern pg_wchar_tbl pg_wchar_table[];
...@@ -220,6 +225,7 @@ extern int pg_mbstrlen(const unsigned char *); ...@@ -220,6 +225,7 @@ extern int pg_mbstrlen(const unsigned char *);
extern int pg_mbstrlen_with_len(const unsigned char *, int); extern int pg_mbstrlen_with_len(const unsigned char *, int);
extern int pg_mbcliplen(const unsigned char *, int, int); extern int pg_mbcliplen(const unsigned char *, int, int);
extern int pg_mbcharcliplen(const unsigned char *, int, int); extern int pg_mbcharcliplen(const unsigned char *, int, int);
extern int pg_encoding_max_length(int);
extern int pg_set_client_encoding(int); extern int pg_set_client_encoding(int);
extern int pg_get_client_encoding(void); extern int pg_get_client_encoding(void);
...@@ -233,8 +239,12 @@ extern int pg_valid_client_encoding(const char *name); ...@@ -233,8 +239,12 @@ extern int pg_valid_client_encoding(const char *name);
extern int pg_valid_server_encoding(const char *name); extern int pg_valid_server_encoding(const char *name);
extern int pg_utf_mblen(const unsigned char *); extern int pg_utf_mblen(const unsigned char *);
extern int pg_find_encoding_converters(int, int, void (**)(), void (**)()); extern int pg_find_encoding_converters(int src, int dest,
extern unsigned char *pg_do_encoding_conversion(unsigned char *, int, void (*)(), void (*)()); to_mic_converter *src_to_mic,
from_mic_converter *dest_from_mic);
extern unsigned char *pg_do_encoding_conversion(unsigned char *src, int len,
to_mic_converter src_to_mic,
from_mic_converter dest_from_mic);
extern unsigned char *pg_client_to_server(unsigned char *, int); extern unsigned char *pg_client_to_server(unsigned char *, int);
extern unsigned char *pg_server_to_client(unsigned char *, int); extern unsigned char *pg_server_to_client(unsigned char *, int);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment