aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>1998-06-16 06:42:02 +0000
committerBruce Momjian <bruce@momjian.us>1998-06-16 06:42:02 +0000
commit8d8bcda2531bbae665c2cbe57dade4271b0eb087 (patch)
tree1cb88a3b8fc135e89d6a070dff2244656696c90a /src
parent67a636918a85fb29333d6b3c8d576ffe62f7df9a (diff)
downloadpostgresql-8d8bcda2531bbae665c2cbe57dade4271b0eb087.tar.gz
postgresql-8d8bcda2531bbae665c2cbe57dade4271b0eb087.zip
Hello!
Attached to the mail is locale-patch.tar.gz. In the archive there are: file README.locale short description directory src/test/locale test suite; currently only koi8-r tests, but the suite can be easily extended file locale.patch the very patch; to apply: patch < locale.patch; should be applied to postgres-6.3.2 (at least I created it with 6.3.2 without any additional patches) Files touched by the patch: src/include/utils/builtins.h src/backend/utils/adt/char.c src/backend/utils/adt/varchar.c src/backend/utils/adt/varlena.c Oleg
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/varchar.c22
-rw-r--r--src/backend/utils/adt/varlena.c127
-rw-r--r--src/include/utils/builtins.h4
-rw-r--r--src/test/locale/Makefile33
-rw-r--r--src/test/locale/README27
-rw-r--r--src/test/locale/koi8-r/Makefile12
-rw-r--r--src/test/locale/koi8-r/expected/koi8-ctype.out257
-rw-r--r--src/test/locale/koi8-r/expected/test-koi8-char.sql.out55
-rw-r--r--src/test/locale/koi8-r/expected/test-koi8-select.sql.out9
-rw-r--r--src/test/locale/koi8-r/expected/test-koi8-sort.out9
-rw-r--r--src/test/locale/koi8-r/expected/test-koi8-text.sql.out55
-rw-r--r--src/test/locale/koi8-r/expected/test-koi8-varchar.sql.out55
-rwxr-xr-xsrc/test/locale/koi8-r/runall52
-rw-r--r--src/test/locale/koi8-r/test-koi8-select.sql.in1
-rw-r--r--src/test/locale/koi8-r/test-koi8-sort.in9
-rw-r--r--src/test/locale/koi8-r/test-koi8.sql.in53
-rwxr-xr-xsrc/test/locale/sort-test.pl12
-rwxr-xr-xsrc/test/locale/sort-test.py18
-rw-r--r--src/test/locale/test-ctype.c65
-rw-r--r--src/test/locale/test-pgsql-locale.c13
20 files changed, 798 insertions, 90 deletions
diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c
index 863e21e2cce..be7130896ef 100644
--- a/src/backend/utils/adt/varchar.c
+++ b/src/backend/utils/adt/varchar.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.33 1998/06/15 19:29:38 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.34 1998/06/16 06:41:50 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -475,7 +475,7 @@ bpcharlt(char *arg1, char *arg2)
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
- cmp = strncmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));
+ cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if (cmp == 0)
return (len1 < len2);
else
@@ -494,7 +494,7 @@ bpcharle(char *arg1, char *arg2)
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
- cmp = strncmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));
+ cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if (0 == cmp)
return (bool) (len1 <= len2 ? 1 : 0);
else
@@ -513,7 +513,7 @@ bpchargt(char *arg1, char *arg2)
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
- cmp = strncmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));
+ cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if (cmp == 0)
return (len1 > len2);
else
@@ -532,7 +532,7 @@ bpcharge(char *arg1, char *arg2)
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
- cmp = strncmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));
+ cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if (0 == cmp)
return (bool) (len1 >= len2 ? 1 : 0);
else
@@ -549,7 +549,7 @@ bpcharcmp(char *arg1, char *arg2)
len1 = bcTruelen(arg1);
len2 = bcTruelen(arg2);
- cmp = strncmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));
+ cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if ((0 == cmp) && (len1 != len2))
return (int32) (len1 < len2 ? -1 : 1);
else
@@ -641,7 +641,7 @@ varcharlt(char *arg1, char *arg2)
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
- cmp = strncmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));
+ cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if (cmp == 0)
return (len1 < len2);
else
@@ -660,7 +660,7 @@ varcharle(char *arg1, char *arg2)
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
- cmp = strncmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));
+ cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if (0 == cmp)
return (bool) (len1 <= len2 ? 1 : 0);
else
@@ -679,7 +679,7 @@ varchargt(char *arg1, char *arg2)
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
- cmp = strncmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));
+ cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if (cmp == 0)
return (len1 > len2);
else
@@ -698,7 +698,7 @@ varcharge(char *arg1, char *arg2)
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
- cmp = strncmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2));
+ cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if (0 == cmp)
return (bool) (len1 >= len2 ? 1 : 0);
else
@@ -715,7 +715,7 @@ varcharcmp(char *arg1, char *arg2)
len1 = VARSIZE(arg1) - VARHDRSZ;
len2 = VARSIZE(arg2) - VARHDRSZ;
- cmp = (strncmp(VARDATA(arg1), VARDATA(arg2), Min(len1, len2)));
+ cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
if ((0 == cmp) && (len1 != len2))
return (int32) (len1 < len2 ? -1 : 1);
else
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index 46f74c41442..596863dd876 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.36 1998/06/15 19:29:38 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.37 1998/06/16 06:41:51 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -468,116 +468,87 @@ textne(text *arg1, text *arg2)
return ((bool) !texteq(arg1, arg2));
}
-/* text_lt()
- * Comparison function for text strings.
+/* varstr_cmp()
+ * Comparison function for text strings with given lengths.
* Includes locale support, but must copy strings to temporary memory
* to allow null-termination for inputs to strcoll().
- * XXX HACK code for textlen() indicates that there can be embedded nulls
- * but it appears that most routines (incl. this one) assume not! - tgl 97/04/07
+ * Returns -1, 0 or 1
*/
-bool
-text_lt(text *arg1, text *arg2)
+int
+varstr_cmp(unsigned char *arg1, int len1, unsigned char *arg2, int len2)
{
- bool result;
-
-#ifdef USE_LOCALE
- int cval;
-
-#endif
- int len;
- unsigned char *a1p,
- *a2p;
-
- if (arg1 == NULL || arg2 == NULL)
- return ((bool) FALSE);
-
- len = (((VARSIZE(arg1) <= VARSIZE(arg2)) ? VARSIZE(arg1) : VARSIZE(arg2)) - VARHDRSZ);
+ int result;
+ unsigned char *a1p, *a2p;
#ifdef USE_LOCALE
- a1p = (unsigned char *) palloc(len + 1);
- a2p = (unsigned char *) palloc(len + 1);
+ a1p = (unsigned char *) palloc(len1 + 1);
+ a2p = (unsigned char *) palloc(len2 + 1);
- memcpy(a1p, VARDATA(arg1), len);
- *(a1p + len) = '\0';
- memcpy(a2p, VARDATA(arg2), len);
- *(a2p + len) = '\0';
+ memcpy(a1p, arg1, len1);
+ *(a1p + len1) = '\0';
+ memcpy(a2p, arg2, len2);
+ *(a2p + len2) = '\0';
- cval = strcoll(a1p, a2p);
- result = ((cval < 0) || ((cval == 0) && (VARSIZE(arg1) < VARSIZE(arg2))));
+ result = strcoll(a1p, a2p);
pfree(a1p);
pfree(a2p);
+
#else
- a1p = (unsigned char *) VARDATA(arg1);
- a2p = (unsigned char *) VARDATA(arg2);
- while (len != 0 && *a1p == *a2p)
- {
- a1p++;
- a2p++;
- len--;
- };
+ a1p = arg1;
+ a2p = arg2;
- result = (len ? (*a1p < *a2p) : (VARSIZE(arg1) < VARSIZE(arg2)));
+ result = strncmp(a1p, a2p, Min(len1, len2));
+ if ((result == 0) && (len1 != len2))
+ result = (len1 < len2) ? -1 : 1;
#endif
return (result);
-} /* text_lt() */
+} /* varstr_cmp() */
-/* text_le()
+/* text_cmp()
* Comparison function for text strings.
* Includes locale support, but must copy strings to temporary memory
* to allow null-termination for inputs to strcoll().
* XXX HACK code for textlen() indicates that there can be embedded nulls
* but it appears that most routines (incl. this one) assume not! - tgl 97/04/07
+ * Returns -1, 0 or 1
*/
-bool
-text_le(text *arg1, text *arg2)
+int
+text_cmp(text *arg1, text *arg2)
{
- bool result;
-
-#ifdef USE_LOCALE
- int cval;
-
-#endif
- int len;
- unsigned char *a1p,
- *a2p;
+ unsigned char *a1p, *a2p;
+ int len1, len2;
if (arg1 == NULL || arg2 == NULL)
- return ((bool) 0);
-
- len = (((VARSIZE(arg1) <= VARSIZE(arg2)) ? VARSIZE(arg1) : VARSIZE(arg2)) - VARHDRSZ);
-
-#ifdef USE_LOCALE
- a1p = (unsigned char *) palloc(len + 1);
- a2p = (unsigned char *) palloc(len + 1);
-
- memcpy(a1p, VARDATA(arg1), len);
- *(a1p + len) = '\0';
- memcpy(a2p, VARDATA(arg2), len);
- *(a2p + len) = '\0';
-
- cval = strcoll(a1p, a2p);
- result = ((cval < 0) || ((cval == 0) && (VARSIZE(arg1) <= VARSIZE(arg2))));
+ return ((bool) FALSE);
- pfree(a1p);
- pfree(a2p);
-#else
a1p = (unsigned char *) VARDATA(arg1);
a2p = (unsigned char *) VARDATA(arg2);
- while (len != 0 && *a1p == *a2p)
- {
- a1p++;
- a2p++;
- len--;
- };
+ len1 = VARSIZE(arg1) - VARHDRSZ;
+ len2 = VARSIZE(arg2) - VARHDRSZ;
- result = (len ? (*a1p <= *a2p) : (VARSIZE(arg1) <= VARSIZE(arg2)));
-#endif
+ return varstr_cmp(a1p, len1, a2p, len2);
+} /* text_cmp() */
- return (result);
+/* text_lt()
+ * Comparison function for text strings.
+ */
+bool
+text_lt(text *arg1, text *arg2)
+{
+ return (bool)(text_cmp(arg1, arg2) < 0);
+} /* text_lt() */
+
+/* text_le()
+ * Comparison function for text strings.
+ */
+bool
+text_le(text *arg1, text *arg2)
+{
+ return (bool)(text_cmp(arg1, arg2) <= 0);
} /* text_le() */
bool
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index b334996f19f..323a42ea70b 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: builtins.h,v 1.43 1998/05/29 13:37:29 thomas Exp $
+ * $Id: builtins.h,v 1.44 1998/06/16 06:41:51 momjian Exp $
*
* NOTES
* This should normally only be included by fmgr.h.
@@ -428,6 +428,8 @@ extern char *textout(text *vlena);
extern text *textcat(text *arg1, text *arg2);
extern bool texteq(text *arg1, text *arg2);
extern bool textne(text *arg1, text *arg2);
+extern int varstr_cmp(unsigned char *arg1, int len1, unsigned char *arg2, int len2);
+extern int text_cmp(text *arg1, text *arg2);
extern bool text_lt(text *arg1, text *arg2);
extern bool text_le(text *arg1, text *arg2);
extern bool text_gt(text *arg1, text *arg2);
diff --git a/src/test/locale/Makefile b/src/test/locale/Makefile
new file mode 100644
index 00000000000..36c951c5d09
--- /dev/null
+++ b/src/test/locale/Makefile
@@ -0,0 +1,33 @@
+#
+# Makefile for example programs
+#
+
+SRCDIR= ../..
+include ../../Makefile.global
+
+#
+# And where libpq goes, so goes the authentication stuff...
+#
+ifdef KRBVERS
+LDFLAGS+= $(KRBLIBS)
+CFLAGS+= $(KRBFLAGS)
+endif
+
+PROGS = test-pgsql-locale test-ctype
+DIRS = koi8-r
+
+all: $(PROGS)
+
+$(PROGS): % : %.c
+ $(CC) $(CFLAGS) -o $@ $@.c $(LDFLAGS)
+
+clean:
+ rm -f $(PROGS) *.out
+ for d in $(DIRS); do \
+ cd $$d; \
+ $(MAKE) clean; \
+ cd ..; \
+ done
+
+test-%: all
+ @cd `echo $@ | sed s/^test-//` && $(MAKE) test
diff --git a/src/test/locale/README b/src/test/locale/README
new file mode 100644
index 00000000000..9cdf64ac23b
--- /dev/null
+++ b/src/test/locale/README
@@ -0,0 +1,27 @@
+
+1998 May 25
+
+ This directory contains a set of tests for locales. I provided one C
+program test-ctype.c to test CTYPE support in libc and installed
+localedata. Then there are test-sort.pl and test-sort.py that tests
+collating. (Also there is test-sort.py but it is commented out in scripts;
+uncomment it if you have Python interpreter installed).
+ To run a test for some locale (koi8, e.g) run
+make all test-$locale
+ (for example)
+make all test-koi8
+
+ Currently, only tests for koi8 locale (russian cyrillic for UN*X)
+provided in koi8 directory. Script `runall' calls test-pgsql-locale to test
+whether locale support had been compiled into PotgreSQL, test-ctype to test
+libc and localedata, test-sort.pl (uncomment test-sort.py, if you have
+Python interpreter installed) and does tests on PostgreSQL with
+test-koi8*.sql.in.
+
+ To add locale tests one need to create directory $locale and create
+Makefile (and other files) similar to koi8-r/*. Actually, the simplest (I
+think) method is just copy koi8-r directory and edit/replace files.
+
+Oleg.
+----
+ Oleg Broytmann http://members.tripod.com/~phd2/ phd2@earthling.net
diff --git a/src/test/locale/koi8-r/Makefile b/src/test/locale/koi8-r/Makefile
new file mode 100644
index 00000000000..281014521ef
--- /dev/null
+++ b/src/test/locale/koi8-r/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for example programs
+#
+
+all:
+ -@echo "make: Nothing to be done for \`all'."
+
+test:
+ @./runall
+
+clean:
+ rm -f *.out
diff --git a/src/test/locale/koi8-r/expected/koi8-ctype.out b/src/test/locale/koi8-r/expected/koi8-ctype.out
new file mode 100644
index 00000000000..9b1d9d41a18
--- /dev/null
+++ b/src/test/locale/koi8-r/expected/koi8-ctype.out
@@ -0,0 +1,257 @@
+char# char alnum alpha cntrl digit lower graph print punct space upper xdigit lo up
+chr#0 +
+chr#1 +
+chr#2 +
+chr#3 +
+chr#4 +
+chr#5 +
+chr#6 +
+chr#7 +
+chr#8 +
+chr#9 + +
+chr#10 + +
+chr#11 + +
+chr#12 + +
+chr#13 + +
+chr#14 +
+chr#15 +
+chr#16 +
+chr#17 +
+chr#18 +
+chr#19 +
+chr#20 +
+chr#21 +
+chr#22 +
+chr#23 +
+chr#24 +
+chr#25 +
+chr#26 +
+chr#27 +
+chr#28 +
+chr#29 +
+chr#30 +
+chr#31 +
+chr#32 + +
+chr#33 ! + + + ! !
+chr#34 " + + + " "
+chr#35 # + + + # #
+chr#36 $ + + + $ $
+chr#37 % + + + % %
+chr#38 & + + + & &
+chr#39 ' + + + ' '
+chr#40 ( + + + ( (
+chr#41 ) + + + ) )
+chr#42 * + + + * *
+chr#43 + + + + + +
+chr#44 , + + + , ,
+chr#45 - + + + - -
+chr#46 . + + + . .
+chr#47 / + + + / /
+chr#48 0 + + + + + 0 0
+chr#49 1 + + + + + 1 1
+chr#50 2 + + + + + 2 2
+chr#51 3 + + + + + 3 3
+chr#52 4 + + + + + 4 4
+chr#53 5 + + + + + 5 5
+chr#54 6 + + + + + 6 6
+chr#55 7 + + + + + 7 7
+chr#56 8 + + + + + 8 8
+chr#57 9 + + + + + 9 9
+chr#58 : + + + : :
+chr#59 ; + + + ; ;
+chr#60 < + + + < <
+chr#61 = + + + = =
+chr#62 > + + + > >
+chr#63 ? + + + ? ?
+chr#64 @ + + + @ @
+chr#65 A + + + + + + a A
+chr#66 B + + + + + + b B
+chr#67 C + + + + + + c C
+chr#68 D + + + + + + d D
+chr#69 E + + + + + + e E
+chr#70 F + + + + + + f F
+chr#71 G + + + + + g G
+chr#72 H + + + + + h H
+chr#73 I + + + + + i I
+chr#74 J + + + + + j J
+chr#75 K + + + + + k K
+chr#76 L + + + + + l L
+chr#77 M + + + + + m M
+chr#78 N + + + + + n N
+chr#79 O + + + + + o O
+chr#80 P + + + + + p P
+chr#81 Q + + + + + q Q
+chr#82 R + + + + + r R
+chr#83 S + + + + + s S
+chr#84 T + + + + + t T
+chr#85 U + + + + + u U
+chr#86 V + + + + + v V
+chr#87 W + + + + + w W
+chr#88 X + + + + + x X
+chr#89 Y + + + + + y Y
+chr#90 Z + + + + + z Z
+chr#91 [ + + + [ [
+chr#92 \ + + + \ \
+chr#93 ] + + + ] ]
+chr#94 ^ + + + ^ ^
+chr#95 _ + + + _ _
+chr#96 ` + + + ` `
+chr#97 a + + + + + + a A
+chr#98 b + + + + + + b B
+chr#99 c + + + + + + c C
+chr#100 d + + + + + + d D
+chr#101 e + + + + + + e E
+chr#102 f + + + + + + f F
+chr#103 g + + + + + g G
+chr#104 h + + + + + h H
+chr#105 i + + + + + i I
+chr#106 j + + + + + j J
+chr#107 k + + + + + k K
+chr#108 l + + + + + l L
+chr#109 m + + + + + m M
+chr#110 n + + + + + n N
+chr#111 o + + + + + o O
+chr#112 p + + + + + p P
+chr#113 q + + + + + q Q
+chr#114 r + + + + + r R
+chr#115 s + + + + + s S
+chr#116 t + + + + + t T
+chr#117 u + + + + + u U
+chr#118 v + + + + + v V
+chr#119 w + + + + + w W
+chr#120 x + + + + + x X
+chr#121 y + + + + + y Y
+chr#122 z + + + + + z Z
+chr#123 { + + + { {
+chr#124 | + + + | |
+chr#125 } + + + } }
+chr#126 ~ + + + ~ ~
+chr#127 +
+chr#128 ─ + + + ─ ─
+chr#129 │ + + + │ │
+chr#130 ┌ + + + ┌ ┌
+chr#131 ┐ + + + ┐ ┐
+chr#132 └ + + + └ └
+chr#133 ┘ + + + ┘ ┘
+chr#134 ├ + + + ├ ├
+chr#135 ┤ + + + ┤ ┤
+chr#136 ┬ + + + ┬ ┬
+chr#137 ┴ + + + ┴ ┴
+chr#138 ┼ + + + ┼ ┼
+chr#139 ▀ + + + ▀ ▀
+chr#140 ▄ + + + ▄ ▄
+chr#141 █ + + + █ █
+chr#142 ▌ + + + ▌ ▌
+chr#143 ▐ + + + ▐ ▐
+chr#144 ░ + + + ░ ░
+chr#145 ▒ + + + ▒ ▒
+chr#146 ▓ + + + ▓ ▓
+chr#147 ⌠ + + + ⌠ ⌠
+chr#148 ■ + + + ■ ■
+chr#149 ∙ + + + ∙ ∙
+chr#150 √ + + + √ √
+chr#151 ≈ + + + ≈ ≈
+chr#152 ≤ + + + ≤ ≤
+chr#153 ≥ + + + ≥ ≥
+chr#154 +
+chr#155 ⌡ + + + ⌡ ⌡
+chr#156 ° + + + ° °
+chr#157 ² + + + ² ²
+chr#158 · + + + · ·
+chr#159 ÷ + + + ÷ ÷
+chr#160 ═ + + + ═ ═
+chr#161 ║ + + + ║ ║
+chr#162 ╒ + + + ╒ ╒
+chr#163 ё + + + + + ё Ё
+chr#164 ╓ + + + ╓ ╓
+chr#165 ╔ + + + ╔ ╔
+chr#166 ╕ + + + ╕ ╕
+chr#167 ╖ + + + ╖ ╖
+chr#168 ╗ + + + ╗ ╗
+chr#169 ╘ + + + ╘ ╘
+chr#170 ╙ + + + ╙ ╙
+chr#171 ╚ + + + ╚ ╚
+chr#172 ╛ + + + ╛ ╛
+chr#173 ╜ + + + ╜ ╜
+chr#174 ╝ + + + ╝ ╝
+chr#175 ╞ + + + ╞ ╞
+chr#176 ╟ + + + ╟ ╟
+chr#177 ╠ + + + ╠ ╠
+chr#178 ╡ + + + ╡ ╡
+chr#179 Ё + + + + + ё Ё
+chr#180 ╢ + + + ╢ ╢
+chr#181 ╣ + + + ╣ ╣
+chr#182 ╤ + + + ╤ ╤
+chr#183 ╥ + + + ╥ ╥
+chr#184 ╦ + + + ╦ ╦
+chr#185 ╧ + + + ╧ ╧
+chr#186 ╨ + + + ╨ ╨
+chr#187 ╩ + + + ╩ ╩
+chr#188 ╪ + + + ╪ ╪
+chr#189 ╫ + + + ╫ ╫
+chr#190 ╬ + + + ╬ ╬
+chr#191 © + + + © ©
+chr#192 ю + + + + + ю Ю
+chr#193 а + + + + + а А
+chr#194 б + + + + + б Б
+chr#195 ц + + + + + ц Ц
+chr#196 д + + + + + д Д
+chr#197 е + + + + + е Е
+chr#198 ф + + + + + ф Ф
+chr#199 г + + + + + г Г
+chr#200 х + + + + + х Х
+chr#201 и + + + + + и И
+chr#202 й + + + + + й Й
+chr#203 к + + + + + к К
+chr#204 л + + + + + л Л
+chr#205 м + + + + + м М
+chr#206 н + + + + + н Н
+chr#207 о + + + + + о О
+chr#208 п + + + + + п П
+chr#209 я + + + + + я Я
+chr#210 р + + + + + р Р
+chr#211 с + + + + + с С
+chr#212 т + + + + + т Т
+chr#213 у + + + + + у У
+chr#214 ж + + + + + ж Ж
+chr#215 в + + + + + в В
+chr#216 ь + + + + + ь Ь
+chr#217 ы + + + + + ы Ы
+chr#218 з + + + + + з З
+chr#219 ш + + + + + ш Ш
+chr#220 э + + + + + э Э
+chr#221 щ + + + + + щ Щ
+chr#222 ч + + + + + ч Ч
+chr#223 ъ + + + + + ъ
+chr#224 Ю + + + + + ю Ю
+chr#225 А + + + + + а А
+chr#226 Б + + + + + б Б
+chr#227 Ц + + + + + ц Ц
+chr#228 Д + + + + + д Д
+chr#229 Е + + + + + е Е
+chr#230 Ф + + + + + ф Ф
+chr#231 Г + + + + + г Г
+chr#232 Х + + + + + х Х
+chr#233 И + + + + + и И
+chr#234 Й + + + + + й Й
+chr#235 К + + + + + к К
+chr#236 Л + + + + + л Л
+chr#237 М + + + + + м М
+chr#238 Н + + + + + н Н
+chr#239 О + + + + + о О
+chr#240 П + + + + + п П
+chr#241 Я + + + + + я Я
+chr#242 Р + + + + + р Р
+chr#243 С + + + + + с С
+chr#244 Т + + + + + т Т
+chr#245 У + + + + + у У
+chr#246 Ж + + + + + ж Ж
+chr#247 В + + + + + в В
+chr#248 Ь + + + + + ь Ь
+chr#249 Ы + + + + + ы Ы
+chr#250 З + + + + + з З
+chr#251 Ш + + + + + ш Ш
+chr#252 Э + + + + + э Э
+chr#253 Щ + + + + + щ Щ
+chr#254 Ч + + + + + ч Ч
+chr#255 + + + + + ъ
diff --git a/src/test/locale/koi8-r/expected/test-koi8-char.sql.out b/src/test/locale/koi8-r/expected/test-koi8-char.sql.out
new file mode 100644
index 00000000000..c574ff06776
--- /dev/null
+++ b/src/test/locale/koi8-r/expected/test-koi8-char.sql.out
@@ -0,0 +1,55 @@
+abbrev|name_en |name_ru
+------+--------------------+------------------------------------------------------------
+ID |Idaho |Айдахо
+IA |Iowa |Айова
+AL |Alabama |Алабама
+AK |Alaska |Аляска
+AZ |Arizona |Аризона
+AR |Arkansas |Арканзас
+WY |Wyoming |Вайоминг
+WA |Washington |Вашингтон
+VT |Vermont |Вермонт
+VA |Virginia |Вирджиния
+WI |Wisconsin |Висконсин
+DE |Delaware |Делавэр
+GA |Georgia |Джорджия
+WV |West Virginia |Западная Вирджиния
+IL |Illinois |Иллинойс
+IN |Indiana |Индиана
+CA |California |Калифорния
+KA |Kansas |Канзас
+KY |Kentucky |Кентукки
+CO |Colorado |Колорадо
+CT |Connecticut |Коннектикут
+LA |Louisiana |Луизиана
+MA |Massachusetts |Массачусетс
+MN |Minnesota |Миннесота
+MS |Mississippi |Миссисипи
+MO |Missouri |Миссури
+MI |Michigan |Мичиган
+MT |Montana |Монтана
+ME |Maine |Мэн
+MD |Maryland |Мэриленд
+NE |Nebraska |Небраска
+NV |Nevada |Невада
+NH |New Hampshire |Нью-Гэмпшир
+NJ |New Jersey |Нью-Джерси
+NY |New York |Нью-Йорк
+NM |New Mexico |Нью-Мексико
+OH |Ohio |Огайо
+OK |Oklahoma |Оклахома
+DC |Washington DC |округ Колумбия (создан специально под столицу)
+OR |Oregon |Орегон
+PA |Pennsylvania |Пенсильвания
+RI |Rhode Island |Род-Айленд
+ND |North Dakota |Северная Дакота
+NC |North Carolina |Северная Каролина
+TN |Tennessee |Теннесси
+TX |Texas |Техас
+FL |Florida |Флорида
+SD |South Dakota |Южная Дакота
+SC |South Carolina |Южная Каролина
+UT |Utah |Юта
+(50 rows)
+
+EOF
diff --git a/src/test/locale/koi8-r/expected/test-koi8-select.sql.out b/src/test/locale/koi8-r/expected/test-koi8-select.sql.out
new file mode 100644
index 00000000000..1e9f97de3c6
--- /dev/null
+++ b/src/test/locale/koi8-r/expected/test-koi8-select.sql.out
@@ -0,0 +1,9 @@
+abbrev|name_en |name_ru
+------+--------------------+----------------------------------------------
+OH |Ohio |Огайо
+OK |Oklahoma |Оклахома
+DC |Washington DC |округ Колумбия (создан специально под столицу)
+OR |Oregon |Орегон
+(4 rows)
+
+EOF
diff --git a/src/test/locale/koi8-r/expected/test-koi8-sort.out b/src/test/locale/koi8-r/expected/test-koi8-sort.out
new file mode 100644
index 00000000000..0089f41b6a4
--- /dev/null
+++ b/src/test/locale/koi8-r/expected/test-koi8-sort.out
@@ -0,0 +1,9 @@
+Bording
+hoarding
+Vesta
+vesta
+альянс
+Африка
+Север
+Цапля
+Юг
diff --git a/src/test/locale/koi8-r/expected/test-koi8-text.sql.out b/src/test/locale/koi8-r/expected/test-koi8-text.sql.out
new file mode 100644
index 00000000000..210a8e2b683
--- /dev/null
+++ b/src/test/locale/koi8-r/expected/test-koi8-text.sql.out
@@ -0,0 +1,55 @@
+abbrev|name_en |name_ru
+------+--------------------+----------------------------------------------
+ID |Idaho |Айдахо
+IA |Iowa |Айова
+AL |Alabama |Алабама
+AK |Alaska |Аляска
+AZ |Arizona |Аризона
+AR |Arkansas |Арканзас
+WY |Wyoming |Вайоминг
+WA |Washington |Вашингтон
+VT |Vermont |Вермонт
+VA |Virginia |Вирджиния
+WI |Wisconsin |Висконсин
+DE |Delaware |Делавэр
+GA |Georgia |Джорджия
+WV |West Virginia |Западная Вирджиния
+IL |Illinois |Иллинойс
+IN |Indiana |Индиана
+CA |California |Калифорния
+KA |Kansas |Канзас
+KY |Kentucky |Кентукки
+CO |Colorado |Колорадо
+CT |Connecticut |Коннектикут
+LA |Louisiana |Луизиана
+MA |Massachusetts |Массачусетс
+MN |Minnesota |Миннесота
+MS |Mississippi |Миссисипи
+MO |Missouri |Миссури
+MI |Michigan |Мичиган
+MT |Montana |Монтана
+ME |Maine |Мэн
+MD |Maryland |Мэриленд
+NE |Nebraska |Небраска
+NV |Nevada |Невада
+NH |New Hampshire |Нью-Гэмпшир
+NJ |New Jersey |Нью-Джерси
+NY |New York |Нью-Йорк
+NM |New Mexico |Нью-Мексико
+OH |Ohio |Огайо
+OK |Oklahoma |Оклахома
+DC |Washington DC |округ Колумбия (создан специально под столицу)
+OR |Oregon |Орегон
+PA |Pennsylvania |Пенсильвания
+RI |Rhode Island |Род-Айленд
+ND |North Dakota |Северная Дакота
+NC |North Carolina |Северная Каролина
+TN |Tennessee |Теннесси
+TX |Texas |Техас
+FL |Florida |Флорида
+SD |South Dakota |Южная Дакота
+SC |South Carolina |Южная Каролина
+UT |Utah |Юта
+(50 rows)
+
+EOF
diff --git a/src/test/locale/koi8-r/expected/test-koi8-varchar.sql.out b/src/test/locale/koi8-r/expected/test-koi8-varchar.sql.out
new file mode 100644
index 00000000000..210a8e2b683
--- /dev/null
+++ b/src/test/locale/koi8-r/expected/test-koi8-varchar.sql.out
@@ -0,0 +1,55 @@
+abbrev|name_en |name_ru
+------+--------------------+----------------------------------------------
+ID |Idaho |Айдахо
+IA |Iowa |Айова
+AL |Alabama |Алабама
+AK |Alaska |Аляска
+AZ |Arizona |Аризона
+AR |Arkansas |Арканзас
+WY |Wyoming |Вайоминг
+WA |Washington |Вашингтон
+VT |Vermont |Вермонт
+VA |Virginia |Вирджиния
+WI |Wisconsin |Висконсин
+DE |Delaware |Делавэр
+GA |Georgia |Джорджия
+WV |West Virginia |Западная Вирджиния
+IL |Illinois |Иллинойс
+IN |Indiana |Индиана
+CA |California |Калифорния
+KA |Kansas |Канзас
+KY |Kentucky |Кентукки
+CO |Colorado |Колорадо
+CT |Connecticut |Коннектикут
+LA |Louisiana |Луизиана
+MA |Massachusetts |Массачусетс
+MN |Minnesota |Миннесота
+MS |Mississippi |Миссисипи
+MO |Missouri |Миссури
+MI |Michigan |Мичиган
+MT |Montana |Монтана
+ME |Maine |Мэн
+MD |Maryland |Мэриленд
+NE |Nebraska |Небраска
+NV |Nevada |Невада
+NH |New Hampshire |Нью-Гэмпшир
+NJ |New Jersey |Нью-Джерси
+NY |New York |Нью-Йорк
+NM |New Mexico |Нью-Мексико
+OH |Ohio |Огайо
+OK |Oklahoma |Оклахома
+DC |Washington DC |округ Колумбия (создан специально под столицу)
+OR |Oregon |Орегон
+PA |Pennsylvania |Пенсильвания
+RI |Rhode Island |Род-Айленд
+ND |North Dakota |Северная Дакота
+NC |North Carolina |Северная Каролина
+TN |Tennessee |Теннесси
+TX |Texas |Техас
+FL |Florida |Флорида
+SD |South Dakota |Южная Дакота
+SC |South Carolina |Южная Каролина
+UT |Utah |Юта
+(50 rows)
+
+EOF
diff --git a/src/test/locale/koi8-r/runall b/src/test/locale/koi8-r/runall
new file mode 100755
index 00000000000..cf6e3b77c30
--- /dev/null
+++ b/src/test/locale/koi8-r/runall
@@ -0,0 +1,52 @@
+#! /bin/sh
+
+PATH=..:$PATH
+
+echo "Testing PostgreSQL compilation..."
+if ! test-pgsql-locale; then
+ exit 1
+fi
+
+LC_CTYPE=ru_RU.KOI8-R
+LC_COLLATE=$LC_CTYPE
+export LC_CTYPE LC_COLLATE
+
+echo "Testing LC_CTYPE..."
+if ! test-ctype > koi8-ctype.out; then
+ exit 1
+fi
+diff expected/koi8-ctype.out koi8-ctype.out
+
+echo "Testing LC_COLLATE..."
+perl ../sort-test.pl test-koi8-sort.in > test-koi8-sort.out
+diff expected/test-koi8-sort.out test-koi8-sort.out
+
+### If you have Python - uncomment the following two lines
+#python ../sort-test.py test-koi8-sort.in > test-koi8-sort.out
+#diff expected/test-koi8-sort.out test-koi8-sort.out
+
+
+abort() {
+ [ "$1" ] && echo "$*"
+ exit 1
+}
+
+for f in char varchar text; do
+ if echo $f | grep -q char; then
+ ftype="$f(60)"
+ else
+ ftype="$f"
+ fi
+ echo "Testing PgSQL: sort on $ftype type..."
+
+ destroydb testlocale >/dev/null 2>&1
+ createdb testlocale || abort "createdb failed"
+ psql -d testlocale -c "CREATE TABLE usastates (abbrev char2, name_en char(20), name_ru $ftype);" >/dev/null 2>&1 || abort "createtable failed"
+ psql testlocale < test-koi8.sql.in > test-koi8-$f.sql.out 2>/dev/null || abort "test query failed"
+ diff expected/test-koi8-$f.sql.out test-koi8-$f.sql.out
+done
+echo "Testing PgSQL: select on regexp..."
+psql testlocale < test-koi8-select.sql.in > test-koi8-select.sql.out 2>/dev/null || abort "select query failed"
+diff expected/test-koi8-select.sql.out test-koi8-select.sql.out
+destroydb testlocale || abort "destroydb failed"
+echo "Finished."
diff --git a/src/test/locale/koi8-r/test-koi8-select.sql.in b/src/test/locale/koi8-r/test-koi8-select.sql.in
new file mode 100644
index 00000000000..5cda505c3d2
--- /dev/null
+++ b/src/test/locale/koi8-r/test-koi8-select.sql.in
@@ -0,0 +1 @@
+SELECT * FROM usastates WHERE name_ru ~* '^о.*' ORDER BY name_ru;
diff --git a/src/test/locale/koi8-r/test-koi8-sort.in b/src/test/locale/koi8-r/test-koi8-sort.in
new file mode 100644
index 00000000000..3394e59d619
--- /dev/null
+++ b/src/test/locale/koi8-r/test-koi8-sort.in
@@ -0,0 +1,9 @@
+Vesta
+vesta
+Юг
+альянс
+Африка
+Север
+Цапля
+Bording
+hoarding
diff --git a/src/test/locale/koi8-r/test-koi8.sql.in b/src/test/locale/koi8-r/test-koi8.sql.in
new file mode 100644
index 00000000000..784d440d2f3
--- /dev/null
+++ b/src/test/locale/koi8-r/test-koi8.sql.in
@@ -0,0 +1,53 @@
+COPY usastates FROM stdin USING DELIMITERS '|';
+AK|Alaska |Аляска
+WA|Washington |Вашингтон
+OR|Oregon |Орегон
+CA|California |Калифорния
+NV|Nevada |Невада
+ID|Idaho |Айдахо
+UT|Utah |Юта
+AZ|Arizona |Аризона
+MT|Montana |Монтана
+WY|Wyoming |Вайоминг
+CO|Colorado |Колорадо
+NM|New Mexico |Нью-Мексико
+ND|North Dakota |Северная Дакота
+SD|South Dakota |Южная Дакота
+NE|Nebraska |Небраска
+KA|Kansas |Канзас
+OK|Oklahoma |Оклахома
+TX|Texas |Техас
+MN|Minnesota |Миннесота
+IA|Iowa |Айова
+MO|Missouri |Миссури
+AR|Arkansas |Арканзас
+LA|Louisiana |Луизиана
+WI|Wisconsin |Висконсин
+IL|Illinois |Иллинойс
+IN|Indiana |Индиана
+MS|Mississippi |Миссисипи
+AL|Alabama |Алабама
+MI|Michigan |Мичиган
+OH|Ohio |Огайо
+KY|Kentucky |Кентукки
+TN|Tennessee |Теннесси
+GA|Georgia |Джорджия
+FL|Florida |Флорида
+PA|Pennsylvania |Пенсильвания
+WV|West Virginia |Западная Вирджиния
+VA|Virginia |Вирджиния
+NC|North Carolina|Северная Каролина
+SC|South Carolina|Южная Каролина
+NY|New York |Нью-Йорк
+NJ|New Jersey |Нью-Джерси
+DE|Delaware |Делавэр
+MD|Maryland |Мэриленд
+DC|Washington DC |округ Колумбия (создан специально под столицу)
+VT|Vermont |Вермонт
+MA|Massachusetts |Массачусетс
+CT|Connecticut |Коннектикут
+ME|Maine |Мэн
+NH|New Hampshire |Нью-Гэмпшир
+RI|Rhode Island |Род-Айленд
+\.
+SELECT * FROM usastates ORDER BY name_ru;
diff --git a/src/test/locale/sort-test.pl b/src/test/locale/sort-test.pl
new file mode 100755
index 00000000000..7d9b8ef0340
--- /dev/null
+++ b/src/test/locale/sort-test.pl
@@ -0,0 +1,12 @@
+#!/usr/local/bin/perl -w
+use locale;
+
+open(INFILE, "<$ARGV[0]");
+chop(my(@words) = <INFILE>);
+close(INFILE);
+
+$"="\n";
+my(@result) = sort @words;
+
+print "@result\n";
+
diff --git a/src/test/locale/sort-test.py b/src/test/locale/sort-test.py
new file mode 100755
index 00000000000..112dd2d5f75
--- /dev/null
+++ b/src/test/locale/sort-test.py
@@ -0,0 +1,18 @@
+#! /usr/local/bin/python
+
+import sys, string, locale
+locale.setlocale(locale.LC_ALL, "")
+
+if len(sys.argv) <> 2:
+ sys.stderr.write("Usage: sort.py filename\n")
+ sys.exit(1)
+
+infile = open(sys.argv[1], 'r')
+list = infile.readlines()
+infile.close()
+
+for i in range(0, len(list)):
+ list[i] = list[i][:-1] # chop!
+
+list.sort(locale.strcoll)
+print string.join(list, '\n')
diff --git a/src/test/locale/test-ctype.c b/src/test/locale/test-ctype.c
new file mode 100644
index 00000000000..c16f1710928
--- /dev/null
+++ b/src/test/locale/test-ctype.c
@@ -0,0 +1,65 @@
+
+/*
+
+ test-ctype.c
+
+Written by Oleg BroytMann, phd2@earthling.net
+ with help from Oleg Bartunov, oleg@sai.msu.su
+Copyright (C) 1998 PhiloSoft Design
+
+This is copyrighted but free software. You can use it, modify and distribute
+in original or modified form providing that the author's names and the above
+copyright notice will remain.
+
+Disclaimer, legal notice and absence of warranty.
+ This software provided "as is" without any kind of warranty. In no event
+the author shall be liable for any damage, etc.
+
+*/
+
+#include <stdio.h>
+#include <locale.h>
+#include <ctype.h>
+
+char * flag(int b);
+void describe_char(int c);
+
+#undef LONG_FLAG
+
+char * flag(int b)
+{
+#ifdef LONG_FLAG
+ return b ? "yes" : "no";
+#else
+ return b ? "+" : " ";
+#endif
+}
+
+void describe_char(int c)
+{
+ char cp = c, up = toupper(c), lo = tolower(c);
+ if (!isprint(cp)) cp = ' ';
+ if (!isprint(up)) up = ' ';
+ if (!isprint(lo)) lo = ' ';
+
+ printf("chr#%-4d%2c%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s%6s%4c%4c\n", c, cp, flag(isalnum(c)), flag(isalpha(c)), flag(iscntrl(c)), flag(isdigit(c)), flag(islower(c)), flag(isgraph(c)), flag(isprint(c)), flag(ispunct(c)), flag(isspace(c)), flag(isupper(c)), flag(isxdigit(c)), lo, up);
+}
+
+int main() {
+ short c;
+ char * cur_locale;
+
+ cur_locale = setlocale(LC_ALL, "");
+ if (cur_locale) {
+ fprintf(stderr, "Successfulle set locale to %s\n", cur_locale);
+ } else {
+ fprintf(stderr, "Cannot setup locale. Either your libc does not provide\nlocale support, or your locale data is corrupt, or you have not set\nLANG or LC_CTYPE environment variable to proper value. Program aborted.\n");
+ return 1;
+ }
+
+ printf("char# char alnum alpha cntrl digit lower graph print punct space upper xdigit lo up\n");
+ for (c = 0; c <= 255; c++)
+ describe_char(c);
+
+ return 0;
+}
diff --git a/src/test/locale/test-pgsql-locale.c b/src/test/locale/test-pgsql-locale.c
new file mode 100644
index 00000000000..acae1a2aeec
--- /dev/null
+++ b/src/test/locale/test-pgsql-locale.c
@@ -0,0 +1,13 @@
+
+#include <stdio.h>
+#include "postgres.h"
+
+int main() {
+ #ifdef USE_LOCALE
+ printf("PostgreSQL compiled with locale support\n");
+ return 0;
+ #else
+ printf("PostgreSQL compiled without locale support\n");
+ return 1;
+ #endif
+}