Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-28

LIMIT ROWS EXAMINED clause to limit the number of rows examined during SELECT processing

Details

    • Task
    • Status: Closed (View Workflow)
    • Major
    • Resolution: Fixed
    • 5.5.21
    • None

    Description

      Description:

      The purpose of this task is to provide the means to terminate the execution of SELECT statements that examines too many rows, and thus uses too much resources. This is achieved through an extension of the LIMIT clause - LIMIT ROWS EXAMINED <number_of_rows>. Whenever possible the semantics of LIMIT ROWS EXAMINED is the same as that of normal LIMIT (for instance for aggregate functions).

      The current syntax for the clause is:

      SELECT ... FROM ... WHERE ...
      [group_clause] [order_clause]
      LIMIT [[offset,] row_count] ROWS EXAMINED rows_limit;

      Similar to the parameters of LIMIT, 'rows_limit' can be both a prepared statement parameter, or a stored program parameter.

      A simple example of the clause is:

      SELECT * from t1, t2 LIMIT 10 ROWS EXAMINED 10000;

      The LIMIT ROWS EXAMINED clause is global for the whole statement. If a composite query (such as UNION, or query with derived tables or with subqueries) contains more than one LIMIT ROWS EXAMINED, the last one parsed is taken into account. In this manner either the last or the outermost one is taken into account. For instance, in the query:

      SELECT * FROM t1
      WHERE c1 IN (SELECT * FROM t2 WHERE c2 > ' ' LIMIT ROWS EXAMINED 0)
      LIMIT ROWS EXAMINED 11;

      The limit that is taken into account is 11, not 0.

      The LIMIT ROWS EXAMINED clause is taken into account by the query engine only during query execution. Thus the clause is ignored in the following cases:

      • If a query is EXPLAIN-ed.
      • During query optimization.
      • During auxiliary operations such as writing to system tables (e.g. logs).

      The clause is not applicable to DELETE/UPDATE statements, and if used in these statements produces a syntax error.

      The effects of this clause are as follows:

      • The server counts the number of read, inserted, modified, and deleted rows during query execution. This takes into account the use of temporary tables, and sorting for intermediate query operations.
      • Once the counter exceeds the value specified in the LIMIT ROWS EXAMINED clause, query execution is terminated as soon as possible.
      • The effects of terminating the query because of LIMIT ROWS EXAMINED are as follows:
        • The result of the query is a subset of the complete query, depending on when the query engine detected that the limit was reached. The result may be empty if no result rows could be computed before reaching the limit.
        • A warning is generated of the form: "Query execution was interrupted. The query examined at least 100 rows, which exceeds LIMIT ROWS EXAMINED (20). The query result may be incomplete."
        • If query processing was interrupted during filesort, an error is returned in addition to the warning.
        • If a UNION was interrupted during execution of one of its queries, the last step of the UNION is still executed in order to produce a partial result.
        • Depending on the join and other execution strategies used for a query, the same query may produce no result at all, or a different subset of the complete result when terminated due to LIMIT ROWS EXAMINED.
        • If the query contains a GROUP BY clause, the last group where the limit was reached will be discarded.

      The LIMIT ROWS EXAMINED clause cannot be specified on per-subquery basis. There can be only one LIMIT ROWS EXAMINED clause for the whole SELECT statement. If a SELECT statement contains several subqueries with LIMIT ROWS EXAMINED, the one that is parsed last is taken into account.

      Low-level design:

      The implementation has the following aspects:

      1. Counting the number of examined rows.
      2. Checking if the limit has been exceeded.
      3. Interrupting query execution.

      These are implemented as follows:

      Counting the number of examined rows.

      The patch introduces a new thread-level counter THD::accessed_rows_and_keys. This counter is increased at each call to any of the family of handler methods handler::ha_*. Therefore this counter is equivalent to the sum of all counters increased by handler::increment_statistics(). Unlike all other handler counters in THD::status_var, accessed_rows_and_keys is reset automatically before each statement.

      The counter is equivalent to the sum of the following handler counters:

      ha_read_key_count, ha_read_next_count, ha_read_prev_count, ha_read_first_count, ha_read_last_count, ha_read_rnd_next_count, ha_read_rnd_count, ha_tmp_write_count, ha_tmp_update_count, ha_write_count, ha_update_count, ha_delete_count.

      These are the counters increased by handler::increment_statistics() which is
      used to increase the counter for LIMIT ROWS EXAMINED.

      Checking if the limit has been exceeded.

      The test if LIMIT_ROWS_EXAMINED has been exceeded is done in the method THD::check_limit_rows_examined(). This method is called by handler::increment_statistics(), which is called in its turn by all methods in the family handler::ha_*.

      Once the limit is exceeded, the handler method sets THD::killed = ABORT_QUERY, where ABORT_QUERY is a new enum in enum killed_state.

      In order not to stop query processing with an error, at the end of handle_select() we test for thd->killed == ABORT_QUERY, and if true,
      issue a warning, and reset the killed state. The warning can be tested with 'show warnings'.

      Interrupting query execution.

      The implementation reuses the fact that the query executioner checks in
      multiple places if THD::killed has been set, and stops execution.

      One goal of this task is to stop execution, but still produce the rows found until LIMIT ROWS EXAMINED was reached. Therefore at the end of the main execution loop, the function handle_select() resets both THD::killed, and removes the limit in order not to affect data accesses needed for system purposes (such as writing to log tables). As a result:

      • query execution is stopped,
      • a warning is generated,
      • the query finishes without an error (except when query execution was
        interrupted during filesort).

      TODO:

      • consider issuing an error (or warning) if there is more than one
        LIMIT ROWS EXAMINED clause in the whole query.

      Attachments

        Issue Links

          Activity

            timour Timour Katchaounov (Inactive) created issue -
            ratzpo Rasmus Johansson (Inactive) made changes -
            Field Original Value New Value
            Issue Type Story [ 6 ] Task [ 3 ]
            serg Sergei Golubchik made changes -
            Labels paid-for
            timour Timour Katchaounov (Inactive) made changes -
            Status Open [ 1 ] In Progress [ 3 ]
            timour Timour Katchaounov (Inactive) made changes -
            Fix Version/s 5.6.1 [ 10000 ]
            timour Timour Katchaounov (Inactive) made changes -
            Description ================================================================================
            Description:
            ================================================================================

            The purpose of this task is to provide the means to terminate the execution of
            SELECT statements that examine too many rows, and thus take too long, and use
            too much resources. This is achieved through a variant of the LIMIT clause,
            LIMIT_ROWS_EXAMINED number_of_rows.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows
              during query execution. This takes into account the use of temporary tables,
              and sorting for intermediate query operations.

            * Once the counter exeeds the value specified in the LIMIT_ROWS_EXAMINED clause
              query execution is terminated as soon as possible, in a manner similar to
              killing the query

            * The effects of terminating the query because of LIMIT_ROWS_EXAMINED are as
              follows:
            ** A warning is generated.
            ** The result of the query is incomplete, and includes rows sent to the client
               before LIMIT_ROWS_EXAMINED was reached.
            ** If the query contains a GROUP BY clause, the last group contains only the
               rows found before query termination. Accordingly aggregate functions take
               into account only these rows.

            Due to the implementation of this feature, the LIMIT_ROWS_EXAMINED clause
            cannot be specified on per-subquery basis. There can be only one
            LIMIT_ROWS_EXAMINED clause for the whole SELECT statement. If a SELECT statement
            contains several subqueries with the LIMIT_ROWS_EXAMINED, the one that is parsed
            last is taken into account.

            ================================================================================
            Low-level design:
            ================================================================================

            TODO:
            * change the implementation so that clause affects only SELECT statements
            * fix the parser:
            ** make it possible to combine LIMIT_ROWS_EXAMINED with LIMIT in all meaningful
               ways,
            ** consider replacing it by 'LIMIT ROWS'
            ** consider limiting the clause to the outer-most statement
            * check why GROUP BY results in two warnings, and error 'sort aborted'
            * add test cases
            * run through QA, fix bugs
            timour Timour Katchaounov (Inactive) made changes -
            Description ================================================================================
            Description:
            ================================================================================

            The purpose of this task is to provide the means to terminate the execution of
            SELECT statements that examine too many rows, and thus take too long, and use
            too much resources. This is achieved through a variant of the LIMIT clause,
            LIMIT_ROWS_EXAMINED number_of_rows.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows
              during query execution. This takes into account the use of temporary tables,
              and sorting for intermediate query operations.

            * Once the counter exeeds the value specified in the LIMIT_ROWS_EXAMINED clause
              query execution is terminated as soon as possible, in a manner similar to
              killing the query

            * The effects of terminating the query because of LIMIT_ROWS_EXAMINED are as
              follows:
            ** A warning is generated.
            ** The result of the query is incomplete, and includes rows sent to the client
               before LIMIT_ROWS_EXAMINED was reached.
            ** If the query contains a GROUP BY clause, the last group contains only the
               rows found before query termination. Accordingly aggregate functions take
               into account only these rows.

            Due to the implementation of this feature, the LIMIT_ROWS_EXAMINED clause
            cannot be specified on per-subquery basis. There can be only one
            LIMIT_ROWS_EXAMINED clause for the whole SELECT statement. If a SELECT statement
            contains several subqueries with the LIMIT_ROWS_EXAMINED, the one that is parsed
            last is taken into account.

            ================================================================================
            Low-level design:
            ================================================================================

            TODO:
            * change the implementation so that clause affects only SELECT statements
            * fix the parser:
            ** make it possible to combine LIMIT_ROWS_EXAMINED with LIMIT in all meaningful
               ways,
            ** consider replacing it by 'LIMIT ROWS'
            ** consider limiting the clause to the outer-most statement
            * check why GROUP BY results in two warnings, and error 'sort aborted'
            * add test cases
            * run through QA, fix bugs
            ================================================================================
            Description:
            ================================================================================

            The purpose of this task is to provide the means to terminate the execution of
            SELECT statements that examine too many rows, and thus take too long, and use
            too much resources. This is achieved through a variant of the LIMIT clause,
            LIMIT_ROWS_EXAMINED number_of_rows.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows
              during query execution. This takes into account the use of temporary tables,
              and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT_ROWS_EXAMINED clause
              query execution is terminated as soon as possible, in a manner similar to
              killing the query

            * The effects of terminating the query because of LIMIT_ROWS_EXAMINED are as
              follows:
            ** A warning is generated.
            ** The result of the query is incomplete, and includes rows sent to the client
               before LIMIT_ROWS_EXAMINED was reached.
            ** Depending on the join and other execution strategies used for a query, the
               same query may produce no result at all, or a different result when
               terminated due to LIMIT_ROWS_EXAMINED.
            ** If the query contains a GROUP BY clause, the last group contains only the
               rows found before query termination. Accordingly aggregate functions take
               into account only these rows.

            Due to the implementation of this feature, the LIMIT_ROWS_EXAMINED clause
            cannot be specified on per-subquery basis. There can be only one
            LIMIT_ROWS_EXAMINED clause for the whole SELECT statement. If a SELECT statement
            contains several subqueries with the LIMIT_ROWS_EXAMINED, the one that is parsed
            last is taken into account.

            ================================================================================
            Low-level design:
            ================================================================================

            TODO:
            * fix failing test cases:
              Failing test(s): rpl.rpl_stop_slave rpl.rpl_start_stop_slave
            * change the implementation so that clause affects only SELECT statements
            * fix the parser:
            ** make it possible to combine LIMIT_ROWS_EXAMINED with LIMIT in all meaningful
               ways,
            ** consider replacing it by 'LIMIT ROWS'
            ** consider limiting the clause to the outer-most statement
            * check why GROUP BY results in two warnings, and error 'sort aborted'
            * add test cases
            * run through QA, fix bugs
            timour Timour Katchaounov (Inactive) made changes -
            Description ================================================================================
            Description:
            ================================================================================

            The purpose of this task is to provide the means to terminate the execution of
            SELECT statements that examine too many rows, and thus take too long, and use
            too much resources. This is achieved through a variant of the LIMIT clause,
            LIMIT_ROWS_EXAMINED number_of_rows.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows
              during query execution. This takes into account the use of temporary tables,
              and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT_ROWS_EXAMINED clause
              query execution is terminated as soon as possible, in a manner similar to
              killing the query

            * The effects of terminating the query because of LIMIT_ROWS_EXAMINED are as
              follows:
            ** A warning is generated.
            ** The result of the query is incomplete, and includes rows sent to the client
               before LIMIT_ROWS_EXAMINED was reached.
            ** Depending on the join and other execution strategies used for a query, the
               same query may produce no result at all, or a different result when
               terminated due to LIMIT_ROWS_EXAMINED.
            ** If the query contains a GROUP BY clause, the last group contains only the
               rows found before query termination. Accordingly aggregate functions take
               into account only these rows.

            Due to the implementation of this feature, the LIMIT_ROWS_EXAMINED clause
            cannot be specified on per-subquery basis. There can be only one
            LIMIT_ROWS_EXAMINED clause for the whole SELECT statement. If a SELECT statement
            contains several subqueries with the LIMIT_ROWS_EXAMINED, the one that is parsed
            last is taken into account.

            ================================================================================
            Low-level design:
            ================================================================================

            TODO:
            * fix failing test cases:
              Failing test(s): rpl.rpl_stop_slave rpl.rpl_start_stop_slave
            * change the implementation so that clause affects only SELECT statements
            * fix the parser:
            ** make it possible to combine LIMIT_ROWS_EXAMINED with LIMIT in all meaningful
               ways,
            ** consider replacing it by 'LIMIT ROWS'
            ** consider limiting the clause to the outer-most statement
            * check why GROUP BY results in two warnings, and error 'sort aborted'
            * add test cases
            * run through QA, fix bugs

            h2. Description:

            The purpose of this task is to provide the means to terminate the execution of
            SELECT statements that examine too many rows, and thus take too long, and use
            too much resources. This is achieved through a variant of the LIMIT clause,
            LIMIT_ROWS_EXAMINED number_of_rows.

            The current syntax for the clause is:

            {code}
            SELECT ... FROM ... WHERE ... LIMIT_ROWS_EXAMINED integer_constant;
            {code}

            NOTICE:
            For simplicity, ATM the clause is parsed as an alternative to the LIMIT clause,
            and cannot be mixed with a LIMIT clause. This is a limitation that will be fixed
            once the rest of the task is accepted.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows
              during query execution. This takes into account the use of temporary tables,
              and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT_ROWS_EXAMINED clause
              query execution is terminated as soon as possible, in a manner similar to
              killing the query

            * The effects of terminating the query because of LIMIT_ROWS_EXAMINED are as
              follows:
            ** A warning is generated.
            ** The result of the query is incomplete, and includes rows sent to the client
               before LIMIT_ROWS_EXAMINED was reached.
            ** Depending on the join and other execution strategies used for a query, the
               same query may produce no result at all, or a different result when
               terminated due to LIMIT_ROWS_EXAMINED.
            ** If the query contains a GROUP BY clause, the last group contains only the
               rows found before query termination. Accordingly aggregate functions take
               into account only these rows.

            Due to the implementation of this feature, the LIMIT_ROWS_EXAMINED clause
            cannot be specified on per-subquery basis. There can be only one
            LIMIT_ROWS_EXAMINED clause for the whole SELECT statement. If a SELECT statement
            contains several subqueries with the LIMIT_ROWS_EXAMINED, the one that is parsed
            last is taken into account.


            h2. Low-level design:

            The implementation has the following aspects:

            # Counting the number of examined rows.
            # Checking if the limit has been exceeded.
            # Interrupting query execution.

            These are implemented as follows:

            h3. Counting the number of examined rows.

            The patch introduces a new thread-level counter
            {{THD::status_var::accessed_rows_and_keys}}. This counter is increased at each
            call to any of the family of handler methods {{handler::ha_*}}. Therefore this
            counter is equivalent to the sum of all counters increased by
            {{handler::increment_statistics()}}. Unlike all other handler counters in
            {{THD::status_var}}, accessed_rows_and_keys is reset automatically before each
            statement.

            h3. Checking if the limit has been exceeded.

            The test if LIMIT_ROWS_EXAMINED has been exceeded is done within each {{handler::ha_*}}
            handler call. Once this happens, the handler method sets {{THD::killed = ABORT_QUERY}},
            and issues a warning that can be tested with 'show warnings'. Here ABORT_QUERY
            is a new enum in {{enum killed_state}}.

            h3. Interrupting query execution.

            The implementation reuses the fact that the query executioner checks in
            multiple places if {{THD::killed}} has been set, and stops execution. One goal
            of this task is to stop execution, but still produce the rows found until
            LIMIT_ROWS_EXAMINED was reached. Therefore at the end of the main execution
            loop, the function {{do_select()}} resets both {{THD::killed}}, and the error
            code propagated from the underlying query execution functions. As a result:

            * execution is stopped,
            * a warning is generated,
            * the query finishes without an error.


            h2. TODO:
            * fix failing test cases:
              Failing test(s): rpl.rpl_stop_slave rpl.rpl_start_stop_slave
              (the cause is the change in the values of enum killed_state because of adding a new
              kill state).
            * change the implementation so that LIMIT_ROWS_EXAMINED affects only SELECT statements
            * fix the parser:
            ** make it possible to combine LIMIT_ROWS_EXAMINED with LIMIT in all meaningful
               ways,
            ** consider replacing it by {{LIMIT ROWS}} or some other more SQL-like clause,
            ** consider limiting the clause to the outer-most SELECT statement.
            * check why GROUP BY results in two warnings, and error 'sort aborted'
            * add test cases
            * run through QA, fix bugs

            Simple test case:

            create table t1 (c1 char(2));
            create table t2 (c2 char(2));

            insert into t1 values ('bb'), ('cc'), ('aa');
            insert into t2 values ('bb'), ('cc'), ('dd');

            select * from t1, t2 where c1 = c2;
            show warnings;

            set @@join_cache_level=0;
            select * from t1, t2 where c1 = c2 LIMIT_ROWS_EXAMINED 2;
            show warnings;

            set @@join_cache_level=1;
            select * from t1, t2 where c1 = c2 LIMIT_ROWS_EXAMINED 2;
            show warnings;

            create table t3 (c1 char(2), c2 int);

            insert into t3 values
            ('aa', 1),
            ('aa', 2),
            ('bb', 3),
            ('bb', 4),
            ('bb', 5);

            select c1, sum(c2) from t3 group by c1;

            select c1, sum(c2) from t3 group by c1 LIMIT_ROWS_EXAMINED 3;
            show warnings;

            timour Timour Katchaounov (Inactive) added a comment - Simple test case: create table t1 (c1 char(2)); create table t2 (c2 char(2)); insert into t1 values ('bb'), ('cc'), ('aa'); insert into t2 values ('bb'), ('cc'), ('dd'); select * from t1, t2 where c1 = c2; show warnings; set @@join_cache_level=0; select * from t1, t2 where c1 = c2 LIMIT_ROWS_EXAMINED 2; show warnings; set @@join_cache_level=1; select * from t1, t2 where c1 = c2 LIMIT_ROWS_EXAMINED 2; show warnings; create table t3 (c1 char(2), c2 int); insert into t3 values ('aa', 1), ('aa', 2), ('bb', 3), ('bb', 4), ('bb', 5); select c1, sum(c2) from t3 group by c1; select c1, sum(c2) from t3 group by c1 LIMIT_ROWS_EXAMINED 3; show warnings;
            timour Timour Katchaounov (Inactive) made changes -
            Description
            h2. Description:

            The purpose of this task is to provide the means to terminate the execution of
            SELECT statements that examine too many rows, and thus take too long, and use
            too much resources. This is achieved through a variant of the LIMIT clause,
            LIMIT_ROWS_EXAMINED number_of_rows.

            The current syntax for the clause is:

            {code}
            SELECT ... FROM ... WHERE ... LIMIT_ROWS_EXAMINED integer_constant;
            {code}

            NOTICE:
            For simplicity, ATM the clause is parsed as an alternative to the LIMIT clause,
            and cannot be mixed with a LIMIT clause. This is a limitation that will be fixed
            once the rest of the task is accepted.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows
              during query execution. This takes into account the use of temporary tables,
              and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT_ROWS_EXAMINED clause
              query execution is terminated as soon as possible, in a manner similar to
              killing the query

            * The effects of terminating the query because of LIMIT_ROWS_EXAMINED are as
              follows:
            ** A warning is generated.
            ** The result of the query is incomplete, and includes rows sent to the client
               before LIMIT_ROWS_EXAMINED was reached.
            ** Depending on the join and other execution strategies used for a query, the
               same query may produce no result at all, or a different result when
               terminated due to LIMIT_ROWS_EXAMINED.
            ** If the query contains a GROUP BY clause, the last group contains only the
               rows found before query termination. Accordingly aggregate functions take
               into account only these rows.

            Due to the implementation of this feature, the LIMIT_ROWS_EXAMINED clause
            cannot be specified on per-subquery basis. There can be only one
            LIMIT_ROWS_EXAMINED clause for the whole SELECT statement. If a SELECT statement
            contains several subqueries with the LIMIT_ROWS_EXAMINED, the one that is parsed
            last is taken into account.


            h2. Low-level design:

            The implementation has the following aspects:

            # Counting the number of examined rows.
            # Checking if the limit has been exceeded.
            # Interrupting query execution.

            These are implemented as follows:

            h3. Counting the number of examined rows.

            The patch introduces a new thread-level counter
            {{THD::status_var::accessed_rows_and_keys}}. This counter is increased at each
            call to any of the family of handler methods {{handler::ha_*}}. Therefore this
            counter is equivalent to the sum of all counters increased by
            {{handler::increment_statistics()}}. Unlike all other handler counters in
            {{THD::status_var}}, accessed_rows_and_keys is reset automatically before each
            statement.

            h3. Checking if the limit has been exceeded.

            The test if LIMIT_ROWS_EXAMINED has been exceeded is done within each {{handler::ha_*}}
            handler call. Once this happens, the handler method sets {{THD::killed = ABORT_QUERY}},
            and issues a warning that can be tested with 'show warnings'. Here ABORT_QUERY
            is a new enum in {{enum killed_state}}.

            h3. Interrupting query execution.

            The implementation reuses the fact that the query executioner checks in
            multiple places if {{THD::killed}} has been set, and stops execution. One goal
            of this task is to stop execution, but still produce the rows found until
            LIMIT_ROWS_EXAMINED was reached. Therefore at the end of the main execution
            loop, the function {{do_select()}} resets both {{THD::killed}}, and the error
            code propagated from the underlying query execution functions. As a result:

            * execution is stopped,
            * a warning is generated,
            * the query finishes without an error.


            h2. TODO:
            * fix failing test cases:
              Failing test(s): rpl.rpl_stop_slave rpl.rpl_start_stop_slave
              (the cause is the change in the values of enum killed_state because of adding a new
              kill state).
            * change the implementation so that LIMIT_ROWS_EXAMINED affects only SELECT statements
            * fix the parser:
            ** make it possible to combine LIMIT_ROWS_EXAMINED with LIMIT in all meaningful
               ways,
            ** consider replacing it by {{LIMIT ROWS}} or some other more SQL-like clause,
            ** consider limiting the clause to the outer-most SELECT statement.
            * check why GROUP BY results in two warnings, and error 'sort aborted'
            * add test cases
            * run through QA, fix bugs
            h2. Description:

            The purpose of this task is to provide the means to terminate the execution of
            SELECT statements that examine too many rows, and thus take too long, and use
            too much resources. This is achieved through a variant of the LIMIT clause,
            LIMIT_ROWS_EXAMINED number_of_rows.

            The current syntax for the clause is:

            {code}
            SELECT ... FROM ... WHERE ... LIMIT_ROWS_EXAMINED integer_constant;
            {code}

            NOTICE:
            For simplicity, ATM the clause is parsed as an alternative to the LIMIT clause,
            and cannot be mixed with a LIMIT clause. This is a limitation that will be fixed
            once the rest of the task is accepted.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows
              during query execution. This takes into account the use of temporary tables,
              and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT_ROWS_EXAMINED clause
              query execution is terminated as soon as possible, in a manner similar to
              killing the query

            * The effects of terminating the query because of LIMIT_ROWS_EXAMINED are as
              follows:
            ** A warning is generated.
            ** The result of the query is incomplete, and includes rows sent to the client
               before LIMIT_ROWS_EXAMINED was reached.
            ** Depending on the join and other execution strategies used for a query, the
               same query may produce no result at all, or a different result when
               terminated due to LIMIT_ROWS_EXAMINED.
            ** If the query contains a GROUP BY clause, the last group contains only the
               rows found before query termination. Accordingly aggregate functions take
               into account only these rows.

            Due to the implementation of this feature, the LIMIT_ROWS_EXAMINED clause
            cannot be specified on per-subquery basis. There can be only one
            LIMIT_ROWS_EXAMINED clause for the whole SELECT statement. If a SELECT statement
            contains several subqueries with the LIMIT_ROWS_EXAMINED, the one that is parsed
            last is taken into account.


            h2. Low-level design:

            The implementation has the following aspects:

            # Counting the number of examined rows.
            # Checking if the limit has been exceeded.
            # Interrupting query execution.

            These are implemented as follows:

            h3. Counting the number of examined rows.

            The patch introduces a new thread-level counter
            {{THD::status_var::accessed_rows_and_keys}}. This counter is increased at each
            call to any of the family of handler methods {{handler::ha_*}}. Therefore this
            counter is equivalent to the sum of all counters increased by
            {{handler::increment_statistics()}}. Unlike all other handler counters in
            {{THD::status_var}}, accessed_rows_and_keys is reset automatically before each
            statement.

            h3. Checking if the limit has been exceeded.

            The test if LIMIT_ROWS_EXAMINED has been exceeded is done within each {{handler::ha_*}}
            handler call. Once this happens, the handler method sets {{THD::killed = ABORT_QUERY}},
            and issues a warning that can be tested with 'show warnings'. Here ABORT_QUERY
            is a new enum in {{enum killed_state}}.

            h3. Interrupting query execution.

            The implementation reuses the fact that the query executioner checks in
            multiple places if {{THD::killed}} has been set, and stops execution. One goal
            of this task is to stop execution, but still produce the rows found until
            LIMIT_ROWS_EXAMINED was reached. Therefore at the end of the main execution
            loop, the function {{do_select()}} resets both {{THD::killed}}, and the error
            code propagated from the underlying query execution functions. As a result:

            * execution is stopped,
            * a warning is generated,
            * the query finishes without an error.


            h2. TODO:
            * fix failing test cases:
              Failing test(s): rpl.rpl_stop_slave rpl.rpl_start_stop_slave
              (the cause is the change in the values of enum killed_state because of adding a new
              kill state).
            * change the implementation so that LIMIT_ROWS_EXAMINED affects only SELECT statements
            * fix the parser:
            ** make it possible to combine LIMIT_ROWS_EXAMINED with LIMIT in all meaningful
               ways,
            ** consider replacing it by {{LIMIT ROWS}} or some other more SQL-like clause,
            ** consider limiting the clause to the outer-most SELECT statement.
            * check why GROUP BY results in two warnings, and error 'sort aborted'
            * add test cases
            * run through QA, fix bugs

            The output of the above test case is:

            MariaDB [test]> create table t1 (c1 char(2));
            Query OK, 0 rows affected (0.30 sec)

            MariaDB [test]> create table t2 (c2 char(2));
            Query OK, 0 rows affected (0.03 sec)

            MariaDB [test]>
            MariaDB [test]> insert into t1 values ('bb'), ('cc'), ('aa');
            Query OK, 3 rows affected (0.00 sec)
            Records: 3 Duplicates: 0 Warnings: 0

            MariaDB [test]> insert into t2 values ('bb'), ('cc'), ('dd');
            Query OK, 3 rows affected (0.00 sec)
            Records: 3 Duplicates: 0 Warnings: 0

            MariaDB [test]>
            MariaDB [test]> select * from t1, t2 where c1 = c2;
            ----------+

            c1 c2

            ----------+

            bb bb
            cc cc

            ----------+
            2 rows in set (0.00 sec)

            MariaDB [test]> show warnings;
            Empty set (0.00 sec)

            MariaDB [test]>
            MariaDB [test]> set @@join_cache_level=0;
            Query OK, 0 rows affected (0.00 sec)

            MariaDB [test]> select * from t1, t2 where c1 = c2 LIMIT_ROWS_EXAMINED 2;
            ----------+

            c1 c2

            ----------+

            bb bb

            ----------+
            1 row in set, 1 warning (0.00 sec)

            MariaDB [test]> show warnings;
            -------------------------------------------------------------------------------------------------------------------------------------------

            Level Code Message

            -------------------------------------------------------------------------------------------------------------------------------------------

            Warning 1930 Query execution was interrupted. The query examined 3 rows, which exceeds LIMIT_ROWS_EXAMINED. The query result is incomplete.

            -------------------------------------------------------------------------------------------------------------------------------------------
            1 row in set (0.00 sec)

            MariaDB [test]>
            MariaDB [test]> set @@join_cache_level=1;
            Query OK, 0 rows affected (0.00 sec)

            MariaDB [test]> select * from t1, t2 where c1 = c2 LIMIT_ROWS_EXAMINED 2;
            Empty set, 1 warning (0.00 sec)

            MariaDB [test]> show warnings;
            -------------------------------------------------------------------------------------------------------------------------------------------

            Level Code Message

            -------------------------------------------------------------------------------------------------------------------------------------------

            Warning 1930 Query execution was interrupted. The query examined 3 rows, which exceeds LIMIT_ROWS_EXAMINED. The query result is incomplete.

            -------------------------------------------------------------------------------------------------------------------------------------------
            1 row in set (0.00 sec)

            MariaDB [test]>
            MariaDB [test]>
            MariaDB [test]> create table t3 (c1 char(2), c2 int);
            Query OK, 0 rows affected (0.04 sec)

            MariaDB [test]>
            MariaDB [test]> insert into t3 values
            -> ('aa', 1),
            -> ('aa', 2),
            -> ('bb', 3),
            -> ('bb', 4),
            -> ('bb', 5);
            Query OK, 5 rows affected (0.01 sec)
            Records: 5 Duplicates: 0 Warnings: 0

            MariaDB [test]>
            MariaDB [test]> select c1, sum(c2) from t3 group by c1;
            -------------+

            c1 sum(c2)

            -------------+

            aa 3
            bb 12

            -------------+
            2 rows in set (0.01 sec)

            MariaDB [test]>
            MariaDB [test]> select c1, sum(c2) from t3 group by c1 LIMIT_ROWS_EXAMINED 3;
            ERROR 1028 (HY000): Sort aborted
            MariaDB [test]> show warnings;
            -------------------------------------------------------------------------------------------------------------------------------------------

            Level Code Message

            -------------------------------------------------------------------------------------------------------------------------------------------

            Warning 1930 Query execution was interrupted. The query examined 4 rows, which exceeds LIMIT_ROWS_EXAMINED. The query result is incomplete.
            Warning 1930 Query execution was interrupted. The query examined 5 rows, which exceeds LIMIT_ROWS_EXAMINED. The query result is incomplete.
            Error 1028 Sort aborted

            -------------------------------------------------------------------------------------------------------------------------------------------
            3 rows in set (0.00 sec)

            timour Timour Katchaounov (Inactive) added a comment - The output of the above test case is: MariaDB [test] > create table t1 (c1 char(2)); Query OK, 0 rows affected (0.30 sec) MariaDB [test] > create table t2 (c2 char(2)); Query OK, 0 rows affected (0.03 sec) MariaDB [test] > MariaDB [test] > insert into t1 values ('bb'), ('cc'), ('aa'); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 MariaDB [test] > insert into t2 values ('bb'), ('cc'), ('dd'); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 MariaDB [test] > MariaDB [test] > select * from t1, t2 where c1 = c2; ----- -----+ c1 c2 ----- -----+ bb bb cc cc ----- -----+ 2 rows in set (0.00 sec) MariaDB [test] > show warnings; Empty set (0.00 sec) MariaDB [test] > MariaDB [test] > set @@join_cache_level=0; Query OK, 0 rows affected (0.00 sec) MariaDB [test] > select * from t1, t2 where c1 = c2 LIMIT_ROWS_EXAMINED 2; ----- -----+ c1 c2 ----- -----+ bb bb ----- -----+ 1 row in set, 1 warning (0.00 sec) MariaDB [test] > show warnings; -------- ---- ------------------------------------------------------------------------------------------------------------------------------- Level Code Message -------- ---- ------------------------------------------------------------------------------------------------------------------------------- Warning 1930 Query execution was interrupted. The query examined 3 rows, which exceeds LIMIT_ROWS_EXAMINED. The query result is incomplete. -------- ---- ------------------------------------------------------------------------------------------------------------------------------- 1 row in set (0.00 sec) MariaDB [test] > MariaDB [test] > set @@join_cache_level=1; Query OK, 0 rows affected (0.00 sec) MariaDB [test] > select * from t1, t2 where c1 = c2 LIMIT_ROWS_EXAMINED 2; Empty set, 1 warning (0.00 sec) MariaDB [test] > show warnings; -------- ---- ------------------------------------------------------------------------------------------------------------------------------- Level Code Message -------- ---- ------------------------------------------------------------------------------------------------------------------------------- Warning 1930 Query execution was interrupted. The query examined 3 rows, which exceeds LIMIT_ROWS_EXAMINED. The query result is incomplete. -------- ---- ------------------------------------------------------------------------------------------------------------------------------- 1 row in set (0.00 sec) MariaDB [test] > MariaDB [test] > MariaDB [test] > create table t3 (c1 char(2), c2 int); Query OK, 0 rows affected (0.04 sec) MariaDB [test] > MariaDB [test] > insert into t3 values -> ('aa', 1), -> ('aa', 2), -> ('bb', 3), -> ('bb', 4), -> ('bb', 5); Query OK, 5 rows affected (0.01 sec) Records: 5 Duplicates: 0 Warnings: 0 MariaDB [test] > MariaDB [test] > select c1, sum(c2) from t3 group by c1; ----- --------+ c1 sum(c2) ----- --------+ aa 3 bb 12 ----- --------+ 2 rows in set (0.01 sec) MariaDB [test] > MariaDB [test] > select c1, sum(c2) from t3 group by c1 LIMIT_ROWS_EXAMINED 3; ERROR 1028 (HY000): Sort aborted MariaDB [test] > show warnings; -------- ---- ------------------------------------------------------------------------------------------------------------------------------- Level Code Message -------- ---- ------------------------------------------------------------------------------------------------------------------------------- Warning 1930 Query execution was interrupted. The query examined 4 rows, which exceeds LIMIT_ROWS_EXAMINED. The query result is incomplete. Warning 1930 Query execution was interrupted. The query examined 5 rows, which exceeds LIMIT_ROWS_EXAMINED. The query result is incomplete. Error 1028 Sort aborted -------- ---- ------------------------------------------------------------------------------------------------------------------------------- 3 rows in set (0.00 sec)
            serg Sergei Golubchik made changes -
            Workflow jira [ 10300 ] defaullt [ 10721 ]
            timour Timour Katchaounov (Inactive) made changes -
            Description h2. Description:

            The purpose of this task is to provide the means to terminate the execution of
            SELECT statements that examine too many rows, and thus take too long, and use
            too much resources. This is achieved through a variant of the LIMIT clause,
            LIMIT_ROWS_EXAMINED number_of_rows.

            The current syntax for the clause is:

            {code}
            SELECT ... FROM ... WHERE ... LIMIT_ROWS_EXAMINED integer_constant;
            {code}

            NOTICE:
            For simplicity, ATM the clause is parsed as an alternative to the LIMIT clause,
            and cannot be mixed with a LIMIT clause. This is a limitation that will be fixed
            once the rest of the task is accepted.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows
              during query execution. This takes into account the use of temporary tables,
              and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT_ROWS_EXAMINED clause
              query execution is terminated as soon as possible, in a manner similar to
              killing the query

            * The effects of terminating the query because of LIMIT_ROWS_EXAMINED are as
              follows:
            ** A warning is generated.
            ** The result of the query is incomplete, and includes rows sent to the client
               before LIMIT_ROWS_EXAMINED was reached.
            ** Depending on the join and other execution strategies used for a query, the
               same query may produce no result at all, or a different result when
               terminated due to LIMIT_ROWS_EXAMINED.
            ** If the query contains a GROUP BY clause, the last group contains only the
               rows found before query termination. Accordingly aggregate functions take
               into account only these rows.

            Due to the implementation of this feature, the LIMIT_ROWS_EXAMINED clause
            cannot be specified on per-subquery basis. There can be only one
            LIMIT_ROWS_EXAMINED clause for the whole SELECT statement. If a SELECT statement
            contains several subqueries with the LIMIT_ROWS_EXAMINED, the one that is parsed
            last is taken into account.


            h2. Low-level design:

            The implementation has the following aspects:

            # Counting the number of examined rows.
            # Checking if the limit has been exceeded.
            # Interrupting query execution.

            These are implemented as follows:

            h3. Counting the number of examined rows.

            The patch introduces a new thread-level counter
            {{THD::status_var::accessed_rows_and_keys}}. This counter is increased at each
            call to any of the family of handler methods {{handler::ha_*}}. Therefore this
            counter is equivalent to the sum of all counters increased by
            {{handler::increment_statistics()}}. Unlike all other handler counters in
            {{THD::status_var}}, accessed_rows_and_keys is reset automatically before each
            statement.

            h3. Checking if the limit has been exceeded.

            The test if LIMIT_ROWS_EXAMINED has been exceeded is done within each {{handler::ha_*}}
            handler call. Once this happens, the handler method sets {{THD::killed = ABORT_QUERY}},
            and issues a warning that can be tested with 'show warnings'. Here ABORT_QUERY
            is a new enum in {{enum killed_state}}.

            h3. Interrupting query execution.

            The implementation reuses the fact that the query executioner checks in
            multiple places if {{THD::killed}} has been set, and stops execution. One goal
            of this task is to stop execution, but still produce the rows found until
            LIMIT_ROWS_EXAMINED was reached. Therefore at the end of the main execution
            loop, the function {{do_select()}} resets both {{THD::killed}}, and the error
            code propagated from the underlying query execution functions. As a result:

            * execution is stopped,
            * a warning is generated,
            * the query finishes without an error.


            h2. TODO:
            * fix failing test cases:
              Failing test(s): rpl.rpl_stop_slave rpl.rpl_start_stop_slave
              (the cause is the change in the values of enum killed_state because of adding a new
              kill state).
            * change the implementation so that LIMIT_ROWS_EXAMINED affects only SELECT statements
            * fix the parser:
            ** make it possible to combine LIMIT_ROWS_EXAMINED with LIMIT in all meaningful
               ways,
            ** consider replacing it by {{LIMIT ROWS}} or some other more SQL-like clause,
            ** consider limiting the clause to the outer-most SELECT statement.
            * check why GROUP BY results in two warnings, and error 'sort aborted'
            * add test cases
            * run through QA, fix bugs
            h2. Description:

            The purpose of this task is to provide the means to terminate the execution of
            SELECT statements that examine too many rows, and thus take too long, and use
            too much resources. This is achieved through a variant of the LIMIT clause,
            LIMIT_ROWS_EXAMINED number_of_rows.

            The current syntax for the clause is:

            {code}
            SELECT ... FROM ... WHERE ...
            [group_clause] [order_clause]
            [limit_clause] LIMIT_ROWS_EXAMINED integer_constant;
            {code}

            The clause is global for the whole query. If a composite query (such as UNION,
            or query with derived tables or with subqueries) contains more than one
            LIMIT_ROWS_EXAMINED, the last one parsed is taken into account. In this manner
            either the last or the outermost one is taken into account.

            The LIMIT_ROWS_EXAMINED clause is not taken into account in the following cases:
            * If a query is EXPLAIN-ed, the clause is ignored.
            * The clause is ignored during query optimization.
            * The clause is not available for DELETE/UPDATE statements.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows
              during query execution. This takes into account the use of temporary tables,
              and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT_ROWS_EXAMINED clause
              query execution is terminated as soon as possible, in a manner similar to
              killing the query

            * The effects of terminating the query because of LIMIT_ROWS_EXAMINED are as
              follows:
            ** A warning is generated.
            ** If query processing was interrupted during filesort, an error is returned.
            ** If a UNION was interrupted during execution of one if its queries, the last
            step of the UNION is still executed in order to produce a partial result.
            ** The result of the query is incomplete, and includes rows sent to the client
               before LIMIT_ROWS_EXAMINED was reached.
            ** Depending on the join and other execution strategies used for a query, the
               same query may produce no result at all, or a different result when
               terminated due to LIMIT_ROWS_EXAMINED.
            ** If the query contains a GROUP BY clause, the last group contains only the
               rows found before query termination. Accordingly aggregate functions take
               into account only these rows.

            Due to the implementation of this feature, the LIMIT_ROWS_EXAMINED clause
            cannot be specified on per-subquery basis. There can be only one
            LIMIT_ROWS_EXAMINED clause for the whole SELECT statement. If a SELECT statement
            contains several subqueries with the LIMIT_ROWS_EXAMINED, the one that is parsed
            last is taken into account.


            h2. Low-level design:

            The implementation has the following aspects:

            # Counting the number of examined rows.
            # Checking if the limit has been exceeded.
            # Interrupting query execution.

            These are implemented as follows:

            h3. Counting the number of examined rows.

            The patch introduces a new thread-level counter
            {{THD::status_var::accessed_rows_and_keys}}. This counter is increased at each
            call to any of the family of handler methods {{handler::ha_*}}. Therefore this
            counter is equivalent to the sum of all counters increased by
            {{handler::increment_statistics()}}. Unlike all other handler counters in
            {{THD::status_var}}, accessed_rows_and_keys is reset automatically before each
            statement.

            The counter is equivalent to the sum of the following handler counters:

            ha_read_key_count, ha_read_next_count, ha_read_prev_count, ha_read_first_count,
            ha_read_last_count, ha_read_rnd_next_count, ha_read_rnd_count, ha_tmp_write_count,
            ha_tmp_update_count, ha_write_count, ha_update_count, ha_delete_count.

            These are the counters increased by handler::increment_statistics() which is
            used to increase the counted for LIMIT_ROWS_EXAMINED.

            h3. Checking if the limit has been exceeded.

            The test if LIMIT_ROWS_EXAMINED has been exceeded is done within each {{handler::ha_*}}
            handler call. Once this happens, the handler method sets {{THD::killed = ABORT_QUERY}},
            and issues a warning that can be tested with 'show warnings'. Here ABORT_QUERY
            is a new enum in {{enum killed_state}}.

            h3. Interrupting query execution.

            The implementation reuses the fact that the query executioner checks in
            multiple places if {{THD::killed}} has been set, and stops execution. One goal
            of this task is to stop execution, but still produce the rows found until
            LIMIT_ROWS_EXAMINED was reached. Therefore at the end of the main execution
            loop, the function {{do_select()}} resets both {{THD::killed}}, and the error
            code propagated from the underlying query execution functions. As a result:

            * execution is stopped,
            * a warning is generated,
            * the query finishes without an error (except when query execution was
              interrupted during filesort).

            h2. TODO:
            * fix the parser:
            ** reduce the number of shift/reduce conflicts
            ** consider issuing an error (or warning) if there is more than one
               LIMIT_ROWS_EXAMINED clause in the whole query.
            * run through QA, fix bugs.
            elenst Elena Stepanova made changes -
            elenst Elena Stepanova made changes -
            elenst Elena Stepanova made changes -
            elenst Elena Stepanova made changes -
            ratzpo Rasmus Johansson (Inactive) made changes -
            Labels paid-for pf1
            elenst Elena Stepanova made changes -
            ratzpo Rasmus Johansson (Inactive) made changes -
            Fix Version/s 5.5.21 [ 10101 ]
            Fix Version/s 5.6.1 [ 10000 ]
            timour Timour Katchaounov (Inactive) made changes -
            Description h2. Description:

            The purpose of this task is to provide the means to terminate the execution of
            SELECT statements that examine too many rows, and thus take too long, and use
            too much resources. This is achieved through a variant of the LIMIT clause,
            LIMIT_ROWS_EXAMINED number_of_rows.

            The current syntax for the clause is:

            {code}
            SELECT ... FROM ... WHERE ...
            [group_clause] [order_clause]
            [limit_clause] LIMIT_ROWS_EXAMINED integer_constant;
            {code}

            The clause is global for the whole query. If a composite query (such as UNION,
            or query with derived tables or with subqueries) contains more than one
            LIMIT_ROWS_EXAMINED, the last one parsed is taken into account. In this manner
            either the last or the outermost one is taken into account.

            The LIMIT_ROWS_EXAMINED clause is not taken into account in the following cases:
            * If a query is EXPLAIN-ed, the clause is ignored.
            * The clause is ignored during query optimization.
            * The clause is not available for DELETE/UPDATE statements.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows
              during query execution. This takes into account the use of temporary tables,
              and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT_ROWS_EXAMINED clause
              query execution is terminated as soon as possible, in a manner similar to
              killing the query

            * The effects of terminating the query because of LIMIT_ROWS_EXAMINED are as
              follows:
            ** A warning is generated.
            ** If query processing was interrupted during filesort, an error is returned.
            ** If a UNION was interrupted during execution of one if its queries, the last
            step of the UNION is still executed in order to produce a partial result.
            ** The result of the query is incomplete, and includes rows sent to the client
               before LIMIT_ROWS_EXAMINED was reached.
            ** Depending on the join and other execution strategies used for a query, the
               same query may produce no result at all, or a different result when
               terminated due to LIMIT_ROWS_EXAMINED.
            ** If the query contains a GROUP BY clause, the last group contains only the
               rows found before query termination. Accordingly aggregate functions take
               into account only these rows.

            Due to the implementation of this feature, the LIMIT_ROWS_EXAMINED clause
            cannot be specified on per-subquery basis. There can be only one
            LIMIT_ROWS_EXAMINED clause for the whole SELECT statement. If a SELECT statement
            contains several subqueries with the LIMIT_ROWS_EXAMINED, the one that is parsed
            last is taken into account.


            h2. Low-level design:

            The implementation has the following aspects:

            # Counting the number of examined rows.
            # Checking if the limit has been exceeded.
            # Interrupting query execution.

            These are implemented as follows:

            h3. Counting the number of examined rows.

            The patch introduces a new thread-level counter
            {{THD::status_var::accessed_rows_and_keys}}. This counter is increased at each
            call to any of the family of handler methods {{handler::ha_*}}. Therefore this
            counter is equivalent to the sum of all counters increased by
            {{handler::increment_statistics()}}. Unlike all other handler counters in
            {{THD::status_var}}, accessed_rows_and_keys is reset automatically before each
            statement.

            The counter is equivalent to the sum of the following handler counters:

            ha_read_key_count, ha_read_next_count, ha_read_prev_count, ha_read_first_count,
            ha_read_last_count, ha_read_rnd_next_count, ha_read_rnd_count, ha_tmp_write_count,
            ha_tmp_update_count, ha_write_count, ha_update_count, ha_delete_count.

            These are the counters increased by handler::increment_statistics() which is
            used to increase the counted for LIMIT_ROWS_EXAMINED.

            h3. Checking if the limit has been exceeded.

            The test if LIMIT_ROWS_EXAMINED has been exceeded is done within each {{handler::ha_*}}
            handler call. Once this happens, the handler method sets {{THD::killed = ABORT_QUERY}},
            and issues a warning that can be tested with 'show warnings'. Here ABORT_QUERY
            is a new enum in {{enum killed_state}}.

            h3. Interrupting query execution.

            The implementation reuses the fact that the query executioner checks in
            multiple places if {{THD::killed}} has been set, and stops execution. One goal
            of this task is to stop execution, but still produce the rows found until
            LIMIT_ROWS_EXAMINED was reached. Therefore at the end of the main execution
            loop, the function {{do_select()}} resets both {{THD::killed}}, and the error
            code propagated from the underlying query execution functions. As a result:

            * execution is stopped,
            * a warning is generated,
            * the query finishes without an error (except when query execution was
              interrupted during filesort).

            h2. TODO:
            * fix the parser:
            ** reduce the number of shift/reduce conflicts
            ** consider issuing an error (or warning) if there is more than one
               LIMIT_ROWS_EXAMINED clause in the whole query.
            * run through QA, fix bugs.
            h2. Description:

            The purpose of this task is to provide the means to terminate the
            execution of SELECT statements that examines too many rows, and thus
            uses too much resources. This is achieved through a variant of the LIMIT
            clause, LIMIT ROWS_EXAMINED number_of_rows.

            The current syntax for the clause is:

            {code}
            SELECT ... FROM ... WHERE ...
            [group_clause] [order_clause]
            [limit_clause] LIMIT ROWS_EXAMINED integer_constant;
            {code}

            The clause is global for the whole statement. If a composite query
            (such as UNION, or query with derived tables or with subqueries)
            contains more than one LIMIT ROWS_EXAMINED, the last one parsed is
            taken into account. In this manner either the last or the outermost
            one is taken into account.

            The LIMIT ROWS_EXAMINED clause is not taken into account in the
            following cases:
            * If a query is EXPLAIN-ed, the clause is ignored.
            * The clause is ignored during query optimization.
            * The clause is not available for DELETE/UPDATE statements.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows
              during query execution. This takes into account the use of temporary tables,
              and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT_ROWS_EXAMINED clause
              query execution is terminated as soon as possible, in a manner similar to
              killing the query

            * The effects of terminating the query because of LIMIT_ROWS_EXAMINED are as
              follows:
            ** A warning is generated.
            ** If query processing was interrupted during filesort, an error is returned.
            ** If a UNION was interrupted during execution of one if its queries, the last
            step of the UNION is still executed in order to produce a partial result.
            ** The result of the query is incomplete, and includes rows sent to the client
               before LIMIT_ROWS_EXAMINED was reached.
            ** Depending on the join and other execution strategies used for a query, the
               same query may produce no result at all, or a different result when
               terminated due to LIMIT_ROWS_EXAMINED.
            ** If the query contains a GROUP BY clause, the last group contains only the
               rows found before query termination. Accordingly aggregate functions take
               into account only these rows.

            Due to the implementation of this feature, the LIMIT_ROWS_EXAMINED clause
            cannot be specified on per-subquery basis. There can be only one
            LIMIT_ROWS_EXAMINED clause for the whole SELECT statement. If a SELECT statement
            contains several subqueries with the LIMIT_ROWS_EXAMINED, the one that is parsed
            last is taken into account.


            h2. Low-level design:

            The implementation has the following aspects:

            # Counting the number of examined rows.
            # Checking if the limit has been exceeded.
            # Interrupting query execution.

            These are implemented as follows:

            h3. Counting the number of examined rows.

            The patch introduces a new thread-level counter
            {{THD::status_var::accessed_rows_and_keys}}. This counter is increased at each
            call to any of the family of handler methods {{handler::ha_*}}. Therefore this
            counter is equivalent to the sum of all counters increased by
            {{handler::increment_statistics()}}. Unlike all other handler counters in
            {{THD::status_var}}, accessed_rows_and_keys is reset automatically before each
            statement.

            The counter is equivalent to the sum of the following handler counters:

            ha_read_key_count, ha_read_next_count, ha_read_prev_count, ha_read_first_count,
            ha_read_last_count, ha_read_rnd_next_count, ha_read_rnd_count, ha_tmp_write_count,
            ha_tmp_update_count, ha_write_count, ha_update_count, ha_delete_count.

            These are the counters increased by handler::increment_statistics() which is
            used to increase the counted for LIMIT_ROWS_EXAMINED.

            h3. Checking if the limit has been exceeded.

            The test if LIMIT_ROWS_EXAMINED has been exceeded is done within each {{handler::ha_*}}
            handler call. Once this happens, the handler method sets {{THD::killed = ABORT_QUERY}},
            and issues a warning that can be tested with 'show warnings'. Here ABORT_QUERY
            is a new enum in {{enum killed_state}}.

            h3. Interrupting query execution.

            The implementation reuses the fact that the query executioner checks in
            multiple places if {{THD::killed}} has been set, and stops execution. One goal
            of this task is to stop execution, but still produce the rows found until
            LIMIT_ROWS_EXAMINED was reached. Therefore at the end of the main execution
            loop, the function {{do_select()}} resets both {{THD::killed}}, and the error
            code propagated from the underlying query execution functions. As a result:

            * execution is stopped,
            * a warning is generated,
            * the query finishes without an error (except when query execution was
              interrupted during filesort).

            h2. TODO:
            * fix the parser:
            ** reduce the number of shift/reduce conflicts
            ** consider issuing an error (or warning) if there is more than one
               LIMIT_ROWS_EXAMINED clause in the whole query.
            * run through QA, fix bugs.
            timour Timour Katchaounov (Inactive) made changes -
            Description h2. Description:

            The purpose of this task is to provide the means to terminate the
            execution of SELECT statements that examines too many rows, and thus
            uses too much resources. This is achieved through a variant of the LIMIT
            clause, LIMIT ROWS_EXAMINED number_of_rows.

            The current syntax for the clause is:

            {code}
            SELECT ... FROM ... WHERE ...
            [group_clause] [order_clause]
            [limit_clause] LIMIT ROWS_EXAMINED integer_constant;
            {code}

            The clause is global for the whole statement. If a composite query
            (such as UNION, or query with derived tables or with subqueries)
            contains more than one LIMIT ROWS_EXAMINED, the last one parsed is
            taken into account. In this manner either the last or the outermost
            one is taken into account.

            The LIMIT ROWS_EXAMINED clause is not taken into account in the
            following cases:
            * If a query is EXPLAIN-ed, the clause is ignored.
            * The clause is ignored during query optimization.
            * The clause is not available for DELETE/UPDATE statements.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows
              during query execution. This takes into account the use of temporary tables,
              and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT_ROWS_EXAMINED clause
              query execution is terminated as soon as possible, in a manner similar to
              killing the query

            * The effects of terminating the query because of LIMIT_ROWS_EXAMINED are as
              follows:
            ** A warning is generated.
            ** If query processing was interrupted during filesort, an error is returned.
            ** If a UNION was interrupted during execution of one if its queries, the last
            step of the UNION is still executed in order to produce a partial result.
            ** The result of the query is incomplete, and includes rows sent to the client
               before LIMIT_ROWS_EXAMINED was reached.
            ** Depending on the join and other execution strategies used for a query, the
               same query may produce no result at all, or a different result when
               terminated due to LIMIT_ROWS_EXAMINED.
            ** If the query contains a GROUP BY clause, the last group contains only the
               rows found before query termination. Accordingly aggregate functions take
               into account only these rows.

            Due to the implementation of this feature, the LIMIT_ROWS_EXAMINED clause
            cannot be specified on per-subquery basis. There can be only one
            LIMIT_ROWS_EXAMINED clause for the whole SELECT statement. If a SELECT statement
            contains several subqueries with the LIMIT_ROWS_EXAMINED, the one that is parsed
            last is taken into account.


            h2. Low-level design:

            The implementation has the following aspects:

            # Counting the number of examined rows.
            # Checking if the limit has been exceeded.
            # Interrupting query execution.

            These are implemented as follows:

            h3. Counting the number of examined rows.

            The patch introduces a new thread-level counter
            {{THD::status_var::accessed_rows_and_keys}}. This counter is increased at each
            call to any of the family of handler methods {{handler::ha_*}}. Therefore this
            counter is equivalent to the sum of all counters increased by
            {{handler::increment_statistics()}}. Unlike all other handler counters in
            {{THD::status_var}}, accessed_rows_and_keys is reset automatically before each
            statement.

            The counter is equivalent to the sum of the following handler counters:

            ha_read_key_count, ha_read_next_count, ha_read_prev_count, ha_read_first_count,
            ha_read_last_count, ha_read_rnd_next_count, ha_read_rnd_count, ha_tmp_write_count,
            ha_tmp_update_count, ha_write_count, ha_update_count, ha_delete_count.

            These are the counters increased by handler::increment_statistics() which is
            used to increase the counted for LIMIT_ROWS_EXAMINED.

            h3. Checking if the limit has been exceeded.

            The test if LIMIT_ROWS_EXAMINED has been exceeded is done within each {{handler::ha_*}}
            handler call. Once this happens, the handler method sets {{THD::killed = ABORT_QUERY}},
            and issues a warning that can be tested with 'show warnings'. Here ABORT_QUERY
            is a new enum in {{enum killed_state}}.

            h3. Interrupting query execution.

            The implementation reuses the fact that the query executioner checks in
            multiple places if {{THD::killed}} has been set, and stops execution. One goal
            of this task is to stop execution, but still produce the rows found until
            LIMIT_ROWS_EXAMINED was reached. Therefore at the end of the main execution
            loop, the function {{do_select()}} resets both {{THD::killed}}, and the error
            code propagated from the underlying query execution functions. As a result:

            * execution is stopped,
            * a warning is generated,
            * the query finishes without an error (except when query execution was
              interrupted during filesort).

            h2. TODO:
            * fix the parser:
            ** reduce the number of shift/reduce conflicts
            ** consider issuing an error (or warning) if there is more than one
               LIMIT_ROWS_EXAMINED clause in the whole query.
            * run through QA, fix bugs.
            h2. Description:

            The purpose of this task is to provide the means to terminate the
            execution of SELECT statements that examines too many rows, and thus
            uses too much resources. This is achieved through a variant of the LIMIT
            clause, LIMIT ROWS_EXAMINED number_of_rows.

            The current syntax for the clause is:

            {code}
            SELECT ... FROM ... WHERE ...
            [group_clause] [order_clause]
            [limit_clause] LIMIT ROWS_EXAMINED integer_constant;
            {code}

            The clause is global for the whole statement. If a composite query
            (such as UNION, or query with derived tables or with subqueries)
            contains more than one LIMIT ROWS_EXAMINED, the last one parsed is
            taken into account. In this manner either the last or the outermost
            one is taken into account.

            The LIMIT ROWS_EXAMINED clause is taken into account by the query
            engine only during query execution. Thus the clause is not effective
            in the following cases:
            * If a query is EXPLAIN-ed, the clause is ignored.
            * The clause is ignored during query optimization.
            * The clause is not available for DELETE/UPDATE statements.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted
            rows during query execution. This takes into account the use of temporary tables, and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT ROWS_EXAMINED clause query execution is terminated as soon as possible, in a manner similar to killing the query.

            * The effects of terminating the query because of LIMIT ROWS_EXAMINED
            are as follows:
            ** The result of the query is incomplete, and includes rows sent to the client before LIMIT ROWS_EXAMINED was reached. The result may be empty
            if no result rows could be computed before reaching the limit.
            ** A warning is generated of the form:
            "Query execution was interrupted. The query examined at least 100 rows, which exceeds LIMIT ROWS_EXAMINED (20). The query result may be incomplete."
            ** If query processing was interrupted during filesort, an error is returned in addition to the warning.
            ** If a UNION was interrupted during execution of one of its queries, the last step of the UNION is still executed in order to produce a partial result.
            ** Depending on the join and other execution strategies used for a query, the same query may produce no result at all, or a different subset of the complete result when terminated due to LIMIT ROWS_EXAMINED.
            ** If the query contains a GROUP BY clause, the last group where the limit was reached will be discarded.

            The LIMIT ROWS_EXAMINED clause
            cannot be specified on per-subquery basis. There can be only one
            LIMIT ROWS_EXAMINED clause for the whole SELECT statement. If a SELECT statement contains several subqueries with the LIMIT ROWS_EXAMINED, the one that is parsed last is taken into account.


            h2. Low-level design:

            The implementation has the following aspects:

            # Counting the number of examined rows.
            # Checking if the limit has been exceeded.
            # Interrupting query execution.

            These are implemented as follows:

            h3. Counting the number of examined rows.

            The patch introduces a new thread-level counter
            {{THD::status_var::accessed_rows_and_keys}}. This counter is increased at each
            call to any of the family of handler methods {{handler::ha_*}}. Therefore this
            counter is equivalent to the sum of all counters increased by
            {{handler::increment_statistics()}}. Unlike all other handler counters in
            {{THD::status_var}}, accessed_rows_and_keys is reset automatically before each
            statement.

            The counter is equivalent to the sum of the following handler counters:

            ha_read_key_count, ha_read_next_count, ha_read_prev_count, ha_read_first_count,
            ha_read_last_count, ha_read_rnd_next_count, ha_read_rnd_count, ha_tmp_write_count,
            ha_tmp_update_count, ha_write_count, ha_update_count, ha_delete_count.

            These are the counters increased by handler::increment_statistics() which is
            used to increase the counted for LIMIT_ROWS_EXAMINED.

            h3. Checking if the limit has been exceeded.

            The test if LIMIT_ROWS_EXAMINED has been exceeded is done within each {{handler::ha_*}}
            handler call. Once this happens, the handler method sets {{THD::killed = ABORT_QUERY}},
            and issues a warning that can be tested with 'show warnings'. Here ABORT_QUERY
            is a new enum in {{enum killed_state}}.

            h3. Interrupting query execution.

            The implementation reuses the fact that the query executioner checks in
            multiple places if {{THD::killed}} has been set, and stops execution. One goal
            of this task is to stop execution, but still produce the rows found until
            LIMIT_ROWS_EXAMINED was reached. Therefore at the end of the main execution
            loop, the function {{do_select()}} resets both {{THD::killed}}, and the error
            code propagated from the underlying query execution functions. As a result:

            * execution is stopped,
            * a warning is generated,
            * the query finishes without an error (except when query execution was
              interrupted during filesort).

            h2. TODO:
            * fix the parser:
            ** reduce the number of shift/reduce conflicts
            ** consider issuing an error (or warning) if there is more than one
               LIMIT_ROWS_EXAMINED clause in the whole query.
            * run through QA, fix bugs.
            timour Timour Katchaounov (Inactive) made changes -
            Description h2. Description:

            The purpose of this task is to provide the means to terminate the
            execution of SELECT statements that examines too many rows, and thus
            uses too much resources. This is achieved through a variant of the LIMIT
            clause, LIMIT ROWS_EXAMINED number_of_rows.

            The current syntax for the clause is:

            {code}
            SELECT ... FROM ... WHERE ...
            [group_clause] [order_clause]
            [limit_clause] LIMIT ROWS_EXAMINED integer_constant;
            {code}

            The clause is global for the whole statement. If a composite query
            (such as UNION, or query with derived tables or with subqueries)
            contains more than one LIMIT ROWS_EXAMINED, the last one parsed is
            taken into account. In this manner either the last or the outermost
            one is taken into account.

            The LIMIT ROWS_EXAMINED clause is taken into account by the query
            engine only during query execution. Thus the clause is not effective
            in the following cases:
            * If a query is EXPLAIN-ed, the clause is ignored.
            * The clause is ignored during query optimization.
            * The clause is not available for DELETE/UPDATE statements.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted
            rows during query execution. This takes into account the use of temporary tables, and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT ROWS_EXAMINED clause query execution is terminated as soon as possible, in a manner similar to killing the query.

            * The effects of terminating the query because of LIMIT ROWS_EXAMINED
            are as follows:
            ** The result of the query is incomplete, and includes rows sent to the client before LIMIT ROWS_EXAMINED was reached. The result may be empty
            if no result rows could be computed before reaching the limit.
            ** A warning is generated of the form:
            "Query execution was interrupted. The query examined at least 100 rows, which exceeds LIMIT ROWS_EXAMINED (20). The query result may be incomplete."
            ** If query processing was interrupted during filesort, an error is returned in addition to the warning.
            ** If a UNION was interrupted during execution of one of its queries, the last step of the UNION is still executed in order to produce a partial result.
            ** Depending on the join and other execution strategies used for a query, the same query may produce no result at all, or a different subset of the complete result when terminated due to LIMIT ROWS_EXAMINED.
            ** If the query contains a GROUP BY clause, the last group where the limit was reached will be discarded.

            The LIMIT ROWS_EXAMINED clause
            cannot be specified on per-subquery basis. There can be only one
            LIMIT ROWS_EXAMINED clause for the whole SELECT statement. If a SELECT statement contains several subqueries with the LIMIT ROWS_EXAMINED, the one that is parsed last is taken into account.


            h2. Low-level design:

            The implementation has the following aspects:

            # Counting the number of examined rows.
            # Checking if the limit has been exceeded.
            # Interrupting query execution.

            These are implemented as follows:

            h3. Counting the number of examined rows.

            The patch introduces a new thread-level counter
            {{THD::status_var::accessed_rows_and_keys}}. This counter is increased at each
            call to any of the family of handler methods {{handler::ha_*}}. Therefore this
            counter is equivalent to the sum of all counters increased by
            {{handler::increment_statistics()}}. Unlike all other handler counters in
            {{THD::status_var}}, accessed_rows_and_keys is reset automatically before each
            statement.

            The counter is equivalent to the sum of the following handler counters:

            ha_read_key_count, ha_read_next_count, ha_read_prev_count, ha_read_first_count,
            ha_read_last_count, ha_read_rnd_next_count, ha_read_rnd_count, ha_tmp_write_count,
            ha_tmp_update_count, ha_write_count, ha_update_count, ha_delete_count.

            These are the counters increased by handler::increment_statistics() which is
            used to increase the counted for LIMIT_ROWS_EXAMINED.

            h3. Checking if the limit has been exceeded.

            The test if LIMIT_ROWS_EXAMINED has been exceeded is done within each {{handler::ha_*}}
            handler call. Once this happens, the handler method sets {{THD::killed = ABORT_QUERY}},
            and issues a warning that can be tested with 'show warnings'. Here ABORT_QUERY
            is a new enum in {{enum killed_state}}.

            h3. Interrupting query execution.

            The implementation reuses the fact that the query executioner checks in
            multiple places if {{THD::killed}} has been set, and stops execution. One goal
            of this task is to stop execution, but still produce the rows found until
            LIMIT_ROWS_EXAMINED was reached. Therefore at the end of the main execution
            loop, the function {{do_select()}} resets both {{THD::killed}}, and the error
            code propagated from the underlying query execution functions. As a result:

            * execution is stopped,
            * a warning is generated,
            * the query finishes without an error (except when query execution was
              interrupted during filesort).

            h2. TODO:
            * fix the parser:
            ** reduce the number of shift/reduce conflicts
            ** consider issuing an error (or warning) if there is more than one
               LIMIT_ROWS_EXAMINED clause in the whole query.
            * run through QA, fix bugs.
            h2. Description:

            The purpose of this task is to provide the means to terminate the execution of SELECT statements that examines too many rows, and thus uses too much resources. This is achieved through a variant of the LIMIT clause, LIMIT ROWS_EXAMINED number_of_rows. Whenever possible the semantics of LIMIT ROWS_EXAMINED is the same as that of normal LIMIT (for instance for aggregate functions).

            The current syntax for the clause is:

            {code}
            SELECT ... FROM ... WHERE ...
            [group_clause] [order_clause]
            [limit_clause] LIMIT ROWS_EXAMINED integer_constant;
            {code}

            The clause is global for the whole statement. If a composite query (such as UNION, or query with derived tables or with subqueries) contains more than one LIMIT ROWS_EXAMINED, the last one parsed is taken into account. In this manner either the last or the outermost one is taken into account.

            The LIMIT ROWS_EXAMINED clause is taken into account by the query engine only during query execution. Thus the clause is not effective in the following cases:
            * If a query is EXPLAIN-ed, the clause is ignored.
            * The clause is ignored during query optimization.
            * The clause is not available for DELETE/UPDATE statements.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows during query execution. This takes into account the use of temporary tables, and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT ROWS_EXAMINED clause query execution is terminated as soon as possible, in a manner similar to killing the query.

            * The effects of terminating the query because of LIMIT ROWS_EXAMINED
            are as follows:
            ** The result of the query is a subset of the complete query, depending on when the query engine detected that the limit was reached. The result may be empty if no result rows could be computed before reaching the limit.
            ** A warning is generated of the form:

            "Query execution was interrupted. The query examined at least 100 rows, which exceeds LIMIT ROWS_EXAMINED (20). The query result may be incomplete."

            ** If query processing was interrupted during filesort, an error is returned in addition to the warning.
            ** If a UNION was interrupted during execution of one of its queries, the last step of the UNION is still executed in order to produce a partial result.
            ** Depending on the join and other execution strategies used for a query, the same query may produce no result at all, or a different subset of the complete result when terminated due to LIMIT ROWS_EXAMINED.
            ** If the query contains a GROUP BY clause, the last group where the limit was reached will be discarded.

            The LIMIT ROWS_EXAMINED clause cannot be specified on per-subquery basis. There can be only one LIMIT ROWS_EXAMINED clause for the whole SELECT statement. If a SELECT statement contains several subqueries with the LIMIT ROWS_EXAMINED, the one that is parsed last is taken into account.


            h2. Low-level design:

            The implementation has the following aspects:

            # Counting the number of examined rows.
            # Checking if the limit has been exceeded.
            # Interrupting query execution.

            These are implemented as follows:

            h3. Counting the number of examined rows.

            The patch introduces a new thread-level counter
            {{THD::status_var::accessed_rows_and_keys}}. This counter is increased at each
            call to any of the family of handler methods {{handler::ha_*}}. Therefore this
            counter is equivalent to the sum of all counters increased by
            {{handler::increment_statistics()}}. Unlike all other handler counters in
            {{THD::status_var}}, accessed_rows_and_keys is reset automatically before each
            statement.

            The counter is equivalent to the sum of the following handler counters:

            ha_read_key_count, ha_read_next_count, ha_read_prev_count, ha_read_first_count,
            ha_read_last_count, ha_read_rnd_next_count, ha_read_rnd_count, ha_tmp_write_count,
            ha_tmp_update_count, ha_write_count, ha_update_count, ha_delete_count.

            These are the counters increased by handler::increment_statistics() which is
            used to increase the counted for LIMIT_ROWS_EXAMINED.

            h3. Checking if the limit has been exceeded.

            The test if LIMIT_ROWS_EXAMINED has been exceeded is done within each {{handler::ha_*}}
            handler call. Once this happens, the handler method sets {{THD::killed = ABORT_QUERY}},
            and issues a warning that can be tested with 'show warnings'. Here ABORT_QUERY
            is a new enum in {{enum killed_state}}.

            h3. Interrupting query execution.

            The implementation reuses the fact that the query executioner checks in
            multiple places if {{THD::killed}} has been set, and stops execution. One goal
            of this task is to stop execution, but still produce the rows found until
            LIMIT_ROWS_EXAMINED was reached. Therefore at the end of the main execution
            loop, the function {{do_select()}} resets both {{THD::killed}}, and the error
            code propagated from the underlying query execution functions. As a result:

            * execution is stopped,
            * a warning is generated,
            * the query finishes without an error (except when query execution was
              interrupted during filesort).

            h2. TODO:
            * fix the parser:
            ** reduce the number of shift/reduce conflicts
            ** consider issuing an error (or warning) if there is more than one
               LIMIT_ROWS_EXAMINED clause in the whole query.
            * run through QA, fix bugs.
            timour Timour Katchaounov (Inactive) made changes -
            Description h2. Description:

            The purpose of this task is to provide the means to terminate the execution of SELECT statements that examines too many rows, and thus uses too much resources. This is achieved through a variant of the LIMIT clause, LIMIT ROWS_EXAMINED number_of_rows. Whenever possible the semantics of LIMIT ROWS_EXAMINED is the same as that of normal LIMIT (for instance for aggregate functions).

            The current syntax for the clause is:

            {code}
            SELECT ... FROM ... WHERE ...
            [group_clause] [order_clause]
            [limit_clause] LIMIT ROWS_EXAMINED integer_constant;
            {code}

            The clause is global for the whole statement. If a composite query (such as UNION, or query with derived tables or with subqueries) contains more than one LIMIT ROWS_EXAMINED, the last one parsed is taken into account. In this manner either the last or the outermost one is taken into account.

            The LIMIT ROWS_EXAMINED clause is taken into account by the query engine only during query execution. Thus the clause is not effective in the following cases:
            * If a query is EXPLAIN-ed, the clause is ignored.
            * The clause is ignored during query optimization.
            * The clause is not available for DELETE/UPDATE statements.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows during query execution. This takes into account the use of temporary tables, and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT ROWS_EXAMINED clause query execution is terminated as soon as possible, in a manner similar to killing the query.

            * The effects of terminating the query because of LIMIT ROWS_EXAMINED
            are as follows:
            ** The result of the query is a subset of the complete query, depending on when the query engine detected that the limit was reached. The result may be empty if no result rows could be computed before reaching the limit.
            ** A warning is generated of the form:

            "Query execution was interrupted. The query examined at least 100 rows, which exceeds LIMIT ROWS_EXAMINED (20). The query result may be incomplete."

            ** If query processing was interrupted during filesort, an error is returned in addition to the warning.
            ** If a UNION was interrupted during execution of one of its queries, the last step of the UNION is still executed in order to produce a partial result.
            ** Depending on the join and other execution strategies used for a query, the same query may produce no result at all, or a different subset of the complete result when terminated due to LIMIT ROWS_EXAMINED.
            ** If the query contains a GROUP BY clause, the last group where the limit was reached will be discarded.

            The LIMIT ROWS_EXAMINED clause cannot be specified on per-subquery basis. There can be only one LIMIT ROWS_EXAMINED clause for the whole SELECT statement. If a SELECT statement contains several subqueries with the LIMIT ROWS_EXAMINED, the one that is parsed last is taken into account.


            h2. Low-level design:

            The implementation has the following aspects:

            # Counting the number of examined rows.
            # Checking if the limit has been exceeded.
            # Interrupting query execution.

            These are implemented as follows:

            h3. Counting the number of examined rows.

            The patch introduces a new thread-level counter
            {{THD::status_var::accessed_rows_and_keys}}. This counter is increased at each
            call to any of the family of handler methods {{handler::ha_*}}. Therefore this
            counter is equivalent to the sum of all counters increased by
            {{handler::increment_statistics()}}. Unlike all other handler counters in
            {{THD::status_var}}, accessed_rows_and_keys is reset automatically before each
            statement.

            The counter is equivalent to the sum of the following handler counters:

            ha_read_key_count, ha_read_next_count, ha_read_prev_count, ha_read_first_count,
            ha_read_last_count, ha_read_rnd_next_count, ha_read_rnd_count, ha_tmp_write_count,
            ha_tmp_update_count, ha_write_count, ha_update_count, ha_delete_count.

            These are the counters increased by handler::increment_statistics() which is
            used to increase the counted for LIMIT_ROWS_EXAMINED.

            h3. Checking if the limit has been exceeded.

            The test if LIMIT_ROWS_EXAMINED has been exceeded is done within each {{handler::ha_*}}
            handler call. Once this happens, the handler method sets {{THD::killed = ABORT_QUERY}},
            and issues a warning that can be tested with 'show warnings'. Here ABORT_QUERY
            is a new enum in {{enum killed_state}}.

            h3. Interrupting query execution.

            The implementation reuses the fact that the query executioner checks in
            multiple places if {{THD::killed}} has been set, and stops execution. One goal
            of this task is to stop execution, but still produce the rows found until
            LIMIT_ROWS_EXAMINED was reached. Therefore at the end of the main execution
            loop, the function {{do_select()}} resets both {{THD::killed}}, and the error
            code propagated from the underlying query execution functions. As a result:

            * execution is stopped,
            * a warning is generated,
            * the query finishes without an error (except when query execution was
              interrupted during filesort).

            h2. TODO:
            * fix the parser:
            ** reduce the number of shift/reduce conflicts
            ** consider issuing an error (or warning) if there is more than one
               LIMIT_ROWS_EXAMINED clause in the whole query.
            * run through QA, fix bugs.
            h2. Description:

            The purpose of this task is to provide the means to terminate the execution of SELECT statements that examines too many rows, and thus uses too much resources. This is achieved through a variant of the LIMIT clause, LIMIT ROWS_EXAMINED number_of_rows. Whenever possible the semantics of LIMIT ROWS_EXAMINED is the same as that of normal LIMIT (for instance for aggregate functions).

            The current syntax for the clause is:

            {code}
            SELECT ... FROM ... WHERE ...
            [group_clause] [order_clause]
            [limit_clause] LIMIT ROWS_EXAMINED integer_constant;
            {code}

            The clause is global for the whole statement. If a composite query (such as UNION, or query with derived tables or with subqueries) contains more than one LIMIT ROWS_EXAMINED, the last one parsed is taken into account. In this manner either the last or the outermost one is taken into account.

            The LIMIT ROWS_EXAMINED clause is taken into account by the query engine only during query execution. Thus the clause is not effective in the following cases:
            * If a query is EXPLAIN-ed, the clause is ignored.
            * The clause is ignored during query optimization.
            * The clause is not available for DELETE/UPDATE statements.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows during query execution. This takes into account the use of temporary tables, and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT ROWS_EXAMINED clause query execution is terminated as soon as possible, in a manner similar to killing the query.

            * The effects of terminating the query because of LIMIT ROWS_EXAMINED
            are as follows:
            ** The result of the query is a subset of the complete query, depending on when the query engine detected that the limit was reached. The result may be empty if no result rows could be computed before reaching the limit.
            ** A warning is generated of the form: "Query execution was interrupted. The query examined at least 100 rows, which exceeds LIMIT ROWS_EXAMINED (20). The query result may be incomplete."
            ** If query processing was interrupted during filesort, an error is returned in addition to the warning.
            ** If a UNION was interrupted during execution of one of its queries, the last step of the UNION is still executed in order to produce a partial result.
            ** Depending on the join and other execution strategies used for a query, the same query may produce no result at all, or a different subset of the complete result when terminated due to LIMIT ROWS_EXAMINED.
            ** If the query contains a GROUP BY clause, the last group where the limit was reached will be discarded.

            The LIMIT ROWS_EXAMINED clause cannot be specified on per-subquery basis. There can be only one LIMIT ROWS_EXAMINED clause for the whole SELECT statement. If a SELECT statement contains several subqueries with the LIMIT ROWS_EXAMINED, the one that is parsed last is taken into account.


            h2. Low-level design:

            The implementation has the following aspects:

            # Counting the number of examined rows.
            # Checking if the limit has been exceeded.
            # Interrupting query execution.

            These are implemented as follows:

            h3. Counting the number of examined rows.

            The patch introduces a new thread-level counter
            {{THD::status_var::accessed_rows_and_keys}}. This counter is increased at each
            call to any of the family of handler methods {{handler::ha_*}}. Therefore this
            counter is equivalent to the sum of all counters increased by
            {{handler::increment_statistics()}}. Unlike all other handler counters in
            {{THD::status_var}}, accessed_rows_and_keys is reset automatically before each
            statement.

            The counter is equivalent to the sum of the following handler counters:

            ha_read_key_count, ha_read_next_count, ha_read_prev_count, ha_read_first_count,
            ha_read_last_count, ha_read_rnd_next_count, ha_read_rnd_count, ha_tmp_write_count,
            ha_tmp_update_count, ha_write_count, ha_update_count, ha_delete_count.

            These are the counters increased by handler::increment_statistics() which is
            used to increase the counted for LIMIT_ROWS_EXAMINED.

            h3. Checking if the limit has been exceeded.

            The test if LIMIT_ROWS_EXAMINED has been exceeded is done within each {{handler::ha_*}}
            handler call. Once this happens, the handler method sets {{THD::killed = ABORT_QUERY}},
            and issues a warning that can be tested with 'show warnings'. Here ABORT_QUERY
            is a new enum in {{enum killed_state}}.

            h3. Interrupting query execution.

            The implementation reuses the fact that the query executioner checks in
            multiple places if {{THD::killed}} has been set, and stops execution. One goal
            of this task is to stop execution, but still produce the rows found until
            LIMIT_ROWS_EXAMINED was reached. Therefore at the end of the main execution
            loop, the function {{do_select()}} resets both {{THD::killed}}, and the error
            code propagated from the underlying query execution functions. As a result:

            * execution is stopped,
            * a warning is generated,
            * the query finishes without an error (except when query execution was
              interrupted during filesort).

            h2. TODO:
            * fix the parser:
            ** reduce the number of shift/reduce conflicts
            ** consider issuing an error (or warning) if there is more than one
               LIMIT_ROWS_EXAMINED clause in the whole query.
            * run through QA, fix bugs.
            timour Timour Katchaounov (Inactive) made changes -
            Summary LIMIT_ROWS_EXAMINED clause to limit the number of rows examined during SELECT processing LIMIT ROWS_EXAMINED clause to limit the number of rows examined during SELECT processing
            elenst Elena Stepanova made changes -
            timour Timour Katchaounov (Inactive) made changes -
            Due Date 2012-03-12
            Summary LIMIT ROWS_EXAMINED clause to limit the number of rows examined during SELECT processing LIMIT ROWS EXAMINED clause to limit the number of rows examined during SELECT processing
            elenst Elena Stepanova made changes -
            elenst Elena Stepanova made changes -
            timour Timour Katchaounov (Inactive) made changes -
            Description h2. Description:

            The purpose of this task is to provide the means to terminate the execution of SELECT statements that examines too many rows, and thus uses too much resources. This is achieved through a variant of the LIMIT clause, LIMIT ROWS_EXAMINED number_of_rows. Whenever possible the semantics of LIMIT ROWS_EXAMINED is the same as that of normal LIMIT (for instance for aggregate functions).

            The current syntax for the clause is:

            {code}
            SELECT ... FROM ... WHERE ...
            [group_clause] [order_clause]
            [limit_clause] LIMIT ROWS_EXAMINED integer_constant;
            {code}

            The clause is global for the whole statement. If a composite query (such as UNION, or query with derived tables or with subqueries) contains more than one LIMIT ROWS_EXAMINED, the last one parsed is taken into account. In this manner either the last or the outermost one is taken into account.

            The LIMIT ROWS_EXAMINED clause is taken into account by the query engine only during query execution. Thus the clause is not effective in the following cases:
            * If a query is EXPLAIN-ed, the clause is ignored.
            * The clause is ignored during query optimization.
            * The clause is not available for DELETE/UPDATE statements.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows during query execution. This takes into account the use of temporary tables, and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT ROWS_EXAMINED clause query execution is terminated as soon as possible, in a manner similar to killing the query.

            * The effects of terminating the query because of LIMIT ROWS_EXAMINED
            are as follows:
            ** The result of the query is a subset of the complete query, depending on when the query engine detected that the limit was reached. The result may be empty if no result rows could be computed before reaching the limit.
            ** A warning is generated of the form: "Query execution was interrupted. The query examined at least 100 rows, which exceeds LIMIT ROWS_EXAMINED (20). The query result may be incomplete."
            ** If query processing was interrupted during filesort, an error is returned in addition to the warning.
            ** If a UNION was interrupted during execution of one of its queries, the last step of the UNION is still executed in order to produce a partial result.
            ** Depending on the join and other execution strategies used for a query, the same query may produce no result at all, or a different subset of the complete result when terminated due to LIMIT ROWS_EXAMINED.
            ** If the query contains a GROUP BY clause, the last group where the limit was reached will be discarded.

            The LIMIT ROWS_EXAMINED clause cannot be specified on per-subquery basis. There can be only one LIMIT ROWS_EXAMINED clause for the whole SELECT statement. If a SELECT statement contains several subqueries with the LIMIT ROWS_EXAMINED, the one that is parsed last is taken into account.


            h2. Low-level design:

            The implementation has the following aspects:

            # Counting the number of examined rows.
            # Checking if the limit has been exceeded.
            # Interrupting query execution.

            These are implemented as follows:

            h3. Counting the number of examined rows.

            The patch introduces a new thread-level counter
            {{THD::status_var::accessed_rows_and_keys}}. This counter is increased at each
            call to any of the family of handler methods {{handler::ha_*}}. Therefore this
            counter is equivalent to the sum of all counters increased by
            {{handler::increment_statistics()}}. Unlike all other handler counters in
            {{THD::status_var}}, accessed_rows_and_keys is reset automatically before each
            statement.

            The counter is equivalent to the sum of the following handler counters:

            ha_read_key_count, ha_read_next_count, ha_read_prev_count, ha_read_first_count,
            ha_read_last_count, ha_read_rnd_next_count, ha_read_rnd_count, ha_tmp_write_count,
            ha_tmp_update_count, ha_write_count, ha_update_count, ha_delete_count.

            These are the counters increased by handler::increment_statistics() which is
            used to increase the counted for LIMIT_ROWS_EXAMINED.

            h3. Checking if the limit has been exceeded.

            The test if LIMIT_ROWS_EXAMINED has been exceeded is done within each {{handler::ha_*}}
            handler call. Once this happens, the handler method sets {{THD::killed = ABORT_QUERY}},
            and issues a warning that can be tested with 'show warnings'. Here ABORT_QUERY
            is a new enum in {{enum killed_state}}.

            h3. Interrupting query execution.

            The implementation reuses the fact that the query executioner checks in
            multiple places if {{THD::killed}} has been set, and stops execution. One goal
            of this task is to stop execution, but still produce the rows found until
            LIMIT_ROWS_EXAMINED was reached. Therefore at the end of the main execution
            loop, the function {{do_select()}} resets both {{THD::killed}}, and the error
            code propagated from the underlying query execution functions. As a result:

            * execution is stopped,
            * a warning is generated,
            * the query finishes without an error (except when query execution was
              interrupted during filesort).

            h2. TODO:
            * fix the parser:
            ** reduce the number of shift/reduce conflicts
            ** consider issuing an error (or warning) if there is more than one
               LIMIT_ROWS_EXAMINED clause in the whole query.
            * run through QA, fix bugs.
            h2. Description:

            The purpose of this task is to provide the means to terminate the execution of SELECT statements that examines too many rows, and thus uses too much resources. This is achieved through an extension of the LIMIT clause - LIMIT ROWS EXAMINED <number_of_rows>. Whenever possible the semantics of LIMIT ROWS EXAMINED is the same as that of normal LIMIT (for instance for aggregate functions).

            The current syntax for the clause is:

            {code}
            SELECT ... FROM ... WHERE ...
            [group_clause] [order_clause]
            LIMIT [[offset,] row_count] ROWS EXAMINED rows_limit;
            {code}

            Similar to the parameters of LIMIT, 'rows_limit' can be both a prepared statement parameter, or a stored program parameter.

            The LIMIT ROWS EXAMINED clause is global for the whole statement. If a composite query (such as UNION, or query with derived tables or with subqueries) contains more than one LIMIT ROWS EXAMINED, the last one parsed is taken into account. In this manner either the last or the outermost one is taken into account.

            The LIMIT ROWS EXAMINED clause is taken into account by the query engine only during query execution. Thus the clause is ignored in the following cases:
            * If a query is EXPLAIN-ed.
            * During query optimization.
            * During auxiliary operations such as writing to system tables (e.g. logs).

            The clause is not applicable to DELETE/UPDATE statements, and if used in these statements produces a syntax error.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows during query execution. This takes into account the use of temporary tables, and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT ROWS EXAMINED clause, query execution is terminated as soon as possible.

            * The effects of terminating the query because of LIMIT ROWS EXAMINED are as follows:
            ** The result of the query is a subset of the complete query, depending on when the query engine detected that the limit was reached. The result may be empty if no result rows could be computed before reaching the limit.
            ** A warning is generated of the form: "Query execution was interrupted. The query examined at least 100 rows, which exceeds LIMIT ROWS EXAMINED (20). The query result may be incomplete."
            ** If query processing was interrupted during filesort, an error is returned in addition to the warning.
            ** If a UNION was interrupted during execution of one of its queries, the last step of the UNION is still executed in order to produce a partial result.
            ** Depending on the join and other execution strategies used for a query, the same query may produce no result at all, or a different subset of the complete result when terminated due to LIMIT ROWS EXAMINED.
            ** If the query contains a GROUP BY clause, the last group where the limit was reached will be discarded.

            The LIMIT ROWS EXAMINED clause cannot be specified on per-subquery basis. There can be only one LIMIT ROWS EXAMINED clause for the whole SELECT statement. If a SELECT statement contains several subqueries with LIMIT ROWS EXAMINED, the one that is parsed last is taken into account.


            h2. Low-level design:

            The implementation has the following aspects:

            # Counting the number of examined rows.
            # Checking if the limit has been exceeded.
            # Interrupting query execution.

            These are implemented as follows:

            h3. Counting the number of examined rows.

            The patch introduces a new thread-level counter
            {{THD::status_var::accessed_rows_and_keys}}. This counter is increased at each
            call to any of the family of handler methods {{handler::ha_*}}. Therefore this
            counter is equivalent to the sum of all counters increased by
            {{handler::increment_statistics()}}. Unlike all other handler counters in
            {{THD::status_var}}, accessed_rows_and_keys is reset automatically before each
            statement.

            The counter is equivalent to the sum of the following handler counters:

            ha_read_key_count, ha_read_next_count, ha_read_prev_count, ha_read_first_count,
            ha_read_last_count, ha_read_rnd_next_count, ha_read_rnd_count, ha_tmp_write_count,
            ha_tmp_update_count, ha_write_count, ha_update_count, ha_delete_count.

            These are the counters increased by handler::increment_statistics() which is
            used to increase the counted for LIMIT_ROWS_EXAMINED.

            h3. Checking if the limit has been exceeded.

            The test if LIMIT_ROWS_EXAMINED has been exceeded is done within each {{handler::ha_*}}
            handler call. Once this happens, the handler method sets {{THD::killed = ABORT_QUERY}},
            and issues a warning that can be tested with 'show warnings'. Here ABORT_QUERY
            is a new enum in {{enum killed_state}}.

            h3. Interrupting query execution.

            The implementation reuses the fact that the query executioner checks in
            multiple places if {{THD::killed}} has been set, and stops execution. One goal
            of this task is to stop execution, but still produce the rows found until
            LIMIT_ROWS_EXAMINED was reached. Therefore at the end of the main execution
            loop, the function {{do_select()}} resets both {{THD::killed}}, and the error
            code propagated from the underlying query execution functions. As a result:

            * execution is stopped,
            * a warning is generated,
            * the query finishes without an error (except when query execution was
              interrupted during filesort).

            h2. TODO:
            * fix the parser:
            ** reduce the number of shift/reduce conflicts
            ** consider issuing an error (or warning) if there is more than one
               LIMIT_ROWS_EXAMINED clause in the whole query.
            * run through QA, fix bugs.
            timour Timour Katchaounov (Inactive) made changes -
            Description h2. Description:

            The purpose of this task is to provide the means to terminate the execution of SELECT statements that examines too many rows, and thus uses too much resources. This is achieved through an extension of the LIMIT clause - LIMIT ROWS EXAMINED <number_of_rows>. Whenever possible the semantics of LIMIT ROWS EXAMINED is the same as that of normal LIMIT (for instance for aggregate functions).

            The current syntax for the clause is:

            {code}
            SELECT ... FROM ... WHERE ...
            [group_clause] [order_clause]
            LIMIT [[offset,] row_count] ROWS EXAMINED rows_limit;
            {code}

            Similar to the parameters of LIMIT, 'rows_limit' can be both a prepared statement parameter, or a stored program parameter.

            The LIMIT ROWS EXAMINED clause is global for the whole statement. If a composite query (such as UNION, or query with derived tables or with subqueries) contains more than one LIMIT ROWS EXAMINED, the last one parsed is taken into account. In this manner either the last or the outermost one is taken into account.

            The LIMIT ROWS EXAMINED clause is taken into account by the query engine only during query execution. Thus the clause is ignored in the following cases:
            * If a query is EXPLAIN-ed.
            * During query optimization.
            * During auxiliary operations such as writing to system tables (e.g. logs).

            The clause is not applicable to DELETE/UPDATE statements, and if used in these statements produces a syntax error.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows during query execution. This takes into account the use of temporary tables, and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT ROWS EXAMINED clause, query execution is terminated as soon as possible.

            * The effects of terminating the query because of LIMIT ROWS EXAMINED are as follows:
            ** The result of the query is a subset of the complete query, depending on when the query engine detected that the limit was reached. The result may be empty if no result rows could be computed before reaching the limit.
            ** A warning is generated of the form: "Query execution was interrupted. The query examined at least 100 rows, which exceeds LIMIT ROWS EXAMINED (20). The query result may be incomplete."
            ** If query processing was interrupted during filesort, an error is returned in addition to the warning.
            ** If a UNION was interrupted during execution of one of its queries, the last step of the UNION is still executed in order to produce a partial result.
            ** Depending on the join and other execution strategies used for a query, the same query may produce no result at all, or a different subset of the complete result when terminated due to LIMIT ROWS EXAMINED.
            ** If the query contains a GROUP BY clause, the last group where the limit was reached will be discarded.

            The LIMIT ROWS EXAMINED clause cannot be specified on per-subquery basis. There can be only one LIMIT ROWS EXAMINED clause for the whole SELECT statement. If a SELECT statement contains several subqueries with LIMIT ROWS EXAMINED, the one that is parsed last is taken into account.


            h2. Low-level design:

            The implementation has the following aspects:

            # Counting the number of examined rows.
            # Checking if the limit has been exceeded.
            # Interrupting query execution.

            These are implemented as follows:

            h3. Counting the number of examined rows.

            The patch introduces a new thread-level counter
            {{THD::status_var::accessed_rows_and_keys}}. This counter is increased at each
            call to any of the family of handler methods {{handler::ha_*}}. Therefore this
            counter is equivalent to the sum of all counters increased by
            {{handler::increment_statistics()}}. Unlike all other handler counters in
            {{THD::status_var}}, accessed_rows_and_keys is reset automatically before each
            statement.

            The counter is equivalent to the sum of the following handler counters:

            ha_read_key_count, ha_read_next_count, ha_read_prev_count, ha_read_first_count,
            ha_read_last_count, ha_read_rnd_next_count, ha_read_rnd_count, ha_tmp_write_count,
            ha_tmp_update_count, ha_write_count, ha_update_count, ha_delete_count.

            These are the counters increased by handler::increment_statistics() which is
            used to increase the counted for LIMIT_ROWS_EXAMINED.

            h3. Checking if the limit has been exceeded.

            The test if LIMIT_ROWS_EXAMINED has been exceeded is done within each {{handler::ha_*}}
            handler call. Once this happens, the handler method sets {{THD::killed = ABORT_QUERY}},
            and issues a warning that can be tested with 'show warnings'. Here ABORT_QUERY
            is a new enum in {{enum killed_state}}.

            h3. Interrupting query execution.

            The implementation reuses the fact that the query executioner checks in
            multiple places if {{THD::killed}} has been set, and stops execution. One goal
            of this task is to stop execution, but still produce the rows found until
            LIMIT_ROWS_EXAMINED was reached. Therefore at the end of the main execution
            loop, the function {{do_select()}} resets both {{THD::killed}}, and the error
            code propagated from the underlying query execution functions. As a result:

            * execution is stopped,
            * a warning is generated,
            * the query finishes without an error (except when query execution was
              interrupted during filesort).

            h2. TODO:
            * fix the parser:
            ** reduce the number of shift/reduce conflicts
            ** consider issuing an error (or warning) if there is more than one
               LIMIT_ROWS_EXAMINED clause in the whole query.
            * run through QA, fix bugs.
            h2. Description:

            The purpose of this task is to provide the means to terminate the execution of SELECT statements that examines too many rows, and thus uses too much resources. This is achieved through an extension of the LIMIT clause - LIMIT ROWS EXAMINED <number_of_rows>. Whenever possible the semantics of LIMIT ROWS EXAMINED is the same as that of normal LIMIT (for instance for aggregate functions).

            The current syntax for the clause is:

            {code}
            SELECT ... FROM ... WHERE ...
            [group_clause] [order_clause]
            LIMIT [[offset,] row_count] ROWS EXAMINED rows_limit;
            {code}

            Similar to the parameters of LIMIT, 'rows_limit' can be both a prepared statement parameter, or a stored program parameter.

            The LIMIT ROWS EXAMINED clause is global for the whole statement. If a composite query (such as UNION, or query with derived tables or with subqueries) contains more than one LIMIT ROWS EXAMINED, the last one parsed is taken into account. In this manner either the last or the outermost one is taken into account.

            The LIMIT ROWS EXAMINED clause is taken into account by the query engine only during query execution. Thus the clause is ignored in the following cases:
            * If a query is EXPLAIN-ed.
            * During query optimization.
            * During auxiliary operations such as writing to system tables (e.g. logs).

            The clause is not applicable to DELETE/UPDATE statements, and if used in these statements produces a syntax error.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows during query execution. This takes into account the use of temporary tables, and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT ROWS EXAMINED clause, query execution is terminated as soon as possible.

            * The effects of terminating the query because of LIMIT ROWS EXAMINED are as follows:
            ** The result of the query is a subset of the complete query, depending on when the query engine detected that the limit was reached. The result may be empty if no result rows could be computed before reaching the limit.
            ** A warning is generated of the form: "Query execution was interrupted. The query examined at least 100 rows, which exceeds LIMIT ROWS EXAMINED (20). The query result may be incomplete."
            ** If query processing was interrupted during filesort, an error is returned in addition to the warning.
            ** If a UNION was interrupted during execution of one of its queries, the last step of the UNION is still executed in order to produce a partial result.
            ** Depending on the join and other execution strategies used for a query, the same query may produce no result at all, or a different subset of the complete result when terminated due to LIMIT ROWS EXAMINED.
            ** If the query contains a GROUP BY clause, the last group where the limit was reached will be discarded.

            The LIMIT ROWS EXAMINED clause cannot be specified on per-subquery basis. There can be only one LIMIT ROWS EXAMINED clause for the whole SELECT statement. If a SELECT statement contains several subqueries with LIMIT ROWS EXAMINED, the one that is parsed last is taken into account.


            h2. Low-level design:

            The implementation has the following aspects:

            # Counting the number of examined rows.
            # Checking if the limit has been exceeded.
            # Interrupting query execution.

            These are implemented as follows:

            h3. Counting the number of examined rows.

            The patch introduces a new thread-level counter {{THD::accessed_rows_and_keys}}. This counter is increased at each call to any of the family of handler methods {{handler::ha_*}}. Therefore this counter is equivalent to the sum of all counters increased by {{handler::increment_statistics()}}. Unlike all other handler counters in {{THD::status_var}}, accessed_rows_and_keys is reset automatically before each statement.

            The counter is equivalent to the sum of the following handler counters:

            ha_read_key_count, ha_read_next_count, ha_read_prev_count, ha_read_first_count, ha_read_last_count, ha_read_rnd_next_count, ha_read_rnd_count, ha_tmp_write_count, ha_tmp_update_count, ha_write_count, ha_update_count, ha_delete_count.

            These are the counters increased by handler::increment_statistics() which is
            used to increase the counter for LIMIT ROWS EXAMINED.

            h3. Checking if the limit has been exceeded.

            The test if LIMIT_ROWS_EXAMINED has been exceeded is done in the method THD::check_limit_rows_examined(). This method is called by handler::increment_statistics(), which is called in its turn by all methods in the family {{handler::ha_*}}.

            Once the limit is exceeded, the handler method sets {{THD::killed = ABORT_QUERY}}, where ABORT_QUERY is a new enum in {{enum killed_state}}.

            In order not to stop query processing with an error, at the end of handle_select() we test for thd->killed == ABORT_QUERY, and if true,
            issue a warning, and reset the killed state. The warning can be tested with 'show warnings'.

            h3. Interrupting query execution.

            The implementation reuses the fact that the query executioner checks in
            multiple places if {{THD::killed}} has been set, and stops execution.

            One goal of this task is to stop execution, but still produce the rows found until LIMIT ROWS EXAMINED was reached. Therefore at the end of the main execution loop, the function {{handle_select()}} resets both {{THD::killed}}, and removes the limit in order not to affect data accesses needed for system purposes (such as writing to log tables). As a result:

            * query execution is stopped,
            * a warning is generated,
            * the query finishes without an error (except when query execution was
              interrupted during filesort).

            h2. TODO:
            * consider issuing an error (or warning) if there is more than one
               LIMIT ROWS EXAMINED clause in the whole query.

            timour Timour Katchaounov (Inactive) made changes -
            Description h2. Description:

            The purpose of this task is to provide the means to terminate the execution of SELECT statements that examines too many rows, and thus uses too much resources. This is achieved through an extension of the LIMIT clause - LIMIT ROWS EXAMINED <number_of_rows>. Whenever possible the semantics of LIMIT ROWS EXAMINED is the same as that of normal LIMIT (for instance for aggregate functions).

            The current syntax for the clause is:

            {code}
            SELECT ... FROM ... WHERE ...
            [group_clause] [order_clause]
            LIMIT [[offset,] row_count] ROWS EXAMINED rows_limit;
            {code}

            Similar to the parameters of LIMIT, 'rows_limit' can be both a prepared statement parameter, or a stored program parameter.

            The LIMIT ROWS EXAMINED clause is global for the whole statement. If a composite query (such as UNION, or query with derived tables or with subqueries) contains more than one LIMIT ROWS EXAMINED, the last one parsed is taken into account. In this manner either the last or the outermost one is taken into account.

            The LIMIT ROWS EXAMINED clause is taken into account by the query engine only during query execution. Thus the clause is ignored in the following cases:
            * If a query is EXPLAIN-ed.
            * During query optimization.
            * During auxiliary operations such as writing to system tables (e.g. logs).

            The clause is not applicable to DELETE/UPDATE statements, and if used in these statements produces a syntax error.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows during query execution. This takes into account the use of temporary tables, and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT ROWS EXAMINED clause, query execution is terminated as soon as possible.

            * The effects of terminating the query because of LIMIT ROWS EXAMINED are as follows:
            ** The result of the query is a subset of the complete query, depending on when the query engine detected that the limit was reached. The result may be empty if no result rows could be computed before reaching the limit.
            ** A warning is generated of the form: "Query execution was interrupted. The query examined at least 100 rows, which exceeds LIMIT ROWS EXAMINED (20). The query result may be incomplete."
            ** If query processing was interrupted during filesort, an error is returned in addition to the warning.
            ** If a UNION was interrupted during execution of one of its queries, the last step of the UNION is still executed in order to produce a partial result.
            ** Depending on the join and other execution strategies used for a query, the same query may produce no result at all, or a different subset of the complete result when terminated due to LIMIT ROWS EXAMINED.
            ** If the query contains a GROUP BY clause, the last group where the limit was reached will be discarded.

            The LIMIT ROWS EXAMINED clause cannot be specified on per-subquery basis. There can be only one LIMIT ROWS EXAMINED clause for the whole SELECT statement. If a SELECT statement contains several subqueries with LIMIT ROWS EXAMINED, the one that is parsed last is taken into account.


            h2. Low-level design:

            The implementation has the following aspects:

            # Counting the number of examined rows.
            # Checking if the limit has been exceeded.
            # Interrupting query execution.

            These are implemented as follows:

            h3. Counting the number of examined rows.

            The patch introduces a new thread-level counter {{THD::accessed_rows_and_keys}}. This counter is increased at each call to any of the family of handler methods {{handler::ha_*}}. Therefore this counter is equivalent to the sum of all counters increased by {{handler::increment_statistics()}}. Unlike all other handler counters in {{THD::status_var}}, accessed_rows_and_keys is reset automatically before each statement.

            The counter is equivalent to the sum of the following handler counters:

            ha_read_key_count, ha_read_next_count, ha_read_prev_count, ha_read_first_count, ha_read_last_count, ha_read_rnd_next_count, ha_read_rnd_count, ha_tmp_write_count, ha_tmp_update_count, ha_write_count, ha_update_count, ha_delete_count.

            These are the counters increased by handler::increment_statistics() which is
            used to increase the counter for LIMIT ROWS EXAMINED.

            h3. Checking if the limit has been exceeded.

            The test if LIMIT_ROWS_EXAMINED has been exceeded is done in the method THD::check_limit_rows_examined(). This method is called by handler::increment_statistics(), which is called in its turn by all methods in the family {{handler::ha_*}}.

            Once the limit is exceeded, the handler method sets {{THD::killed = ABORT_QUERY}}, where ABORT_QUERY is a new enum in {{enum killed_state}}.

            In order not to stop query processing with an error, at the end of handle_select() we test for thd->killed == ABORT_QUERY, and if true,
            issue a warning, and reset the killed state. The warning can be tested with 'show warnings'.

            h3. Interrupting query execution.

            The implementation reuses the fact that the query executioner checks in
            multiple places if {{THD::killed}} has been set, and stops execution.

            One goal of this task is to stop execution, but still produce the rows found until LIMIT ROWS EXAMINED was reached. Therefore at the end of the main execution loop, the function {{handle_select()}} resets both {{THD::killed}}, and removes the limit in order not to affect data accesses needed for system purposes (such as writing to log tables). As a result:

            * query execution is stopped,
            * a warning is generated,
            * the query finishes without an error (except when query execution was
              interrupted during filesort).

            h2. TODO:
            * consider issuing an error (or warning) if there is more than one
               LIMIT ROWS EXAMINED clause in the whole query.

            h2. Description:

            The purpose of this task is to provide the means to terminate the execution of SELECT statements that examines too many rows, and thus uses too much resources. This is achieved through an extension of the LIMIT clause - LIMIT ROWS EXAMINED <number_of_rows>. Whenever possible the semantics of LIMIT ROWS EXAMINED is the same as that of normal LIMIT (for instance for aggregate functions).

            The current syntax for the clause is:

            {code}
            SELECT ... FROM ... WHERE ...
            [group_clause] [order_clause]
            LIMIT [[offset,] row_count] ROWS EXAMINED rows_limit;
            {code}

            Similar to the parameters of LIMIT, 'rows_limit' can be both a prepared statement parameter, or a stored program parameter.

            A simple example of the clause is:
            {code}
            SELECT * from t1, t2 LIMIT 10 ROWS EXAMINED 10000;
            {code}

            The LIMIT ROWS EXAMINED clause is global for the whole statement. If a composite query (such as UNION, or query with derived tables or with subqueries) contains more than one LIMIT ROWS EXAMINED, the last one parsed is taken into account. In this manner either the last or the outermost one is taken into account. For instance, in the query:

            {code}
            SELECT * FROM t1
            WHERE c1 IN (SELECT * FROM t2 WHERE c2 > ' ' LIMIT ROWS EXAMINED 0)
            LIMIT ROWS EXAMINED 11;
            {code}

            The limit that is taken into account is {{11}}, not {{0}}.

            The LIMIT ROWS EXAMINED clause is taken into account by the query engine only during query execution. Thus the clause is ignored in the following cases:
            * If a query is EXPLAIN-ed.
            * During query optimization.
            * During auxiliary operations such as writing to system tables (e.g. logs).

            The clause is not applicable to DELETE/UPDATE statements, and if used in these statements produces a syntax error.

            The effects of this clause are as follows:

            * The server counts the number of read, inserted, modified, and deleted rows during query execution. This takes into account the use of temporary tables, and sorting for intermediate query operations.

            * Once the counter exceeds the value specified in the LIMIT ROWS EXAMINED clause, query execution is terminated as soon as possible.

            * The effects of terminating the query because of LIMIT ROWS EXAMINED are as follows:
            ** The result of the query is a subset of the complete query, depending on when the query engine detected that the limit was reached. The result may be empty if no result rows could be computed before reaching the limit.
            ** A warning is generated of the form: "Query execution was interrupted. The query examined at least 100 rows, which exceeds LIMIT ROWS EXAMINED (20). The query result may be incomplete."
            ** If query processing was interrupted during filesort, an error is returned in addition to the warning.
            ** If a UNION was interrupted during execution of one of its queries, the last step of the UNION is still executed in order to produce a partial result.
            ** Depending on the join and other execution strategies used for a query, the same query may produce no result at all, or a different subset of the complete result when terminated due to LIMIT ROWS EXAMINED.
            ** If the query contains a GROUP BY clause, the last group where the limit was reached will be discarded.

            The LIMIT ROWS EXAMINED clause cannot be specified on per-subquery basis. There can be only one LIMIT ROWS EXAMINED clause for the whole SELECT statement. If a SELECT statement contains several subqueries with LIMIT ROWS EXAMINED, the one that is parsed last is taken into account.


            h2. Low-level design:

            The implementation has the following aspects:

            # Counting the number of examined rows.
            # Checking if the limit has been exceeded.
            # Interrupting query execution.

            These are implemented as follows:

            h3. Counting the number of examined rows.

            The patch introduces a new thread-level counter {{THD::accessed_rows_and_keys}}. This counter is increased at each call to any of the family of handler methods {{handler::ha_*}}. Therefore this counter is equivalent to the sum of all counters increased by {{handler::increment_statistics()}}. Unlike all other handler counters in {{THD::status_var}}, accessed_rows_and_keys is reset automatically before each statement.

            The counter is equivalent to the sum of the following handler counters:

            ha_read_key_count, ha_read_next_count, ha_read_prev_count, ha_read_first_count, ha_read_last_count, ha_read_rnd_next_count, ha_read_rnd_count, ha_tmp_write_count, ha_tmp_update_count, ha_write_count, ha_update_count, ha_delete_count.

            These are the counters increased by handler::increment_statistics() which is
            used to increase the counter for LIMIT ROWS EXAMINED.

            h3. Checking if the limit has been exceeded.

            The test if LIMIT_ROWS_EXAMINED has been exceeded is done in the method THD::check_limit_rows_examined(). This method is called by handler::increment_statistics(), which is called in its turn by all methods in the family {{handler::ha_*}}.

            Once the limit is exceeded, the handler method sets {{THD::killed = ABORT_QUERY}}, where ABORT_QUERY is a new enum in {{enum killed_state}}.

            In order not to stop query processing with an error, at the end of handle_select() we test for thd->killed == ABORT_QUERY, and if true,
            issue a warning, and reset the killed state. The warning can be tested with 'show warnings'.

            h3. Interrupting query execution.

            The implementation reuses the fact that the query executioner checks in
            multiple places if {{THD::killed}} has been set, and stops execution.

            One goal of this task is to stop execution, but still produce the rows found until LIMIT ROWS EXAMINED was reached. Therefore at the end of the main execution loop, the function {{handle_select()}} resets both {{THD::killed}}, and removes the limit in order not to affect data accesses needed for system purposes (such as writing to log tables). As a result:

            * query execution is stopped,
            * a warning is generated,
            * the query finishes without an error (except when query execution was
              interrupted during filesort).

            h2. TODO:
            * consider issuing an error (or warning) if there is more than one
               LIMIT ROWS EXAMINED clause in the whole query.

            timour Timour Katchaounov (Inactive) made changes -
            Status In Progress [ 3 ] Open [ 1 ]
            timour Timour Katchaounov (Inactive) made changes -
            Status Open [ 1 ] In Progress [ 3 ]

            Resolved remaining issues, merged with 5.5 and pushed into 5.5.

            timour Timour Katchaounov (Inactive) added a comment - Resolved remaining issues, merged with 5.5 and pushed into 5.5.
            timour Timour Katchaounov (Inactive) made changes -
            Resolution Fixed [ 1 ]
            Status In Progress [ 3 ] Closed [ 6 ]
            serg Sergei Golubchik made changes -
            Workflow defaullt [ 10721 ] MariaDB v2 [ 44440 ]
            ratzpo Rasmus Johansson (Inactive) made changes -
            Workflow MariaDB v2 [ 44440 ] MariaDB v3 [ 63796 ]
            serg Sergei Golubchik made changes -
            Workflow MariaDB v3 [ 63796 ] MariaDB v4 [ 131878 ]

            People

              timour Timour Katchaounov (Inactive)
              timour Timour Katchaounov (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.