Index: sql/sql_lex.cc
===================================================================
--- sql/sql_lex.cc      (revision 3993)
+++ sql/sql_lex.cc      (revision 4070)
@@ -443,6 +443,11 @@
   lex->is_lex_started= TRUE;
   lex->used_tables= 0;
   lex->reset_slave_info.all= false;
+  
+  lex->return_update= false;
+  lex->return_update_list.empty();
+  lex->real_query_start= 0;
+
   DBUG_VOID_RETURN;
 }
 
Index: sql/sql_yacc.yy
===================================================================
--- sql/sql_yacc.yy     (revision 3993)
+++ sql/sql_yacc.yy     (revision 4070)
@@ -991,6 +991,7 @@
 %token  GENERAL
 %token  GEOMETRYCOLLECTION
 %token  GEOMETRY_SYM
+%token  GET_SYM                       /* GET-UPDATE */
 %token  GET_FORMAT                    /* MYSQL-FUNC */
 %token  GLOBAL_SYM                    /* SQL-2003-R */
 %token  GRANT                         /* SQL-2003-R */
@@ -1609,6 +1610,7 @@
         part_column_list
         server_def server_options_list server_option
         definer_opt no_definer definer
+        get_update
 END_OF_INPUT
 
 %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
@@ -1734,6 +1736,7 @@
         | execute
         | flush
         | grant
+        | get_update
         | handler
         | help
         | insert
@@ -10619,6 +10622,45 @@
           KEY_SYM UPDATE_SYM insert_update_list
         ;
 
+/*
+  Impliment Oracle/PostgreSQL's 
+  "UPDATE...RETURNING..." as "GET...UPDATE..."
+*/
+
+get_update:
+          GET_SYM
+          {
+            LEX *lex= Lex;
+            mysql_init_select(lex);
+          }
+          select_item_list FROM
+          UPDATE_SYM
+          {
+            LEX *lex= Lex;
+            
+            lex->sql_command= SQLCOM_UPDATE;
+            lex->duplicates= DUP_ERROR;
+            
+            lex->return_update= true;
+            lex->real_query_start= YYLIP->get_tok_start() - YYTHD->query();
+
+            lex->return_update_list.swap(Select->item_list);
+            Select->item_list.empty();
+          }
+          opt_low_priority opt_ignore table_ident
+          SET update_list
+          {
+            if (!Select->add_table_to_list(YYTHD, $9, NULL, 
+                                           TL_OPTION_UPDATING, 
+                                           TL_READ_DEFAULT,
+                                           MDL_SHARED_READ))
+              MYSQL_YYABORT;
+            Select->set_lock_for_tables($7);
+          }
+          where_clause opt_order_clause delete_limit_clause {}
+        ;
+
+
 /* Update rows in a table */
 
 update:
Index: sql/sql_update.cc
===================================================================
--- sql/sql_update.cc   (revision 3993)
+++ sql/sql_update.cc   (revision 4070)
@@ -281,12 +281,25 @@
   THD::killed_state killed_status= THD::NOT_KILLED;
   DBUG_ENTER("mysql_update");
 
+  bool return_update= thd->lex->return_update;
+  select_send result;
+  List<Item> &return_fields= thd->lex->return_update_list;
+
   if (open_tables(thd, &table_list, &table_count, 0))
     DBUG_RETURN(1);
 
   if (table_list->multitable_view)
   {
     DBUG_ASSERT(table_list->view != 0);
+
+    // get result from multitable-view update is not supported
+    if (return_update)
+    {
+      my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->table_name, 
+               "GET...UPDATE");
+      DBUG_RETURN(1);
+    }
+
     DBUG_PRINT("info", ("Switch to multi-update"));
     /* pass counter value */
     thd->lex->table_count= table_count;
@@ -389,12 +402,31 @@
     bitmap_union(table->read_set, table->write_set);
   // Don't count on usage of 'only index' when calculating which key to use
   table->covering_keys.clear_all();
+ 
+  if (return_update) 
+  {
+    if (setup_wild(thd, table_list, return_fields, 0, select_lex->with_wild))
+      DBUG_RETURN(1);
+    if (setup_fields(thd, 0, return_fields, MARK_COLUMNS_READ, 0, 0))
+      DBUG_RETURN(1);
+    
+    result.set_thd(thd);
+    result.prepare(return_fields, &(thd->lex->unit));
+    if (return_update 
+        && result.send_result_set_metadata(return_fields,
+                                           Protocol::SEND_NUM_ROWS | 
+                                           Protocol::SEND_EOF))
+      DBUG_RETURN(1);
+ }
 
 #ifdef WITH_PARTITION_STORAGE_ENGINE
   if (prune_partitions(thd, table, conds))
   {
     free_underlaid_joins(thd, select_lex);
-    my_ok(thd);                                // No matching records
+    if (return_update) 
+      result.send_eof();
+    else
+      my_ok(thd);         // No matching records
     DBUG_RETURN(0);
   }
 #endif
@@ -418,7 +450,10 @@
     {
       DBUG_RETURN(1);                          // Error in where
     }
-    my_ok(thd);                                // No matching records
+    if (return_update)
+      result.send_eof();
+    else
     DBUG_RETURN(0);
   }
 
@@ -715,7 +750,11 @@
         if (!error || error == HA_ERR_RECORD_IS_THE_SAME)
        {
           if (error != HA_ERR_RECORD_IS_THE_SAME)
+          {
             updated++;
+            if (return_update && result.send_data(return_fields))
+              goto err;
+          }
           else
             error= 0;
        }
@@ -879,8 +918,11 @@
       else
         errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
 
+      uint32 query_start= (return_update)? thd->lex->real_query_start: 0;
+
       if (thd->binlog_query(THD::ROW_QUERY_TYPE,
-                            thd->query(), thd->query_length(),
+                            thd->query() + query_start, 
+                            thd->query_length() - query_start,
                             transactional_table, FALSE, FALSE, errcode))
       {
         error=1;                               // Rollback update
@@ -902,7 +944,10 @@
                 (ulong) thd->warning_info->statement_warn_count());
     ha_rows row_count=
       (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
-    my_ok(thd, row_count, id, buff);
+    if (return_update) 
+      result.send_eof();
+    else
+      my_ok(thd, row_count, id, buff);
     thd->updated_row_count += row_count;
     DBUG_PRINT("info",("%ld records updated", (long) updated));
   }
Index: sql/sql_lex.h
===================================================================
--- sql/sql_lex.h       (revision 3993)
+++ sql/sql_lex.h       (revision 4070)
@@ -2463,6 +2463,14 @@
   */
   table_map  used_tables;
 
+  /*
+    Impliment Oracle/PostgreSQL's 
+    "UPDATE...RETURNING..." as "GET...UPDATE..."
+  */
+  bool return_update;
+  List<Item> return_update_list;
+  uint32 real_query_start;
+
   LEX();
 
   virtual ~LEX()
Index: sql/lex.h
===================================================================
--- sql/lex.h   (revision 3993)
+++ sql/lex.h   (revision 4070)
@@ -234,6 +234,7 @@
   { "GENERAL",          SYM(GENERAL)},
   { "GEOMETRY",                SYM(GEOMETRY_SYM)},
   { "GEOMETRYCOLLECTION",SYM(GEOMETRYCOLLECTION)},
+  { "GET",    SYM(GET_SYM)},
   { "GET_FORMAT",       SYM(GET_FORMAT)},
   { "GLOBAL",          SYM(GLOBAL_SYM)},
   { "GRANT",           SYM(GRANT)},