diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c
index 6f8f82d84061155f6825281890b6a1e799b78844..b6b14cb922e8a29de1091236613f5b55c038907a 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.39 1998/09/01 04:32:53 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.40 1998/09/25 01:46:21 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -147,7 +147,14 @@ bpchar(char *s, int32 len)
 	if ((len == -1) || (len == VARSIZE(s)))
 		return s;
 
+#ifdef MULTIBYTE
+	/* truncate multi-byte string in a way not to break
+	   multi-byte boundary */
+	rlen = pg_mbcliplen(VARDATA(s), len - VARHDRSZ, len - VARHDRSZ);
+	len = rlen + VARHDRSZ;
+#else
 	rlen = len - VARHDRSZ;
+#endif
 
 	if (rlen > 4096)
 		elog(ERROR, "bpchar: length of char() must be less than 4096");
@@ -367,7 +374,14 @@ varchar(char *s, int32 slen)
 
 	/* only reach here if we need to truncate string... */
 
+#ifdef MULTIBYTE
+	/* truncate multi-byte string in a way not to break
+	   multi-byte boundary */
+	len = pg_mbcliplen(VARDATA(s), slen - VARHDRSZ, slen - VARHDRSZ);
+	slen = len + VARHDRSZ;
+#else
 	len = slen - VARHDRSZ;
+#endif
 
 	if (len > 4096)
 		elog(ERROR, "varchar: length of varchar() must be less than 4096");
diff --git a/src/backend/utils/mb/mbutils.c b/src/backend/utils/mb/mbutils.c
index 2e0a446de20b77a202b5f5b6d4f2ebe5d9435113..e359a53df3d4350b2c673d52f39a00daf6dc7548 100644
--- a/src/backend/utils/mb/mbutils.c
+++ b/src/backend/utils/mb/mbutils.c
@@ -3,7 +3,7 @@
  * client encoding and server internal encoding.
  * (currently mule internal code (mic) is used)
  * Tatsuo Ishii
- * $Id: mbutils.c,v 1.3 1998/09/01 04:33:22 momjian Exp $ */
+ * $Id: mbutils.c,v 1.4 1998/09/25 01:46:23 momjian Exp $ */
 
 #include <stdio.h>
 #include <string.h>
@@ -201,6 +201,34 @@ pg_mbstrlen_with_len(const unsigned char *mbstr, int limit)
 	return (len);
 }
 
+/*
+ * returns the length of a multi-byte string
+ * (not necessarily  NULL terminated)
+ * that is not longer than limit.
+ * this function does not break multi-byte word boundary.
+ */
+int
+pg_mbcliplen(const unsigned char *mbstr, int len, int limit)
+{
+	int			clen = 0;
+	int			l;
+
+	while (*mbstr &&  len > 0)
+	{
+		l = pg_mblen(mbstr);
+		if ((clen + l) > limit) {
+			break;
+		}
+		clen += l;
+		if (clen == limit) {
+			break;
+		}
+		len -= l;
+		mbstr += l;
+	}
+	return (clen);
+}
+
 /*
  * fuctions for utils/init
  */
diff --git a/src/include/mb/pg_wchar.h b/src/include/mb/pg_wchar.h
index 5d7c2458dda1b7a228999bb8a5c4607b674ae13e..62bbe60cb1623b36311f09407200184fcc5c9335 100644
--- a/src/include/mb/pg_wchar.h
+++ b/src/include/mb/pg_wchar.h
@@ -1,4 +1,4 @@
-/* $Id: pg_wchar.h,v 1.4 1998/09/01 04:36:34 momjian Exp $ */
+/* $Id: pg_wchar.h,v 1.5 1998/09/25 01:46:25 momjian Exp $ */
 
 #ifndef PG_WCHAR_H
 #define PG_WCHAR_H
@@ -103,6 +103,7 @@ extern int	pg_mule_mblen(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);
+extern int	pg_mbcliplen(const unsigned char *, int, int);
 extern pg_encoding_conv_tbl *pg_get_encent_by_encoding(int);
 extern bool show_client_encoding(void);
 extern bool reset_client_encoding(void);