diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok
index 961cfb5c9a5506dc1de11f45448c75168191eb1c..5c0d5076d9ab3d08e8b78ce5dccd5912baa1fd9b 100644
--- a/BitKeeper/etc/logging_ok
+++ b/BitKeeper/etc/logging_ok
@@ -73,3 +73,4 @@ worm@altair.is.lan
 zak@balfor.local
 zak@linux.local
 zgreant@mysql.com
+ram@ram.(none)
diff --git a/sql/item_create.cc b/sql/item_create.cc
index e75c7049a74d8b1787914eac3d188810296ae049..f28e3248c6155954b9ddbc5b50286397c2bc9ee1 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -440,3 +440,7 @@ Item *create_func_is_free_lock(Item* a)
   return new Item_func_is_free_lock(a);
 }
 
+Item *create_func_quote(Item* a)
+{
+  return new Item_func_quote(a);
+}
diff --git a/sql/item_create.h b/sql/item_create.h
index 730a151098876b5e7b60089e4e4de4a7ad2331ac..28fbd61df8fa65c7dbdace1f8417fcf87e10393d 100644
--- a/sql/item_create.h
+++ b/sql/item_create.h
@@ -93,3 +93,4 @@ Item *create_func_weekday(Item* a);
 Item *create_load_file(Item* a);
 Item *create_wait_for_master_pos(Item* a, Item* b);
 Item *create_func_is_free_lock(Item* a);
+Item *create_func_quote(Item* a);
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index f074629e3761366fe129a9ecc3e3339b6e7d6dbe..69aa4af980ee4dfd270eb23060c800ee9d777240 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -2070,3 +2070,41 @@ String* Item_func_inet_ntoa::val_str(String* str)
   str->length(str->length()-1);			// Remove last '.';
   return str;
 }
+
+/*
+  QUOTE() function returns argument string in single quotes,
+  also adds a \ before \, ' CHAR(0) and CHAR(24)
+*/
+String *Item_func_quote::val_str(String *str)
+{
+  static char escmask[64] = {0x01, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00,
+			     0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+			     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+			     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+  String *arg= args[0]->val_str(str);
+  char *from, *to, *end;
+  uint delta= 2; /* for beginning and ending ' signs */
+
+  for (from= (char*) arg->ptr(), end= from + arg->length(); from < end; from++)
+  {
+    if (*(escmask + (*from >> 3)) and (1 << (*from & 7)))
+      delta++;
+  }
+  if (str->alloc(arg->length() + delta))
+  {
+    null_value= 1;
+    return 0;
+  }
+  to= (char*) str->ptr() + arg->length() + delta - 1;
+  *to--= '\'';
+  for (end= (char*) arg->ptr(), from= end + arg->length() - 1; from >= end; 
+       from--, to--)
+  {
+    *to= *from;
+    if (*(escmask + (*from >> 3)) and (1 << (*from & 7)))
+      *--to= '\\';
+  }
+  *to= '\'';
+  str->length(arg->length() + delta);
+  return str;
+}
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 618a6f56bcfc5ded0bb62ed57a06a18bd2da9c56..3bbec149e9c104e366f4a06e9d4b072571a3a049 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -526,3 +526,12 @@ class Item_func_export_set: public Item_str_func
   const char *func_name() const { return "inet_ntoa"; }
   void fix_length_and_dec() { decimals = 0; max_length=3*8+7; }
 };
+
+class Item_func_quote :public Item_str_func
+{
+public:
+  Item_func_quote(Item *a) :Item_str_func(a) {}
+  const char *func_name() const { return "quote"; }
+  String *val_str(String *);
+  void fix_length_and_dec() { max_length= args[0]->max_length * 2 + 2; }
+};
diff --git a/sql/lex.h b/sql/lex.h
index c1d647c47aa383d0fbf334d5c0468780e9c80b1e..0a1505581cd22b673bb3a8cdcdbfe0df3d6ec8e8 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -475,6 +475,7 @@ static SYMBOL sql_functions[] = {
   { "POW",		SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)},
   { "POWER",		SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)},
   { "QUARTER",		SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_quarter)},
+  { "QUOTE",		SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_quote)},
   { "RADIANS",		SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_radians)},
   { "RAND",		SYM(RAND),0,0},
   { "RELEASE_LOCK",	SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_release_lock)},