diff --git a/mysql-test/r/func_regexp.result b/mysql-test/r/func_regexp.result
index 8d22994ef2b050904388ef1208a17ad393b91e43..35742136ee6c4cd736f4b360198c27e7073e4edf 100644
--- a/mysql-test/r/func_regexp.result
+++ b/mysql-test/r/func_regexp.result
@@ -52,3 +52,27 @@ select * from t1 where xxx REGEXP '^this is some text: to test - out\\.reg exp [
 xxx
 this is some text: to test - out.reg exp (22/45)
 drop table t1;
+select _latin1 0xFF regexp _latin1 '[[:lower:]]' COLLATE latin1_bin;
+_latin1 0xFF regexp _latin1 '[[:lower:]]' COLLATE latin1_bin
+1
+select _koi8r  0xFF regexp _koi8r  '[[:lower:]]' COLLATE koi8r_bin;
+_koi8r  0xFF regexp _koi8r  '[[:lower:]]' COLLATE koi8r_bin
+0
+select _latin1 0xFF regexp _latin1 '[[:upper:]]' COLLATE latin1_bin;
+_latin1 0xFF regexp _latin1 '[[:upper:]]' COLLATE latin1_bin
+0
+select _koi8r  0xFF regexp _koi8r  '[[:upper:]]' COLLATE koi8r_bin;
+_koi8r  0xFF regexp _koi8r  '[[:upper:]]' COLLATE koi8r_bin
+1
+select _latin1 0xF7 regexp _latin1 '[[:alpha:]]';
+_latin1 0xF7 regexp _latin1 '[[:alpha:]]'
+0
+select _koi8r  0xF7 regexp _koi8r  '[[:alpha:]]';
+_koi8r  0xF7 regexp _koi8r  '[[:alpha:]]'
+1
+select _latin1'a' regexp _latin1'A' collate latin1_general_ci;
+_latin1'a' regexp _latin1'A' collate latin1_general_ci
+1
+select _latin1'a' regexp _latin1'A' collate latin1_bin;
+_latin1'a' regexp _latin1'A' collate latin1_bin
+0
diff --git a/mysql-test/t/func_regexp.test b/mysql-test/t/func_regexp.test
index 6e5d601844e75c27a9610a5ffdc421d514296197..6ecb56ef9c4429b02bd4e2c2806e7e3b51a42d47 100644
--- a/mysql-test/t/func_regexp.test
+++ b/mysql-test/t/func_regexp.test
@@ -45,3 +45,17 @@ create table t1 (xxx char(128));
 insert into t1 (xxx) values('this is some text: to test - out.reg exp (22/45)');
 select * from t1 where xxx REGEXP '^this is some text: to test - out\\.reg exp [[(][0-9]+[/\\][0-9]+[])][ ]*$';
 drop table t1;
+
+#
+# Check with different character sets and collations
+#
+select _latin1 0xFF regexp _latin1 '[[:lower:]]' COLLATE latin1_bin;
+select _koi8r  0xFF regexp _koi8r  '[[:lower:]]' COLLATE koi8r_bin;
+select _latin1 0xFF regexp _latin1 '[[:upper:]]' COLLATE latin1_bin;
+select _koi8r  0xFF regexp _koi8r  '[[:upper:]]' COLLATE koi8r_bin;
+
+select _latin1 0xF7 regexp _latin1 '[[:alpha:]]';
+select _koi8r  0xF7 regexp _koi8r  '[[:alpha:]]';
+
+select _latin1'a' regexp _latin1'A' collate latin1_general_ci;
+select _latin1'a' regexp _latin1'A' collate latin1_bin;
diff --git a/regex/cclass.h b/regex/cclass.h
index e0f752f38b8cc17f3e84e0282471c94cdbef2d08..b877b5dee6b770579cffeac0e4866521921707d2 100644
--- a/regex/cclass.h
+++ b/regex/cclass.h
@@ -18,4 +18,5 @@ extern struct cclass {
 	const char *name;
 	const char *chars;
 	const char *multis;
+	uint  mask;
 } cclasses[];
diff --git a/regex/regcomp.c b/regex/regcomp.c
index d95a0ddf5d025725703f633cc8cbe7a753c0fbc2..6af99456c280f98bb9ffeb74a905fa0117fd41e0 100644
--- a/regex/regcomp.c
+++ b/regex/regcomp.c
@@ -36,19 +36,19 @@ struct parse {
 static char nuls[10];		/* place to point scanner in event of error */
 
 struct cclass cclasses[CCLASS_LAST+1]= {
-  { "alnum",	"","" },
-  { "alpha",	"","" },
-  { "blank",	"","" },
-  { "cntrl",	"","" },
-  { "digit",	"","" },
-  { "graph",	"","" },
-  { "lower",	"","" },
-  { "print",	"","" },
-  { "punct",	"","" },
-  { "space",	"","" },
-  { "upper",	"","" },
-  { "xdigit",	"","" },
-  { NULL,NULL,NULL }
+  { "alnum",	"","", _U | _L | _NMR},
+  { "alpha",	"","", _U | _L },
+  { "blank",	"","", _B },
+  { "cntrl",	"","", _CTR },
+  { "digit",	"","", _NMR },
+  { "graph",	"","", _PNT | _U | _L | _NMR},
+  { "lower",	"","", _L },
+  { "print",	"","", _PNT | _U | _L | _NMR | _B },
+  { "punct",	"","", _PNT },
+  { "space",	"","", _SPC },
+  { "upper",	"","", _U },
+  { "xdigit",	"","", _X },
+  { NULL,NULL,NULL, 0 }
 };
 
 /*
@@ -747,9 +747,7 @@ register cset *cs;
 	register char *sp = p->next;
 	register struct cclass *cp;
 	register size_t len;
-	register char *u;
-	register char c;
-
+	
 	while (MORE() && my_isalpha(p->charset,PEEK()))
 		NEXT();
 	len = p->next - sp;
@@ -762,11 +760,26 @@ register cset *cs;
 		return;
 	}
 
-	u = (char*) cp->chars;
-	while ((c = *u++) != '\0')
-		CHadd(cs, c);
-	for (u = (char*) cp->multis; *u != '\0'; u += strlen(u) + 1)
-		MCadd(p, cs, u);
+#ifndef USE_ORIG_REGEX_CODE
+	{
+		register size_t i;
+		for (i=1 ; i<256 ; i++)
+			if (p->charset->ctype[i+1] & cp->mask)
+				CHadd(cs, i);
+	}
+#else	
+	{
+		register char *u = (char*) cp->chars;
+		register char c;
+		
+		while ((c = *u++) != '\0')
+			CHadd(cs, c);
+		
+		for (u = (char*) cp->multis; *u != '\0'; u += strlen(u) + 1)
+			MCadd(p, cs, u);
+	}
+#endif
+
 }
 
 /*