From cb7cbc16fa4b5933fb5d63052568e3ed6859857b Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Tue, 16 Jun 1998 07:29:54 +0000 Subject: [PATCH] Hi, here are the patches to enhance existing MB handling. This time I have implemented a framework of encoding translation between the backend and the frontend. Also I have added a new variable setting command: SET CLIENT_ENCODING TO 'encoding'; Other features include: Latin1 support more 8 bit cleaness See doc/README.mb for more details. Note that the pacthes are against May 30 snapshot. Tatsuo Ishii --- doc/README.mb | 65 +++- doc/README.mb.jp | 101 ++++- src/Makefile.global.in | 4 +- src/backend/access/common/Makefile | 6 +- src/backend/access/common/printtup.c | 19 +- src/backend/commands/Makefile | 10 +- src/backend/commands/variable.c | 58 ++- src/backend/libpq/Makefile | 6 +- src/backend/libpq/pqcomm.c | 44 ++- src/backend/parser/scan.c | 30 +- src/backend/parser/scan.l | 8 +- src/backend/regex/engine.c | 3 + src/backend/regex/regcomp.c | 2 +- src/backend/regex/utils.c | 388 ++++++++------------ src/backend/tcop/Makefile | 6 +- src/backend/tcop/postgres.c | 21 +- src/bin/pg_dump/pg_dump.c | 5 +- src/bin/psql/Makefile.in | 6 +- src/bin/psql/psql.c | 52 ++- src/bin/psql/psqlHelp.h | 17 +- src/configure | 4 +- src/configure.in | 4 +- src/include/commands/variable.h | 14 +- src/include/libpq/libpq.h | 7 +- src/include/regex/pg_wchar.h | 37 +- src/include/regex/regex2.h | 2 + src/interfaces/libpq/Makefile.in | 10 +- src/interfaces/libpq/fe-connect.c | 11 +- src/interfaces/libpq/fe-exec.c | 7 +- src/interfaces/libpq/fe-print.c | 38 +- src/interfaces/libpq/libpq-fe.h | 6 +- src/test/regress/expected/euc_cn.out | 32 ++ src/test/regress/expected/euc_kr.out | 32 ++ src/test/regress/expected/mule_internal.out | 310 ++++++++++++++-- src/test/regress/sql/euc_cn.sql | 4 + src/test/regress/sql/euc_kr.sql | 4 + src/test/regress/sql/mule_internal.sql | 65 +++- 37 files changed, 1106 insertions(+), 332 deletions(-) diff --git a/doc/README.mb b/doc/README.mb index 80270c136a..775d05c48b 100644 --- a/doc/README.mb +++ b/doc/README.mb @@ -1,10 +1,10 @@ -postgresql 6.3 multi-byte (MB) support README April 21 1998 +postgresql 6.4 multi-byte (MB) support README Jun 5 1998 Tatsuo Ishii t-ishii@sra.co.jp http://www.sra.co.jp/people/t-ishii/PostgreSQL/ -Introduction +0. Introduction The MB support is intended for allowing PostgreSQL to handle multi-byte character sets such as EUC(Extended Unix Code), Unicode and @@ -18,7 +18,7 @@ have been fixed. I just confirmed that the regression test ran fine and a few French characters could be used with the patch. Please let me know if you find any problem while using 8-bit characters) -How to use +1. How to use create src/Makefile.custom with a line including: @@ -36,6 +36,7 @@ where encoding_system is one of: EUC_TW Taiwan EUC UNICODE Unicode(UTF-8) MULE_INTERNAL Mule internal + LATIN1 ISO 8859-1 English and some European laguages Example: @@ -49,7 +50,54 @@ Example: If MB is disabled, nothing is changed except better supporting for 8-bit single byte character sets. -References +2. PGCLIENTENCODING + +If an environment variable PGCLIENTENCODING is defined on the +frontend, automatic encoding translation is done by the backend. For +example, if the backend has been compiled with MB=EUC_JP and +PGCLIENTENCODING=SJIS(Shift JIS: yet another Japanese encoding +system), then any SJIS strings coming from the frontend would be +translated to EUC_JP before going into the parser. Outputs from the +backend would be translated to SJIS of course. + +Supported encodings for PGCLIENTENCODING are: + + EUC_JP Japanese EUC + SJIS Yet another Japanese encoding + EUC_CN Chinese EUC + EUC_KR Korean EUC + EUC_TW Taiwan EUC + MULE_INTERNAL Mule internal + LATIN1 ISO 8859-1 English and some European laguages + +Note that UNICODE is not supported(yet). Also note that the +translation is not always possible. Suppose you choose EUC_JP for the +backend, LATIN1 for the frotend, then some Japanese characters cannot +be translated into latin. In this case, a letter cannot be represented +in the Latin character set, would be transformed as: + + (HEXA DECIMAL) + +3. SET CLIENT_ENCODING TO command + +Actually setting the frontend side encoding information is done by a +new command: + + SET CLIENT_ENCODING TO 'encoding'; + +where encoding is one of the encodings those can be set to +PGCLIENTENCODING. To query the current the frontend encoding: + + SHOW CLIENT_ENCODING; + +To return to the default encoding: + + RESET CLIENT_ENCODING; + +This would reset the frontend encoding to same as the backend +encoding, thus no endoing translation would be performed. + +4. References These are good sources to start learning various kind of encoding systems. @@ -64,7 +112,14 @@ Unicode: http://www.unicode.org/ RFC 2044 UTF-8 is defined here. -History +5. History + +Jun 5, 1988 + * add support for the encoding translation between the backend + and the frontend + * new command SET CLIENT_ENCODING etc. added + * add support for LATIN1 character set + * enhance 8 bit cleaness April 21, 1998 some enhancements/fixes * character_length(), position(), substring() are now aware of diff --git a/doc/README.mb.jp b/doc/README.mb.jp index f4666c8434..3fde80f420 100644 --- a/doc/README.mb.jp +++ b/doc/README.mb.jp @@ -1,4 +1,4 @@ -postgresql 6.3.2 multi-byte (MB) support README 1998/4/21 $B:n@.(B +postgresql 6.3.2 multi-byte (MB) support README 1998/5/25 $B:n@.(B $B@P0fC#IW(B t-ishii@sra.co.jp @@ -9,8 +9,8 @@ postgresql 6.3.2 multi-byte (MB) support README 1998/4/21 $B:n@.(B PostgreSQL $B$K$*$1$k%^%k%A%P%$%H%5%]!<%H$O0J2<$N$h$&$JFCD'$r;}$C$F$$$^$9!#(B 1.$B%^%k%A%P%$%HJ8;z$H$7$F!"F|K\8l!"Cf9q8l$J$I$N3F9q$N(B EUC$B!"(BUnicode$B!"(B - mule internal code $B$,%3%s%Q%$%k;~$KA*Br2DG=!#%G!<%?%Y!<%9$K$O(B - $B$3$N%3!<%I$N$^$^3JG<$5$l$^$9!#(B + mule internal code, ISO-8859-1 $B$,%3%s%Q%$%k;~$KA*Br2DG=!#(B + $B%G!<%?%Y!<%9$K$O$3$N%3!<%I$N$^$^3JG<$5$l$^$9!#(B 2.$B%F!<%V%kL>$K%^%k%A%P%$%HJ8;z$,;HMQ2DG=(B($B$?$@$7!"(BOS $B$,%^%k%A%P%$%H(B $B$N%U%!%$%kL>$r5v$7$F$$$k$3$H$,I,MW(B) 3.$B%+%i%`L>$K%^%k%A%P%$%HJ8;z$,;HMQ2DG=(B @@ -19,6 +19,8 @@ postgresql 6.3.2 multi-byte (MB) support README 1998/4/21 $B:n@.(B 6.$B%^%k%A%P%$%HJ8;z$N(B LIKE $B8!:w$,;HMQ2DG=(B 7.character_length(), position(), substring() $B$G$N%^%k%A%P%$%H(B $B%5%]!<%H(B + 8.$B4D6-JQ?t(B PGCLIENTENCODING $B$K$h$j!"%/%i%$%"%s%HB&$NJ8;z%3!<%I(B + $B$,%P%C%/%(%s%IB&$H0[$k>l9g$K!"<+F0E*$K%3!<%IJQ49$r9T$J$$$^$9!#(B $B%$%s%9%H!<%k!'(B $B%G%U%)%k%H$G$O(B PostgreSQL $B$O%^%k%A%P%$%H$r%5%]!<%H$7$F$$$^$;$s!#(B @@ -46,6 +48,9 @@ postgresql 6.3.2 multi-byte (MB) support README 1998/4/21 $B:n@.(B $B$9$J$o$A(B 0xffff $B$^$G$G$9!#(B MULE_INTERNAL mule $B$NFbIt%3!<%I!#$?$@$7!"(BType N $B$NITDjD9J8;z$O(B $B%5%]!<%H$7$F$$$^$;$s!#(B + LATIN1 ISO8859 Latin 1$B!#%7%s%0%k%P%$%H$J$s$G$9$1$I!"(B + $B;n$7$H$$$&$3$H$G(B:-)$B$A$J$_$K!"(BLATIN2 etc. $B$O(B + $BL$%5%]!<%H!#(B $BA*Br$NL\0B$H$7$F$O!"1Q8l$HF|K\8l$7$+;H$o$J$$>l9g$O(B EUC_JP($BF1MM$K!"Cf(B $B9q8l$7$+;H$o$J$$>l9g$O(B EUC_CN... $B$J$I$H$J$j$^$9(B)$B!"$=$NB>$N8@8l$b;H$$$?(B @@ -64,13 +69,101 @@ postgresql 6.3.2 multi-byte (MB) support README 1998/4/21 $B:n@.(B http://www.sra.co.jp/people/t-ishii/PostgreSQL/ $B$G$b4JC1$J%$%s%9%H!<(B $B%kJ}K!$r>R2p$7$F$$$^$9!#(B +$B4D6-JQ?t(B PGCLIENTENCODING $B$K$D$$$F!'(B + + $B%G%U%)%k%H$G$O!"%3%s%Q%$%k;~$K;XDj$7$?%5!<%PB&$NJ8;z%3!<%I$H!"(Bpsql + $B$J$I$N%/%i%$%"%s%HB&$NJ8;z%3!<%I$,0lCW$7$F$$$k$b$N$H8+Jo$5$l$^$9!#%5!<(B + $B%PB&$H0[$kJ8;z%3!<%I$r;H$$$?$$>l9g$O!"4D6-JQ?t(B PGCLIENTENCODING $B$r@_(B + $BDj$7$^$9!#@_Dj2DG=$JJ8;z%3!<%I$O!">e5-$K2C$(!"(BSJIS ($B%7%U%H(BJIS) + $B$,;XDj$G$-$^$9!#(B + + $B$A$J$_$K!"(BSJIS $B$O(B JISX0201 $B$N(B 1$B%P%$%H%+%J!"$$$o$f$k!VH>3Q%+%?(B + $B%+%J!W$b%5%]!<%H$7$F$$$^$9(B($B7h$7$F!VH>3Q%+%?%+%J!W$N;HMQ$r$*4+(B + $B$a$7$F$$$k$o$1$8$c$J$$$G$9$,(B)$B!#(B + + $B$?$H$($P!"(BMB=EUC_JP $B$G(B PostgeSQL $B$,%$%s%9%H!<%k$5$l$F$$$k>l9g!"(B + postmaster $B$rN)$A>e$2$k$H$-$K4D6-JQ?t(B PGCLIENTENCODING $B$K(B SJIS $B$r@_(B + $BDj$9$k$H!"%/%i%$%"%s%H$O(B SJIS $B%3!<%I$G(B PostgreSQL $B$K%"%/%;%9$G$-$k$h(B + $B$&$K$J$j$^$9!#$?$@$7!"%G!<%?%Y!<%9$K3JG<$5$l$k%G!<%?<+BN$O$"$/$^$G(B + MB $B$G;XDj$7$?(B EUC_JP $B$N$^$^$G$9!#(B + + $B%/%i%$%"%s%HB&$G%;%C%7%g%sKh$KJ8;z%3!<%I$rJQ$($k$3$H$b$G$-$^$9!#(B + $B%;%C%7%g%s3+;O;~$K4D6-JQ?t(B PGCLIENTENCODING $B$,%;%C%H$5$l$F$$$k$H!"$=(B + $B$l$,M%@h$5$l$F%/%i%$%"%s%HB&$NJ8;z%3!<%I$K:NMQ$5$l$^$9!#$3$N5!G=$rMx(B + $BMQ$9$k$H!"$"$k%f!<%6$O(B EUC_JP $B$G!"JL$J%f!<%6$O(B SJIS $B$GF1$8%G!<%?%Y!<(B + $B%9$K%"%/%;%9$9$k$H$$$&$h$&$J$3$H$,$G$-$k$h$&$K$J$j$^$9!#(B + + MB=MULE_INTERNAL $B$G(B PostgreSQL $B$r%$%s%9%H!<%k$7$F$*$/$H!"IaCJ$O(B + EUC_JP $B$G%/%i%$%"%s%H$rMxMQ$7!"J#?t$NJ8;z=89g$r:.:_$5$;$k$H$-$@$1%/(B + $B%i%$%"%s%H$r(B MULE_INTERNAL $B$K@_Dj$9$k$J$I$N;H$$J,$1$,$G$-$FJXMx$G$9!#(B + $B$?$@!"0lHL$K(B EUC_JP $B$KHf$Y!"(BMULE_INTERNAL $B$K$h$k%G!<%?I=8=$O$d$d%9%Z!<(B + $B%9$r6t$&$N$G!"$=$N$X$s$O9MN8$7$F$*$/I,MW$,$"$j$^$9!#$?$H$($P!"(B2$B%P%$(B + $B%H$GI=8=$G$-$k4A;z$O(B MULE_INTERNAL $B$G$O(B 3$B%P%$%H$rMW$7$^$9!#(B + + $BCm0U$7$F$*$/I,MW$,$"$k$N$O!"%5!<%PB&$NJ8;z%3!<%I$H%/%i%$%"%s%HB&$NJ8(B + $B;z%3!<%I$,$$$D$bAj8_JQ49$G$-$k$H$O8B$i$J$$$3$H$G$9!#6KC<$JOC!"%5!<%P(B + $BB&$,(B EUC_JP $B$J$N$K!"%/%i%$%"%s%HB&$,(B EUC_KR $B$@$C$?$i$I$&$J$k$G$7$g$&!#(B + $B$3$N>l9g(B PostgreSQL $B$OJQ49$G$-$J$$%3!<%I$r(B 16$B?JI=8=$KJQ49$7$F$7$^$$(B + $B$^$9!#$?$H$($P!"(B"(bdae)" $B$N$h$&$K!#$J$*!"$3$N(B 16$B?JI=8=$O(B mule + internalcode $B$N%3!<%I$G$"$k$3$H$KCm0U$7$F2<$5$$!#$3$l$O!"D>@\%/%i%$(B + $B%"%s%H(B <--> $B%5!<%P$NJ8;z%3!<%I$rJQ49$9$k$N$G$O$J$/!"0lEYFbItI=8=$G$"(B + $B$k(B mule internal code $B$r7PM3$7$F$$$k$?$a$G$9!#(B + + $B%/%i%$%"%s%HB&$NJ8;z%3!<%I$N@_Dj$O!"(B"set client_encoding" $B%3%^%s%I$G(B + $B$b2DG=$G$9!#$?$H$($P!"(B + + set client_encoding to 'sjis'; + + $B$GL@<(E*$K%/%i%$%"%s%HB&$NJ8;z%3!<%I$r(B SJIS $B$K@_Dj$G$-$^$9!#$9I,MW$,$"$j$^$9!#(B(psql $B$K$O8=:_$3$N(B + $B5!G=$,$J$$$?$a!";veF0E*$K%/%i%$%"%s%HB&$NJ8;z%3!<%I$r@_Dj$9$k$3$H(B + $B$,$G$-$^$;$s!#(B) + + $B8=:_@_Dj$5$l$F$$$k%/%i%$%"%s%HB&$NJ8;z%3!<%I$O(B + + show client_encoding; + + $B$G;2>H$G$-$^$9!#$^$?!"(B + + reset client_encoding; + + $B$O!"%G%U%)%k%H$N%/%i%$%"%s%HJ8;z%3!<%I@_Dj$KI|5"$5$;$^$9!#(Bpostmaster + $B$rN)$A>e$2$k$H$-$K4D6-JQ?t(B PGCLIENTENCODING $B$,@_Dj$5$l$F$$$k$H$=$NJ8(B + $B;z%3!<%I$K!"$=$&$G$J$1$l$P%3%s%Q%$%k;~$K;XDj$7$?%5!<%PB&$NJ8;z%3!<%I(B + $B$HF1$8$K$J$j$^$9!#(B + +$B@)8B;v9`!'(B + + SJIS $B$r;HMQ$9$k>l9g!"(BPostgreSQL $B$N%/%i%$%"%s%H$G$^$H$b$KBP1~$7$F$$$k(B + $B$N$O(B psql $B$@$1$G$9!#(BTcl/Tk$B!"$=$N$[$+$OBP1~$7$F$^$;$s!#(B + $B$7I,MW(B diff --git a/src/Makefile.global.in b/src/Makefile.global.in index 4472d875e1..ebd5c4ba93 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 73b1b3ea82..76974644fa 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 8b27415cf6..ccebe24382 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 #include +#ifdef MB +#include +#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 7e4fe415c3..fc2b7199ab 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 9e138b82a9..51f9d871bd 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 a608044fac..5176f2996a 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 a3ff7bcffd..9b699a22e4 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 dd0304b97f..83ae575e89 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 6fe3af8369..bf18df010c 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 6381d5990c..b95b6491eb 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 01b95427c6..4eb71eb525 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 67b9f2a737..0308140118 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 + /* - * 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 45cddf43aa..e8e88d8439 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 9670f32640..2c457bf05e 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 613b2a5b88..d80a2676dc 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 - dave@bensoft.com - 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 071ab34c50..d34abdef46 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 9f699ad8d7..1ed9e4561f 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 0ecfa7b6c9..91786543e4 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 "}, {"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 on [,...] 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 set =,...= [from ] [where ];"}, diff --git a/src/configure b/src/configure index bcbee80cb9..691a42c511 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 987ee1e253..07c7abb578 100644 --- a/src/configure.in +++ b/src/configure.in @@ -194,12 +194,12 @@ AC_ARG_WITH(mb, [ --with-mb= 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 920536e50f..ebf6390116 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 61c8c9910d..9a347989c4 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 b135df82f1..bfbd8ba37b 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 01cdadff45..4590862486 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 460debb82f..5e59f56663 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 20c02950b1..ba386d6392 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 8b4a55e290..506edc8b1a 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 140658b942..ae820561c0 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 #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 7b93276276..1bfd0f5a3e 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 d927b28d20..f35356b5e8 100644 --- a/src/test/regress/expected/euc_cn.out +++ b/src/test/regress/expected/euc_cn.out @@ -53,3 +53,35 @@ QUERY: select * from µçÄÔͼÐÎ |·Ö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 56634d5f24..e0bf3e0e45 100644 --- a/src/test/regress/expected/euc_kr.out +++ b/src/test/regress/expected/euc_kr.out @@ -53,3 +53,35 @@ QUERY: select * from ͪߩѦ ÄÄÇ»Åͱ׷¡ÇȽº |ÝÂ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 c797072e3d..da81d55a4e 100644 --- a/src/test/regress/expected/mule_internal.out +++ b/src/test/regress/expected/mule_internal.out @@ -6,9 +6,6 @@ QUERY: create index 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 ’¥³’¥ó’¥Ô’¥å’¡¼’¥¿’¥×’¥í’¥°’¥é’¥Þ’¡¼|’¿Í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 ’¥³’¥ó’¥Ô’¥å’¡¼’¥¿’¥°’¥é’¥Õ’¥£’¥Ã’¥¯’¥¹|’ʬ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 461c0c864f..7cd0b9b0e2 100644 --- a/src/test/regress/sql/euc_cn.sql +++ b/src/test/regress/sql/euc_cn.sql @@ -13,3 +13,7 @@ select * from 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 034eca8bdb..cf9e07fd1c 100644 --- a/src/test/regress/sql/euc_kr.sql +++ b/src/test/regress/sql/euc_kr.sql @@ -13,3 +13,7 @@ select * from ͪߩѦ 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 6d07906ff7..2e381f0f7e 100644 --- a/src/test/regress/sql/mule_internal.sql +++ b/src/test/regress/sql/mule_internal.sql @@ -5,17 +5,68 @@ create index 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; -- 2.40.0