[Commits] Rev 3393: Temporary commit for MDEV-28 in file:///home/tsk/mprog/src/5.3-md-28-limit/

timour at askmonty.org timour at askmonty.org
Tue Jan 24 17:56:04 EET 2012


At file:///home/tsk/mprog/src/5.3-md-28-limit/

------------------------------------------------------------
revno: 3393
revision-id: timour at askmonty.org-20120124155540-9wxlaxzudpo7j9ma
parent: igor at askmonty.org-20120122205430-xhmu8rw8qz7xppzl
committer: timour at askmonty.org
branch nick: 5.3-md-28-limit
timestamp: Tue 2012-01-24 17:55:40 +0200
message:
  Temporary commit for MDEV-28
  https://mariadb.atlassian.net/browse/MDEV-28
-------------- next part --------------
=== modified file 'sql/lex.h'
--- a/sql/lex.h	2011-12-11 09:34:44 +0000
+++ b/sql/lex.h	2012-01-24 15:55:40 +0000
@@ -302,6 +302,7 @@ static SYMBOL symbols[] = {
   { "LEVEL",            SYM(LEVEL_SYM)},
   { "LIKE",             SYM(LIKE)},
   { "LIMIT",            SYM(LIMIT)},
+  { "LIMIT_ROWS_EXAMINED",SYM(LIMIT_ROWS_EXAMINED)},
   { "LINEAR",           SYM(LINEAR_SYM)},
   { "LINES",            SYM(LINES)},
   { "LINESTRING",       SYM(LINESTRING)},

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2012-01-13 12:35:49 +0000
+++ b/sql/mysqld.cc	2012-01-24 15:55:40 +0000
@@ -2774,6 +2774,9 @@ the thread stack. Please read http://dev
     case KILL_SERVER_HARD:
       kreason= "KILL_SERVER";
       break;
+    case ABORT_QUERY:
+      kreason= "ABORT_QUERY";
+      break;
     }
     fprintf(stderr, "\nTrying to get some variables.\n"
                     "Some pointers may be invalid and cause the dump to abort.\n");

=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt	2011-12-11 09:34:44 +0000
+++ b/sql/share/errmsg.txt	2012-01-24 15:55:40 +0000
@@ -6296,4 +6296,6 @@ ER_INTERNAL_ERROR
         eng "Internal error: '%-.192s'"
 ER_SPATIAL_MUST_HAVE_GEOM_COL 42000
   eng "A SPATIAL index may only contain a geometrical type column"
+ER_QUERY_EXCEEDED_EXAMINED_ROWS_LIMIT
+        eng "Query execution was interrupted. The query examined %ld rows, which exceeds LIMIT_ROWS_EXAMINED. The query result is incomplete."
 

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2011-12-11 16:39:33 +0000
+++ b/sql/sql_class.cc	2012-01-24 15:55:40 +0000
@@ -675,6 +675,7 @@ THD::THD()
    first_successful_insert_id_in_cur_stmt(0),
    stmt_depends_on_first_successful_insert_id_in_prev_stmt(FALSE),
    examined_row_count(0),
+   examined_rows_limit_cnt(HA_POS_ERROR),
    global_read_lock(0),
    global_disable_checkpoint(0),
    is_fatal_error(0),
@@ -1391,6 +1392,8 @@ int killed_errno(killed_state killed)
   case KILL_SERVER:
   case KILL_SERVER_HARD:
     return ER_SERVER_SHUTDOWN;
+  case ABORT_QUERY:
+    return 0;
   }
   return 0;                                     // Keep compiler happy
 }

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2012-01-13 12:35:49 +0000
+++ b/sql/sql_class.h	2012-01-24 15:55:40 +0000
@@ -374,16 +374,17 @@ enum killed_state
   KILL_BAD_DATA_HARD= 3,
   KILL_QUERY= 4,
   KILL_QUERY_HARD= 5,
+  ABORT_QUERY= 6,
   /*
     All of the following killed states will kill the connection
     KILL_CONNECTION must be the first of these!
   */
-  KILL_CONNECTION= 6,
-  KILL_CONNECTION_HARD= 7,
-  KILL_SYSTEM_THREAD= 8,
-  KILL_SYSTEM_THREAD_HARD= 9,
-  KILL_SERVER= 10,
-  KILL_SERVER_HARD= 11
+  KILL_CONNECTION= 7,
+  KILL_CONNECTION_HARD= 8,
+  KILL_SYSTEM_THREAD= 9,
+  KILL_SYSTEM_THREAD_HARD= 10,
+  KILL_SERVER= 11,
+  KILL_SERVER_HARD= 12
 };
 
 extern int killed_errno(killed_state killed);
@@ -639,6 +640,7 @@ typedef struct system_status_var
   ulonglong rows_sent;
   ulonglong rows_tmp_read;
   ulonglong binlog_bytes_written;
+  ulonglong accessed_rows_and_keys;
   double last_query_cost;
   double cpu_time, busy_time;
 } STATUS_VAR;
@@ -1947,6 +1949,26 @@ class THD :public Statement,
     filesort() before reading it for e.g. update.
   */
   ha_rows    examined_row_count;
+  /**
+    Number of rows and/or keys examined by the query, both read, changed
+    or written.
+  */
+  ha_rows examined_rows_limit_cnt;
+  /**
+    Check if the number of rows accessed by a statement exceeded
+    LIMIT_ROWS_EXAMINED. If so, stop execution.
+  */
+  void check_examined_rows_limit()
+  {
+    if (++status_var.accessed_rows_and_keys > examined_rows_limit_cnt)
+    {
+      push_warning_printf(this, MYSQL_ERROR::WARN_LEVEL_WARN,
+                          ER_QUERY_EXCEEDED_EXAMINED_ROWS_LIMIT,
+                          ER(ER_QUERY_EXCEEDED_EXAMINED_ROWS_LIMIT),
+                          status_var.accessed_rows_and_keys);
+      killed= ABORT_QUERY;
+    }
+  }
 
   USER_CONN *user_connect;
   CHARSET_INFO *db_charset;
@@ -3636,6 +3659,8 @@ void mark_transaction_to_rollback(THD *t
 inline void handler::increment_statistics(ulong SSV::*offset) const
 {
   status_var_increment(table->in_use->status_var.*offset);
+  if (table->in_use->examined_rows_limit_cnt < HA_POS_ERROR)
+    table->in_use->check_examined_rows_limit();
 }
 
 inline void handler::decrement_statistics(ulong SSV::*offset) const

=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc	2011-12-11 17:28:05 +0000
+++ b/sql/sql_lex.cc	2012-01-24 15:55:40 +0000
@@ -1674,6 +1674,7 @@ void st_select_lex::init_select()
   /* Set limit and offset to default values */
   select_limit= 0;      /* denotes the default limit = HA_POS_ERROR */
   offset_limit= 0;      /* denotes the default offset = 0 */
+  examined_rows_limit= 0; /* denotes the default limit = HA_POS_ERROR */
   with_sum_func= 0;
   is_correlated= 0;
   cur_pos_in_select_list= UNDEF_POS;
@@ -2581,6 +2582,14 @@ void st_select_lex_unit::set_limit(st_se
   select_limit_cnt= select_limit_val + offset_limit_cnt;
   if (select_limit_cnt < select_limit_val)
     select_limit_cnt= HA_POS_ERROR;             // no limit
+
+  val= sl->examined_rows_limit ? sl->examined_rows_limit->val_uint() : HA_POS_ERROR;
+  thd->examined_rows_limit_cnt= (ha_rows)val;
+#ifndef BIG_TABLES
+  /* Check for truncation. */
+  if (val != (ulonglong)thd->examined_rows_limit_cnt)
+    thd->examined_rows_limit_cnt= HA_POS_ERROR;
+#endif
 }
 
 

=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h	2011-12-11 16:39:33 +0000
+++ b/sql/sql_lex.h	2012-01-24 15:55:40 +0000
@@ -657,6 +657,7 @@ class st_select_lex: public st_select_le
   SQL_I_List<ORDER> order_list;   /* ORDER clause */
   SQL_I_List<ORDER> *gorder_list;
   Item *select_limit, *offset_limit;  /* LIMIT clause parameters */
+  Item *examined_rows_limit; /* LIMIT_ROWS_EXAMINED parameter */
   // Arrays of pointers to top elements of all_fields list
   Item **ref_pointer_array;
 

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2011-12-13 12:00:20 +0000
+++ b/sql/sql_parse.cc	2012-01-24 15:55:40 +0000
@@ -2220,7 +2220,8 @@ mysql_execute_command(THD *thd)
   status_var_increment(thd->status_var.com_stat[lex->sql_command]);
   thd->progress.report_to_client= test(sql_command_flags[lex->sql_command] &
                                        CF_REPORT_PROGRESS);
-
+  thd->status_var.accessed_rows_and_keys= 0;
+  
   DBUG_ASSERT(thd->transaction.stmt.modified_non_trans_table == FALSE);
   
   switch (lex->sql_command) {
@@ -6048,6 +6049,7 @@ void mysql_init_multi_delete(LEX *lex)
   mysql_init_select(lex);
   lex->select_lex.select_limit= 0;
   lex->unit.select_limit_cnt= HA_POS_ERROR;
+  lex->select_lex.examined_rows_limit= 0;
   lex->select_lex.table_list.save_and_clear(&lex->auxiliary_table_list);
   lex->lock_option= TL_READ_DEFAULT;
   lex->query_tables= 0;
@@ -6797,6 +6799,7 @@ bool st_select_lex_unit::add_fake_select
   fake_select_lex->make_empty_select();
   fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE;
   fake_select_lex->select_limit= 0;
+  fake_select_lex->examined_rows_limit= 0;
 
   fake_select_lex->context.outer_context=first_sl->context.outer_context;
   /* allow item list resolving in fake select for ORDER BY */

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2012-01-19 22:11:53 +0000
+++ b/sql/sql_select.cc	2012-01-24 15:55:40 +0000
@@ -15027,6 +15027,11 @@ do_select(JOIN *join,List<Item> *fields,
   }
   if (error == NESTED_LOOP_NO_MORE_ROWS)
     error= NESTED_LOOP_OK;
+  if (join->thd->killed == ABORT_QUERY)
+  {
+    error= NESTED_LOOP_OK; 
+    join->thd->killed= NOT_KILLED;
+  }
 
   if (table == NULL)                            // If sending data to client
   {

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2011-12-11 09:34:44 +0000
+++ b/sql/sql_yacc.yy	2012-01-24 15:55:40 +0000
@@ -687,7 +687,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
   Currently there are 174 shift/reduce conflicts.
   We should not introduce new conflicts any more.
 */
-%expect 174
+%expect 177
 
 /*
    Comments for TOKENS.
@@ -961,6 +961,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %token  LEX_HOSTNAME
 %token  LIKE                          /* SQL-2003-R */
 %token  LIMIT
+%token  LIMIT_ROWS_EXAMINED
 %token  LINEAR_SYM
 %token  LINES
 %token  LINESTRING
@@ -9620,6 +9621,7 @@ rule: <-- starts at col 1
             SELECT_LEX *sel= lex->current_select;
             sel->offset_limit= 0;
             sel->select_limit= 0;
+            sel->examined_rows_limit= 0;
           }
         | limit_clause {}
         ;
@@ -9631,6 +9633,12 @@ rule: <-- starts at col 1
 
 limit_clause:
           LIMIT limit_options {}
+          /* TODO: make it possible to mix both LIMIT clauses. */
+        | LIMIT_ROWS_EXAMINED limit_option
+          {
+            SELECT_LEX *sel= Select;
+            sel->examined_rows_limit= $2;
+          }
         ;
 
 limit_options:
@@ -9687,6 +9695,7 @@ rule: <-- starts at col 1
           {
             LEX *lex=Lex;
             lex->current_select->select_limit= 0;
+            lex->current_select->examined_rows_limit= 0;
           }
         | LIMIT limit_option
           {
@@ -13011,6 +13020,7 @@ select_var_ident:
               MYSQL_YYABORT;
             lex->current_select->select_limit= one;
             lex->current_select->offset_limit= 0;
+            lex->current_select->examined_rows_limit= 0;
             if (!lex->current_select->add_table_to_list(lex->thd, $2, 0, 0))
               MYSQL_YYABORT;
           }



More information about the commits mailing list