diff options
Diffstat (limited to 'src')
35 files changed, 949 insertions, 323 deletions
diff --git a/src/Makefile.global.in b/src/Makefile.global.in index 4472d875e10..ebd5c4ba933 100644 --- a/src/Makefile.global.in +++ b/src/Makefile.global.in @@ -7,7 +7,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/Makefile.global.in,v 1.42 1998/05/12 15:42:08 momjian Exp $ +# $Header: /cvsroot/pgsql/src/Makefile.global.in,v 1.43 1998/06/16 07:29:15 momjian Exp $ # # NOTES # Essentially all Postgres make files include this file and use the @@ -150,7 +150,7 @@ X11_LIBS= -lX11 @X_EXTRA_LIBS@ # # enable multi-byte support # choose one of: -# EUC_JP,EHC_CN,EUC_KR,EUC_TW,UNICODE,MULE_INTERNAL +# EUC_JP,EUC_CN,EUC_KR,EUC_TW,UNICODE,MULE_INTERNAL,LATIN1 MB=@MB@ ############################################################################## diff --git a/src/backend/access/common/Makefile b/src/backend/access/common/Makefile index 73b1b3ea82e..76974644fa6 100644 --- a/src/backend/access/common/Makefile +++ b/src/backend/access/common/Makefile @@ -4,7 +4,7 @@ # Makefile for access/common # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/access/common/Makefile,v 1.10 1998/04/06 00:20:44 momjian Exp $ +# $Header: /cvsroot/pgsql/src/backend/access/common/Makefile,v 1.11 1998/06/16 07:29:18 momjian Exp $ # #------------------------------------------------------------------------- @@ -13,6 +13,10 @@ include ../../../Makefile.global CFLAGS+=-I../.. +ifdef MB +CFLAGS+= -DMB=$(MB) +endif + OBJS = heaptuple.o heapvalid.o indextuple.o indexvalid.o printtup.o \ scankey.o tupdesc.o diff --git a/src/backend/access/common/printtup.c b/src/backend/access/common/printtup.c index 8b27415cf68..ccebe243825 100644 --- a/src/backend/access/common/printtup.c +++ b/src/backend/access/common/printtup.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.28 1998/05/14 17:18:12 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.29 1998/06/16 07:29:18 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -23,6 +23,10 @@ #include <libpq/libpq.h> #include <utils/syscache.h> +#ifdef MB +#include <commands/variable.h> +#endif + /* ---------------------------------------------------------------- * printtup / debugtup support * ---------------------------------------------------------------- @@ -80,6 +84,9 @@ printtup(HeapTuple tuple, TupleDesc typeinfo) Datum attr; bool isnull; Oid typoutput; +#ifdef MB + unsigned char *p; +#endif /* ---------------- * tell the frontend to expect new tuple data @@ -125,8 +132,14 @@ printtup(HeapTuple tuple, TupleDesc typeinfo) outputstr = fmgr(typoutput, attr, gettypelem(typeinfo->attrs[i]->atttypid), typeinfo->attrs[i]->atttypmod); +#ifdef MB + p = pg_server_to_client(outputstr, strlen(outputstr)); + pq_putint(strlen(p) + VARHDRSZ, VARHDRSZ); + pq_putnchar(p, strlen(p)); +#else pq_putint(strlen(outputstr) + VARHDRSZ, VARHDRSZ); pq_putnchar(outputstr, strlen(outputstr)); +#endif pfree(outputstr); } } @@ -268,8 +281,12 @@ printtup_internal(HeapTuple tuple, TupleDesc typeinfo) /* variable length, assume a varlena structure */ len = VARSIZE(attr) - VARHDRSZ; +#ifdef MB + pq_putncharlen(VARDATA(attr), len); +#else pq_putint(len, VARHDRSZ); pq_putnchar(VARDATA(attr), len); +#endif #ifdef IPORTAL_DEBUG { char *d = VARDATA(attr); diff --git a/src/backend/commands/Makefile b/src/backend/commands/Makefile index 7e4fe415c3b..fc2b7199ab0 100644 --- a/src/backend/commands/Makefile +++ b/src/backend/commands/Makefile @@ -4,7 +4,7 @@ # Makefile for commands # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/commands/Makefile,v 1.12 1998/04/06 00:22:19 momjian Exp $ +# $Header: /cvsroot/pgsql/src/backend/commands/Makefile,v 1.13 1998/06/16 07:29:20 momjian Exp $ # #------------------------------------------------------------------------- @@ -13,11 +13,19 @@ include ../../Makefile.global CFLAGS += -I.. +ifdef MB +CFLAGS += -DMB=$(MB) +endif + OBJS = async.o creatinh.o command.o copy.o defind.o define.o \ remove.o rename.o vacuum.o version.o view.o cluster.o \ recipe.o explain.o sequence.o trigger.o user.o proclang.o \ dbcommands.o variable.o +ifdef MB +OBJS += mbutils.o +endif + all: SUBSYS.o SUBSYS.o: $(OBJS) diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c index 9e138b82a91..51f9d871bdf 100644 --- a/src/backend/commands/variable.c +++ b/src/backend/commands/variable.c @@ -2,7 +2,7 @@ * Routines for handling of 'SET var TO', * 'SHOW var' and 'RESET var' statements. * - * $Id: variable.c,v 1.6 1998/06/15 19:28:17 momjian Exp $ + * $Id: variable.c,v 1.7 1998/06/16 07:29:21 momjian Exp $ * */ @@ -15,6 +15,9 @@ #include "commands/variable.h" #include "utils/builtins.h" #include "optimizer/internal.h" +#ifdef MB +#include "regex/pg_wchar.h" +#endif extern Cost _cpu_page_wight_; extern Cost _cpu_index_page_wight_; @@ -519,6 +522,54 @@ reset_timezone() return TRUE; } /* reset_timezone() */ +#ifdef MB +/*-----------------------------------------------------------------------*/ +bool +parse_client_encoding(const char *value) +{ + int encoding; + + encoding = pg_valid_client_encoding(value); + if (encoding < 0) { + elog(ERROR, "Client encoding %s is not supported", value); + } else { + if (pg_set_client_encoding(encoding)) { + elog(ERROR, "Conversion between %s and %s is not supported", + value, pg_encoding_to_char(MB)); + } + } + return TRUE; +} + +bool +show_client_encoding() +{ + elog(NOTICE, "Current client encoding is %s", + pg_encoding_to_char(pg_get_client_encoding())); + return TRUE; +} + +bool +reset_client_encoding() +{ + int encoding; + char *env = getenv("PGCLIENTENCODING"); + + if (env) { + encoding = pg_char_to_encoding(env); + if (encoding < 0) { + encoding = MB; + } + } else { + encoding = MB; + } + pg_set_client_encoding(encoding); + return TRUE; +} + +/*-----------------------------------------------------------------------*/ +#endif + /*-----------------------------------------------------------------------*/ struct VariableParsers { @@ -547,6 +598,11 @@ struct VariableParsers { "r_plans", parse_r_plans, show_r_plans, reset_r_plans }, +#ifdef MB + { + "client_encoding", parse_client_encoding, show_client_encoding, reset_client_encoding + }, +#endif { NULL, NULL, NULL, NULL } diff --git a/src/backend/libpq/Makefile b/src/backend/libpq/Makefile index a608044facf..5176f2996a8 100644 --- a/src/backend/libpq/Makefile +++ b/src/backend/libpq/Makefile @@ -4,7 +4,7 @@ # Makefile for libpq subsystem (backend half of libpq interface) # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.11 1998/04/06 00:22:39 momjian Exp $ +# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.12 1998/06/16 07:29:22 momjian Exp $ # #------------------------------------------------------------------------- @@ -19,6 +19,10 @@ CFLAGS+= $(KRBFLAGS) LDFLAGS+= $(KRBLIBS) endif +ifdef MB +CFLAGS+= -DMB=$(MB) +endif + OBJS = be-dumpdata.o be-fsstubs.o be-pqexec.o pqcomprim.o\ auth.o hba.o crypt.o pqcomm.o portal.o util.o portalbuf.o pqpacket.o pqsignal.o \ password.o diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index a3ff7bcffd1..9b699a22e4b 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.44 1998/06/15 19:28:27 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.45 1998/06/16 07:29:23 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -23,6 +23,9 @@ * pq_putstr - send a null terminated string to connection * pq_putnchar - send n characters to connection * pq_putint - send an integer to connection + * pq_putncharlen - send n characters to connection + * (also send an int header indicating + * the length) * pq_getinaddr - initialize address from host and port number * pq_getinserv - initialize address from host and service name * pq_connect - create remote input / output connection @@ -66,6 +69,9 @@ #include "libpq/auth.h" #include "libpq/libpq.h" /* where the declarations go */ #include "storage/ipc.h" +#ifdef MB +#include "commands/variable.h" +#endif /* ---------------- * declarations @@ -180,6 +186,14 @@ pq_getstr(char *s, int maxlen) { int c = '\0'; +#ifdef MB + unsigned char *p, *ps; + int len; + + ps = s; + len = maxlen; +#endif + if (Pfin == (FILE *) NULL) { /* elog(DEBUG, "Input descriptor is null"); */ @@ -190,6 +204,13 @@ pq_getstr(char *s, int maxlen) *s++ = c; *s = '\0'; +#ifdef MB + p = pg_client_to_server(ps, len); + if (ps != p) { /* actual conversion has been done? */ + strcpy(ps, p); + } +#endif + /* ----------------- * If EOF reached let caller know. * (This will only happen if we hit EOF before the string @@ -325,7 +346,14 @@ pq_getint(int b) void pq_putstr(char *s) { +#ifdef MB + unsigned char *p; + + p = pg_server_to_client(s, strlen(s)); + if (pqPutString(p, Pfout)) +#else if (pqPutString(s, Pfout)) +#endif { sprintf(PQerrormsg, "FATAL: pq_putstr: fputs() failed: errno=%d\n", errno); @@ -788,3 +816,17 @@ StreamOpen(char *hostName, short portName, Port *port) return (STATUS_OK); } + +#ifdef MB +void +pq_putncharlen(char *s, int n) +{ + unsigned char *p; + int len; + + p = pg_server_to_client(s, n); + len = strlen(p); + pq_putint(len, sizeof(int)); + pq_putnchar(p, len); +} +#endif diff --git a/src/backend/parser/scan.c b/src/backend/parser/scan.c index dd0304b97f0..83ae575e894 100644 --- a/src/backend/parser/scan.c +++ b/src/backend/parser/scan.c @@ -1,7 +1,7 @@ /* A lexical scanner generated by flex */ /* Scanner skeleton version: - * $Header: /cvsroot/pgsql/src/backend/parser/Attic/scan.c,v 1.21 1998/06/15 19:28:56 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/Attic/scan.c,v 1.22 1998/06/16 07:29:25 momjian Exp $ */ #define FLEX_SCANNER @@ -555,7 +555,7 @@ char *yytext; * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/Attic/scan.c,v 1.21 1998/06/15 19:28:56 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/Attic/scan.c,v 1.22 1998/06/16 07:29:25 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1178,7 +1178,8 @@ YY_RULE_SETUP BEGIN(xm); for(i = 0; yytext[i]; i++) - if (isupper(yytext[i])) + if (isascii((unsigned char)yytext[i]) && + isupper(yytext[i])) yytext[i] = tolower(yytext[i]); keyword = ScanKeywordLookup((char*)yytext); @@ -1194,7 +1195,7 @@ YY_RULE_SETUP YY_BREAK case 34: YY_RULE_SETUP -#line 336 "scan.l" +#line 337 "scan.l" { char* endptr; @@ -1216,7 +1217,7 @@ YY_RULE_SETUP YY_BREAK case 35: YY_RULE_SETUP -#line 354 "scan.l" +#line 355 "scan.l" { char* endptr; @@ -1231,7 +1232,7 @@ YY_RULE_SETUP YY_BREAK case 36: YY_RULE_SETUP -#line 365 "scan.l" +#line 366 "scan.l" { char* endptr; @@ -1252,7 +1253,7 @@ YY_RULE_SETUP YY_BREAK case 37: YY_RULE_SETUP -#line 382 "scan.l" +#line 383 "scan.l" { char* endptr; @@ -1266,13 +1267,14 @@ YY_RULE_SETUP YY_BREAK case 38: YY_RULE_SETUP -#line 394 "scan.l" +#line 395 "scan.l" { int i; ScanKeyword *keyword; for(i = 0; yytext[i]; i++) - if (isupper(yytext[i])) + if (isascii((unsigned char)yytext[i]) && + isupper(yytext[i])) yytext[i] = tolower(yytext[i]); keyword = ScanKeywordLookup((char*)yytext); @@ -1288,20 +1290,20 @@ YY_RULE_SETUP YY_BREAK case 39: YY_RULE_SETUP -#line 412 "scan.l" +#line 414 "scan.l" { /* ignore */ } YY_BREAK case 40: YY_RULE_SETUP -#line 414 "scan.l" +#line 416 "scan.l" { return (yytext[0]); } YY_BREAK case 41: YY_RULE_SETUP -#line 416 "scan.l" +#line 418 "scan.l" ECHO; YY_BREAK -#line 1305 "lex.yy.c" +#line 1307 "lex.yy.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(xb): case YY_STATE_EOF(xc): @@ -2187,7 +2189,7 @@ int main() return 0; } #endif -#line 416 "scan.l" +#line 418 "scan.l" void yyerror(char message[]) diff --git a/src/backend/parser/scan.l b/src/backend/parser/scan.l index 6fe3af8369c..bf18df010c2 100644 --- a/src/backend/parser/scan.l +++ b/src/backend/parser/scan.l @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.39 1998/05/09 23:15:20 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/scan.l,v 1.40 1998/06/16 07:29:27 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -320,7 +320,8 @@ other . BEGIN(xm); for(i = 0; yytext[i]; i++) - if (isupper(yytext[i])) + if (isascii((unsigned char)yytext[i]) && + isupper(yytext[i])) yytext[i] = tolower(yytext[i]); keyword = ScanKeywordLookup((char*)yytext); @@ -396,7 +397,8 @@ other . ScanKeyword *keyword; for(i = 0; yytext[i]; i++) - if (isupper(yytext[i])) + if (isascii((unsigned char)yytext[i]) && + isupper(yytext[i])) yytext[i] = tolower(yytext[i]); keyword = ScanKeywordLookup((char*)yytext); diff --git a/src/backend/regex/engine.c b/src/backend/regex/engine.c index 6381d5990c9..b95b6491eb6 100644 --- a/src/backend/regex/engine.c +++ b/src/backend/regex/engine.c @@ -127,6 +127,9 @@ extern "C" # elif MB == UNICODE # define NONCHAR(c) ((c) > USHRT_MAX) # define NNONCHAR (CODEMAX-USHRT_MAX) +# else /* assume 1 byte code such as ISO8859-1 */ +# define NONCHAR(c) ((c) > UCHAR_MAX) +# define NNONCHAR (CODEMAX-UCHAR_MAX) # endif #else # define NONCHAR(c) ((c) > CHAR_MAX) diff --git a/src/backend/regex/regcomp.c b/src/backend/regex/regcomp.c index 01b95427c62..4eb71eb525e 100644 --- a/src/backend/regex/regcomp.c +++ b/src/backend/regex/regcomp.c @@ -1344,7 +1344,7 @@ cset *cs; for (i = 0; i < css; i++) if (CHIN(cs, i)) - return ((char) i); + return (i); assert(never); return (0); /* arbitrary */ } diff --git a/src/backend/regex/utils.c b/src/backend/regex/utils.c index 67b9f2a737a..0308140118b 100644 --- a/src/backend/regex/utils.c +++ b/src/backend/regex/utils.c @@ -1,202 +1,97 @@ /* * misc conversion functions between pg_wchar and other encodings. * Tatsuo Ishii - * $Id: utils.c,v 1.2 1998/04/27 17:07:53 scrappy Exp $ + * $Id: utils.c,v 1.3 1998/06/16 07:29:29 momjian Exp $ */ #include <regex/pg_wchar.h> + /* - * convert EUC to pg_wchar (EUC process code) - * caller should allocate enough space for "to" + * conversion to pg_wchar is done by "table driven." + * to add an encoding support, define mb2wchar_with_len(), mblen() + * for the particular encoding. Note that if the encoding is only + * supported in the client, you don't need to define + * mb2wchar_with_len() function (SJIS is the case). */ -static void pg_euc2wchar(const unsigned char *from, pg_wchar *to) -{ - while (*from) { - if (*from == SS2) { - from++; - *to = *from++; - } else if (*from == SS3) { - from++; - *to = *from++ << 8; - *to |= 0x3f & *from++; - } else if (*from & 0x80) { - *to = *from++ << 8; - *to |= *from++; - } else { - *to = *from++; - } - to++; - } - *to = 0; -} - -static void pg_eucjp2wchar(const unsigned char *from, pg_wchar *to) -{ - pg_euc2wchar(from,to); -} - -static void pg_euckr2wchar(const unsigned char *from, pg_wchar *to) -{ - pg_euc2wchar(from,to); -} +typedef struct { + void (*mb2wchar_with_len)(); /* convert a multi-byte string to a wchar */ + int (*mblen)(); /* returns the length of a multi-byte word */ +} pg_wchar_tbl; -static void pg_eucch2wchar(const unsigned char *from, pg_wchar *to) +static void pg_euc2wchar_with_len +(const unsigned char *from, pg_wchar *to, int len) { - while (*from) { + while (*from && len > 0) { if (*from == SS2) { from++; - *to = 0x3f00 & (*from++ << 8); - *to = *from++; + len--; + *to = 0xff & *from++; + len--; } else if (*from == SS3) { from++; *to = *from++ << 8; *to |= 0x3f & *from++; + len -= 3; } else if (*from & 0x80) { *to = *from++ << 8; *to |= *from++; + len -= 2; } else { *to = *from++; + len--; } to++; } *to = 0; } -static void pg_euccn2wchar(const unsigned char *from, pg_wchar *to) +static int pg_euc_mblen(const unsigned char *s) { - while (*from) { - if (*from == SS2) { - from++; - *to = *from++ << 16; - *to |= *from++ << 8; - *to |= *from++; - } else if (*from == SS3) { - from++; - *to = *from++ << 8; - *to |= 0x3f & *from++; - } else if (*from & 0x80) { - *to = *from++ << 8; - *to |= *from++; - } else { - *to = *from++; - } - to++; + int len; + + if (*s == SS2) { + len = 2; + } else if (*s == SS3) { + len = 3; + } else if (*s & 0x80) { + len = 2; + } else { + len = 1; } - *to = 0; + return(len); } /* - * convert UTF-8 to pg_wchar (UCS-2) - * caller should allocate enough space for "to" + * EUC_JP */ -static void pg_utf2wchar(const unsigned char *from, pg_wchar *to) +static void pg_eucjp2wchar_with_len +(const unsigned char *from, pg_wchar *to, int len) { - unsigned char c1,c2,c3; - while (*from) { - if ((*from & 0x80) == 0) { - *to = *from++; - } else if ((*from & 0xe0) == 0xc0) { - c1 = *from++ & 0x1f; - c2 = *from++ & 0x3f; - *to = c1 << 6; - *to |= c2; - } else if ((*from & 0xe0) == 0xe0) { - c1 = *from++ & 0x0f; - c2 = *from++ & 0x3f; - c3 = *from++ & 0x3f; - *to = c1 << 12; - *to |= c2 << 6; - *to |= c3; - } - to++; - } - *to = 0; + pg_euc2wchar_with_len(from,to,len); } -/* - * convert mule internal code to pg_wchar. - * in this case pg_wchar consists of following 4 bytes: - * - * 0x00(unused) - * 0x00(ASCII)|leading character (one of LC1, LC12, LC2 or LC22) - * 0x00(ASCII,1 byte code)|other than 0x00(2 byte code) - * the lowest byte of the code - * - * note that Type N (variable length byte encoding) cannot be represented by - * this schema. sorry. - * caller should allocate enough space for "to" - */ -static void pg_mule2wchar(const unsigned char *from, pg_wchar *to) +static int pg_eucjp_mblen(const unsigned char *s) { - while (*from) { - if (IS_LC1(*from)) { - *to = *from++ << 16; - *to |= *from++; - } else if (IS_LCPRV1(*from)) { - from++; - *to = *from++ << 16; - *to |= *from++; - } else if (IS_LC2(*from)) { - *to = *from++ << 16; - *to |= *from++ << 8; - *to |= *from++; - } else if (IS_LCPRV2(*from)) { - from++; - *to = *from++ << 16; - *to |= *from++ << 8; - *to |= *from++; - } else { /* assume ASCII */ - *to = *from++; - } - to++; - } - *to = 0; + return(pg_euc_mblen(s)); } /* - * convert EUC to pg_wchar (EUC process code) - * caller should allocate enough space for "to" - * len: length of from. - * "from" not necessarily null terminated. + * EUC_KR */ -static void pg_euc2wchar_with_len(const unsigned char *from, pg_wchar *to, int len) -{ - while (*from && len > 0) { - if (*from == SS2) { - from++; - len--; - *to = 0xff & *from++; - len--; - } else if (*from == SS3) { - from++; - *to = *from++ << 8; - *to |= 0x3f & *from++; - len -= 3; - } else if (*from & 0x80) { - *to = *from++ << 8; - *to |= *from++; - len -= 2; - } else { - *to = *from++; - len--; - } - to++; - } - *to = 0; -} - -static void pg_eucjp2wchar_with_len +static void pg_euckr2wchar_with_len (const unsigned char *from, pg_wchar *to, int len) { pg_euc2wchar_with_len(from,to,len); } -static void pg_euckr2wchar_with_len -(const unsigned char *from, pg_wchar *to, int len) +static int pg_euckr_mblen(const unsigned char *s) { - pg_euc2wchar_with_len(from,to,len); + return(pg_euc_mblen(s)); } -static void pg_eucch2wchar_with_len +/* + * EUC_CN + */ +static void pg_euccn2wchar_with_len (const unsigned char *from, pg_wchar *to, int len) { while (*from && len > 0) { @@ -224,7 +119,26 @@ static void pg_eucch2wchar_with_len *to = 0; } -static void pg_euccn2wchar_with_len +static int pg_euccn_mblen(const unsigned char *s) +{ + int len; + + if (*s == SS2) { + len = 3; + } else if (*s == SS3) { + len = 3; + } else if (*s & 0x80) { + len = 2; + } else { + len = 1; + } + return(len); +} + +/* + * EUC_TW + */ +static void pg_euctw2wchar_with_len (const unsigned char *from, pg_wchar *to, int len) { while (*from && len > 0) { @@ -253,6 +167,22 @@ static void pg_euccn2wchar_with_len *to = 0; } +static int pg_euctw_mblen(const unsigned char *s) +{ + int len; + + if (*s == SS2) { + len = 4; + } else if (*s == SS3) { + len = 3; + } else if (*s & 0x80) { + len = 2; + } else { + len = 1; + } + return(len); +} + /* * convert UTF-8 to pg_wchar (UCS-2) * caller should allocate enough space for "to" @@ -286,6 +216,20 @@ static void pg_utf2wchar_with_len(const unsigned char *from, pg_wchar *to, int l *to = 0; } +static int pg_utf_mblen(const unsigned char *s) +{ + int len = 1; + + if ((*s & 0x80) == 0) { + len = 1; + } else if ((*s & 0xe0) == 0xc0) { + len = 2; + } else if ((*s & 0xe0) == 0xe0) { + len = 3; + } + return(len); +} + /* * convert mule internal code to pg_wchar * caller should allocate enough space for "to" @@ -324,115 +268,89 @@ static void pg_mule2wchar_with_len(const unsigned char *from, pg_wchar *to, int *to = 0; } -static int pg_euc_mblen(const unsigned char *s) +static int pg_mule_mblen(const unsigned char *s) { int len; - if (*s == SS2) { - len = 2; - } else if (*s == SS3) { - len = 3; - } else if (*s & 0x80) { + if (IS_LC1(*s)) { len = 2; - } else { - len = 1; - } - return(len); -} - -static int pg_eucjp_mblen(const unsigned char *s) -{ - return(pg_euc_mblen(s)); -} - -static int pg_euckr_mblen(const unsigned char *s) -{ - return(pg_euc_mblen(s)); -} - -static int pg_eucch_mblen(const unsigned char *s) -{ - int len; - - if (*s == SS2) { + } else if (IS_LCPRV1(*s)) { len = 3; - } else if (*s == SS3) { + } else if (IS_LC2(*s)) { len = 3; - } else if (*s & 0x80) { - len = 2; - } else { + } else if (IS_LCPRV2(*s)) { + len = 4; + } else { /* assume ASCII */ len = 1; } return(len); } -static int pg_euccn_mblen(const unsigned char *s) +/* + * ISO8859-1 + */ +static void pg_latin12wchar_with_len(const unsigned char *from, pg_wchar *to, int len) { - int len; - - if (*s == SS2) { - len = 4; - } else if (*s == SS3) { - len = 3; - } else if (*s & 0x80) { - len = 2; - } else { - len = 1; + while (*from && len-- > 0) { + *to++ = *from++; } - return(len); + *to = 0; } -static int pg_utf_mblen(const unsigned char *s) +static int pg_latin1_mblen(const unsigned char *s) { - int len = 1; - - if ((*s & 0x80) == 0) { - len = 1; - } else if ((*s & 0xe0) == 0xc0) { - len = 2; - } else if ((*s & 0xe0) == 0xe0) { - len = 3; - } - return(len); + return(1); } -static int pg_mule_mblen(const unsigned char *s) +/* + * SJIS + */ +static int pg_sjis_mblen(const unsigned char *s) { int len; - if (IS_LC1(*s)) { + if (*s >= 0xa1 && *s <= 0xdf) { /* 1 byte kana? */ + len = 1; + } else if (*s > 0x7f) { /* kanji? */ len = 2; - } else if (IS_LCPRV1(*s)) { - len = 3; - } else if (IS_LC2(*s)) { - len = 3; - } else if (IS_LCPRV2(*s)) { - len = 4; - } else { /* assume ASCII */ + } else { /* should be ASCII */ len = 1; } return(len); } -typedef struct { - void (*mb2wchar)(); /* convert a multi-byte string to a wchar */ - void (*mb2wchar_with_len)(); /* convert a multi-byte string to a wchar - with a limited length */ - int (*mblen)(); /* returns the length of a multi-byte word */ -} pg_wchar_tbl; - static pg_wchar_tbl pg_wchar_table[] = { - {pg_eucjp2wchar, pg_eucjp2wchar_with_len, pg_eucjp_mblen}, - {pg_eucch2wchar, pg_eucch2wchar_with_len, pg_eucch_mblen}, - {pg_euckr2wchar, pg_euckr2wchar_with_len, pg_euckr_mblen}, - {pg_euccn2wchar, pg_euccn2wchar_with_len, pg_euccn_mblen}, - {pg_utf2wchar, pg_utf2wchar_with_len, pg_utf_mblen}, - {pg_mule2wchar, pg_mule2wchar_with_len, pg_mule_mblen}}; + {pg_eucjp2wchar_with_len, pg_eucjp_mblen}, + {pg_euccn2wchar_with_len, pg_euccn_mblen}, + {pg_euckr2wchar_with_len, pg_euckr_mblen}, + {pg_euctw2wchar_with_len, pg_euctw_mblen}, + {pg_utf2wchar_with_len, pg_utf_mblen}, + {pg_mule2wchar_with_len, pg_mule_mblen}, + {pg_latin12wchar_with_len, pg_latin1_mblen}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, pg_sjis_mblen} +}; + +/* + *######################################################################## + * + * Public functions + * + *######################################################################## + */ /* convert a multi-byte string to a wchar */ void pg_mb2wchar(const unsigned char *from, pg_wchar *to) { - (*pg_wchar_table[MB].mb2wchar)(from,to); + (*pg_wchar_table[MB].mb2wchar_with_len)(from,to,strlen(from)); } /* convert a multi-byte string to a wchar with a limited length */ @@ -447,6 +365,18 @@ int pg_mblen(const unsigned char *mbstr) return((*pg_wchar_table[MB].mblen)(mbstr)); } +/* returns the byte length of a multi-byte word for an encoding */ +int pg_encoding_mblen(int encoding, const unsigned char *mbstr) +{ + return((*pg_wchar_table[encoding].mblen)(mbstr)); +} + +/* returns the byte length of a word for mule internal code */ +int pg_mic_mblen(const unsigned char *mbstr) +{ + return(pg_mule_mblen(mbstr)); +} + /* returns the length (counted as a wchar) of a multi-byte string */ int pg_mbstrlen(const unsigned char *mbstr) { diff --git a/src/backend/tcop/Makefile b/src/backend/tcop/Makefile index 45cddf43aaa..e8e88d84392 100644 --- a/src/backend/tcop/Makefile +++ b/src/backend/tcop/Makefile @@ -4,7 +4,7 @@ # Makefile for tcop # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/tcop/Makefile,v 1.16 1998/04/06 00:26:05 momjian Exp $ +# $Header: /cvsroot/pgsql/src/backend/tcop/Makefile,v 1.17 1998/06/16 07:29:30 momjian Exp $ # #------------------------------------------------------------------------- @@ -13,6 +13,10 @@ include ../../Makefile.global CFLAGS+= -I.. +ifdef MB +CFLAGS+= -DMB=$(MB) +endif + ifeq ($(CC), gcc) CFLAGS+= -Wno-error endif diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 9670f326404..2c457bf05e0 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.76 1998/06/15 19:29:27 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.77 1998/06/16 07:29:30 momjian Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -83,6 +83,10 @@ #include "nodes/memnodes.h" #endif +#ifdef MB +#include "commands/variable.h" +#endif + /* ---------------- * global variables * ---------------- @@ -1270,6 +1274,19 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) InitPostgres(DBName); +#ifdef MB + /* set default client encoding */ + if (!Quiet) + { + puts("\treset_client_encoding().."); + } + reset_client_encoding(); + if (!Quiet) + { + puts("\treset_client_encoding() done."); + } +#endif + /* ---------------- * if an exception is encountered, processing resumes here * so we abort the current transaction and start a new one. @@ -1308,7 +1325,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) if (!IsUnderPostmaster) { puts("\nPOSTGRES backend interactive interface"); - puts("$Revision: 1.76 $ $Date: 1998/06/15 19:29:27 $"); + puts("$Revision: 1.77 $ $Date: 1998/06/16 07:29:30 $"); } /* ---------------- diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 613b2a5b88a..d80a2676dc1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -21,7 +21,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.73 1998/06/16 06:52:15 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.74 1998/06/16 07:29:32 momjian Exp $ * * Modifications - 6/10/96 - [email protected] - version 1.13.dhb * @@ -597,7 +597,8 @@ main(int argc, char **argv) tablename = strdup(optarg); for (i = 0; tablename[i]; i++) - if (isupper(tablename[i])) + if (isascii((unsigned char)tablename[i]) && + isupper(tablename[i])) tablename[i] = tolower(tablename[i]); } break; diff --git a/src/bin/psql/Makefile.in b/src/bin/psql/Makefile.in index 071ab34c509..d34abdef46c 100644 --- a/src/bin/psql/Makefile.in +++ b/src/bin/psql/Makefile.in @@ -7,7 +7,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/bin/psql/Attic/Makefile.in,v 1.11 1998/04/06 16:51:44 momjian Exp $ +# $Header: /cvsroot/pgsql/src/bin/psql/Attic/Makefile.in,v 1.12 1998/06/16 07:29:37 momjian Exp $ # #------------------------------------------------------------------------- @@ -24,6 +24,10 @@ LDFLAGS+= $(KRBLIBS) CFLAGS+= $(KRBFLAGS) endif +ifdef MB +CFLAGS+= -DMB=$(MB) +endif + OBJS= psql.o stringutils.o @STRDUP@ all: submake psql diff --git a/src/bin/psql/psql.c b/src/bin/psql/psql.c index 9f699ad8d74..1ed9e4561fd 100644 --- a/src/bin/psql/psql.c +++ b/src/bin/psql/psql.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.145 1998/06/15 19:30:07 momjian Exp $ + * $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.146 1998/06/16 07:29:38 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -639,8 +639,13 @@ tableDesc(PsqlSettings *pset, char *table, FILE *fout) } else { +#ifdef MB + for (i = 0; table[i]; i += PQmblen(table+i)) +#else for (i = 0; table[i]; i++) - if (isupper(table[i])) +#endif + if (isascii((unsigned char)table[i]) && + isupper(table[i])) table[i] = tolower(table[i]); } @@ -811,7 +816,11 @@ objectDescription(PsqlSettings *pset, char *object, FILE *fout) } else { +#ifdef MB + for (i = 0; object[i]; i += PQmblen(object+i)) +#else for (i = 0; object[i]; i++) +#endif if (isupper(object[i])) object[i] = tolower(object[i]); } @@ -2296,9 +2305,16 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source) { int i; - was_bslash = false; +#ifdef MB + int mblen = 1; +#endif + was_bslash = false; +#ifdef MB + for (i = 0; i < len; mblen=PQmblen(line+i), i+=mblen) +#else for (i = 0; i < len; i++) +#endif { if (line[i] == '\\' && !in_quote) { @@ -2322,7 +2338,9 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source) /* start an extended comment? */ } - if (querySent && !isspace(line[i])) + if (querySent && + isascii((unsigned char)(line[i])) && + !isspace(line[i])) { query[0] = '\0'; querySent = false; @@ -2330,7 +2348,11 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source) if (was_bslash) was_bslash = false; +#ifdef MB + else if (i > 0 && line[i - mblen] == '\\') +#else else if (i > 0 && line[i - 1] == '\\') +#endif was_bslash = true; /* inside a quote? */ @@ -2339,22 +2361,42 @@ MainLoop(PsqlSettings *pset, char *query, FILE *source) else if (xcomment != NULL) /* inside an extended * comment? */ { +#ifdef MB + if (line[i] == '*' && line[i + mblen] == '/') +#else if (line[i] == '*' && line[i + 1] == '/') +#endif { xcomment = NULL; +#ifdef MB + i += mblen; +#else i++; +#endif } } /* possible backslash command? */ +#ifdef MB + else if (line[i] == '/' && line[i + mblen] == '*') +#else else if (line[i] == '/' && line[i + 1] == '*') +#endif { xcomment = line + i; +#ifdef MB + i += mblen; +#else i++; - +#endif } /* single-line comment? truncate line */ +#ifdef MB + else if ((line[i] == '-' && line[i + mblen] == '-') || + (line[i] == '/' && line[i + mblen] == '/')) +#else else if ((line[i] == '-' && line[i + 1] == '-') || (line[i] == '/' && line[i + 1] == '/')) +#endif { /* print comment at top of query */ if (pset->singleStep) diff --git a/src/bin/psql/psqlHelp.h b/src/bin/psql/psqlHelp.h index 0ecfa7b6c94..91786543e4b 100644 --- a/src/bin/psql/psqlHelp.h +++ b/src/bin/psql/psqlHelp.h @@ -5,7 +5,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: psqlHelp.h,v 1.43 1998/06/15 18:39:49 momjian Exp $ + * $Id: psqlHelp.h,v 1.44 1998/06/16 07:29:39 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -263,7 +263,11 @@ static struct _helpStruct QL_HELP[] = { "notify <class_name>"}, {"reset", "set run-time environment back to default", +#ifdef MB + "reset {DateStyle | GEQO | R_PLANS | CLIENT_ENCODING}"}, +#else "reset {DateStyle | GEQO | R_PLANS}"}, +#endif {"revoke", "revoke access control from a user or group", "revoke <privilege[,privilege,...]> on <rel1>[,...<reln>] from \n\ @@ -284,12 +288,23 @@ static struct _helpStruct QL_HELP[] = { \t[union [all] select ...];"}, {"set", "set run-time environment", +#ifdef MB + "set DateStyle to {'ISO' | 'SQL' | 'Postgres' | 'European' | 'US' | 'NonEuropean'}\n\ +set GEQO to {'ON[=#]' | 'OFF'}\n\ +set R_PLANS to {'ON' | 'OFF'}\n\ +set CLIENT_ENCODING to {'EUC_JP' | 'SJIS' | 'EUC_CN' | 'EUC_KR' | 'EUC_TW' | 'MULE_INTERNAL' | 'LATIN1'}"}, +#else "set DateStyle to {'ISO' | 'SQL' | 'Postgres' | 'European' | 'US' | 'NonEuropean'}\n\ set GEQO to {'ON[=#]' | 'OFF'}\n\ set R_PLANS to {'ON' | 'OFF'}"}, +#endif {"show", "show current run-time environment", +#ifdef MB + "show {DateStyle | GEQO | R_PLANS | CLIENT_ENCODING}"}, +#else "show {DateStyle | GEQO | R_PLANS}"}, +#endif {"update", "update tuples", "update <class_name> set <attr1>=<expr1>,...<attrN>=<exprN> [from <from_clause>] [where <qual>];"}, diff --git a/src/configure b/src/configure index bcbee80cb9d..691a42c5112 100755 --- a/src/configure +++ b/src/configure @@ -807,12 +807,12 @@ if test "${with_mb+set}" = set; then withval="$with_mb" case "$withval" in - EUC_JP|EHC_CN|EUC_KR|EUC_TW|UNICODE|MULE_INTERNAL) + EUC_JP|EHC_CN|EUC_KR|EUC_TW|UNICODE|MULE_INTERNAL|LATIN1) MB="$withval"; echo "$ac_t"""enabled with $withval"" 1>&6 ;; *) - { echo "configure: error: *** You must supply an argument to the --with-mb option one of EUC_JP,EHC_CN,EUC_KR,EUC_TW,UNICODE,MULE_INTERNAL" 1>&2; exit 1; } + { echo "configure: error: *** You must supply an argument to the --with-mb option one of EUC_JP,EHC_CN,EUC_KR,EUC_TW,UNICODE,MULE_INTERNAL,LATIN1" 1>&2; exit 1; } ;; esac MB="$withval" diff --git a/src/configure.in b/src/configure.in index 987ee1e2533..07c7abb5789 100644 --- a/src/configure.in +++ b/src/configure.in @@ -194,12 +194,12 @@ AC_ARG_WITH(mb, [ --with-mb=<encoding> enable multi-byte support ], [ case "$withval" in - EUC_JP|EHC_CN|EUC_KR|EUC_TW|UNICODE|MULE_INTERNAL) + EUC_JP|EHC_CN|EUC_KR|EUC_TW|UNICODE|MULE_INTERNAL|LATIN1) MB="$withval"; AC_MSG_RESULT("enabled with $withval") ;; *) - AC_MSG_ERROR([*** You must supply an argument to the --with-mb option one of EUC_JP,EHC_CN,EUC_KR,EUC_TW,UNICODE,MULE_INTERNAL]) + AC_MSG_ERROR([*** You must supply an argument to the --with-mb option one of EUC_JP,EHC_CN,EUC_KR,EUC_TW,UNICODE,MULE_INTERNAL,LATIN1]) ;; esac MB="$withval" diff --git a/src/include/commands/variable.h b/src/include/commands/variable.h index 920536e50f2..ebf6390116d 100644 --- a/src/include/commands/variable.h +++ b/src/include/commands/variable.h @@ -2,7 +2,7 @@ * Headers for handling of 'SET var TO', 'SHOW var' and 'RESET var' * statements * - * $Id: variable.h,v 1.2 1998/02/26 04:41:13 momjian Exp $ + * $Id: variable.h,v 1.3 1998/06/16 07:29:40 momjian Exp $ * */ #ifndef VARIABLE_H @@ -54,5 +54,17 @@ extern bool set_geqo(void); extern bool show_geqo(void); extern bool reset_geqo(void); extern bool parse_geqo(const char *); +#ifdef MB +extern bool show_client_encoding(void); +extern bool reset_client_encoding(void); +extern bool parse_client_encoding(const char *); +extern int pg_set_client_encoding(int); +extern int pg_get_client_encoding(void); +extern unsigned char *pg_client_to_server(unsigned char *, int); +extern unsigned char *pg_server_to_client(unsigned char *, int); +extern int pg_valid_client_encoding(const char *); +extern const char *pg_encoding_to_char(int); +extern int pg_char_to_encoding(const char *); +#endif #endif /* VARIABLE_H */ diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h index 61c8c9910dd..9a347989c40 100644 --- a/src/include/libpq/libpq.h +++ b/src/include/libpq/libpq.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: libpq.h,v 1.15 1998/05/29 17:00:24 momjian Exp $ + * $Id: libpq.h,v 1.16 1998/06/16 07:29:41 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -272,6 +272,11 @@ extern int pq_sendoob(char *msg, int len); extern int pq_recvoob(char *msgPtr, int len); extern int pq_getinaddr(struct sockaddr_in * sin, char *host, int port); extern int pq_getinserv(struct sockaddr_in * sin, char *host, char *serv); + +#ifdef MB +extern void pq_putncharlen(char *s, int n); +#endif + extern int pq_connect(char *dbname, char *user, char *args, char *hostName, char *debugTty, char *execFile, short portName); diff --git a/src/include/regex/pg_wchar.h b/src/include/regex/pg_wchar.h index b135df82f12..bfbd8ba37bb 100644 --- a/src/include/regex/pg_wchar.h +++ b/src/include/regex/pg_wchar.h @@ -1,4 +1,4 @@ -/* $Id: pg_wchar.h,v 1.2 1998/04/27 17:09:12 scrappy Exp $ */ +/* $Id: pg_wchar.h,v 1.3 1998/06/16 07:29:43 momjian Exp $ */ #ifndef PG_WCHAR_H #define PG_WCHAR_H @@ -11,9 +11,20 @@ #define EUC_TW 3 /* EUC for Taiwan */ #define UNICODE 4 /* Unicode UTF-8 */ #define MULE_INTERNAL 5 /* Mule internal code */ +#define LATIN1 6 /* ISO-8859 Latin 1 */ +#define LATIN2 7 /* ISO-8859 Latin 2 */ +#define LATIN3 8 /* ISO-8859 Latin 3 */ +#define LATIN4 9 /* ISO-8859 Latin 4 */ +#define LATIN5 10 /* ISO-8859 Latin 5 */ +/* followings are for client encoding only */ +#define SJIS 16 /* Shift JIS */ #ifdef MB +# if LATIN1 <= MB && MB <= LATIN5 +typedef unsigned char pg_wchar; +# else typedef unsigned int pg_wchar; +# endif #else #define pg_wchar char #endif @@ -32,6 +43,28 @@ typedef unsigned int pg_wchar; #define IS_LC2(c) ((unsigned char)(c) >= 0x90 && (unsigned char)(c) <= 0x99) #define IS_LCPRV2(c) ((unsigned char)(c) == 0x9c || (unsigned char)(c) == 0x9d) +/* + * leading characters + */ +#define LC_ISO8859_1 0x81 /* ISO8859 Latin 1 */ +#define LC_ISO8859_2 0x82 /* ISO8859 Latin 2 */ +#define LC_ISO8859_3 0x83 /* ISO8859 Latin 3 */ +#define LC_ISO8859_4 0x84 /* ISO8859 Latin 4 */ +#define LC_ISO8859_5 0x8d /* ISO8859 Latin 5 */ +#define LC_JISX0201K 0x89 /* Japanese 1 byte kana */ +#define LC_JISX0201R 0x90 /* Japanese 1 byte Roman */ +#define LC_GB2312_80 0x91 /* Chinese */ +#define LC_JISX0208 0x92 /* Japanese Kanji */ +#define LC_KS5601 0x93 /* Korean */ +#define LC_JISX0212 0x94 /* Japanese Kanji (JISX0212) */ +#define LC_CNS11643_1 0x95 /* CNS 11643-1992 Plane 1 */ +#define LC_CNS11643_2 0x96 /* CNS 11643-1992 Plane 2 */ +#define LC_CNS11643_3 0xf6 /* CNS 11643-1992 Plane 3 */ +#define LC_CNS11643_4 0xf7 /* CNS 11643-1992 Plane 4 */ +#define LC_CNS11643_5 0xf8 /* CNS 11643-1992 Plane 5 */ +#define LC_CNS11643_6 0xf9 /* CNS 11643-1992 Plane 6 */ +#define LC_CNS11643_7 0xfa /* CNS 11643-1992 Plane 7 */ + #ifdef MB extern void pg_mb2wchar(const unsigned char *, pg_wchar *); extern void pg_mb2wchar_with_len(const unsigned char *, pg_wchar *, int); @@ -40,6 +73,8 @@ extern int pg_wchar_strncmp(const pg_wchar *, const pg_wchar *, size_t); extern int pg_char_and_wchar_strncmp(const char *, const pg_wchar *, size_t); extern size_t pg_wchar_strlen(const pg_wchar *); extern int pg_mblen(const unsigned char *); +extern int pg_encoding_mblen(int, const unsigned char *); +extern int pg_mic_mblen(const unsigned char *); extern int pg_mbstrlen(const unsigned char *); extern int pg_mbstrlen_with_len(const unsigned char *, int); #endif diff --git a/src/include/regex/regex2.h b/src/include/regex/regex2.h index 01cdadff451..4590862486c 100644 --- a/src/include/regex/regex2.h +++ b/src/include/regex/regex2.h @@ -203,6 +203,8 @@ struct re_guts # define OUT (USHRT_MAX+1) /* 2 bytes */ # elif MB == UNICODE # define OUT (USHRT_MAX+1) /* 2 bytes. assuming UCS-2 */ +# else +# define OUT (UCHAR_MAX+1) /* other codes. assuming 1 byte */ # endif #else # define OUT (CHAR_MAX+1) /* a non-character value */ diff --git a/src/interfaces/libpq/Makefile.in b/src/interfaces/libpq/Makefile.in index 460debb82fa..5e59f566631 100644 --- a/src/interfaces/libpq/Makefile.in +++ b/src/interfaces/libpq/Makefile.in @@ -7,7 +7,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/interfaces/libpq/Attic/Makefile.in,v 1.21 1998/06/16 03:17:47 momjian Exp $ +# $Header: /cvsroot/pgsql/src/interfaces/libpq/Attic/Makefile.in,v 1.22 1998/06/16 07:29:45 momjian Exp $ # #------------------------------------------------------------------------- @@ -25,9 +25,17 @@ ifdef KRBVERS CFLAGS+= $(KRBFLAGS) endif +ifdef MB +CFLAGS+= -DMB=$(MB) +endif + OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \ dllist.o pqsignal.o +ifdef MB +OBJS+= pqutils.o pqmbutils.o +endif + # Shared library stuff shlib := install-shlib-dep := diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index 20c02950b1d..ba386d6392e 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.67 1998/06/15 19:30:23 momjian Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.68 1998/06/16 07:29:47 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -120,7 +120,11 @@ struct EnvironmentOptions { "PGTZ", "timezone" }, - +#ifdef MB + { + "PGCLIENTENCODING", "client_encoding" + }, +#endif /* internal performance-related settings */ { "PGCOSTHEAP", "cost_heap" @@ -371,7 +375,8 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions, cons } else for (i = 0; conn->dbName[i]; i++) - if (isupper(conn->dbName[i])) + if (isascii((unsigned char)conn->dbName[i]) && + isupper(conn->dbName[i])) conn->dbName[i] = tolower(conn->dbName[i]); } diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c index 8b4a55e290e..506edc8b1a3 100644 --- a/src/interfaces/libpq/fe-exec.c +++ b/src/interfaces/libpq/fe-exec.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.53 1998/06/15 19:30:25 momjian Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-exec.c,v 1.54 1998/06/16 07:29:48 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1264,7 +1264,8 @@ PQfnumber(PGresult *res, const char *field_name) } else for (i = 0; field_case[i]; i++) - if (isupper(field_case[i])) + if (isascii((unsigned char)field_case[i]) && + isupper(field_case[i])) field_case[i] = tolower(field_case[i]); for (i = 0; i < res->numAttributes; i++) @@ -1466,8 +1467,6 @@ PQgetvalue(PGresult *res, int tup_num, int field_num) return res->tuples[tup_num][field_num].value; } - - /* PQgetlength: returns the length of a field value in bytes. If res is binary, i.e. a result of a binary portal, then the length returned does diff --git a/src/interfaces/libpq/fe-print.c b/src/interfaces/libpq/fe-print.c index 140658b9422..ae820561c06 100644 --- a/src/interfaces/libpq/fe-print.c +++ b/src/interfaces/libpq/fe-print.c @@ -9,7 +9,7 @@ * didn't really belong there. * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-print.c,v 1.4 1998/06/16 06:57:27 momjian Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-print.c,v 1.5 1998/06/16 07:29:49 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -28,6 +28,10 @@ #include <termios.h> #endif +#ifdef MB +#include "regex/pg_wchar.h" +#include "commands/variable.h" +#endif #ifdef TIOCGWINSZ static struct winsize screen_size; @@ -469,7 +473,29 @@ PQprintTuples(PGresult *res, } } - +#ifdef MB +/* + * returns the byte length of the word beginning s. + * Client side encoding is determined by the environment variable + * "PGCLIENTENCODING". + * if this variable is not defined, the same encoding as + * the backend is assumed. + */ +int PQmblen(unsigned char *s) +{ + char *str; + int encoding = -1; + + str = getenv("PGCLIENTENCODING"); + if (str) { + encoding = pg_char_to_encoding(str); + } + if (encoding < 0) { + encoding = MB; + } + return(pg_encoding_mblen(encoding, s)); +} +#endif static void do_field(PQprintOpt *po, PGresult *res, @@ -504,7 +530,15 @@ do_field(PQprintOpt *po, PGresult *res, if (!skipit) { +#ifdef MB + int len; + + for (p = pval, o = buf; *p; + len = PQmblen(p),memcpy(o,p,len), + o+=len, p+=len) +#else for (p = pval, o = buf; *p; *(o++) = *(p++)) +#endif { if ((fs_len == 1 && (*p == *(po->fieldSep))) || *p == '\\' || *p == '\n') *(o++) = '\\'; diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h index 7b932762761..1bfd0f5a3e4 100644 --- a/src/interfaces/libpq/libpq-fe.h +++ b/src/interfaces/libpq/libpq-fe.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: libpq-fe.h,v 1.29 1998/05/06 23:51:16 momjian Exp $ + * $Id: libpq-fe.h,v 1.30 1998/06/16 07:29:49 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -364,6 +364,10 @@ extern "C" * 0, use variable width */ ); +#ifdef MB + extern int PQmblen(unsigned char *s); +#endif + /* === in fe-auth.c === */ extern MsgType fe_getauthsvc(char *PQerrormsg); extern void fe_setauthsvc(const char *name, char *PQerrormsg); diff --git a/src/test/regress/expected/euc_cn.out b/src/test/regress/expected/euc_cn.out index d927b28d205..f35356b5e85 100644 --- a/src/test/regress/expected/euc_cn.out +++ b/src/test/regress/expected/euc_cn.out @@ -53,3 +53,35 @@ QUERY: select * from ��������� where ���� ~* '����[��ͼ]'; ����ͼ�� |��B01��| (2 rows) +QUERY: select *,character_length(����) from ���������; +���� |����� |��ע1a|length +----------+-------+------+------ +������ʾ��|��A01��| | 5 +����ͼ�� |��B01��| | 4 +���Գ���Ա|��Z01��| | 5 +(3 rows) + +QUERY: select *,octet_length(����) from ���������; +���� |����� |��ע1a|octet_length +----------+-------+------+------------ +������ʾ��|��A01��| | 10 +����ͼ�� |��B01��| | 8 +���Գ���Ա|��Z01��| | 10 +(3 rows) + +QUERY: select *,position('��' in ����) from ���������; +���� |����� |��ע1a|strpos +----------+-------+------+------ +������ʾ��|��A01��| | 3 +����ͼ�� |��B01��| | 0 +���Գ���Ա|��Z01��| | 0 +(3 rows) + +QUERY: select *,substring(���� from 3 for 4) from ���������; +���� |����� |��ע1a|substr +----------+-------+------+------ +������ʾ��|��A01��| |��ʾ�� +����ͼ�� |��B01��| |ͼ�� +���Գ���Ա|��Z01��| |����Ա +(3 rows) + diff --git a/src/test/regress/expected/euc_kr.out b/src/test/regress/expected/euc_kr.out index 56634d5f24d..e0bf3e0e452 100644 --- a/src/test/regress/expected/euc_kr.out +++ b/src/test/regress/expected/euc_kr.out @@ -53,3 +53,35 @@ QUERY: select * from ͪߩѦ��� where ��� ~* '��ǻ��[���]'; ��ǻ�ͱ��Ƚ� |��B10�� | (2 rows) +QUERY: select *,character_length(���) from ͪߩѦ���; +��� |���ڵ�|���1a��|length +----------------+--------+----------+------ +��ǻ�͵��÷���|ѦA01߾ | | 8 +��ǻ�ͱ��Ƚ� |��B10�� | | 7 +��ǻ�����α���|��Z01�� | | 8 +(3 rows) + +QUERY: select *,octet_length(���) from ͪߩѦ���; +��� |���ڵ�|���1a��|octet_length +----------------+--------+----------+------------ +��ǻ�͵��÷���|ѦA01߾ | | 16 +��ǻ�ͱ��Ƚ� |��B10�� | | 14 +��ǻ�����α���|��Z01�� | | 16 +(3 rows) + +QUERY: select *,position('��' in ���) from ͪߩѦ���; +��� |���ڵ�|���1a��|strpos +----------------+--------+----------+------ +��ǻ�͵��÷���|ѦA01߾ | | 4 +��ǻ�ͱ��Ƚ� |��B10�� | | 0 +��ǻ�����α���|��Z01�� | | 0 +(3 rows) + +QUERY: select *,substring(��� from 3 for 4) from ͪߩѦ���; +��� |���ڵ�|���1a��|substr +----------------+--------+----------+-------- +��ǻ�͵��÷���|ѦA01߾ | |�͵��� +��ǻ�ͱ��Ƚ� |��B10�� | |�ͱ��� +��ǻ�����α���|��Z01�� | |�����α� +(3 rows) + diff --git a/src/test/regress/expected/mule_internal.out b/src/test/regress/expected/mule_internal.out index c797072e3d9..da81d55a4ed 100644 --- a/src/test/regress/expected/mule_internal.out +++ b/src/test/regress/expected/mule_internal.out @@ -6,9 +6,6 @@ QUERY: create index ��ג�������ђ��index2 on ��ג�������ђ�� using hash (�ʬ���� QUERY: insert into ��ג�������ђ�� values('������Ԓ�咡������ǒ�������ג�쒥�','���A01���'); QUERY: insert into ��ג�������ђ�� values('������Ԓ�咡���������钥Ւ����Ò�����','�ʬB10���'); QUERY: insert into ��ג�������ђ�� values('������Ԓ�咡������ג�풥���钥ޒ��','���Z01���'); -QUERY: insert into ��ג�������ђ�� values('����ԑ�ԑʾ���','���A01���'); -QUERY: insert into ��ג�������ђ�� values('����ԑͼ���','���B01���'); -QUERY: insert into ��ג�������ђ�� values('����ԑ�̑��Ա','���Z01���'); QUERY: vacuum ��ג�������ђ��; QUERY: select * from ��ג�������ђ��; ��ђ�� |�ʬ������������|������1a������ @@ -16,10 +13,7 @@ QUERY: select * from ��ג�������ђ��; ������Ԓ�咡������ǒ�������ג�쒥� |���A01��� | ������Ԓ�咡���������钥Ւ����Ò�����|�ʬB10��� | ������Ԓ�咡������ג�풥���钥ޒ�� |���Z01��� | -����ԑ�ԑʾ��� |���A01��� | -����ԑͼ��� |���B01��� | -����ԑ�̑��Ա |���Z01��� | -(6 rows) +(3 rows) QUERY: select * from ��ג�������ђ�� where �ʬ������������ = '���Z01���'; ��ђ�� |�ʬ������������|������1a������ @@ -27,33 +21,23 @@ QUERY: select * from ��ג�������ђ�� where �ʬ������������ = '���Z01���'; ������Ԓ�咡������ג�풥���钥ޒ��|���Z01��� | (1 row) -QUERY: select * from ��ג�������ђ�� where �ʬ������������ ~ 'Z01'; +QUERY: select * from ��ג�������ђ�� where �ʬ������������ ~* '���z01���'; ��ђ�� |�ʬ������������|������1a������ ------------------------------------+---------------+-------------- ������Ԓ�咡������ג�풥���钥ޒ��|���Z01��� | -����ԑ�̑��Ա |���Z01��� | -(2 rows) - -QUERY: select * from ��ג�������ђ�� where �ʬ������������ ~* 'z01'; -��ђ�� |�ʬ������������|������1a������ -------------------------------------+---------------+-------------- -������Ԓ�咡������ג�풥���钥ޒ��|���Z01��� | -����ԑ�̑��Ա |���Z01��� | -(2 rows) +(1 row) QUERY: select * from ��ג�������ђ�� where �ʬ������������ like '_Z01_'; ��ђ�� |�ʬ������������|������1a������ ------------------------------------+---------------+-------------- ������Ԓ�咡������ג�풥���钥ޒ��|���Z01��� | -����ԑ�̑��Ա |���Z01��� | -(2 rows) +(1 row) QUERY: select * from ��ג�������ђ�� where �ʬ������������ like '_Z%'; ��ђ�� |�ʬ������������|������1a������ ------------------------------------+---------------+-------------- ������Ԓ�咡������ג�풥���钥ޒ��|���Z01��� | -����ԑ�̑��Ա |���Z01��� | -(2 rows) +(1 row) QUERY: select * from ��ג�������ђ�� where ��ђ�� ~ '������Ԓ�咡����[��ǒ��]'; ��ђ�� |�ʬ������������|������1a������ @@ -69,17 +53,281 @@ QUERY: select * from ��ג�������ђ�� where ��ђ�� ~* '������Ԓ�咡����[��ǒ��] ������Ԓ�咡���������钥Ւ����Ò�����|�ʬB10��� | (2 rows) -QUERY: select * from ��ג�������ђ�� where ��ђ�� ~ '�����[��ԑͼ]'; -��ђ�� |�ʬ������������|������1a������ ----------------+---------------+-------------- -����ԑ�ԑʾ���|���A01��� | -����ԑͼ��� |���B01��� | +QUERY: select *,character_length(��ђ��) from ��ג�������ђ��; +��ђ�� |�ʬ������������|������1a������|length +---------------------------------------+---------------+--------------+------ +������Ԓ�咡������ǒ�������ג�쒥� |���A01��� | | 12 +������Ԓ�咡���������钥Ւ����Ò�����|�ʬB10��� | | 13 +������Ԓ�咡������ג�풥���钥ޒ�� |���Z01��� | | 12 +(3 rows) + +QUERY: select *,octet_length(��ђ��) from ��ג�������ђ��; +��ђ�� |�ʬ������������|������1a������|octet_length +---------------------------------------+---------------+--------------+------------ +������Ԓ�咡������ǒ�������ג�쒥� |���A01��� | | 36 +������Ԓ�咡���������钥Ւ����Ò�����|�ʬB10��� | | 39 +������Ԓ�咡������ג�풥���钥ޒ�� |���Z01��� | | 36 +(3 rows) + +QUERY: select *,position('���' in ��ђ��) from ��ג�������ђ��; +��ђ�� |�ʬ������������|������1a������|strpos +---------------------------------------+---------------+--------------+------ +������Ԓ�咡������ǒ�������ג�쒥� |���A01��� | | 7 +������Ԓ�咡���������钥Ւ����Ò�����|�ʬB10��� | | 0 +������Ԓ�咡������ג�풥���钥ޒ�� |���Z01��� | | 0 +(3 rows) + +QUERY: select *,substring(��ђ�� from 10 for 4) from ��ג�������ђ��; +��ђ�� |�ʬ������������|������1a������|substr +---------------------------------------+---------------+--------------+------------ +������Ԓ�咡������ǒ�������ג�쒥� |���A01��� | |��ג�쒥� +������Ԓ�咡���������钥Ւ����Ò�����|�ʬB10��� | |�����Ò����� +������Ԓ�咡������ג�풥���钥ޒ�� |���Z01��� | |��钥ޒ�� +(3 rows) + +QUERY: drop table ��Ƒ�㑻�������; +ERROR: Relation ��Ƒ�㑻������� Does Not Exist! +QUERY: create table ��Ƒ�㑻�������(������ text, ��֑����� varchar, ����ע1A char(16)); +QUERY: create index ��Ƒ�㑻�������index1 on ��Ƒ�㑻������� using btree(������); +QUERY: create index ��Ƒ�㑻�������index2 on ��Ƒ�㑻������� using btree(��֑�����); +QUERY: insert into ��Ƒ�㑻������� values('����ԑ�ԑʾ���','���A01���'); +QUERY: insert into ��Ƒ�㑻������� values('����ԑͼ���','���B01���'); +QUERY: insert into ��Ƒ�㑻������� values('����ԑ�̑��Ա','���Z01���'); +QUERY: vacuum ��Ƒ�㑻�������; +QUERY: select * from ��Ƒ�㑻�������; +������ |��֑�����|����ע1a +---------------+---------+-------- +����ԑ�ԑʾ���|���A01���| +����ԑͼ��� |���B01���| +����ԑ�̑��Ա|���Z01���| +(3 rows) + +QUERY: select * from ��Ƒ�㑻������� where ��֑����� = '���Z01���'; +������ |��֑�����|����ע1a +---------------+---------+-------- +����ԑ�̑��Ա|���Z01���| +(1 row) + +QUERY: select * from ��Ƒ�㑻������� where ��֑����� ~* '���z01���'; +������ |��֑�����|����ע1a +---------------+---------+-------- +����ԑ�̑��Ա|���Z01���| +(1 row) + +QUERY: select * from ��Ƒ�㑻������� where ��֑����� like '_Z01_'; +������ |��֑�����|����ע1a +---------------+---------+-------- +����ԑ�̑��Ա|���Z01���| +(1 row) + +QUERY: select * from ��Ƒ�㑻������� where ��֑����� like '_Z%'; +������ |��֑�����|����ע1a +---------------+---------+-------- +����ԑ�̑��Ա|���Z01���| +(1 row) + +QUERY: select * from ��Ƒ�㑻������� where ������ ~ '�����[��ԑͼ]'; +������ |��֑�����|����ע1a +---------------+---------+-------- +����ԑ�ԑʾ���|���A01���| +����ԑͼ��� |���B01���| +(2 rows) + +QUERY: select * from ��Ƒ�㑻������� where ������ ~* '�����[��ԑͼ]'; +������ |��֑�����|����ע1a +---------------+---------+-------- +����ԑ�ԑʾ���|���A01���| +����ԑͼ��� |���B01���| +(2 rows) + +QUERY: select *,character_length(������) from ��Ƒ�㑻�������; +������ |��֑�����|����ע1a|length +---------------+---------+--------+------ +����ԑ�ԑʾ���|���A01���| | 5 +����ԑͼ��� |���B01���| | 4 +����ԑ�̑��Ա|���Z01���| | 5 +(3 rows) + +QUERY: select *,octet_length(������) from ��Ƒ�㑻�������; +������ |��֑�����|����ע1a|octet_length +---------------+---------+--------+------------ +����ԑ�ԑʾ���|���A01���| | 15 +����ԑͼ��� |���B01���| | 12 +����ԑ�̑��Ա|���Z01���| | 15 +(3 rows) + +QUERY: select *,position('���' in ������) from ��Ƒ�㑻�������; +������ |��֑�����|����ע1a|strpos +---------------+---------+--------+------ +����ԑ�ԑʾ���|���A01���| | 3 +����ԑͼ��� |���B01���| | 0 +����ԑ�̑��Ա|���Z01���| | 0 +(3 rows) + +QUERY: select *,substring(������ from 3 for 4) from ��Ƒ�㑻�������; +������ |��֑�����|����ע1a|substr +---------------+---------+--------+--------- +����ԑ�ԑʾ���|���A01���| |��ԑʾ��� +����ԑͼ��� |���B01���| |�ͼ��� +����ԑ�̑��Ա|���Z01���| |��̑��Ա +(3 rows) + +QUERY: drop table �ͪ�ߩ�Ѧ��듾�; +ERROR: Relation �ͪ�ߩ�Ѧ��듾� Does Not Exist! +QUERY: create table �ͪ�ߩ�Ѧ��듾� (��듾� text, ����ړ�� varchar, ����1A�� char(16)); +QUERY: create index �ͪ�ߩ�Ѧ��듾�index1 on �ͪ�ߩ�Ѧ��듾� using btree (��듾�); +QUERY: create index �ͪ�ߩ�Ѧ��듾�index2 on �ͪ�ߩ�Ѧ��듾� using hash (����ړ��); +QUERY: insert into �ͪ�ߩ�Ѧ��듾� values('��ēǻ��͓���Ó�����', '�ѦA01�߾'); +QUERY: insert into �ͪ�ߩ�Ѧ��듾� values('��ēǻ��͓�ד����ȓ��', '���B10���'); +QUERY: insert into �ͪ�ߩ�Ѧ��듾� values('��ēǻ��͓����Γ�ד�����', '���Z01���'); +QUERY: vacuum �ͪ�ߩ�Ѧ��듾�; +QUERY: select * from �ͪ�ߩ�Ѧ��듾�; +��듾� |����ړ��|����1a�� +------------------------+------------+-------------- +��ēǻ��͓���Ó�����|�ѦA01�߾ | +��ēǻ��͓�ד����ȓ�� |���B10��� | +��ēǻ��͓����Γ�ד�����|���Z01��� | +(3 rows) + +QUERY: select * from �ͪ�ߩ�Ѧ��듾� where ����ړ�� = '���Z01���'; +��듾� |����ړ��|����1a�� +------------------------+------------+-------------- +��ēǻ��͓����Γ�ד�����|���Z01��� | +(1 row) + +QUERY: select * from �ͪ�ߩ�Ѧ��듾� where ����ړ�� ~* '���z01���'; +��듾� |����ړ��|����1a�� +------------------------+------------+-------------- +��ēǻ��͓����Γ�ד�����|���Z01��� | +(1 row) + +QUERY: select * from �ͪ�ߩ�Ѧ��듾� where ����ړ�� like '_Z01_'; +��듾� |����ړ��|����1a�� +------------------------+------------+-------------- +��ēǻ��͓����Γ�ד�����|���Z01��� | +(1 row) + +QUERY: select * from �ͪ�ߩ�Ѧ��듾� where ����ړ�� like '_Z%'; +��듾� |����ړ��|����1a�� +------------------------+------------+-------------- +��ēǻ��͓����Γ�ד�����|���Z01��� | +(1 row) + +QUERY: select * from �ͪ�ߩ�Ѧ��듾� where ��듾� ~ '��ēǻ���[����]'; +��듾� |����ړ��|����1a�� +------------------------+------------+-------------- +��ēǻ��͓���Ó�����|�ѦA01�߾ | +��ēǻ��͓�ד����ȓ�� |���B10��� | (2 rows) -QUERY: select * from ��ג�������ђ�� where ��ђ�� ~* '�����[��ԑͼ]'; -��ђ�� |�ʬ������������|������1a������ ----------------+---------------+-------------- -����ԑ�ԑʾ���|���A01��� | -����ԑͼ��� |���B01��� | +QUERY: select * from �ͪ�ߩ�Ѧ��듾� where ��듾� ~* '��ēǻ���[����]'; +��듾� |����ړ��|����1a�� +------------------------+------------+-------------- +��ēǻ��͓���Ó�����|�ѦA01�߾ | +��ēǻ��͓�ד����ȓ�� |���B10��� | (2 rows) +QUERY: select *,character_length(��듾�) from �ͪ�ߩ�Ѧ��듾�; +��듾� |����ړ��|����1a��|length +------------------------+------------+--------------+------ +��ēǻ��͓���Ó�����|�ѦA01�߾ | | 8 +��ēǻ��͓�ד����ȓ�� |���B10��� | | 7 +��ēǻ��͓����Γ�ד�����|���Z01��� | | 8 +(3 rows) + +QUERY: select *,octet_length(��듾�) from �ͪ�ߩ�Ѧ��듾�; +��듾� |����ړ��|����1a��|octet_length +------------------------+------------+--------------+------------ +��ēǻ��͓���Ó�����|�ѦA01�߾ | | 24 +��ēǻ��͓�ד����ȓ�� |���B10��� | | 21 +��ēǻ��͓����Γ�ד�����|���Z01��� | | 24 +(3 rows) + +QUERY: select *,position('���' in ��듾�) from �ͪ�ߩ�Ѧ��듾�; +��듾� |����ړ��|����1a��|strpos +------------------------+------------+--------------+------ +��ēǻ��͓���Ó�����|�ѦA01�߾ | | 4 +��ēǻ��͓�ד����ȓ�� |���B10��� | | 0 +��ēǻ��͓����Γ�ד�����|���Z01��� | | 0 +(3 rows) + +QUERY: select *,substring(��듾� from 3 for 4) from �ͪ�ߩ�Ѧ��듾�; +��듾� |����ړ��|����1a��|substr +------------------------+------------+--------------+------------ +��ēǻ��͓���Ó�����|�ѦA01�߾ | |��͓���� +��ēǻ��͓�ד����ȓ�� |���B10��� | |��͓�ד����� +��ēǻ��͓����Γ�ד�����|���Z01��� | |��͓����Γ�� +(3 rows) + +QUERY: drop table test; +ERROR: Relation test Does Not Exist! +QUERY: create table test (t text); +QUERY: insert into test values('ENGLISH'); +QUERY: insert into test values('FRAN��AIS'); +QUERY: insert into test values('ESPA��OL'); +QUERY: insert into test values('��SLENSKA'); +QUERY: insert into test values('ENGLISH FRAN��AIS ESPA��OL ��SLENSKA'); +QUERY: vacuum test; +QUERY: select * from test; +t +------------------------------------ +ENGLISH +FRAN��AIS +ESPA��OL +��SLENSKA +ENGLISH FRAN��AIS ESPA��OL ��SLENSKA +(5 rows) + +QUERY: select * from test where t = 'ESPA��OL'; +t +-------- +ESPA��OL +(1 row) + +QUERY: select * from test where t ~* 'espa��ol'; +t +------------------------------------ +ESPA��OL +ENGLISH FRAN��AIS ESPA��OL ��SLENSKA +(2 rows) + +QUERY: select *,character_length(t) from test; +t |length +------------------------------------+------ +ENGLISH | 7 +FRAN��AIS | 8 +ESPA��OL | 7 +��SLENSKA | 8 +ENGLISH FRAN��AIS ESPA��OL ��SLENSKA| 33 +(5 rows) + +QUERY: select *,octet_length(t) from test; +t |octet_length +------------------------------------+------------ +ENGLISH | 7 +FRAN��AIS | 9 +ESPA��OL | 8 +��SLENSKA | 9 +ENGLISH FRAN��AIS ESPA��OL ��SLENSKA| 36 +(5 rows) + +QUERY: select *,position('L' in t) from test; +t |strpos +------------------------------------+------ +ENGLISH | 4 +FRAN��AIS | 0 +ESPA��OL | 7 +��SLENSKA | 3 +ENGLISH FRAN��AIS ESPA��OL ��SLENSKA| 4 +(5 rows) + +QUERY: select *,substring(t from 3 for 4) from test; +t |substr +------------------------------------+------ +ENGLISH |GLIS +FRAN��AIS |AN��A +ESPA��OL |PA��O +��SLENSKA |LENS +ENGLISH FRAN��AIS ESPA��OL ��SLENSKA|GLIS +(5 rows) + diff --git a/src/test/regress/sql/euc_cn.sql b/src/test/regress/sql/euc_cn.sql index 461c0c864f8..7cd0b9b0e25 100644 --- a/src/test/regress/sql/euc_cn.sql +++ b/src/test/regress/sql/euc_cn.sql @@ -13,3 +13,7 @@ select * from ��������� where ����� like '_Z01_'; select * from ��������� where ����� like '_Z%'; select * from ��������� where ���� ~ '����[��ͼ]'; select * from ��������� where ���� ~* '����[��ͼ]'; +select *,character_length(����) from ���������; +select *,octet_length(����) from ���������; +select *,position('��' in ����) from ���������; +select *,substring(���� from 3 for 4) from ���������; diff --git a/src/test/regress/sql/euc_kr.sql b/src/test/regress/sql/euc_kr.sql index 034eca8bdb6..cf9e07fd1c6 100644 --- a/src/test/regress/sql/euc_kr.sql +++ b/src/test/regress/sql/euc_kr.sql @@ -13,3 +13,7 @@ select * from ͪߩѦ��� where ���ڵ� like '_Z01_'; select * from ͪߩѦ��� where ���ڵ� like '_Z%'; select * from ͪߩѦ��� where ��� ~ '��ǻ��[���]'; select * from ͪߩѦ��� where ��� ~* '��ǻ��[���]'; +select *,character_length(���) from ͪߩѦ���; +select *,octet_length(���) from ͪߩѦ���; +select *,position('��' in ���) from ͪߩѦ���; +select *,substring(��� from 3 for 4) from ͪߩѦ���; diff --git a/src/test/regress/sql/mule_internal.sql b/src/test/regress/sql/mule_internal.sql index 6d07906ff78..2e381f0f7ed 100644 --- a/src/test/regress/sql/mule_internal.sql +++ b/src/test/regress/sql/mule_internal.sql @@ -5,17 +5,68 @@ create index ��ג�������ђ��index2 on ��ג�������ђ�� using hash (�ʬ����������� insert into ��ג�������ђ�� values('������Ԓ�咡������ǒ�������ג�쒥�','���A01���'); insert into ��ג�������ђ�� values('������Ԓ�咡���������钥Ւ����Ò�����','�ʬB10���'); insert into ��ג�������ђ�� values('������Ԓ�咡������ג�풥���钥ޒ��','���Z01���'); -insert into ��ג�������ђ�� values('����ԑ�ԑʾ���','���A01���'); -insert into ��ג�������ђ�� values('����ԑͼ���','���B01���'); -insert into ��ג�������ђ�� values('����ԑ�̑��Ա','���Z01���'); vacuum ��ג�������ђ��; select * from ��ג�������ђ��; select * from ��ג�������ђ�� where �ʬ������������ = '���Z01���'; -select * from ��ג�������ђ�� where �ʬ������������ ~ 'Z01'; -select * from ��ג�������ђ�� where �ʬ������������ ~* 'z01'; +select * from ��ג�������ђ�� where �ʬ������������ ~* '���z01���'; select * from ��ג�������ђ�� where �ʬ������������ like '_Z01_'; select * from ��ג�������ђ�� where �ʬ������������ like '_Z%'; select * from ��ג�������ђ�� where ��ђ�� ~ '������Ԓ�咡����[��ǒ��]'; select * from ��ג�������ђ�� where ��ђ�� ~* '������Ԓ�咡����[��ǒ��]'; -select * from ��ג�������ђ�� where ��ђ�� ~ '�����[��ԑͼ]'; -select * from ��ג�������ђ�� where ��ђ�� ~* '�����[��ԑͼ]'; +select *,character_length(��ђ��) from ��ג�������ђ��; +select *,octet_length(��ђ��) from ��ג�������ђ��; +select *,position('���' in ��ђ��) from ��ג�������ђ��; +select *,substring(��ђ�� from 10 for 4) from ��ג�������ђ��; +drop table ��Ƒ�㑻�������; +create table ��Ƒ�㑻�������(������ text, ��֑����� varchar, ����ע1A char(16)); +create index ��Ƒ�㑻�������index1 on ��Ƒ�㑻������� using btree(������); +create index ��Ƒ�㑻�������index2 on ��Ƒ�㑻������� using btree(��֑�����); +insert into ��Ƒ�㑻������� values('����ԑ�ԑʾ���','���A01���'); +insert into ��Ƒ�㑻������� values('����ԑͼ���','���B01���'); +insert into ��Ƒ�㑻������� values('����ԑ�̑��Ա','���Z01���'); +vacuum ��Ƒ�㑻�������; +select * from ��Ƒ�㑻�������; +select * from ��Ƒ�㑻������� where ��֑����� = '���Z01���'; +select * from ��Ƒ�㑻������� where ��֑����� ~* '���z01���'; +select * from ��Ƒ�㑻������� where ��֑����� like '_Z01_'; +select * from ��Ƒ�㑻������� where ��֑����� like '_Z%'; +select * from ��Ƒ�㑻������� where ������ ~ '�����[��ԑͼ]'; +select * from ��Ƒ�㑻������� where ������ ~* '�����[��ԑͼ]'; +select *,character_length(������) from ��Ƒ�㑻�������; +select *,octet_length(������) from ��Ƒ�㑻�������; +select *,position('���' in ������) from ��Ƒ�㑻�������; +select *,substring(������ from 3 for 4) from ��Ƒ�㑻�������; +drop table �ͪ�ߩ�Ѧ��듾�; +create table �ͪ�ߩ�Ѧ��듾� (��듾� text, ����ړ�� varchar, ����1A�� char(16)); +create index �ͪ�ߩ�Ѧ��듾�index1 on �ͪ�ߩ�Ѧ��듾� using btree (��듾�); +create index �ͪ�ߩ�Ѧ��듾�index2 on �ͪ�ߩ�Ѧ��듾� using hash (����ړ��); +insert into �ͪ�ߩ�Ѧ��듾� values('��ēǻ��͓���Ó�����', '�ѦA01�߾'); +insert into �ͪ�ߩ�Ѧ��듾� values('��ēǻ��͓�ד����ȓ��', '���B10���'); +insert into �ͪ�ߩ�Ѧ��듾� values('��ēǻ��͓����Γ�ד�����', '���Z01���'); +vacuum �ͪ�ߩ�Ѧ��듾�; +select * from �ͪ�ߩ�Ѧ��듾�; +select * from �ͪ�ߩ�Ѧ��듾� where ����ړ�� = '���Z01���'; +select * from �ͪ�ߩ�Ѧ��듾� where ����ړ�� ~* '���z01���'; +select * from �ͪ�ߩ�Ѧ��듾� where ����ړ�� like '_Z01_'; +select * from �ͪ�ߩ�Ѧ��듾� where ����ړ�� like '_Z%'; +select * from �ͪ�ߩ�Ѧ��듾� where ��듾� ~ '��ēǻ���[����]'; +select * from �ͪ�ߩ�Ѧ��듾� where ��듾� ~* '��ēǻ���[����]'; +select *,character_length(��듾�) from �ͪ�ߩ�Ѧ��듾�; +select *,octet_length(��듾�) from �ͪ�ߩ�Ѧ��듾�; +select *,position('���' in ��듾�) from �ͪ�ߩ�Ѧ��듾�; +select *,substring(��듾� from 3 for 4) from �ͪ�ߩ�Ѧ��듾�; +drop table test; +create table test (t text); +insert into test values('ENGLISH'); +insert into test values('FRAN��AIS'); +insert into test values('ESPA��OL'); +insert into test values('��SLENSKA'); +insert into test values('ENGLISH FRAN��AIS ESPA��OL ��SLENSKA'); +vacuum test; +select * from test; +select * from test where t = 'ESPA��OL'; +select * from test where t ~* 'espa��ol'; +select *,character_length(t) from test; +select *,octet_length(t) from test; +select *,position('L' in t) from test; +select *,substring(t from 3 for 4) from test; |