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
ca0ba8e0
Commit
ca0ba8e0
authored
Apr 13, 2001
by
serg@serg.mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
this won't be pushed
parent
a981cfbd
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 @
ca0ba8e0
...
...
@@ -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
...
...
@@ -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
...
...
@@ -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
...
...
@@ -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
View file @
ca0ba8e0
...
...
@@ -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
;
...
...
@@ -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
View file @
ca0ba8e0
...
...
@@ -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
);
...
...
sql/sql_base.cc
View file @
ca0ba8e0
...
...
@@ -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
;
...
...
sql/sql_class.cc
View file @
ca0ba8e0
...
...
@@ -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
;
...
...
@@ -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
;
...
...
@@ -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
);
...
...
sql/sql_class.h
View file @
ca0ba8e0
...
...
@@ -231,7 +231,7 @@ class THD :public ilink {
const
char
*
proc_info
;
uint
client_capabilities
,
max_packet_length
;
uint
master_access
,
db_access
;
TABLE
*
open_tables
,
*
temporary_tables
;
TABLE
*
open_tables
,
*
temporary_tables
,
*
handler_tables
;
MYSQL_LOCK
*
lock
,
*
locked_tables
;
ULL
*
ull
;
struct
st_my_thread_var
*
mysys_var
;
...
...
@@ -253,7 +253,7 @@ class THD :public ilink {
#ifdef HAVE_GEMINI_DB
struct
st_gemini
gemini
;
#endif
Item
*
free_list
;
Item
*
free_list
,
*
handler_items
;
CONVERT
*
convert_set
;
Field
*
dupp_field
;
#ifndef __WIN__
...
...
@@ -278,7 +278,7 @@ class THD :public ilink {
bool
slave_thread
;
bool
set_query_id
,
locked
,
count_cuted_fields
,
some_tables_deleted
;
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
query_error
,
bootstrap
;
bool
volatile
killed
;
...
...
sql/sql_handler.cc
View file @
ca0ba8e0
...
...
@@ -17,23 +17,53 @@
/* HANDLER ... commands - direct access to ISAM */
#include <assert.h>
#include "mysql_priv.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
);
int
mysql_ha_open
(
THD
*
thd
,
TABLE_LIST
*
tables
)
{
HANDLER_TABLES_HACK
(
thd
);
int
err
=
open_tables
(
thd
,
tables
);
if
(
!
err
)
{
thd
->
manual_open
=
1
;
send_ok
(
&
thd
->
net
);
}
HANDLER_TABLES_HACK
(
thd
);
if
(
err
)
return
-
1
;
send_ok
(
&
thd
->
net
);
return
0
;
}
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
);
return
0
;
}
...
...
@@ -43,27 +73,30 @@ static enum enum_ha_read_modes rkey_to_rnext[]=
int
mysql_ha_read
(
THD
*
thd
,
TABLE_LIST
*
tables
,
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
)
{
int
err
;
int
err
,
keyno
=-
1
;
TABLE
*
table
=
find_table_by_name
(
thd
,
tables
->
db
,
tables
->
name
);
if
(
!
table
)
{
my_printf_error
(
ER_UNKNOWN_TABLE
,
ER
(
ER_UNKNOWN_TABLE
),
MYF
(
0
),
tables
->
name
,
"HANDLER"
);
// send_error(&thd->net,ER_UNKNOWN_TABLE);
// send_ok(&thd->net);
tables
->
name
,
"HANDLER"
);
return
-
1
;
}
tables
->
table
=
table
;
if
(
cond
&&
cond
->
fix_fields
(
thd
,
tables
))
return
-
1
;
int
keyno
=
find_type
(
keyname
,
&
table
->
keynames
,
1
+
2
)
-
1
;
if
(
keyno
<
0
)
if
(
keyname
)
{
my_printf_error
(
ER_KEY_DOES_NOT_EXITS
,
ER
(
ER_KEY_DOES_NOT_EXITS
),
MYF
(
0
),
keyname
,
tables
->
name
);
return
-
1
;
if
((
keyno
=
find_type
(
keyname
,
&
table
->
keynames
,
1
+
2
)
-
1
)
<
0
)
{
my_printf_error
(
ER_KEY_DOES_NOT_EXITS
,
ER
(
ER_KEY_DOES_NOT_EXITS
),
MYF
(
0
),
keyname
,
tables
->
name
);
return
-
1
;
}
}
List
<
Item
>
list
;
...
...
@@ -72,99 +105,121 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
it
++
;
insert_fields
(
thd
,
tables
,
tables
->
name
,
&
it
);
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
;
num_rows
++
)
for
(
uint
num_rows
=
0
;
num_rows
<
select_limit
;
)
{
switch
(
mode
)
{
case
RFIRST
:
err
=
table
->
file
->
index_first
(
table
->
record
[
0
]);
mode
=
RNEXT
;
break
;
err
=
keyname
?
table
->
file
->
index_first
(
table
->
record
[
0
])
:
table
->
file
->
rnd_init
(
1
)
||
table
->
file
->
rnd_next
(
table
->
record
[
0
]);
mode
=
RNEXT
;
break
;
case
RLAST
:
err
=
table
->
file
->
index_last
(
table
->
record
[
0
]);
mode
=
RPREV
;
break
;
dbug_assert
(
keyname
!=
0
);
err
=
table
->
file
->
index_last
(
table
->
record
[
0
]);
mode
=
RPREV
;
break
;
case
RNEXT
:
err
=
table
->
file
->
index_next
(
table
->
record
[
0
]);
break
;
err
=
keyname
?
table
->
file
->
index_next
(
table
->
record
[
0
])
:
table
->
file
->
rnd_next
(
table
->
record
[
0
]);
break
;
case
RPREV
:
err
=
table
->
file
->
index_prev
(
table
->
record
[
0
]);
break
;
dbug_assert
(
keyname
!=
0
);
err
=
table
->
file
->
index_prev
(
table
->
record
[
0
]);
break
;
case
RKEY
:
{
KEY
*
keyinfo
=
table
->
key_info
+
keyno
;
uint
key_len
=
0
,
i
;
byte
*
key
,
*
buf
;
if
(
key_expr
->
elements
>
keyinfo
->
key_parts
)
{
my_printf_error
(
ER_TOO_MANY_KEY_PARTS
,
ER
(
ER_TOO_MANY_KEY_PARTS
),
MYF
(
0
),
keyinfo
->
key_parts
);
return
-
1
;
}
for
(
i
=
0
;
i
<
key_expr
->
elements
;
i
++
)
key_len
+=
keyinfo
->
key_part
[
i
].
store_length
;
if
(
!
(
key
=
sql_calloc
(
ALIGN_SIZE
(
key_len
))))
{
send_error
(
&
thd
->
net
,
ER_OUTOFMEMORY
);
return
-
1
;
}
List_iterator
<
Item
>
it_ke
(
*
key_expr
);
for
(
i
=
0
,
buf
=
key
;
i
<
key_expr
->
elements
;
i
++
)
{
uint
maybe_null
=
test
(
keyinfo
->
key_part
[
i
].
null_bit
);
store_key_item
ski
=
store_key_item
(
keyinfo
->
key_part
[
i
].
field
,
(
char
*
)
buf
+
maybe_null
,
maybe_null
?
(
char
*
)
buf
:
0
,
keyinfo
->
key_part
[
i
].
length
,
it_ke
++
);
ski
.
copy
();
buf
+=
keyinfo
->
key_part
[
i
].
store_length
;
}
err
=
table
->
file
->
index_read
(
table
->
record
[
0
],
key
,
key_len
,
ha_rkey_mode
);
mode
=
rkey_to_rnext
[(
int
)
ha_rkey_mode
];
break
;
}
{
dbug_assert
(
keyname
!=
0
);
KEY
*
keyinfo
=
table
->
key_info
+
keyno
;
KEY_PART_INFO
*
key_part
=
keyinfo
->
key_part
;
uint
key_len
;
byte
*
key
;
if
(
key_expr
->
elements
>
keyinfo
->
key_parts
)
{
my_printf_error
(
ER_TOO_MANY_KEY_PARTS
,
ER
(
ER_TOO_MANY_KEY_PARTS
),
MYF
(
0
),
keyinfo
->
key_parts
);
goto
err
;
}
List_iterator
<
Item
>
it_ke
(
*
key_expr
);
Item
*
item
;
for
(
key_len
=
0
;
(
item
=
it_ke
++
)
;
key_part
++
)
{
item
->
save_in_field
(
key_part
->
field
);
key_len
+=
key_part
->
store_length
;
}
if
(
!
(
key
=
sql_calloc
(
ALIGN_SIZE
(
key_len
))))
{
send_error
(
&
thd
->
net
,
ER_OUTOFMEMORY
);
goto
err
;
}
key_copy
(
key
,
table
,
keyno
,
key_len
);
err
=
table
->
file
->
index_read
(
table
->
record
[
0
],
key
,
key_len
,
ha_rkey_mode
);
mode
=
rkey_to_rnext
[(
int
)
ha_rkey_mode
];
break
;
}
default:
send_error
(
&
thd
->
net
,
ER_ILLEGAL_HA
);
return
-
1
;
send_error
(
&
thd
->
net
,
ER_ILLEGAL_HA
);
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"
,
err
);
table
->
file
->
print_error
(
err
,
MYF
(
0
));
return
-
1
;
if
(
err
!=
HA_ERR_KEY_NOT_FOUND
&&
err
!=
HA_ERR_END_OF_FILE
)
{
sql_print_error
(
"mysql_ha_read: Got error %d when reading table"
,
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
)
send_fields
(
thd
,
list
,
1
);
if
(
!
err
)
{
String
*
packet
=
&
thd
->
packet
;
Item
*
item
;
packet
->
length
(
0
);
it
.
rewind
();
while
((
item
=
it
++
))
{
if
(
item
->
send
(
packet
))
{
packet
->
free
();
// Free used
my_error
(
ER_OUT_OF_RESOURCES
,
MYF
(
0
));
return
-
1
;
}
}
my_net_write
(
&
thd
->
net
,
(
char
*
)
packet
->
ptr
(),
packet
->
length
());
String
*
packet
=
&
thd
->
packet
;
Item
*
item
;
packet
->
length
(
0
);
it
.
rewind
();
while
((
item
=
it
++
))
{
if
(
item
->
send
(
packet
))
{
packet
->
free
();
// Free used
my_error
(
ER_OUT_OF_RESOURCES
,
MYF
(
0
));
goto
err
;
}
}
my_net_write
(
&
thd
->
net
,
(
char
*
)
packet
->
ptr
(),
packet
->
length
());
}
}
num_rows
++
;
}
ok:
mysql_unlock_tables
(
thd
,
lock
);
send_eof
(
&
thd
->
net
);
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)
if
(
!
db
||
!
*
db
)
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
)
&&
!
my_strcasecmp
(
table
->
table_name
,
table_name
))
!
my_strcasecmp
(
table
->
table_name
,
table_name
))
return
table
;
}
return
(
0
);
...
...
sql/sql_parse.cc
View file @
ca0ba8e0
...
...
@@ -2009,8 +2009,8 @@ mysql_execute_command(void)
case
SQLCOM_HA_READ
:
if
(
check_db_used
(
thd
,
tables
)
||
check_table_access
(
thd
,
SELECT_ACL
,
tables
))
goto
error
;
res
=
mysql_ha_read
(
thd
,
tables
,
lex
->
ha_read_mode
,
lex
->
backup_dir
,
lex
->
insert_list
,
lex
->
ha_rkey_mod
e
,
res
=
mysql_ha_read
(
thd
,
tables
,
lex
->
ha_read_mode
,
lex
->
backup_dir
,
lex
->
insert_list
,
lex
->
ha_rkey_mode
,
lex
->
wher
e
,
lex
->
select_limit
,
lex
->
offset_limit
);
break
;
...
...
@@ -2059,7 +2059,7 @@ mysql_execute_command(void)
}
thd
->
proc_info
=
"query end"
;
// QQ
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:
DBUG_VOID_RETURN
;
...
...
sql/sql_yacc.yy
View file @
ca0ba8e0
...
...
@@ -535,7 +535,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
equal optional_braces opt_key_definition key_usage_list2
opt_mi_check_type opt_to mi_check_types normal_join
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>
'-' '+' '*' '/' '%' '(' ')'
...
...
@@ -1904,7 +1905,8 @@ order_dir:
limit_clause:
/* 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;
}
| LIMIT ULONG_NUM
...
...
@@ -2844,7 +2846,7 @@ unlock:
/*
**
Table
: direct access to ISAM functions
**
Handler
: direct access to ISAM functions
*/
handler:
...
...
@@ -2860,45 +2862,40 @@ handler:
if (!add_table_to_list($2,0,0))
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->backup_dir= $4.str;
if (!add_table_to_list($2,0,0))
YYABORT;
}
}
where_clause limit_clause { }
handler_read_function:
FIRST_SYM
{
Lex->ha_read_mode = RFIRST;
}
| NEXT_SYM
{
Lex->ha_read_mode = RNEXT;
}
| PREV_SYM
{
Lex->ha_read_mode = RPREV;
}
| LAST_SYM
{
Lex->ha_read_mode = RLAST;
}
handler_read_or_scan:
handler_scan_function { Lex->backup_dir= 0; }
| ident handler_rkey_function { Lex->backup_dir= $1.str; }
handler_scan_function:
FIRST_SYM { Lex->ha_read_mode = RFIRST; }
| NEXT_SYM { Lex->ha_read_mode = RNEXT; }
handler_rkey_function:
FIRST_SYM { Lex->ha_read_mode = RFIRST; }
| NEXT_SYM { Lex->ha_read_mode = RNEXT; }
| PREV_SYM { Lex->ha_read_mode = RPREV; }
| LAST_SYM { Lex->ha_read_mode = RLAST; }
| handler_rkey_mode
{
Lex->ha_read_mode = RKEY;
if (!(Lex->insert_list = new List_item))
YYABORT;
}
'(' values ')' { }
} '(' values ')' { }
handler_rkey_mode:
EQ
{ Lex->ha_rkey_mode=HA_READ_KEY_EXACT;
}
| GE { Lex->ha_rkey_mode=HA_READ_KEY_OR_NEXT; }
| LE { Lex->ha_rkey_mode=HA_READ_KEY_OR_PREV; }
| GT_SYM {
Lex->ha_rkey_mode=HA_READ_AFTER_KEY;
}
| LT
{ Lex->ha_rkey_mode=HA_READ_BEFORE_KEY;
}
EQ
{ Lex->ha_rkey_mode=HA_READ_KEY_EXACT;
}
| GE
{ Lex->ha_rkey_mode=HA_READ_KEY_OR_NEXT; }
| LE
{ Lex->ha_rkey_mode=HA_READ_KEY_OR_PREV; }
| GT_SYM {
Lex->ha_rkey_mode=HA_READ_AFTER_KEY;
}
| LT
{ Lex->ha_rkey_mode=HA_READ_BEFORE_KEY;
}
/* 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