Loading Docs/manual.texi +45 −2 Original line number Diff line number Diff line Loading @@ -409,6 +409,7 @@ MySQL Language Reference * LOCK TABLES:: @code{LOCK TABLES/UNLOCK TABLES} syntax * SET OPTION:: @code{SET OPTION} syntax * GRANT:: @code{GRANT} and @code{REVOKE} syntax * HANDLER:: @code{HANDLER} syntax * CREATE INDEX:: @code{CREATE INDEX} syntax * DROP INDEX:: @code{DROP INDEX} syntax * Comments:: Comment syntax Loading Loading @@ -13483,6 +13484,7 @@ to restart @code{mysqld} with @code{--skip-grant-tables} to run * SET OPTION:: @code{SET OPTION} syntax * SET TRANSACTION:: @code{SET TRANSACTION} syntax * GRANT:: @code{GRANT} and @code{REVOKE} syntax * HANDLER:: @code{HANDLER} syntax * CREATE INDEX:: @code{CREATE INDEX} syntax * DROP INDEX:: @code{DROP INDEX} syntax * Comments:: Comment syntax Loading Loading @@ -22396,7 +22398,7 @@ You can set the default isolation level for @code{mysqld} with @findex GRANT @findex REVOKE @node GRANT, CREATE INDEX, SET TRANSACTION, Reference @node GRANT, HANDLER, SET TRANSACTION, Reference @section @code{GRANT} and @code{REVOKE} Syntax @example Loading Loading @@ -22624,11 +22626,52 @@ dropped only with explicit @code{REVOKE} commands or by manipulating the @strong{MySQL} grant tables. @end itemize @findex HANDLER @node HANDLER, CREATE INDEX, GRANT, Reference @section @code{HANDLER} Syntax @example HANDLER table OPEN [ AS alias ] HANDLER table READ index @{ = | >= | <= | < @} (value1, value2, ... ) [ WHERE ... ] [LIMIT ... ] HANDLER table READ index @{ FIRST | NEXT | PREV | LAST @} [ WHERE ... ] [LIMIT ... ] HANDLER table READ @{ FIRST | NEXT @} [ WHERE ... ] [LIMIT ... ] HANDLER table CLOSE @end example The @code{HANDLER} statement provides direct access to @strong{MySQL} table interface, bypassing SQL optimizer. Thus, it is faster then SELECT. The first form of @code{HANDLER} statement opens a table, making in accessible via the following @code{HANDLER ... READ} routines. The second form fetches one (or, specified by @code{LIMIT} clause) row where the index specified complies to the condition and @code{WHERE} condition is met. If the index consists of several parts (spans over several columns) the values are specified in comma-separated list, providing values only for few first columns is possible. The third form fetches one (or, specified by @code{LIMIT} clause) row from the table in index order, matching @code{WHERE} condition. The fourth form (without index specification) fetches one (or, specified by @code{LIMIT} clause) row from the table in natural row order (as stored in data file) matching @code{WHERE} condition. It is faster than @code{HANDLER table READ index} when full table scan is desired. The last form closes the table, opened with @code{HANDLER ... OPEN}. @code{HANDLER} is somewhat low-level statement, for example it does not provide consistency. That is @code{HANDLER ... OPEN} does @strong{not} takes a snapshot of the table, and does @strong{not} locks the table. The above means, that after @code{HANDLER ... OPEN} table data can be modified (by this or other thread) and these modifications may appear only partially in @code{HANDLER ... NEXT} or @code{HANDLER ... PREV} scans. @cindex indexes @cindex indexes, multi-part @cindex multi-part index @findex CREATE INDEX @node CREATE INDEX, DROP INDEX, GRANT, Reference @node CREATE INDEX, DROP INDEX, HANDLER, Reference @section @code{CREATE INDEX} Syntax @example mysql-test/t/handler.test +10 −1 Original line number Diff line number Diff line Loading @@ -5,8 +5,8 @@ drop table if exists t1; create table t1 (a int, b char(10), key a(a), key b(a,b)); insert into t1 values (14,"aaa"),(15,"bbb"),(16,"ccc"),(16,"xxx"), (17,"ddd"),(18,"eee"),(19,"fff"),(19,"yyy"), (14,"aaa"),(15,"bbb"),(16,"ccc"),(16,"xxx"), (20,"ggg"),(21,"hhh"),(22,"iii"); handler t1 open as t2; handler t2 read a first; Loading Loading @@ -50,7 +50,16 @@ handler t2 read a next limit 3; handler t2 read a prev limit 10; handler t2 read a>=(16) limit 4; handler t2 read a>=(16) limit 2,2; handler t2 read a last limit 3; handler t2 read a=(19); handler t2 read a=(19) where b="yyy"; handler t2 read first; handler t2 read next; handler t2 read next; handler t2 read last; handler t2 close; drop table if exists t1; sql/mysql_priv.h +2 −2 Original line number Diff line number Diff line Loading @@ -384,8 +384,8 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables); /* sql_handler.cc */ int mysql_ha_open(THD *thd, TABLE_LIST *tables); int mysql_ha_close(THD *thd, TABLE_LIST *tables); int mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes, char *,List<Item> *,enum ha_rkey_function,ha_rows,ha_rows); int mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *, List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows); /* sql_base.cc */ void set_item_name(Item *item,char *pos,uint length); Loading sql/sql_base.cc +1 −1 Original line number Diff line number Diff line Loading @@ -407,7 +407,7 @@ void close_thread_tables(THD *thd, bool locked) { DBUG_ENTER("close_thread_tables"); if (thd->locked_tables || thd->manual_open) if (thd->locked_tables) DBUG_VOID_RETURN; // LOCK TABLES in use TABLE *table,*next; Loading sql/sql_class.cc +9 −4 Original line number Diff line number Diff line Loading @@ -76,7 +76,7 @@ static void free_var(user_var_entry *entry) ****************************************************************************/ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), insert_id_used(0),in_lock_tables(0),manual_open(0), insert_id_used(0),in_lock_tables(0), global_read_lock(0),bootstrap(0) { host=user=priv_user=db=query=ip=0; Loading @@ -85,7 +85,8 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), query_length=col_access=0; query_error=0; next_insert_id=last_insert_id=0; open_tables=temporary_tables=0; open_tables=temporary_tables=handler_tables=0; handler_items=0; tmp_table=0; lock=locked_tables=0; used_tables=0; Loading Loading @@ -158,10 +159,14 @@ THD::~THD() net_end(&net); } ha_rollback(this); if (locked_tables || manual_open) if (locked_tables) { lock=locked_tables; locked_tables=0; manual_open=0; close_thread_tables(this); } if (handler_tables) { open_tables=handler_tables; handler_tables=0; close_thread_tables(this); } close_temporary_tables(this); Loading Loading
Docs/manual.texi +45 −2 Original line number Diff line number Diff line Loading @@ -409,6 +409,7 @@ MySQL Language Reference * LOCK TABLES:: @code{LOCK TABLES/UNLOCK TABLES} syntax * SET OPTION:: @code{SET OPTION} syntax * GRANT:: @code{GRANT} and @code{REVOKE} syntax * HANDLER:: @code{HANDLER} syntax * CREATE INDEX:: @code{CREATE INDEX} syntax * DROP INDEX:: @code{DROP INDEX} syntax * Comments:: Comment syntax Loading Loading @@ -13483,6 +13484,7 @@ to restart @code{mysqld} with @code{--skip-grant-tables} to run * SET OPTION:: @code{SET OPTION} syntax * SET TRANSACTION:: @code{SET TRANSACTION} syntax * GRANT:: @code{GRANT} and @code{REVOKE} syntax * HANDLER:: @code{HANDLER} syntax * CREATE INDEX:: @code{CREATE INDEX} syntax * DROP INDEX:: @code{DROP INDEX} syntax * Comments:: Comment syntax Loading Loading @@ -22396,7 +22398,7 @@ You can set the default isolation level for @code{mysqld} with @findex GRANT @findex REVOKE @node GRANT, CREATE INDEX, SET TRANSACTION, Reference @node GRANT, HANDLER, SET TRANSACTION, Reference @section @code{GRANT} and @code{REVOKE} Syntax @example Loading Loading @@ -22624,11 +22626,52 @@ dropped only with explicit @code{REVOKE} commands or by manipulating the @strong{MySQL} grant tables. @end itemize @findex HANDLER @node HANDLER, CREATE INDEX, GRANT, Reference @section @code{HANDLER} Syntax @example HANDLER table OPEN [ AS alias ] HANDLER table READ index @{ = | >= | <= | < @} (value1, value2, ... ) [ WHERE ... ] [LIMIT ... ] HANDLER table READ index @{ FIRST | NEXT | PREV | LAST @} [ WHERE ... ] [LIMIT ... ] HANDLER table READ @{ FIRST | NEXT @} [ WHERE ... ] [LIMIT ... ] HANDLER table CLOSE @end example The @code{HANDLER} statement provides direct access to @strong{MySQL} table interface, bypassing SQL optimizer. Thus, it is faster then SELECT. The first form of @code{HANDLER} statement opens a table, making in accessible via the following @code{HANDLER ... READ} routines. The second form fetches one (or, specified by @code{LIMIT} clause) row where the index specified complies to the condition and @code{WHERE} condition is met. If the index consists of several parts (spans over several columns) the values are specified in comma-separated list, providing values only for few first columns is possible. The third form fetches one (or, specified by @code{LIMIT} clause) row from the table in index order, matching @code{WHERE} condition. The fourth form (without index specification) fetches one (or, specified by @code{LIMIT} clause) row from the table in natural row order (as stored in data file) matching @code{WHERE} condition. It is faster than @code{HANDLER table READ index} when full table scan is desired. The last form closes the table, opened with @code{HANDLER ... OPEN}. @code{HANDLER} is somewhat low-level statement, for example it does not provide consistency. That is @code{HANDLER ... OPEN} does @strong{not} takes a snapshot of the table, and does @strong{not} locks the table. The above means, that after @code{HANDLER ... OPEN} table data can be modified (by this or other thread) and these modifications may appear only partially in @code{HANDLER ... NEXT} or @code{HANDLER ... PREV} scans. @cindex indexes @cindex indexes, multi-part @cindex multi-part index @findex CREATE INDEX @node CREATE INDEX, DROP INDEX, GRANT, Reference @node CREATE INDEX, DROP INDEX, HANDLER, Reference @section @code{CREATE INDEX} Syntax @example
mysql-test/t/handler.test +10 −1 Original line number Diff line number Diff line Loading @@ -5,8 +5,8 @@ drop table if exists t1; create table t1 (a int, b char(10), key a(a), key b(a,b)); insert into t1 values (14,"aaa"),(15,"bbb"),(16,"ccc"),(16,"xxx"), (17,"ddd"),(18,"eee"),(19,"fff"),(19,"yyy"), (14,"aaa"),(15,"bbb"),(16,"ccc"),(16,"xxx"), (20,"ggg"),(21,"hhh"),(22,"iii"); handler t1 open as t2; handler t2 read a first; Loading Loading @@ -50,7 +50,16 @@ handler t2 read a next limit 3; handler t2 read a prev limit 10; handler t2 read a>=(16) limit 4; handler t2 read a>=(16) limit 2,2; handler t2 read a last limit 3; handler t2 read a=(19); handler t2 read a=(19) where b="yyy"; handler t2 read first; handler t2 read next; handler t2 read next; handler t2 read last; handler t2 close; drop table if exists t1;
sql/mysql_priv.h +2 −2 Original line number Diff line number Diff line Loading @@ -384,8 +384,8 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables); /* sql_handler.cc */ int mysql_ha_open(THD *thd, TABLE_LIST *tables); int mysql_ha_close(THD *thd, TABLE_LIST *tables); int mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes, char *,List<Item> *,enum ha_rkey_function,ha_rows,ha_rows); int mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *, List<Item> *,enum ha_rkey_function,Item *,ha_rows,ha_rows); /* sql_base.cc */ void set_item_name(Item *item,char *pos,uint length); Loading
sql/sql_base.cc +1 −1 Original line number Diff line number Diff line Loading @@ -407,7 +407,7 @@ void close_thread_tables(THD *thd, bool locked) { DBUG_ENTER("close_thread_tables"); if (thd->locked_tables || thd->manual_open) if (thd->locked_tables) DBUG_VOID_RETURN; // LOCK TABLES in use TABLE *table,*next; Loading
sql/sql_class.cc +9 −4 Original line number Diff line number Diff line Loading @@ -76,7 +76,7 @@ static void free_var(user_var_entry *entry) ****************************************************************************/ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), insert_id_used(0),in_lock_tables(0),manual_open(0), insert_id_used(0),in_lock_tables(0), global_read_lock(0),bootstrap(0) { host=user=priv_user=db=query=ip=0; Loading @@ -85,7 +85,8 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), query_length=col_access=0; query_error=0; next_insert_id=last_insert_id=0; open_tables=temporary_tables=0; open_tables=temporary_tables=handler_tables=0; handler_items=0; tmp_table=0; lock=locked_tables=0; used_tables=0; Loading Loading @@ -158,10 +159,14 @@ THD::~THD() net_end(&net); } ha_rollback(this); if (locked_tables || manual_open) if (locked_tables) { lock=locked_tables; locked_tables=0; manual_open=0; close_thread_tables(this); } if (handler_tables) { open_tables=handler_tables; handler_tables=0; close_thread_tables(this); } close_temporary_tables(this); Loading