diff --git a/lib/modules/Sql.pmod/mysql.pike b/lib/modules/Sql.pmod/mysql.pike
index e47ae1748728025eac34af7d6a94f9b72502a509..def5731786fc60dacb025eb0805d381e01c67b32 100644
--- a/lib/modules/Sql.pmod/mysql.pike
+++ b/lib/modules/Sql.pmod/mysql.pike
@@ -1,5 +1,5 @@
 /*
- * $Id: mysql.pike,v 1.34 2006/11/17 18:43:17 mast Exp $
+ * $Id: mysql.pike,v 1.35 2006/11/27 16:32:41 mast Exp $
  *
  * Glue for the Mysql-module
  */
@@ -138,6 +138,9 @@ int get_unicode_encode_mode()
 
 #if constant (Mysql.mysql.HAVE_MYSQL_FIELD_CHARSETNR)
 void set_unicode_decode_mode (int enable)
+#else
+static void broken_set_unicode_decode_mode (int enable)
+#endif
 //! Enable or disable unicode decode mode.
 //!
 //! In this mode, if the server supports UTF-8 then non-binary text
@@ -175,6 +178,15 @@ void set_unicode_decode_mode (int enable)
     utf8_mode &= ~UNICODE_DECODE_MODE;
   }
 }
+
+#if !constant (Mysql.mysql.HAVE_MYSQL_FIELD_CHARSETNR)
+// See blurb at MySQLBrokenUnicodeWrapper in sql_util.pmod. The
+// PIKE_BROKEN_MYSQL_UNICODE_MODE thingy ought to be a define, but
+// it's an environment variable instead to avoid problems with
+// overcaching in dumped files.
+function(int:void) set_unicode_decode_mode =
+  getenv ("PIKE_BROKEN_MYSQL_UNICODE_MODE") &&
+  broken_set_unicode_decode_mode;
 #endif
 
 int get_unicode_decode_mode()
@@ -266,16 +278,17 @@ void set_charset (string charset)
 #if constant (Mysql.mysql.HAVE_MYSQL_FIELD_CHARSETNR)
     utf8_mode |= UNICODE_DECODE_MODE;
 #else
-    predef::error ("Unicode decode mode not supported - "
-		   "compiled with MySQL client library < 4.1.0.\n");
+    if (set_unicode_decode_mode)
+      utf8_mode |= UNICODE_DECODE_MODE;
+    else
+      predef::error ("Unicode decode mode not supported - "
+		     "compiled with MySQL client library < 4.1.0.\n");
 #endif
   }
-#if constant (Mysql.mysql.HAVE_MYSQL_FIELD_CHARSETNR)
   else if (utf8_mode & UNICODE_DECODE_MODE && charset != "utf8")
     // This setting has been overridden by ::set_charset, so we need
     // to reinstate it.
     ::big_query ("SET character_set_results = utf8");
-#endif
 }
 
 string get_charset()
@@ -564,9 +577,9 @@ int decode_datetime (string timestr)
 }
 
 #if constant (Mysql.mysql.HAVE_MYSQL_FIELD_CHARSETNR)
-#define HAVE_MYSQL_FIELD_CHARSETNR_DO(X...) X
+#define HAVE_MYSQL_FIELD_CHARSETNR_IFELSE(TRUE, FALSE) TRUE
 #else
-#define HAVE_MYSQL_FIELD_CHARSETNR_DO(X...)
+#define HAVE_MYSQL_FIELD_CHARSETNR_IFELSE(TRUE, FALSE) FALSE
 #endif
 
 #define QUERY_BODY(do_query)						\
@@ -647,12 +660,13 @@ int decode_datetime (string timestr)
 									\
   if (!objectp(res)) return res;					\
 									\
-  HAVE_MYSQL_FIELD_CHARSETNR_DO (					\
-    if (utf8_mode & UNICODE_DECODE_MODE) {				\
-      CH_DEBUG ("Using UnicodeWrapper for result.\n");			\
-      return .sql_util.UnicodeWrapper(res);				\
-    }									\
-  );									\
+  if (utf8_mode & UNICODE_DECODE_MODE) {				\
+    CH_DEBUG ("Using unicode wrapper for result.\n");			\
+    return								\
+      HAVE_MYSQL_FIELD_CHARSETNR_IFELSE (				\
+	.sql_util.MySQLUnicodeWrapper(res),				\
+	.sql_util.MySQLBrokenUnicodeWrapper (res));			\
+  }									\
   return res;
 
 Mysql.mysql_result big_query (string query,
@@ -764,15 +778,19 @@ static void create(string|void host, string|void database,
 
     update_unicode_encode_mode_from_charset (lower_case (charset));
 
-#if constant (Mysql.mysql.HAVE_MYSQL_FIELD_CHARSETNR)
-    if (charset == "unicode")
-      utf8_mode |= UNICODE_DECODE_MODE;
-    else if (options->unicode_decode_mode)
-      set_unicode_decode_mode (1);
-#else
-    if (charset == "unicode" || options->unicode_decode_mode)
-      predef::error ("Unicode decode mode not supported - "
-		     "compiled with MySQL client library < 4.1.0.\n");
+#if !constant (Mysql.mysql.HAVE_MYSQL_FIELD_CHARSETNR)
+    if (set_unicode_encode_mode) {
+#endif
+      if (charset == "unicode")
+	utf8_mode |= UNICODE_DECODE_MODE;
+      else if (options->unicode_decode_mode)
+	set_unicode_decode_mode (1);
+#if !constant (Mysql.mysql.HAVE_MYSQL_FIELD_CHARSETNR)
+    }
+    else
+      if (charset == "unicode" || options->unicode_decode_mode)
+	predef::error ("Unicode decode mode not supported - "
+		       "compiled with MySQL client library < 4.1.0.\n");
 #endif
 
   } else {
diff --git a/lib/modules/Sql.pmod/sql_util.pmod b/lib/modules/Sql.pmod/sql_util.pmod
index 6eb80ab9d808f7350aef1d707ce34d46da7e237f..206036a99142be64c131a1017d12f4ad4e3875ba 100644
--- a/lib/modules/Sql.pmod/sql_util.pmod
+++ b/lib/modules/Sql.pmod/sql_util.pmod
@@ -1,5 +1,5 @@
 /*
- * $Id: sql_util.pmod,v 1.16 2006/11/17 18:43:17 mast Exp $
+ * $Id: sql_util.pmod,v 1.17 2006/11/27 16:32:43 mast Exp $
  *
  * Some SQL utility functions.
  * They are kept here to avoid circular references.
@@ -141,6 +141,7 @@ class UnicodeWrapper (
 }
 
 #if constant (Mysql.mysql.HAVE_MYSQL_FIELD_CHARSETNR)
+
 class MySQLUnicodeWrapper
 //! Result wrapper for MySQL that performs UTF-8 decoding of all
 //! nonbinary fields. Useful if the result charset of the connection
@@ -165,4 +166,38 @@ class MySQLUnicodeWrapper
     return row;
   }
 }
+
+#else
+
+class MySQLBrokenUnicodeWrapper
+// This one is used to get bug compatibility when compiled with an old
+// MySQL client lib that doesn't have the charsetnr property in the
+// field info. It looks at the binary flag instead, which is set for
+// binary fields but might also be set for text fields (e.g. with a
+// definition like "VARCHAR(255) BINARY").
+//
+// I.e. the effect of using this one is that text fields with the
+// binary flag won't be correctly decoded in unicode decode mode. This
+// has to be enabled by defining the environment variable
+// PIKE_BROKEN_MYSQL_UNICODE_MODE. With it the unicode decode mode
+// will exist even when the client lib is too old to implement it
+// correctly.
+{
+  inherit UnicodeWrapper;
+
+  int|array(string) fetch_row()
+  {
+    int|array(string) row = master_result->fetch_row();
+    if (!arrayp(row)) return row;
+    array(int|mapping(string:mixed)) field_info = fetch_fields();
+    foreach(row; int i; string|int val) {
+      if (stringp(val) && field_info[i]->flags &&
+	  !field_info[i]->flags->binary) {
+	row[i] = utf8_to_string(val);
+      }
+    }
+    return row;
+  }
+}
+
 #endif