List:Commits« Previous MessageNext Message »
From:Marc Alff Date:May 18 2010 5:58am
Subject:bzr commit into mysql-next-mr-bugfixing branch (marc.alff:3177)
View as plain text  
#At file:///Users/malff/BZR_TREE/mysql-next-mr-bugfixing-53617/ based on revid:marc.alff@stripped

 3177 Marc Alff	2010-05-17 [merge]
      local merge

    added:
      mysql-test/suite/funcs_1/r/row_count_func.result
      mysql-test/suite/funcs_1/t/row_count_func-master.opt
      mysql-test/suite/funcs_1/t/row_count_func.test
    modified:
      mysql-test/include/ctype_numconv.inc
      mysql-test/include/mysqld--help.inc
      mysql-test/r/ctype_binary.result
      mysql-test/r/ctype_cp1251.result
      mysql-test/r/ctype_latin1.result
      mysql-test/r/ctype_ucs.result
      mysql-test/r/sp.result
      mysql-test/suite/funcs_1/r/innodb_storedproc_10.result
      mysql-test/suite/funcs_1/r/memory_storedproc_10.result
      mysql-test/suite/funcs_1/r/myisam_storedproc_10.result
      mysql-test/suite/funcs_1/r/ndb_storedproc_10.result
      mysql-test/t/parser_stack.test
      sql/ha_ndbcluster_binlog.cc
      sql/item_func.cc
      sql/log_event.cc
      sql/protocol.cc
      sql/sql_class.cc
      sql/sql_class.h
      sql/sql_delete.cc
      sql/sql_insert.cc
      sql/sql_lex.cc
      sql/sql_lex.h
      sql/sql_parse.cc
      sql/sql_parse.h
      sql/sql_signal.cc
      sql/sql_update.cc
      storage/perfschema/pfs_engine_table.cc
      storage/perfschema/pfs_global.cc
      storage/perfschema/pfs_global.h
=== modified file 'mysql-test/include/ctype_numconv.inc'
--- a/mysql-test/include/ctype_numconv.inc	2010-02-11 14:28:28 +0000
+++ b/mysql-test/include/ctype_numconv.inc	2010-05-14 05:28:51 +0000
@@ -457,6 +457,8 @@ select * from t1;
 show create table t1;
 drop table t1;
 
+# Ensure that row_count() value is reset after drop table.
+select 1;
 select hex(concat(row_count()));
 create table t1 as select concat(row_count()) as c1;
 show create table t1;

=== modified file 'mysql-test/include/mysqld--help.inc'
--- a/mysql-test/include/mysqld--help.inc	2010-01-26 21:05:41 +0000
+++ b/mysql-test/include/mysqld--help.inc	2010-05-17 15:28:50 +0000
@@ -23,7 +23,7 @@ perl;
   while (<F>) {
     next if 1../The following groups are read/;
     # formatting, skip line consisting entirely of dashes and blanks
-    next if /^[\- ]+$/;
+    next if /^[\- ]+\s?$/;
     next if /Value \(after reading options\)/; # skip table header
     next if /^($re1) /;
     next if /^($re2)-/;

=== modified file 'mysql-test/r/ctype_binary.result'
--- a/mysql-test/r/ctype_binary.result	2010-02-11 14:28:28 +0000
+++ b/mysql-test/r/ctype_binary.result	2010-05-14 05:28:51 +0000
@@ -772,6 +772,9 @@ t1	CREATE TABLE `t1` (
   `c1` varbinary(31) DEFAULT NULL
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 drop table t1;
+select 1;
+1
+1
 select hex(concat(row_count()));
 hex(concat(row_count()))
 2D31

=== modified file 'mysql-test/r/ctype_cp1251.result'
--- a/mysql-test/r/ctype_cp1251.result	2010-02-11 14:28:28 +0000
+++ b/mysql-test/r/ctype_cp1251.result	2010-05-14 05:28:51 +0000
@@ -854,6 +854,9 @@ t1	CREATE TABLE `t1` (
   `c1` varchar(31) CHARACTER SET cp1251 DEFAULT NULL
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 drop table t1;
+select 1;
+1
+1
 select hex(concat(row_count()));
 hex(concat(row_count()))
 2D31

=== modified file 'mysql-test/r/ctype_latin1.result'
--- a/mysql-test/r/ctype_latin1.result	2010-02-11 14:28:28 +0000
+++ b/mysql-test/r/ctype_latin1.result	2010-05-14 05:28:51 +0000
@@ -1182,6 +1182,9 @@ t1	CREATE TABLE `t1` (
   `c1` varchar(31) DEFAULT NULL
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 drop table t1;
+select 1;
+1
+1
 select hex(concat(row_count()));
 hex(concat(row_count()))
 2D31

=== modified file 'mysql-test/r/ctype_ucs.result'
--- a/mysql-test/r/ctype_ucs.result	2010-02-11 14:28:28 +0000
+++ b/mysql-test/r/ctype_ucs.result	2010-05-14 05:28:51 +0000
@@ -2006,6 +2006,9 @@ t1	CREATE TABLE `t1` (
   `c1` varchar(31) CHARACTER SET ucs2 DEFAULT NULL
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 drop table t1;
+select 1;
+1
+1
 select hex(concat(row_count()));
 hex(concat(row_count()))
 002D0031

=== modified file 'mysql-test/r/sp.result'
--- a/mysql-test/r/sp.result	2010-04-19 08:29:52 +0000
+++ b/mysql-test/r/sp.result	2010-05-14 05:29:47 +0000
@@ -2590,11 +2590,11 @@ row_count()
 call bug4905()|
 select row_count()|
 row_count()
--1
+0
 call bug4905()|
 select row_count()|
 row_count()
--1
+0
 select * from t3|
 s1
 1

=== modified file 'mysql-test/suite/funcs_1/r/innodb_storedproc_10.result'
--- a/mysql-test/suite/funcs_1/r/innodb_storedproc_10.result	2009-01-31 19:22:59 +0000
+++ b/mysql-test/suite/funcs_1/r/innodb_storedproc_10.result	2010-05-14 05:28:51 +0000
@@ -375,7 +375,7 @@ row_count() after delete
 2
 SELECT row_count();
 row_count()
--1
+0
 SELECT * FROM temp;
 f1	f2	f3	f4	f5	f6
 qwe	xyz	1998-03-26	100	uvw	1000

=== modified file 'mysql-test/suite/funcs_1/r/memory_storedproc_10.result'
--- a/mysql-test/suite/funcs_1/r/memory_storedproc_10.result	2009-01-31 19:22:59 +0000
+++ b/mysql-test/suite/funcs_1/r/memory_storedproc_10.result	2010-05-14 05:28:51 +0000
@@ -376,7 +376,7 @@ row_count() after delete
 2
 SELECT row_count();
 row_count()
--1
+0
 SELECT * FROM temp;
 f1	f2	f3	f4	f5	f6
 qwe	xyz	1998-03-26	100	uvw	1000

=== modified file 'mysql-test/suite/funcs_1/r/myisam_storedproc_10.result'
--- a/mysql-test/suite/funcs_1/r/myisam_storedproc_10.result	2009-01-31 19:22:59 +0000
+++ b/mysql-test/suite/funcs_1/r/myisam_storedproc_10.result	2010-05-14 05:28:51 +0000
@@ -376,7 +376,7 @@ row_count() after delete
 2
 SELECT row_count();
 row_count()
--1
+0
 SELECT * FROM temp;
 f1	f2	f3	f4	f5	f6
 qwe	xyz	1998-03-26	100	uvw	1000

=== modified file 'mysql-test/suite/funcs_1/r/ndb_storedproc_10.result'
--- a/mysql-test/suite/funcs_1/r/ndb_storedproc_10.result	2009-01-31 19:22:59 +0000
+++ b/mysql-test/suite/funcs_1/r/ndb_storedproc_10.result	2010-05-14 05:28:51 +0000
@@ -375,7 +375,7 @@ row_count() after delete
 2
 SELECT row_count();
 row_count()
--1
+0
 SELECT * FROM temp;
 f1	f2	f3	f4	f5	f6
 qwe	xyz	1998-03-26	100	uvw	1000

=== added file 'mysql-test/suite/funcs_1/r/row_count_func.result'
--- a/mysql-test/suite/funcs_1/r/row_count_func.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/funcs_1/r/row_count_func.result	2010-05-14 05:28:51 +0000
@@ -0,0 +1,79 @@
+
+# -- 
+# -- Test case for Bug#21818.
+# -- 
+
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1), (2), (3);
+
+# -- Check 1.
+SELECT * FROM t1 INTO OUTFILE "MYSQL_TMP_DIR/bug21818.txt";
+affected rows: 3
+
+SELECT ROW_COUNT();
+ROW_COUNT()
+3
+
+# -- Check 2.
+SELECT a FROM t1 LIMIT 1 INTO @a;
+affected rows: 1
+
+SELECT ROW_COUNT();
+ROW_COUNT()
+1
+
+# -- Check 3.
+DROP DATABASE IF EXISTS mysqltest1;
+CREATE DATABASE mysqltest1;
+affected rows: 1
+
+SELECT ROW_COUNT();
+ROW_COUNT()
+1
+DROP DATABASE mysqltest1;
+
+# -- Check 4.
+DELETE FROM t1;
+LOAD DATA INFILE 'MYSQL_TMP_DIR/bug21818.txt' INTO TABLE t1(a);
+affected rows: 3
+info: Records: 3  Deleted: 0  Skipped: 0  Warnings: 0
+
+SELECT ROW_COUNT();
+ROW_COUNT()
+3
+
+# -- Check 5.
+ALTER TABLE t1 ADD COLUMN b VARCHAR(255);
+affected rows: 3
+info: Records: 3  Duplicates: 0  Warnings: 0
+
+SELECT ROW_COUNT();
+ROW_COUNT()
+3
+
+DROP TABLE t1;
+
+# -- Check 6.
+DROP TABLE IF EXISTS t2;
+CREATE TABLE t1(a INT);
+CREATE TABLE t2(a INT);
+INSERT INTO t1 VALUES (1), (2), (3);
+INSERT INTO t2 VALUES (ROW_COUNT());
+SELECT * FROM t2;
+a
+3
+DROP TABLE t1;
+DROP TABLE t2;
+
+# -- Check 7 (check that SQL errors reset row_count to -1).
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1), (2), (3);
+SELECT f1();
+ERROR 42000: FUNCTION test.f1 does not exist
+SELECT ROW_COUNT();
+ROW_COUNT()
+-1
+DROP TABLE t1;
+
+# -- End of test case for Bug#21818.

=== added file 'mysql-test/suite/funcs_1/t/row_count_func-master.opt'
--- a/mysql-test/suite/funcs_1/t/row_count_func-master.opt	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/funcs_1/t/row_count_func-master.opt	2010-05-14 05:28:51 +0000
@@ -0,0 +1 @@
+--secure-file-priv=$MYSQL_TMP_DIR

=== added file 'mysql-test/suite/funcs_1/t/row_count_func.test'
--- a/mysql-test/suite/funcs_1/t/row_count_func.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/funcs_1/t/row_count_func.test	2010-05-14 05:28:51 +0000
@@ -0,0 +1,115 @@
+--echo
+--echo # -- 
+--echo # -- Test case for Bug#21818.
+--echo # -- 
+--echo
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (1), (2), (3);
+
+--echo
+--echo # -- Check 1.
+
+--enable_info
+--echo SELECT * FROM t1 INTO OUTFILE "MYSQL_TMP_DIR/bug21818.txt";
+--disable_query_log # to avoid $MYSQL_TMP_DIR in query log
+--eval SELECT * FROM t1 INTO OUTFILE "$MYSQL_TMP_DIR/bug21818.txt"
+--enable_query_log
+--disable_info
+
+--echo
+SELECT ROW_COUNT();
+
+--echo
+--echo # -- Check 2.
+
+--enable_info
+SELECT a FROM t1 LIMIT 1 INTO @a;
+--disable_info
+
+--echo
+SELECT ROW_COUNT();
+
+--echo
+--echo # -- Check 3.
+
+--disable_warnings
+DROP DATABASE IF EXISTS mysqltest1;
+--enable_warnings
+
+--enable_info
+CREATE DATABASE mysqltest1;
+--disable_info
+
+--echo
+SELECT ROW_COUNT();
+
+DROP DATABASE mysqltest1;
+
+--echo
+--echo # -- Check 4.
+
+DELETE FROM t1;
+
+--enable_info
+--echo LOAD DATA INFILE 'MYSQL_TMP_DIR/bug21818.txt' INTO TABLE t1(a);
+--disable_query_log # to avoid $MYSQL_TMP_DIR in query log
+--eval LOAD DATA INFILE '$MYSQL_TMP_DIR/bug21818.txt' INTO TABLE t1(a)
+--enable_query_log
+--disable_info
+
+--echo
+SELECT ROW_COUNT();
+
+--remove_file $MYSQL_TMP_DIR/bug21818.txt
+
+--echo
+--echo # -- Check 5.
+
+--enable_info
+ALTER TABLE t1 ADD COLUMN b VARCHAR(255);
+--disable_info
+
+--echo
+SELECT ROW_COUNT();
+
+--echo
+DROP TABLE t1;
+
+--echo
+--echo # -- Check 6.
+
+--disable_warnings
+DROP TABLE IF EXISTS t2;
+--enable_warnings
+
+CREATE TABLE t1(a INT);
+CREATE TABLE t2(a INT);
+
+INSERT INTO t1 VALUES (1), (2), (3);
+INSERT INTO t2 VALUES (ROW_COUNT());
+
+SELECT * FROM t2;
+
+DROP TABLE t1;
+DROP TABLE t2;
+
+--echo
+--echo # -- Check 7 (check that SQL errors reset row_count to -1).
+
+CREATE TABLE t1(a INT);
+
+INSERT INTO t1 VALUES (1), (2), (3);
+--error ER_SP_DOES_NOT_EXIST
+SELECT f1();
+
+SELECT ROW_COUNT();
+
+DROP TABLE t1;
+
+--echo
+--echo # -- End of test case for Bug#21818.

=== modified file 'mysql-test/t/parser_stack.test'
--- a/mysql-test/t/parser_stack.test	2008-07-14 21:41:30 +0000
+++ b/mysql-test/t/parser_stack.test	2010-05-14 18:11:25 +0000
@@ -399,4 +399,12 @@ delimiter ;$$
 
 drop procedure p_37228;
 
+#
+# Bug#27863 (excessive memory usage for many small queries in a multiquery
+# packet).
+#
 
+let $i=`select repeat("set @a=1;", 65535)`;
+--disable_query_log
+eval $i;
+--enable_query_log

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2010-03-31 14:05:33 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2010-05-17 12:10:26 +0000
@@ -263,7 +263,6 @@ static void run_query(THD *thd, char *bu
   ulonglong save_thd_options= thd->variables.option_bits;
   DBUG_ASSERT(sizeof(save_thd_options) == sizeof(thd->variables.option_bits));
   NET save_thd_net= thd->net;
-  const char* found_semicolon= NULL;
 
   bzero((char*) &thd->net, sizeof(NET));
   thd->set_query(buf, (uint) (end - buf));
@@ -277,7 +276,10 @@ static void run_query(THD *thd, char *bu
   DBUG_ASSERT(!thd->in_sub_stmt);
   DBUG_ASSERT(!thd->locked_tables_mode);
 
-  mysql_parse(thd, thd->query(), thd->query_length(), &found_semicolon);
+  {
+    Parser_state parser_state(thd, thd->query(), thd->query_length());
+    mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
+  }
 
   if (no_print_error && thd->is_slave_error)
   {

=== modified file 'sql/item_func.cc'
--- a/sql/item_func.cc	2010-04-07 11:58:40 +0000
+++ b/sql/item_func.cc	2010-05-14 05:28:51 +0000
@@ -6030,7 +6030,7 @@ longlong Item_func_row_count::val_int()
   DBUG_ASSERT(fixed == 1);
   THD *thd= current_thd;
 
-  return thd->row_count_func;
+  return thd->get_row_count_func();
 }
 
 

=== modified file 'sql/log_event.cc'
--- a/sql/log_event.cc	2010-04-29 11:20:36 +0000
+++ b/sql/log_event.cc	2010-05-14 18:38:28 +0000
@@ -3290,8 +3290,8 @@ int Query_log_event::do_apply_event(Rela
       thd->table_map_for_update= (table_map)table_map_for_update;
       
       /* Execute the query (note that we bypass dispatch_command()) */
-      const char* found_semicolon= NULL;
-      mysql_parse(thd, thd->query(), thd->query_length(), &found_semicolon);
+      Parser_state parser_state(thd, thd->query(), thd->query_length());
+      mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
       log_slow_statement(thd);
 
       /*

=== modified file 'sql/protocol.cc'
--- a/sql/protocol.cc	2010-03-31 14:05:33 +0000
+++ b/sql/protocol.cc	2010-05-14 05:28:51 +0000
@@ -210,7 +210,7 @@ net_send_ok(THD *thd,
   NET *net= &thd->net;
   uchar buff[MYSQL_ERRMSG_SIZE+10],*pos;
   bool error= FALSE;
-  DBUG_ENTER("my_ok");
+  DBUG_ENTER("net_send_ok");
 
   if (! net->vio)	// hack for re-parsing queries
   {

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2010-04-29 11:20:36 +0000
+++ b/sql/sql_class.cc	2010-05-14 05:29:47 +0000
@@ -512,7 +512,7 @@ THD::THD()
   cuted_fields= 0L;
   sent_row_count= 0L;
   limit_found_rows= 0;
-  row_count_func= -1;
+  m_row_count_func= -1;
   statement_id_counter= 0UL;
   // Must be reset to handle error with THD's created for init of mysqld
   lex->current_select= 0;
@@ -804,7 +804,10 @@ MYSQL_ERROR* THD::raise_condition(uint s
     else
     {
       if (! stmt_da->is_error())
+      {
+        set_row_count_func(-1);
         stmt_da->set_error_status(this, sql_errno, msg, sqlstate);
+      }
     }
   }
 
@@ -1805,11 +1808,6 @@ bool select_to_file::send_eof()
     error= 1;
   if (!error)
   {
-    /*
-      In order to remember the value of affected rows for ROW_COUNT()
-      function, SELECT INTO has to have an own SQLCOM.
-      TODO: split from SQLCOM_SELECT
-    */
     ::my_ok(thd,row_count);
   }
   file= -1;
@@ -2830,11 +2828,6 @@ bool select_dumpvar::send_eof()
   if (! row_count)
     push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
                  ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA));
-  /*
-    In order to remember the value of affected rows for ROW_COUNT()
-    function, SELECT INTO has to have an own SQLCOM.
-    TODO: split from SQLCOM_SELECT
-  */
   ::my_ok(thd,row_count);
   return 0;
 }

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2010-04-26 09:06:35 +0000
+++ b/sql/sql_class.h	2010-05-14 05:29:47 +0000
@@ -1994,7 +1994,50 @@ public:
   }
 
   ulonglong  limit_found_rows;
-  longlong   row_count_func;    /* For the ROW_COUNT() function */
+
+private:
+  /**
+    Stores the result of ROW_COUNT() function.
+
+    ROW_COUNT() function is a MySQL extention, but we try to keep it
+    similar to ROW_COUNT member of the GET DIAGNOSTICS stack of the SQL
+    standard (see SQL99, part 2, search for ROW_COUNT). It's value is
+    implementation defined for anything except INSERT, DELETE, UPDATE.
+
+    ROW_COUNT is assigned according to the following rules:
+
+      - In my_ok():
+        - for DML statements: to the number of affected rows;
+        - for DDL statements: to 0.
+
+      - In my_eof(): to -1 to indicate that there was a result set.
+
+        We derive this semantics from the JDBC specification, where int
+        java.sql.Statement.getUpdateCount() is defined to (sic) "return the
+        current result as an update count; if the result is a ResultSet
+        object or there are no more results, -1 is returned".
+
+      - In my_error(): to -1 to be compatible with the MySQL C API and
+        MySQL ODBC driver.
+
+      - For SIGNAL statements: to 0 per WL#2110 specification (see also
+        sql_signal.cc comment). Zero is used since that's the "default"
+        value of ROW_COUNT in the diagnostics area.
+  */
+
+  longlong m_row_count_func;    /* For the ROW_COUNT() function */
+
+public:
+  inline longlong get_row_count_func() const
+  {
+    return m_row_count_func;
+  }
+
+  inline void set_row_count_func(longlong row_count_func)
+  {
+    m_row_count_func= row_count_func;
+  }
+
   ha_rows    cuted_fields;
 
   /*
@@ -2781,6 +2824,7 @@ inline void
 my_ok(THD *thd, ulonglong affected_rows= 0, ulonglong id= 0,
         const char *message= NULL)
 {
+  thd->set_row_count_func(affected_rows);
   thd->stmt_da->set_ok_status(thd, affected_rows, id, message);
 }
 
@@ -2790,6 +2834,7 @@ my_ok(THD *thd, ulonglong affected_rows=
 inline void
 my_eof(THD *thd)
 {
+  thd->set_row_count_func(-1);
   thd->stmt_da->set_eof_status(thd);
 }
 
@@ -3451,7 +3496,7 @@ public:
 /* Bits in sql_command_flags */
 
 #define CF_CHANGES_DATA           (1U << 0)
-#define CF_HAS_ROW_COUNT          (1U << 1)
+/* The 2nd bit is unused -- it used to be CF_HAS_ROW_COUNT. */
 #define CF_STATUS_COMMAND         (1U << 2)
 #define CF_SHOW_TABLE_COMMAND     (1U << 3)
 #define CF_WRITE_LOGS_COMMAND     (1U << 4)

=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc	2010-04-01 19:34:09 +0000
+++ b/sql/sql_delete.cc	2010-05-14 05:29:47 +0000
@@ -187,8 +187,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *
   if (prune_partitions(thd, table, conds))
   {
     free_underlaid_joins(thd, select_lex);
-    thd->row_count_func= 0;
-    my_ok(thd, (ha_rows) thd->row_count_func);  // No matching records
+    // No matching record
+    my_ok(thd, 0);
     DBUG_RETURN(0);
   }
 #endif
@@ -204,7 +204,6 @@ bool mysql_delete(THD *thd, TABLE_LIST *
   {
     delete select;
     free_underlaid_joins(thd, select_lex);
-    thd->row_count_func= 0;
     /* 
       Error was already created by quick select evaluation (check_quick()).
       TODO: Add error code output parameter to Item::val_xxx() methods.
@@ -213,7 +212,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *
     */
     if (thd->is_error())
       DBUG_RETURN(TRUE);
-    my_ok(thd, (ha_rows) thd->row_count_func);
+    my_ok(thd, 0);
     /*
       We don't need to call reset_auto_increment in this case, because
       mysql_truncate always gives a NULL conds argument, hence we never
@@ -460,8 +459,7 @@ cleanup:
       If a TRUNCATE TABLE was issued, the number of rows should be reported as
       zero since the exact number is unknown.
     */
-    thd->row_count_func= reset_auto_increment ? 0 : deleted;
-    my_ok(thd, (ha_rows) thd->row_count_func);
+    my_ok(thd, reset_auto_increment ? 0 : deleted);
     DBUG_PRINT("info",("%ld records deleted",(long) deleted));
   }
   DBUG_RETURN(error >= 0 || thd->is_error());
@@ -1058,8 +1056,7 @@ bool multi_delete::send_eof()
 
   if (!local_error)
   {
-    thd->row_count_func= deleted;
-    ::my_ok(thd, (ha_rows) thd->row_count_func);
+    ::my_ok(thd, deleted);
   }
   return 0;
 }

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2010-04-07 12:02:19 +0000
+++ b/sql/sql_insert.cc	2010-05-14 05:29:47 +0000
@@ -1005,10 +1005,10 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
   if (values_list.elements == 1 && (!(thd->variables.option_bits & OPTION_WARNINGS) ||
 				    !thd->cuted_fields))
   {
-    thd->row_count_func= info.copied + info.deleted +
-                         ((thd->client_capabilities & CLIENT_FOUND_ROWS) ?
-                          info.touched : info.updated);
-    my_ok(thd, (ulong) thd->row_count_func, id);
+    my_ok(thd, info.copied + info.deleted +
+               ((thd->client_capabilities & CLIENT_FOUND_ROWS) ?
+                info.touched : info.updated),
+          id);
   }
   else
   {
@@ -1024,8 +1024,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
       sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
 	      (ulong) (info.deleted + updated),
               (ulong) thd->warning_info->statement_warn_count());
-    thd->row_count_func= info.copied + info.deleted + updated;
-    ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
+    ::my_ok(thd, info.copied + info.deleted + updated, id, buff);
   }
   thd->abort_on_warning= 0;
   DBUG_RETURN(FALSE);
@@ -3337,7 +3336,7 @@ bool select_insert::send_eof()
 {
   int error;
   bool const trans_table= table->file->has_transactions();
-  ulonglong id;
+  ulonglong id, row_count;
   bool changed;
   THD::killed_state killed_status= thd->killed;
   DBUG_ENTER("select_insert::send_eof");
@@ -3403,16 +3402,15 @@ bool select_insert::send_eof()
     sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records,
 	    (ulong) (info.deleted+info.updated),
             (ulong) thd->warning_info->statement_warn_count());
-  thd->row_count_func= info.copied + info.deleted +
-                       ((thd->client_capabilities & CLIENT_FOUND_ROWS) ?
-                        info.touched : info.updated);
-
+  row_count= info.copied + info.deleted +
+             ((thd->client_capabilities & CLIENT_FOUND_ROWS) ?
+              info.touched : info.updated);
   id= (thd->first_successful_insert_id_in_cur_stmt > 0) ?
     thd->first_successful_insert_id_in_cur_stmt :
     (thd->arg_of_last_insert_id_function ?
      thd->first_successful_insert_id_in_prev_stmt :
      (info.copied ? autoinc_value_of_last_inserted_row : 0));
-  ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
+  ::my_ok(thd, row_count, id, buff);
   DBUG_RETURN(0);
 }
 

=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc	2010-04-19 15:12:28 +0000
+++ b/sql/sql_lex.cc	2010-05-14 18:38:28 +0000
@@ -142,37 +142,64 @@ st_parsing_options::reset()
   allows_derived= TRUE;
 }
 
+
+/**
+  Perform initialization of Lex_input_stream instance.
+
+  Basically, a buffer for pre-processed query. This buffer should be large
+  enough to keep multi-statement query. The allocation is done once in the
+  Lex_input_stream constructor in order to prevent memory pollution when
+  the server is processing large multi-statement queries.
+
+  @todo Check return value of THD::alloc().
+*/
+
 Lex_input_stream::Lex_input_stream(THD *thd,
                                    const char* buffer,
                                    unsigned int length)
-: m_thd(thd),
-  yylineno(1),
-  yytoklen(0),
-  yylval(NULL),
-  lookahead_token(-1),
-  lookahead_yylval(NULL),
-  m_ptr(buffer),
-  m_tok_start(NULL),
-  m_tok_end(NULL),
-  m_end_of_query(buffer + length),
-  m_tok_start_prev(NULL),
-  m_buf(buffer),
-  m_buf_length(length),
-  m_echo(TRUE),
-  m_cpp_tok_start(NULL),
-  m_cpp_tok_start_prev(NULL),
-  m_cpp_tok_end(NULL),
-  m_body_utf8(NULL),
-  m_cpp_utf8_processed_ptr(NULL),
-  next_state(MY_LEX_START),
-  found_semicolon(NULL),
-  ignore_space(test(thd->variables.sql_mode & MODE_IGNORE_SPACE)),
-  stmt_prepare_mode(FALSE),
-  multi_statements(TRUE),
-  in_comment(NO_COMMENT),
-  m_underscore_cs(NULL)
+  :m_thd(thd)
 {
   m_cpp_buf= (char*) thd->alloc(length + 1);
+  reset(buffer, length);
+}
+
+
+/**
+  Prepare Lex_input_stream instance state for use for handling next SQL statement.
+
+  It should be called between two statements in a multi-statement query.
+  The operation resets the input stream to the beginning-of-parse state,
+  but does not reallocate m_cpp_buf.
+*/
+
+void
+Lex_input_stream::reset(const char *buffer, unsigned int length)
+{
+  yylineno= 1;
+  yytoklen= 0;
+  yylval= NULL;
+  lookahead_token= -1;
+  lookahead_yylval= NULL;
+  m_ptr= buffer;
+  m_tok_start= NULL;
+  m_tok_end= NULL;
+  m_end_of_query= buffer + length;
+  m_tok_start_prev= NULL;
+  m_buf= buffer;
+  m_buf_length= length;
+  m_echo= TRUE;
+  m_cpp_tok_start= NULL;
+  m_cpp_tok_start_prev= NULL;
+  m_cpp_tok_end= NULL;
+  m_body_utf8= NULL;
+  m_cpp_utf8_processed_ptr= NULL;
+  next_state= MY_LEX_START;
+  found_semicolon= NULL;
+  ignore_space= test(m_thd->variables.sql_mode & MODE_IGNORE_SPACE);
+  stmt_prepare_mode= FALSE;
+  multi_statements= TRUE;
+  in_comment=NO_COMMENT;
+  m_underscore_cs= NULL;
   m_cpp_ptr= m_cpp_buf;
 }
 

=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h	2010-04-19 15:12:28 +0000
+++ b/sql/sql_lex.h	2010-05-14 18:38:28 +0000
@@ -1378,6 +1378,8 @@ public:
   Lex_input_stream(THD *thd, const char* buff, unsigned int length);
   ~Lex_input_stream();
 
+  void reset(const char *buff, unsigned int length);
+
   /**
     Set the echo mode.
 
@@ -2207,8 +2209,8 @@ struct LEX: public Query_tables_list
 class Set_signal_information
 {
 public:
-  /** Constructor. */
-  Set_signal_information();
+  /** Empty default constructor, use clear() */
+ Set_signal_information() {} 
 
   /** Copy constructor. */
   Set_signal_information(const Set_signal_information& set);
@@ -2221,7 +2223,7 @@ public:
   void clear();
 
   /**
-    For each contition item assignment, m_item[] contains the parsed tree
+    For each condition item assignment, m_item[] contains the parsed tree
     that represents the expression assigned, if any.
     m_item[] is an array indexed by Diag_condition_item_name.
   */
@@ -2238,8 +2240,16 @@ class Yacc_state
 {
 public:
   Yacc_state()
-    : yacc_yyss(NULL), yacc_yyvs(NULL)
-  {}
+  {
+    reset();
+  }
+
+  void reset()
+  {
+    yacc_yyss= NULL;
+    yacc_yyvs= NULL;
+    m_set_signal_info.clear();
+  }
 
   ~Yacc_state();
 
@@ -2284,6 +2294,12 @@ public:
 
   Lex_input_stream m_lip;
   Yacc_state m_yacc;
+
+  void reset(const char *found_semicolon, unsigned int length)
+  {
+    m_lip.reset(found_semicolon, length);
+    m_yacc.reset();
+  }
 };
 
 

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2010-04-26 09:06:35 +0000
+++ b/sql/sql_parse.cc	2010-05-14 18:38:28 +0000
@@ -274,22 +274,20 @@ void init_update_queries(void)
   sql_command_flags[SQLCOM_CREATE_TRIGGER]= CF_AUTO_COMMIT_TRANS;
   sql_command_flags[SQLCOM_DROP_TRIGGER]=   CF_AUTO_COMMIT_TRANS;
 
-  sql_command_flags[SQLCOM_UPDATE]=	    CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
-                                            CF_REEXECUTION_FRAGILE | CF_PROTECT_AGAINST_GRL;
-  sql_command_flags[SQLCOM_UPDATE_MULTI]=   CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
-                                            CF_REEXECUTION_FRAGILE | CF_PROTECT_AGAINST_GRL;
-  sql_command_flags[SQLCOM_INSERT]=	    CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
-                                            CF_REEXECUTION_FRAGILE | CF_PROTECT_AGAINST_GRL;
-  sql_command_flags[SQLCOM_INSERT_SELECT]=  CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
-                                            CF_REEXECUTION_FRAGILE | CF_PROTECT_AGAINST_GRL;
-  sql_command_flags[SQLCOM_DELETE]=         CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
-                                            CF_REEXECUTION_FRAGILE | CF_PROTECT_AGAINST_GRL;
-  sql_command_flags[SQLCOM_DELETE_MULTI]=   CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
-                                            CF_REEXECUTION_FRAGILE | CF_PROTECT_AGAINST_GRL;
-  sql_command_flags[SQLCOM_REPLACE]=        CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
-                                            CF_REEXECUTION_FRAGILE;
-  sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
-                                            CF_REEXECUTION_FRAGILE;
+  sql_command_flags[SQLCOM_UPDATE]=	    CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
+                                            CF_PROTECT_AGAINST_GRL;
+  sql_command_flags[SQLCOM_UPDATE_MULTI]=   CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
+                                            CF_PROTECT_AGAINST_GRL;
+  sql_command_flags[SQLCOM_INSERT]=	    CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
+                                            CF_PROTECT_AGAINST_GRL;
+  sql_command_flags[SQLCOM_INSERT_SELECT]=  CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
+                                            CF_PROTECT_AGAINST_GRL;
+  sql_command_flags[SQLCOM_DELETE]=         CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
+                                            CF_PROTECT_AGAINST_GRL;
+  sql_command_flags[SQLCOM_DELETE_MULTI]=   CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
+                                            CF_PROTECT_AGAINST_GRL;
+  sql_command_flags[SQLCOM_REPLACE]=        CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
+  sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
   sql_command_flags[SQLCOM_SELECT]=         CF_REEXECUTION_FRAGILE;
   sql_command_flags[SQLCOM_SET_OPTION]=     CF_REEXECUTION_FRAGILE | CF_AUTO_COMMIT_TRANS;
   sql_command_flags[SQLCOM_DO]=             CF_REEXECUTION_FRAGILE;
@@ -367,8 +365,7 @@ void init_update_queries(void)
     last called (or executed) statement is preserved.
     See mysql_execute_command() for how CF_ROW_COUNT is used.
   */
-  sql_command_flags[SQLCOM_CALL]=      CF_HAS_ROW_COUNT | CF_REEXECUTION_FRAGILE;
-  sql_command_flags[SQLCOM_EXECUTE]=   CF_HAS_ROW_COUNT;
+  sql_command_flags[SQLCOM_CALL]=      CF_REEXECUTION_FRAGILE;
 
   /*
     The following admin table operations are allowed
@@ -461,7 +458,6 @@ static void handle_bootstrap_impl(THD *t
 {
   MYSQL_FILE *file= bootstrap_file;
   char *buff;
-  const char* found_semicolon= NULL;
 
   DBUG_ENTER("handle_bootstrap");
 
@@ -534,7 +530,8 @@ static void handle_bootstrap_impl(THD *t
       mode we have only one thread.
     */
     thd->set_time();
-    mysql_parse(thd, thd->query(), length, & found_semicolon);
+    Parser_state parser_state(thd, thd->query(), length);
+    mysql_parse(thd, thd->query(), length, &parser_state);
     close_thread_tables(thd);			// Free tables
 
     bootstrap_error= thd->is_error();
@@ -1077,19 +1074,21 @@ bool dispatch_command(enum enum_server_c
                       (char *) thd->security_ctx->host_or_ip);
     char *packet_end= thd->query() + thd->query_length();
     /* 'b' stands for 'buffer' parameter', special for 'my_snprintf' */
-    const char* end_of_stmt= NULL;
 
     general_log_write(thd, command, thd->query(), thd->query_length());
     DBUG_PRINT("query",("%-.4096s",thd->query()));
 #if defined(ENABLED_PROFILING)
     thd->profiling.set_query_source(thd->query(), thd->query_length());
 #endif
+    Parser_state parser_state(thd, thd->query(), thd->query_length());
 
-    mysql_parse(thd, thd->query(), thd->query_length(), &end_of_stmt);
+    mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
 
-    while (!thd->killed && (end_of_stmt != NULL) && ! thd->is_error())
+    while (!thd->killed && (parser_state.m_lip.found_semicolon != NULL) &&
+           ! thd->is_error())
     {
-      char *beginning_of_next_stmt= (char*) end_of_stmt;
+      char *beginning_of_next_stmt= (char*)
+        parser_state.m_lip.found_semicolon;
 
       thd->protocol->end_statement();
       query_cache_end_of_result(thd);
@@ -1130,8 +1129,9 @@ bool dispatch_command(enum enum_server_c
       */
       statistic_increment(thd->status_var.questions, &LOCK_status);
       thd->set_time(); /* Reset the query start time. */
+      parser_state.reset(beginning_of_next_stmt, length);
       /* TODO: set thd->lex->sql_command to SQLCOM_END here */
-      mysql_parse(thd, beginning_of_next_stmt, length, &end_of_stmt);
+      mysql_parse(thd, beginning_of_next_stmt, length, &parser_state);
     }
 
     DBUG_PRINT("info",("query ready"));
@@ -3184,7 +3184,7 @@ end_with_restore_list:
     res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
 		      lex->update_list, lex->value_list,
                       lex->duplicates, lex->ignore);
-    MYSQL_INSERT_DONE(res, (ulong) thd->row_count_func);
+    MYSQL_INSERT_DONE(res, (ulong) thd->get_row_count_func());
     /*
       If we have inserted into a VIEW, and the base table has
       AUTO_INCREMENT column, but this column is not accessible through
@@ -3250,7 +3250,7 @@ end_with_restore_list:
         delete sel_result;
       }
       /* revert changes for SP */
-      MYSQL_INSERT_SELECT_DONE(res, (ulong) thd->row_count_func);
+      MYSQL_INSERT_SELECT_DONE(res, (ulong) thd->get_row_count_func());
       select_lex->table_list.first= (uchar*) first_table;
     }
     /*
@@ -3296,7 +3296,7 @@ end_with_restore_list:
                        &select_lex->order_list,
                        unit->select_limit_cnt, select_lex->options,
                        FALSE);
-    MYSQL_DELETE_DONE(res, (ulong) thd->row_count_func);
+    MYSQL_DELETE_DONE(res, (ulong) thd->get_row_count_func());
     break;
   }
   case SQLCOM_DELETE_MULTI:
@@ -4299,8 +4299,9 @@ create_sp_error:
         thd->server_status&= ~bits_to_be_cleared;
 
 	if (!res)
-          my_ok(thd, (ulong) (thd->row_count_func < 0 ? 0 :
-                              thd->row_count_func));
+        {
+          my_ok(thd, (thd->get_row_count_func() < 0) ? 0 : thd->get_row_count_func());
+        }
 	else
         {
           DBUG_ASSERT(thd->is_error() || thd->killed);
@@ -4687,15 +4688,6 @@ create_sp_error:
   if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION)
     reset_one_shot_variables(thd);
 
-  /*
-    The return value for ROW_COUNT() is "implementation dependent" if the
-    statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
-    wants. We also keep the last value in case of SQLCOM_CALL or
-    SQLCOM_EXECUTE.
-  */
-  if (!(sql_command_flags[lex->sql_command] & CF_HAS_ROW_COUNT))
-    thd->row_count_func= -1;
-
   goto finish;
 
 error:
@@ -5732,7 +5724,7 @@ void mysql_init_multi_delete(LEX *lex)
 */
 
 void mysql_parse(THD *thd, const char *inBuf, uint length,
-                 const char ** found_semicolon)
+                 Parser_state *parser_state)
 {
   int error;
   DBUG_ENTER("mysql_parse");
@@ -5762,10 +5754,7 @@ void mysql_parse(THD *thd, const char *i
   {
     LEX *lex= thd->lex;
 
-    Parser_state parser_state(thd, inBuf, length);
-
-    bool err= parse_sql(thd, & parser_state, NULL);
-    *found_semicolon= parser_state.m_lip.found_semicolon;
+    bool err= parse_sql(thd, parser_state, NULL);
 
     if (!err)
     {
@@ -5780,6 +5769,7 @@ void mysql_parse(THD *thd, const char *i
       {
 	if (! thd->is_error())
 	{
+          const char *found_semicolon= parser_state->m_lip.found_semicolon;
           /*
             Binlog logs a string starting from thd->query and having length
             thd->query_length; so we set thd->query_length correctly (to not
@@ -5790,12 +5780,12 @@ void mysql_parse(THD *thd, const char *i
             PROCESSLIST.
             Note that we don't need LOCK_thread_count to modify query_length.
           */
-          if (*found_semicolon && (ulong) (*found_semicolon - thd->query()))
+          if (found_semicolon && (ulong) (found_semicolon - thd->query()))
             thd->set_query_inner(thd->query(),
-                                 (uint32) (*found_semicolon -
+                                 (uint32) (found_semicolon -
                                            thd->query() - 1));
           /* Actually execute the query */
-          if (*found_semicolon)
+          if (found_semicolon)
           {
             lex->safe_to_cache_query= 0;
             thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
@@ -5832,11 +5822,6 @@ void mysql_parse(THD *thd, const char *i
     thd->cleanup_after_query();
     DBUG_ASSERT(thd->change_list.is_empty());
   }
-  else
-  {
-    /* There are no multi queries in the cache. */
-    *found_semicolon= NULL;
-  }
 
   DBUG_VOID_RETURN;
 }

=== modified file 'sql/sql_parse.h'
--- a/sql/sql_parse.h	2010-04-12 13:17:37 +0000
+++ b/sql/sql_parse.h	2010-05-14 18:11:25 +0000
@@ -84,7 +84,7 @@ bool is_log_table_write_query(enum enum_
 bool alloc_query(THD *thd, const char *packet, uint packet_length);
 void mysql_init_select(LEX *lex);
 void mysql_parse(THD *thd, const char *inBuf, uint length,
-                 const char ** semicolon);
+                 Parser_state *parser_state);
 void mysql_reset_thd_for_next_command(THD *thd);
 bool mysql_new_select(LEX *lex, bool move_down);
 void create_select_for_variable(const char *var_name);

=== modified file 'sql/sql_signal.cc'
--- a/sql/sql_signal.cc	2010-03-31 14:05:33 +0000
+++ b/sql/sql_signal.cc	2010-05-14 18:11:25 +0000
@@ -75,10 +75,6 @@ const LEX_STRING Diag_statement_item_nam
   { C_STRING_WITH_LEN("TRANSACTION_ACTIVE") }
 };
 
-Set_signal_information::Set_signal_information()
-{
-  clear();
-}
 
 Set_signal_information::Set_signal_information(
   const Set_signal_information& set)
@@ -458,8 +454,20 @@ bool Signal_statement::execute(THD *thd)
 
   DBUG_ENTER("Signal_statement::execute");
 
+  /*
+    WL#2110 SIGNAL specification says:
+
+      When SIGNAL is executed, it has five effects, in the following order:
+
+        (1) First, the diagnostics area is completely cleared. So if the
+        SIGNAL is in a DECLARE HANDLER then any pending errors or warnings
+        are gone. So is 'row count'.
+
+    This has roots in the SQL standard specification for SIGNAL.
+  */
+
   thd->stmt_da->reset_diagnostics_area();
-  thd->row_count_func= 0;
+  thd->set_row_count_func(0);
   thd->warning_info->clear_warning_info(thd->query_id);
 
   result= raise_condition(thd, &cond);

=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc	2010-04-21 07:35:37 +0000
+++ b/sql/sql_update.cc	2010-05-14 05:29:47 +0000
@@ -843,9 +843,8 @@ int mysql_update(THD *thd,
     my_snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found,
                 (ulong) updated,
                 (ulong) thd->warning_info->statement_warn_count());
-    thd->row_count_func=
-      (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
-    my_ok(thd, (ulong) thd->row_count_func, id, buff);
+    my_ok(thd, (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated,
+          id, buff);
     DBUG_PRINT("info",("%ld records updated", (long) updated));
   }
   thd->count_cuted_fields= CHECK_FIELD_IGNORE;		/* calc cuted fields */
@@ -2150,8 +2149,7 @@ bool multi_update::send_eof()
     thd->first_successful_insert_id_in_prev_stmt : 0;
   my_snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO),
               (ulong) found, (ulong) updated, (ulong) thd->cuted_fields);
-  thd->row_count_func=
-    (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
-  ::my_ok(thd, (ulong) thd->row_count_func, id, buff);
+  ::my_ok(thd, (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated,
+          id, buff);
   DBUG_RETURN(FALSE);
 }

=== modified file 'storage/perfschema/pfs_engine_table.cc'
--- a/storage/perfschema/pfs_engine_table.cc	2010-05-13 14:23:08 +0000
+++ b/storage/perfschema/pfs_engine_table.cc	2010-05-18 05:58:04 +0000
@@ -36,6 +36,7 @@
 /* For show status */
 #include "pfs_column_values.h"
 #include "pfs_instr.h"
+#include "pfs_global.h"
 
 #include "sql_base.h"                           // close_thread_tables
 #include "lock.h"                               // MYSQL_LOCK_IGNORE_TIMEOUT
@@ -701,6 +702,7 @@ bool pfs_show_status(handlerton *hton, T
     case 40:
       name= "(PFS_FILE_HANDLE).MEMORY";
       size= file_handle_max * sizeof(PFS_file*);
+      total_memory+= size;
       break;
     case 41:
       name= "EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME.ROW_SIZE";
@@ -715,13 +717,41 @@ bool pfs_show_status(handlerton *hton, T
       size= thread_max * instr_class_per_thread * sizeof(PFS_single_stat_chain);
       total_memory+= size;
       break;
+    case 44:
+      name= "(PFS_TABLE_SHARE).ROW_SIZE";
+      size= sizeof(PFS_table_share);
+      break;
+    case 45:
+      name= "(PFS_TABLE_SHARE).ROW_COUNT";
+      size= table_share_max;
+      break;
+    case 46:
+      name= "(PFS_TABLE_SHARE).MEMORY";
+      size= table_share_max * sizeof(PFS_table_share);
+      total_memory+= size;
+      break;
+    case 47:
+      name= "(PFS_TABLE).ROW_SIZE";
+      size= sizeof(PFS_table);
+      break;
+    case 48:
+      name= "(PFS_TABLE).ROW_COUNT";
+      size= table_max;
+      break;
+    case 49:
+      name= "(PFS_TABLE).MEMORY";
+      size= table_max * sizeof(PFS_table);
+      total_memory+= size;
+      break;
     /*
       This case must be last,
       for aggregation in total_memory.
     */
-    case 44:
+    case 50:
       name= "PERFORMANCE_SCHEMA.MEMORY";
       size= total_memory;
+      /* This will fail if something is not advertised here */
+      DBUG_ASSERT(size == pfs_allocated_memory);
       break;
     default:
       goto end;

=== modified file 'storage/perfschema/pfs_global.cc'
--- a/storage/perfschema/pfs_global.cc	2010-04-19 12:26:29 +0000
+++ b/storage/perfschema/pfs_global.cc	2010-05-11 14:19:09 +0000
@@ -26,6 +26,7 @@
 #include <string.h>
 
 bool pfs_initialized= false;
+ulonglong pfs_allocated_memory= 0;
 
 /**
   Memory allocation for the performance schema.
@@ -38,7 +39,9 @@ void *pfs_malloc(size_t size, myf flags)
   DBUG_ASSERT(size > 0);
 
   void *ptr= malloc(size);
-  if (ptr && (flags & MY_ZEROFILL))
+  if (likely(ptr != NULL))
+    pfs_allocated_memory+= size;
+  if (likely((ptr != NULL) && (flags & MY_ZEROFILL)))
     memset(ptr, 0, size);
   return ptr;
 }

=== modified file 'storage/perfschema/pfs_global.h'
--- a/storage/perfschema/pfs_global.h	2010-04-14 09:54:35 +0000
+++ b/storage/perfschema/pfs_global.h	2010-05-11 14:19:09 +0000
@@ -22,6 +22,7 @@
 */
 
 extern bool pfs_initialized;
+extern ulonglong pfs_allocated_memory;
 
 void *pfs_malloc(size_t size, myf flags);
 #define PFS_MALLOC_ARRAY(n, T, f) \


Attachment: [text/bzr-bundle] bzr/marc.alff@oracle.com-20100518055804-qzvqtqfpkjyylp3i.bundle
Thread
bzr commit into mysql-next-mr-bugfixing branch (marc.alff:3177) Marc Alff18 May