Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
ce3b58d6
Commit
ce3b58d6
authored
Apr 13, 2001
by
unknown
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
this won't be pushed
Docs/manual.texi: HANDLER documented mysql-test/t/handler.test: more tests
parent
9ba06976
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
240 additions
and
131 deletions
+240
-131
Docs/manual.texi
Docs/manual.texi
+45
-2
mysql-test/t/handler.test
mysql-test/t/handler.test
+10
-1
sql/mysql_priv.h
sql/mysql_priv.h
+2
-2
sql/sql_base.cc
sql/sql_base.cc
+1
-1
sql/sql_class.cc
sql/sql_class.cc
+9
-4
sql/sql_class.h
sql/sql_class.h
+3
-3
sql/sql_handler.cc
sql/sql_handler.cc
+140
-85
sql/sql_parse.cc
sql/sql_parse.cc
+3
-3
sql/sql_yacc.yy
sql/sql_yacc.yy
+27
-30
No files found.
Docs/manual.texi
View file @
ce3b58d6
...
@@ -409,6 +409,7 @@ MySQL Language Reference
...
@@ -409,6 +409,7 @@ MySQL Language Reference
* LOCK TABLES:: @code{LOCK TABLES/UNLOCK TABLES} syntax
* LOCK TABLES:: @code{LOCK TABLES/UNLOCK TABLES} syntax
* SET OPTION:: @code{SET OPTION} syntax
* SET OPTION:: @code{SET OPTION} syntax
* GRANT:: @code{GRANT} and @code{REVOKE} syntax
* GRANT:: @code{GRANT} and @code{REVOKE} syntax
* HANDLER:: @code{HANDLER} syntax
* CREATE INDEX:: @code{CREATE INDEX} syntax
* CREATE INDEX:: @code{CREATE INDEX} syntax
* DROP INDEX:: @code{DROP INDEX} syntax
* DROP INDEX:: @code{DROP INDEX} syntax
* Comments:: Comment syntax
* Comments:: Comment syntax
...
@@ -13483,6 +13484,7 @@ to restart @code{mysqld} with @code{--skip-grant-tables} to run
...
@@ -13483,6 +13484,7 @@ to restart @code{mysqld} with @code{--skip-grant-tables} to run
* SET OPTION:: @code{SET OPTION} syntax
* SET OPTION:: @code{SET OPTION} syntax
* SET TRANSACTION:: @code{SET TRANSACTION} syntax
* SET TRANSACTION:: @code{SET TRANSACTION} syntax
* GRANT:: @code{GRANT} and @code{REVOKE} syntax
* GRANT:: @code{GRANT} and @code{REVOKE} syntax
* HANDLER:: @code{HANDLER} syntax
* CREATE INDEX:: @code{CREATE INDEX} syntax
* CREATE INDEX:: @code{CREATE INDEX} syntax
* DROP INDEX:: @code{DROP INDEX} syntax
* DROP INDEX:: @code{DROP INDEX} syntax
* Comments:: Comment syntax
* Comments:: Comment syntax
...
@@ -22396,7 +22398,7 @@ You can set the default isolation level for @code{mysqld} with
...
@@ -22396,7 +22398,7 @@ You can set the default isolation level for @code{mysqld} with
@findex GRANT
@findex GRANT
@findex REVOKE
@findex REVOKE
@node GRANT,
CREATE INDEX
, SET TRANSACTION, Reference
@node GRANT,
HANDLER
, SET TRANSACTION, Reference
@section @code{GRANT} and @code{REVOKE} Syntax
@section @code{GRANT} and @code{REVOKE} Syntax
@example
@example
...
@@ -22624,11 +22626,52 @@ dropped only with explicit @code{REVOKE} commands or by manipulating the
...
@@ -22624,11 +22626,52 @@ dropped only with explicit @code{REVOKE} commands or by manipulating the
@strong{MySQL} grant tables.
@strong{MySQL} grant tables.
@end itemize
@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
@cindex indexes, multi-part
@cindex indexes, multi-part
@cindex multi-part index
@cindex multi-part index
@findex CREATE INDEX
@findex CREATE INDEX
@node CREATE INDEX, DROP INDEX,
GRANT
, Reference
@node CREATE INDEX, DROP INDEX,
HANDLER
, Reference
@section @code{CREATE INDEX} Syntax
@section @code{CREATE INDEX} Syntax
@example
@example
mysql-test/t/handler.test
View file @
ce3b58d6
...
@@ -5,8 +5,8 @@
...
@@ -5,8 +5,8 @@
drop
table
if
exists
t1
;
drop
table
if
exists
t1
;
create
table
t1
(
a
int
,
b
char
(
10
),
key
a
(
a
),
key
b
(
a
,
b
));
create
table
t1
(
a
int
,
b
char
(
10
),
key
a
(
a
),
key
b
(
a
,
b
));
insert
into
t1
values
insert
into
t1
values
(
14
,
"aaa"
),(
15
,
"bbb"
),(
16
,
"ccc"
),(
16
,
"xxx"
),
(
17
,
"ddd"
),(
18
,
"eee"
),(
19
,
"fff"
),(
19
,
"yyy"
),
(
17
,
"ddd"
),(
18
,
"eee"
),(
19
,
"fff"
),(
19
,
"yyy"
),
(
14
,
"aaa"
),(
15
,
"bbb"
),(
16
,
"ccc"
),(
16
,
"xxx"
),
(
20
,
"ggg"
),(
21
,
"hhh"
),(
22
,
"iii"
);
(
20
,
"ggg"
),(
21
,
"hhh"
),(
22
,
"iii"
);
handler
t1
open
as
t2
;
handler
t1
open
as
t2
;
handler
t2
read
a
first
;
handler
t2
read
a
first
;
...
@@ -50,7 +50,16 @@ handler t2 read a next limit 3;
...
@@ -50,7 +50,16 @@ handler t2 read a next limit 3;
handler
t2
read
a
prev
limit
10
;
handler
t2
read
a
prev
limit
10
;
handler
t2
read
a
>=
(
16
)
limit
4
;
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
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
;
handler
t2
close
;
drop
table
if
exists
t1
;
drop
table
if
exists
t1
;
sql/mysql_priv.h
View file @
ce3b58d6
...
@@ -384,8 +384,8 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables);
...
@@ -384,8 +384,8 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables);
/* sql_handler.cc */
/* sql_handler.cc */
int
mysql_ha_open
(
THD
*
thd
,
TABLE_LIST
*
tables
);
int
mysql_ha_open
(
THD
*
thd
,
TABLE_LIST
*
tables
);
int
mysql_ha_close
(
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
,
int
mysql_ha_read
(
THD
*
,
TABLE_LIST
*
,
enum
enum_ha_read_modes
,
char
*
,
char
*
,
List
<
Item
>
*
,
enum
ha_rkey_function
,
ha_rows
,
ha_rows
);
List
<
Item
>
*
,
enum
ha_rkey_function
,
Item
*
,
ha_rows
,
ha_rows
);
/* sql_base.cc */
/* sql_base.cc */
void
set_item_name
(
Item
*
item
,
char
*
pos
,
uint
length
);
void
set_item_name
(
Item
*
item
,
char
*
pos
,
uint
length
);
...
...
sql/sql_base.cc
View file @
ce3b58d6
...
@@ -407,7 +407,7 @@ void close_thread_tables(THD *thd, bool locked)
...
@@ -407,7 +407,7 @@ void close_thread_tables(THD *thd, bool locked)
{
{
DBUG_ENTER
(
"close_thread_tables"
);
DBUG_ENTER
(
"close_thread_tables"
);
if
(
thd
->
locked_tables
||
thd
->
manual_open
)
if
(
thd
->
locked_tables
)
DBUG_VOID_RETURN
;
// LOCK TABLES in use
DBUG_VOID_RETURN
;
// LOCK TABLES in use
TABLE
*
table
,
*
next
;
TABLE
*
table
,
*
next
;
...
...
sql/sql_class.cc
View file @
ce3b58d6
...
@@ -76,7 +76,7 @@ static void free_var(user_var_entry *entry)
...
@@ -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
),
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
)
global_read_lock
(
0
),
bootstrap
(
0
)
{
{
host
=
user
=
priv_user
=
db
=
query
=
ip
=
0
;
host
=
user
=
priv_user
=
db
=
query
=
ip
=
0
;
...
@@ -85,7 +85,8 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
...
@@ -85,7 +85,8 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
query_length
=
col_access
=
0
;
query_length
=
col_access
=
0
;
query_error
=
0
;
query_error
=
0
;
next_insert_id
=
last_insert_id
=
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
;
tmp_table
=
0
;
lock
=
locked_tables
=
0
;
lock
=
locked_tables
=
0
;
used_tables
=
0
;
used_tables
=
0
;
...
@@ -158,10 +159,14 @@ THD::~THD()
...
@@ -158,10 +159,14 @@ THD::~THD()
net_end
(
&
net
);
net_end
(
&
net
);
}
}
ha_rollback
(
this
);
ha_rollback
(
this
);
if
(
locked_tables
||
manual_open
)
if
(
locked_tables
)
{
{
lock
=
locked_tables
;
locked_tables
=
0
;
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_thread_tables
(
this
);
}
}
close_temporary_tables
(
this
);
close_temporary_tables
(
this
);
...
...
sql/sql_class.h
View file @
ce3b58d6
...
@@ -231,7 +231,7 @@ class THD :public ilink {
...
@@ -231,7 +231,7 @@ class THD :public ilink {
const
char
*
proc_info
;
const
char
*
proc_info
;
uint
client_capabilities
,
max_packet_length
;
uint
client_capabilities
,
max_packet_length
;
uint
master_access
,
db_access
;
uint
master_access
,
db_access
;
TABLE
*
open_tables
,
*
temporary_tables
;
TABLE
*
open_tables
,
*
temporary_tables
,
*
handler_tables
;
MYSQL_LOCK
*
lock
,
*
locked_tables
;
MYSQL_LOCK
*
lock
,
*
locked_tables
;
ULL
*
ull
;
ULL
*
ull
;
struct
st_my_thread_var
*
mysys_var
;
struct
st_my_thread_var
*
mysys_var
;
...
@@ -253,7 +253,7 @@ class THD :public ilink {
...
@@ -253,7 +253,7 @@ class THD :public ilink {
#ifdef HAVE_GEMINI_DB
#ifdef HAVE_GEMINI_DB
struct
st_gemini
gemini
;
struct
st_gemini
gemini
;
#endif
#endif
Item
*
free_list
;
Item
*
free_list
,
*
handler_items
;
CONVERT
*
convert_set
;
CONVERT
*
convert_set
;
Field
*
dupp_field
;
Field
*
dupp_field
;
#ifndef __WIN__
#ifndef __WIN__
...
@@ -278,7 +278,7 @@ class THD :public ilink {
...
@@ -278,7 +278,7 @@ class THD :public ilink {
bool
slave_thread
;
bool
slave_thread
;
bool
set_query_id
,
locked
,
count_cuted_fields
,
some_tables_deleted
;
bool
set_query_id
,
locked
,
count_cuted_fields
,
some_tables_deleted
;
bool
no_errors
,
allow_sum_func
,
password
,
fatal_error
;
bool
no_errors
,
allow_sum_func
,
password
,
fatal_error
;
bool
query_start_used
,
last_insert_id_used
,
insert_id_used
,
manual_open
;
bool
query_start_used
,
last_insert_id_used
,
insert_id_used
;
bool
system_thread
,
in_lock_tables
,
global_read_lock
;
bool
system_thread
,
in_lock_tables
,
global_read_lock
;
bool
query_error
,
bootstrap
;
bool
query_error
,
bootstrap
;
bool
volatile
killed
;
bool
volatile
killed
;
...
...
sql/sql_handler.cc
View file @
ce3b58d6
...
@@ -17,23 +17,53 @@
...
@@ -17,23 +17,53 @@
/* HANDLER ... commands - direct access to ISAM */
/* HANDLER ... commands - direct access to ISAM */
#include <assert.h>
#include "mysql_priv.h"
#include "mysql_priv.h"
#include "sql_select.h"
#include "sql_select.h"
/* TODO:
HANDLER blabla OPEN [ AS foobar ] [ (column-list) ]
the most natural (easiest, fastest) way to do it is to
compute List<Item> field_list not in mysql_ha_read
but in mysql_ha_open, and then store it in TABLE structure.
The problem here is that mysql_parse calls free_item to free all the
items allocated at the end of every query. The workaround would to
keep two item lists per THD - normal free_list and handler_items.
The second is to be freeed only on thread end. mysql_ha_open should
then do { handler_items=concat(handler_items, free_list); free_list=0; }
But !!! do_cammand calls free_root at the end of every query and frees up
all the sql_alloc'ed memory. It's harder to work around...
*/
#define HANDLER_TABLES_HACK(thd) { \
TABLE *tmp=thd->open_tables; \
thd->open_tables=thd->handler_tables; \
thd->handler_tables=tmp; }
static
TABLE
*
find_table_by_name
(
THD
*
thd
,
char
*
db
,
char
*
table_name
);
static
TABLE
*
find_table_by_name
(
THD
*
thd
,
char
*
db
,
char
*
table_name
);
int
mysql_ha_open
(
THD
*
thd
,
TABLE_LIST
*
tables
)
int
mysql_ha_open
(
THD
*
thd
,
TABLE_LIST
*
tables
)
{
{
HANDLER_TABLES_HACK
(
thd
);
int
err
=
open_tables
(
thd
,
tables
);
int
err
=
open_tables
(
thd
,
tables
);
if
(
!
err
)
HANDLER_TABLES_HACK
(
thd
);
{
if
(
err
)
thd
->
manual_open
=
1
;
return
-
1
;
send_ok
(
&
thd
->
net
);
}
send_ok
(
&
thd
->
net
);
return
0
;
}
}
int
mysql_ha_close
(
THD
*
thd
,
TABLE_LIST
*
tables
)
int
mysql_ha_close
(
THD
*
thd
,
TABLE_LIST
*
tables
)
{
{
/* Perhaps, we should close table here.
But it's not easy - *tables is a single-linked list, designed
to be closed at all once.
So, why bother ? All the tables will be closed at thread exit.
*/
send_ok
(
&
thd
->
net
);
send_ok
(
&
thd
->
net
);
return
0
;
return
0
;
}
}
...
@@ -43,27 +73,30 @@ static enum enum_ha_read_modes rkey_to_rnext[]=
...
@@ -43,27 +73,30 @@ static enum enum_ha_read_modes rkey_to_rnext[]=
int
mysql_ha_read
(
THD
*
thd
,
TABLE_LIST
*
tables
,
int
mysql_ha_read
(
THD
*
thd
,
TABLE_LIST
*
tables
,
enum
enum_ha_read_modes
mode
,
char
*
keyname
,
List
<
Item
>
*
key_expr
,
enum
enum_ha_read_modes
mode
,
char
*
keyname
,
List
<
Item
>
*
key_expr
,
enum
ha_rkey_function
ha_rkey_mode
,
enum
ha_rkey_function
ha_rkey_mode
,
Item
*
cond
,
ha_rows
select_limit
,
ha_rows
offset_limit
)
ha_rows
select_limit
,
ha_rows
offset_limit
)
{
{
int
err
;
int
err
,
keyno
=-
1
;
TABLE
*
table
=
find_table_by_name
(
thd
,
tables
->
db
,
tables
->
name
);
TABLE
*
table
=
find_table_by_name
(
thd
,
tables
->
db
,
tables
->
name
);
if
(
!
table
)
if
(
!
table
)
{
{
my_printf_error
(
ER_UNKNOWN_TABLE
,
ER
(
ER_UNKNOWN_TABLE
),
MYF
(
0
),
my_printf_error
(
ER_UNKNOWN_TABLE
,
ER
(
ER_UNKNOWN_TABLE
),
MYF
(
0
),
tables
->
name
,
"HANDLER"
);
tables
->
name
,
"HANDLER"
);
// send_error(&thd->net,ER_UNKNOWN_TABLE);
// send_ok(&thd->net);
return
-
1
;
return
-
1
;
}
}
tables
->
table
=
table
;
tables
->
table
=
table
;
if
(
cond
&&
cond
->
fix_fields
(
thd
,
tables
))
return
-
1
;
int
keyno
=
find_type
(
keyname
,
&
table
->
keynames
,
1
+
2
)
-
1
;
if
(
keyname
)
if
(
keyno
<
0
)
{
{
my_printf_error
(
ER_KEY_DOES_NOT_EXITS
,
ER
(
ER_KEY_DOES_NOT_EXITS
),
MYF
(
0
),
if
((
keyno
=
find_type
(
keyname
,
&
table
->
keynames
,
1
+
2
)
-
1
)
<
0
)
keyname
,
tables
->
name
);
{
return
-
1
;
my_printf_error
(
ER_KEY_DOES_NOT_EXITS
,
ER
(
ER_KEY_DOES_NOT_EXITS
),
MYF
(
0
),
keyname
,
tables
->
name
);
return
-
1
;
}
}
}
List
<
Item
>
list
;
List
<
Item
>
list
;
...
@@ -72,99 +105,121 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
...
@@ -72,99 +105,121 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
it
++
;
it
++
;
insert_fields
(
thd
,
tables
,
tables
->
name
,
&
it
);
insert_fields
(
thd
,
tables
,
tables
->
name
,
&
it
);
table
->
file
->
index_init
(
keyno
);
table
->
file
->
index_init
(
keyno
);
select_limit
+=
offset_limit
;
send_fields
(
thd
,
list
,
1
);
if
(
select_limit
==
thd
->
default_select_limit
)
select_limit
=
1
;
MYSQL_LOCK
*
lock
=
mysql_lock_tables
(
thd
,
&
tables
->
table
,
1
)
;
select_limit
+=
offset_limit
;
for
(
uint
num_rows
=
0
;
num_rows
<
select_limit
;
)
for
(
uint
num_rows
=
0
;
num_rows
<
select_limit
;
num_rows
++
)
{
{
switch
(
mode
)
switch
(
mode
)
{
{
case
RFIRST
:
case
RFIRST
:
err
=
table
->
file
->
index_first
(
table
->
record
[
0
]);
err
=
keyname
?
mode
=
RNEXT
;
table
->
file
->
index_first
(
table
->
record
[
0
])
:
break
;
table
->
file
->
rnd_init
(
1
)
||
table
->
file
->
rnd_next
(
table
->
record
[
0
]);
mode
=
RNEXT
;
break
;
case
RLAST
:
case
RLAST
:
err
=
table
->
file
->
index_last
(
table
->
record
[
0
]);
dbug_assert
(
keyname
!=
0
);
mode
=
RPREV
;
err
=
table
->
file
->
index_last
(
table
->
record
[
0
]);
break
;
mode
=
RPREV
;
break
;
case
RNEXT
:
case
RNEXT
:
err
=
table
->
file
->
index_next
(
table
->
record
[
0
]);
err
=
keyname
?
break
;
table
->
file
->
index_next
(
table
->
record
[
0
])
:
table
->
file
->
rnd_next
(
table
->
record
[
0
]);
break
;
case
RPREV
:
case
RPREV
:
err
=
table
->
file
->
index_prev
(
table
->
record
[
0
]);
dbug_assert
(
keyname
!=
0
);
break
;
err
=
table
->
file
->
index_prev
(
table
->
record
[
0
]);
break
;
case
RKEY
:
case
RKEY
:
{
{
KEY
*
keyinfo
=
table
->
key_info
+
keyno
;
dbug_assert
(
keyname
!=
0
);
uint
key_len
=
0
,
i
;
KEY
*
keyinfo
=
table
->
key_info
+
keyno
;
byte
*
key
,
*
buf
;
KEY_PART_INFO
*
key_part
=
keyinfo
->
key_part
;
if
(
key_expr
->
elements
>
keyinfo
->
key_parts
)
uint
key_len
;
{
byte
*
key
;
my_printf_error
(
ER_TOO_MANY_KEY_PARTS
,
ER
(
ER_TOO_MANY_KEY_PARTS
),
if
(
key_expr
->
elements
>
keyinfo
->
key_parts
)
MYF
(
0
),
keyinfo
->
key_parts
);
{
return
-
1
;
my_printf_error
(
ER_TOO_MANY_KEY_PARTS
,
ER
(
ER_TOO_MANY_KEY_PARTS
),
}
MYF
(
0
),
keyinfo
->
key_parts
);
for
(
i
=
0
;
i
<
key_expr
->
elements
;
i
++
)
goto
err
;
key_len
+=
keyinfo
->
key_part
[
i
].
store_length
;
}
if
(
!
(
key
=
sql_calloc
(
ALIGN_SIZE
(
key_len
))))
List_iterator
<
Item
>
it_ke
(
*
key_expr
);
{
Item
*
item
;
send_error
(
&
thd
->
net
,
ER_OUTOFMEMORY
);
for
(
key_len
=
0
;
(
item
=
it_ke
++
)
;
key_part
++
)
return
-
1
;
{
}
item
->
save_in_field
(
key_part
->
field
);
List_iterator
<
Item
>
it_ke
(
*
key_expr
);
key_len
+=
key_part
->
store_length
;
for
(
i
=
0
,
buf
=
key
;
i
<
key_expr
->
elements
;
i
++
)
}
{
if
(
!
(
key
=
sql_calloc
(
ALIGN_SIZE
(
key_len
))))
uint
maybe_null
=
test
(
keyinfo
->
key_part
[
i
].
null_bit
);
{
store_key_item
ski
=
store_key_item
(
keyinfo
->
key_part
[
i
].
field
,
send_error
(
&
thd
->
net
,
ER_OUTOFMEMORY
);
(
char
*
)
buf
+
maybe_null
,
maybe_null
?
(
char
*
)
buf
:
0
,
goto
err
;
keyinfo
->
key_part
[
i
].
length
,
it_ke
++
);
}
ski
.
copy
();
key_copy
(
key
,
table
,
keyno
,
key_len
);
buf
+=
keyinfo
->
key_part
[
i
].
store_length
;
err
=
table
->
file
->
index_read
(
table
->
record
[
0
],
}
key
,
key_len
,
ha_rkey_mode
);
err
=
table
->
file
->
index_read
(
table
->
record
[
0
],
mode
=
rkey_to_rnext
[(
int
)
ha_rkey_mode
];
key
,
key_len
,
ha_rkey_mode
);
break
;
mode
=
rkey_to_rnext
[(
int
)
ha_rkey_mode
];
}
break
;
}
default:
default:
send_error
(
&
thd
->
net
,
ER_ILLEGAL_HA
);
send_error
(
&
thd
->
net
,
ER_ILLEGAL_HA
);
return
-
1
;
goto
err
;
}
}
if
(
err
&&
err
!=
HA_ERR_KEY_NOT_FOUND
&&
err
!=
HA_ERR_END_OF_FILE
)
if
(
err
)
{
{
sql_print_error
(
"mysql_ha_read: Got error %d when reading table"
,
if
(
err
!=
HA_ERR_KEY_NOT_FOUND
&&
err
!=
HA_ERR_END_OF_FILE
)
err
);
{
table
->
file
->
print_error
(
err
,
MYF
(
0
));
sql_print_error
(
"mysql_ha_read: Got error %d when reading table"
,
return
-
1
;
err
);
table
->
file
->
print_error
(
err
,
MYF
(
0
));
goto
err
;
}
goto
ok
;
}
if
(
cond
)
{
err
=
err
;
if
(
!
cond
->
val_int
())
continue
;
}
}
if
(
num_rows
>=
offset_limit
)
if
(
num_rows
>=
offset_limit
)
{
{
if
(
num_rows
==
offset_limit
)
send_fields
(
thd
,
list
,
1
);
if
(
!
err
)
if
(
!
err
)
{
{
String
*
packet
=
&
thd
->
packet
;
String
*
packet
=
&
thd
->
packet
;
Item
*
item
;
Item
*
item
;
packet
->
length
(
0
);
packet
->
length
(
0
);
it
.
rewind
();
it
.
rewind
();
while
((
item
=
it
++
))
while
((
item
=
it
++
))
{
{
if
(
item
->
send
(
packet
))
if
(
item
->
send
(
packet
))
{
{
packet
->
free
();
// Free used
packet
->
free
();
// Free used
my_error
(
ER_OUT_OF_RESOURCES
,
MYF
(
0
));
my_error
(
ER_OUT_OF_RESOURCES
,
MYF
(
0
));
return
-
1
;
goto
err
;
}
}
}
}
my_net_write
(
&
thd
->
net
,
(
char
*
)
packet
->
ptr
(),
packet
->
length
());
my_net_write
(
&
thd
->
net
,
(
char
*
)
packet
->
ptr
(),
packet
->
length
());
}
}
}
}
num_rows
++
;
}
}
ok:
mysql_unlock_tables
(
thd
,
lock
);
send_eof
(
&
thd
->
net
);
send_eof
(
&
thd
->
net
);
return
0
;
return
0
;
err:
mysql_unlock_tables
(
thd
,
lock
);
return
-
1
;
}
}
/**************************************************************************
/**************************************************************************
...
@@ -184,10 +239,10 @@ static TABLE *find_table_by_name(THD *thd, char *db, char *table_name)
...
@@ -184,10 +239,10 @@ static TABLE *find_table_by_name(THD *thd, char *db, char *table_name)
if
(
!
db
||
!
*
db
)
db
=
""
;
if
(
!
db
||
!
*
db
)
db
=
""
;
dblen
=
strlen
(
db
);
dblen
=
strlen
(
db
);
for
(
TABLE
*
table
=
thd
->
open
_tables
;
table
;
table
=
table
->
next
)
for
(
TABLE
*
table
=
thd
->
handler
_tables
;
table
;
table
=
table
->
next
)
{
{
if
(
!
memcmp
(
table
->
table_cache_key
,
db
,
dblen
)
&&
if
(
!
memcmp
(
table
->
table_cache_key
,
db
,
dblen
)
&&
!
my_strcasecmp
(
table
->
table_name
,
table_name
))
!
my_strcasecmp
(
table
->
table_name
,
table_name
))
return
table
;
return
table
;
}
}
return
(
0
);
return
(
0
);
...
...
sql/sql_parse.cc
View file @
ce3b58d6
...
@@ -2009,8 +2009,8 @@ mysql_execute_command(void)
...
@@ -2009,8 +2009,8 @@ mysql_execute_command(void)
case
SQLCOM_HA_READ
:
case
SQLCOM_HA_READ
:
if
(
check_db_used
(
thd
,
tables
)
||
check_table_access
(
thd
,
SELECT_ACL
,
tables
))
if
(
check_db_used
(
thd
,
tables
)
||
check_table_access
(
thd
,
SELECT_ACL
,
tables
))
goto
error
;
goto
error
;
res
=
mysql_ha_read
(
thd
,
tables
,
lex
->
ha_read_mode
,
res
=
mysql_ha_read
(
thd
,
tables
,
lex
->
ha_read_mode
,
lex
->
backup_dir
,
lex
->
backup_dir
,
lex
->
insert_list
,
lex
->
ha_rkey_mod
e
,
lex
->
insert_list
,
lex
->
ha_rkey_mode
,
lex
->
wher
e
,
lex
->
select_limit
,
lex
->
offset_limit
);
lex
->
select_limit
,
lex
->
offset_limit
);
break
;
break
;
...
@@ -2059,7 +2059,7 @@ mysql_execute_command(void)
...
@@ -2059,7 +2059,7 @@ mysql_execute_command(void)
}
}
thd
->
proc_info
=
"query end"
;
// QQ
thd
->
proc_info
=
"query end"
;
// QQ
if
(
res
<
0
)
if
(
res
<
0
)
send_error
(
&
thd
->
net
,
thd
->
killed
?
ER_SERVER_SHUTDOWN
:
0
,
0
);
send_error
(
&
thd
->
net
,
thd
->
killed
?
ER_SERVER_SHUTDOWN
:
0
);
error:
error:
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
...
...
sql/sql_yacc.yy
View file @
ce3b58d6
...
@@ -535,7 +535,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
...
@@ -535,7 +535,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
equal optional_braces opt_key_definition key_usage_list2
equal optional_braces opt_key_definition key_usage_list2
opt_mi_check_type opt_to mi_check_types normal_join
opt_mi_check_type opt_to mi_check_types normal_join
table_to_table_list table_to_table opt_table_list opt_as
table_to_table_list table_to_table opt_table_list opt_as
handler_read_function handler_rkey_mode END_OF_INPUT
handler_rkey_function handler_rkey_mode handler_read_or_scan
END_OF_INPUT
%type <NONE>
%type <NONE>
'-' '+' '*' '/' '%' '(' ')'
'-' '+' '*' '/' '%' '(' ')'
...
@@ -1904,7 +1905,8 @@ order_dir:
...
@@ -1904,7 +1905,8 @@ order_dir:
limit_clause:
limit_clause:
/* empty */
/* empty */
{
{
Lex->select_limit= current_thd->default_select_limit;
Lex->select_limit= (Lex->sql_command == SQLCOM_HA_READ) ?
1 : current_thd->default_select_limit;
Lex->offset_limit= 0L;
Lex->offset_limit= 0L;
}
}
| LIMIT ULONG_NUM
| LIMIT ULONG_NUM
...
@@ -2844,7 +2846,7 @@ unlock:
...
@@ -2844,7 +2846,7 @@ unlock:
/*
/*
**
Table
: direct access to ISAM functions
**
Handler
: direct access to ISAM functions
*/
*/
handler:
handler:
...
@@ -2860,45 +2862,40 @@ handler:
...
@@ -2860,45 +2862,40 @@ handler:
if (!add_table_to_list($2,0,0))
if (!add_table_to_list($2,0,0))
YYABORT;
YYABORT;
}
}
| HANDLER_SYM table_ident READ_SYM
ident handler_read_function limit_clause
| HANDLER_SYM table_ident READ_SYM
handler_read_or_scan
{
{
Lex->sql_command = SQLCOM_HA_READ;
Lex->sql_command = SQLCOM_HA_READ;
Lex->backup_dir= $4.str;
if (!add_table_to_list($2,0,0))
if (!add_table_to_list($2,0,0))
YYABORT;
YYABORT;
}
}
where_clause limit_clause { }
handler_read_function:
handler_read_or_scan:
FIRST_SYM
handler_scan_function { Lex->backup_dir= 0; }
{
| ident handler_rkey_function { Lex->backup_dir= $1.str; }
Lex->ha_read_mode = RFIRST;
}
handler_scan_function:
| NEXT_SYM
FIRST_SYM { Lex->ha_read_mode = RFIRST; }
{
| NEXT_SYM { Lex->ha_read_mode = RNEXT; }
Lex->ha_read_mode = RNEXT;
}
handler_rkey_function:
| PREV_SYM
FIRST_SYM { Lex->ha_read_mode = RFIRST; }
{
| NEXT_SYM { Lex->ha_read_mode = RNEXT; }
Lex->ha_read_mode = RPREV;
| PREV_SYM { Lex->ha_read_mode = RPREV; }
}
| LAST_SYM { Lex->ha_read_mode = RLAST; }
| LAST_SYM
{
Lex->ha_read_mode = RLAST;
}
| handler_rkey_mode
| handler_rkey_mode
{
{
Lex->ha_read_mode = RKEY;
Lex->ha_read_mode = RKEY;
if (!(Lex->insert_list = new List_item))
if (!(Lex->insert_list = new List_item))
YYABORT;
YYABORT;
}
} '(' values ')' { }
'(' values ')' { }
handler_rkey_mode:
handler_rkey_mode:
EQ
{ Lex->ha_rkey_mode=HA_READ_KEY_EXACT;
}
EQ
{ Lex->ha_rkey_mode=HA_READ_KEY_EXACT;
}
| GE { Lex->ha_rkey_mode=HA_READ_KEY_OR_NEXT; }
| GE
{ Lex->ha_rkey_mode=HA_READ_KEY_OR_NEXT; }
| LE { Lex->ha_rkey_mode=HA_READ_KEY_OR_PREV; }
| LE
{ Lex->ha_rkey_mode=HA_READ_KEY_OR_PREV; }
| GT_SYM {
Lex->ha_rkey_mode=HA_READ_AFTER_KEY;
}
| GT_SYM {
Lex->ha_rkey_mode=HA_READ_AFTER_KEY;
}
| LT
{ Lex->ha_rkey_mode=HA_READ_BEFORE_KEY;
}
| LT
{ Lex->ha_rkey_mode=HA_READ_BEFORE_KEY;
}
/* GRANT / REVOKE */
/* GRANT / REVOKE */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment