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
9f45c9e3
Commit
9f45c9e3
authored
Jun 23, 2004
by
serg@serg.mylan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
followup to handler cleanup
parent
cfd78595
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
171 additions
and
115 deletions
+171
-115
mysql-test/r/bdb.result
mysql-test/r/bdb.result
+9
-0
mysql-test/t/bdb.test
mysql-test/t/bdb.test
+25
-0
sql/examples/ha_archive.cc
sql/examples/ha_archive.cc
+9
-9
sql/examples/ha_archive.h
sql/examples/ha_archive.h
+9
-12
sql/examples/ha_example.cc
sql/examples/ha_example.cc
+63
-58
sql/examples/ha_example.h
sql/examples/ha_example.h
+53
-29
sql/ha_berkeley.cc
sql/ha_berkeley.cc
+1
-1
sql/ha_berkeley.h
sql/ha_berkeley.h
+1
-1
sql/sql_select.cc
sql/sql_select.cc
+1
-5
No files found.
mysql-test/r/bdb.result
View file @
9f45c9e3
...
@@ -1181,3 +1181,12 @@ a
...
@@ -1181,3 +1181,12 @@ a
A
A
a
a
drop table t1;
drop table t1;
set autocommit=0;
create table t1(b varchar(30)) engine=bdb;
insert into t1 values ('one');
commit;
select b FROM t1 outer_table where
exists (select 'two' from t1 where 'two' = outer_table.b);
b
drop table t1;
set autocommit=1;
mysql-test/t/bdb.test
View file @
9f45c9e3
...
@@ -822,3 +822,28 @@ alter table t1 modify a char(10) binary;
...
@@ -822,3 +822,28 @@ alter table t1 modify a char(10) binary;
explain
select
a
from
t1
;
explain
select
a
from
t1
;
select
a
from
t1
;
select
a
from
t1
;
drop
table
t1
;
drop
table
t1
;
#
# Bug #4000: problem with active cursor.
#
set
autocommit
=
0
;
create
table
t1
(
b
varchar
(
30
))
engine
=
bdb
;
insert
into
t1
values
(
'one'
);
commit
;
select
b
FROM
t1
outer_table
where
exists
(
select
'two'
from
t1
where
'two'
=
outer_table
.
b
);
drop
table
t1
;
set
autocommit
=
1
;
#
# Bug #4089: subselect and open cursor.
#
#create table t1(a int primary key, b varchar(30)) engine=bdb;
#insert into t1 values (1,'one'), (2,'two'), (3,'three'), (4,'four');
#create table t2 like t1;
#insert into t2 (a, b)
# select a, b from t1 where (a, b) in (select a, b from t1);
#select * from t2;
#drop table t1, t2;
sql/examples/ha_archive.cc
View file @
9f45c9e3
...
@@ -481,13 +481,13 @@ int ha_archive::update_row(const byte * old_data, byte * new_data)
...
@@ -481,13 +481,13 @@ int ha_archive::update_row(const byte * old_data, byte * new_data)
{
{
DBUG_ENTER
(
"ha_archive::update_row"
);
DBUG_ENTER
(
"ha_archive::update_row"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
int
ha_archive
::
delete_row
(
const
byte
*
buf
)
int
ha_archive
::
delete_row
(
const
byte
*
buf
)
{
{
DBUG_ENTER
(
"ha_archive::delete_row"
);
DBUG_ENTER
(
"ha_archive::delete_row"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
int
ha_archive
::
index_read
(
byte
*
buf
,
const
byte
*
key
,
int
ha_archive
::
index_read
(
byte
*
buf
,
const
byte
*
key
,
...
@@ -496,7 +496,7 @@ int ha_archive::index_read(byte * buf, const byte * key,
...
@@ -496,7 +496,7 @@ int ha_archive::index_read(byte * buf, const byte * key,
__attribute__
((
unused
)))
__attribute__
((
unused
)))
{
{
DBUG_ENTER
(
"ha_archive::index_read"
);
DBUG_ENTER
(
"ha_archive::index_read"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
int
ha_archive
::
index_read_idx
(
byte
*
buf
,
uint
index
,
const
byte
*
key
,
int
ha_archive
::
index_read_idx
(
byte
*
buf
,
uint
index
,
const
byte
*
key
,
...
@@ -505,32 +505,32 @@ int ha_archive::index_read_idx(byte * buf, uint index, const byte * key,
...
@@ -505,32 +505,32 @@ int ha_archive::index_read_idx(byte * buf, uint index, const byte * key,
__attribute__
((
unused
)))
__attribute__
((
unused
)))
{
{
DBUG_ENTER
(
"ha_archive::index_read_idx"
);
DBUG_ENTER
(
"ha_archive::index_read_idx"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
int
ha_archive
::
index_next
(
byte
*
buf
)
int
ha_archive
::
index_next
(
byte
*
buf
)
{
{
DBUG_ENTER
(
"ha_archive::index_next"
);
DBUG_ENTER
(
"ha_archive::index_next"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
int
ha_archive
::
index_prev
(
byte
*
buf
)
int
ha_archive
::
index_prev
(
byte
*
buf
)
{
{
DBUG_ENTER
(
"ha_archive::index_prev"
);
DBUG_ENTER
(
"ha_archive::index_prev"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
int
ha_archive
::
index_first
(
byte
*
buf
)
int
ha_archive
::
index_first
(
byte
*
buf
)
{
{
DBUG_ENTER
(
"ha_archive::index_first"
);
DBUG_ENTER
(
"ha_archive::index_first"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
int
ha_archive
::
index_last
(
byte
*
buf
)
int
ha_archive
::
index_last
(
byte
*
buf
)
{
{
DBUG_ENTER
(
"ha_archive::index_last"
);
DBUG_ENTER
(
"ha_archive::index_last"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
...
@@ -581,6 +581,6 @@ ha_rows ha_archive::records_in_range(int inx,
...
@@ -581,6 +581,6 @@ ha_rows ha_archive::records_in_range(int inx,
enum
ha_rkey_function
end_search_flag
)
enum
ha_rkey_function
end_search_flag
)
{
{
DBUG_ENTER
(
"ha_archive::records_in_range "
);
DBUG_ENTER
(
"ha_archive::records_in_range "
);
DBUG_RETURN
(
records
);
// HA_ERR_
NOT_IMPLEMENTE
D
DBUG_RETURN
(
records
);
// HA_ERR_
WRONG_COMMAN
D
}
}
#endif
/* HAVE_ARCHIVE_DB */
#endif
/* HAVE_ARCHIVE_DB */
sql/examples/ha_archive.h
View file @
9f45c9e3
...
@@ -22,7 +22,7 @@
...
@@ -22,7 +22,7 @@
/*
/*
Please read ha_archive.cc first. If you are looking for more general
Please read ha_archive.cc first. If you are looking for more general
answers on how storage engines work, look at ha_example.cc and
answers on how storage engines work, look at ha_example.cc and
ha_example.h.
ha_example.h.
*/
*/
...
@@ -36,7 +36,7 @@ typedef struct st_archive_share {
...
@@ -36,7 +36,7 @@ typedef struct st_archive_share {
bool
dirty
;
/* Flag for if a flush should occur */
bool
dirty
;
/* Flag for if a flush should occur */
}
ARCHIVE_SHARE
;
}
ARCHIVE_SHARE
;
/*
/*
Version for file format.
Version for file format.
1 - Initial Version
1 - Initial Version
*/
*/
...
@@ -61,7 +61,7 @@ class ha_archive: public handler
...
@@ -61,7 +61,7 @@ class ha_archive: public handler
/* The size of the offset value we will use for position() */
/* The size of the offset value we will use for position() */
ref_length
=
sizeof
(
z_off_t
);
ref_length
=
sizeof
(
z_off_t
);
}
}
~
ha_archive
()
~
ha_archive
()
{
{
}
}
const
char
*
table_type
()
const
{
return
"ARCHIVE"
;
}
const
char
*
table_type
()
const
{
return
"ARCHIVE"
;
}
...
@@ -69,21 +69,18 @@ class ha_archive: public handler
...
@@ -69,21 +69,18 @@ class ha_archive: public handler
const
char
**
bas_ext
()
const
;
const
char
**
bas_ext
()
const
;
ulong
table_flags
()
const
ulong
table_flags
()
const
{
{
return
(
HA_REC_NOT_IN_SEQ
|
HA_NOT_EXACT_COUNT
|
HA_NO_
WRITE_DELAYED
|
return
(
HA_REC_NOT_IN_SEQ
|
HA_NOT_EXACT_COUNT
|
HA_NO_
AUTO_INCREMENT
|
HA_
NO_AUTO_INCREMENT
);
HA_
FILE_BASED
);
}
}
ulong
index_flags
(
uint
i
nx
)
const
ulong
index_flags
(
uint
i
dx
,
uint
part
)
const
{
{
return
0
;
return
0
;
}
}
/*
/*
This is just a default
, there is no real limit as far as
Have to put something here
, there is no real limit as far as
archive is concerned.
archive is concerned.
*/
*/
uint
max_record_length
()
const
{
return
HA_MAX_REC_LENGTH
;
}
uint
max_supported_record_length
()
const
{
return
UINT_MAX
;
}
uint
max_keys
()
const
{
return
0
;
}
uint
max_key_parts
()
const
{
return
0
;
}
uint
max_key_length
()
const
{
return
0
;
}
/*
/*
Called in test_quick_select to determine if indexes should be used.
Called in test_quick_select to determine if indexes should be used.
*/
*/
...
...
sql/examples/ha_example.cc
View file @
9f45c9e3
...
@@ -14,24 +14,24 @@
...
@@ -14,24 +14,24 @@
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
/*
ha_example is a stubbed storage engine. It does nothing at this point. It
ha_example is a stubbed storage engine. It does nothing at this point. It
will let you create/open/delete tables but that is all. You can enable it
will let you create/open/delete tables but that is all. You can enable it
in your buld by doing the following during your build process:
in your buld by doing the following during your build process:
./configure --with-example-storage-engine
./configure --with-example-storage-engine
Once this is done mysql will let you create tables with:
Once this is done mysql will let you create tables with:
CREATE TABLE A (...) ENGINE=EXAMPLE;
CREATE TABLE A (...) ENGINE=EXAMPLE;
The example is setup to use table locks. It implements an example "SHARE"
The example is setup to use table locks. It implements an example "SHARE"
that is inserted into a hash by table name. You can use this to store
that is inserted into a hash by table name. You can use this to store
information of state that any example handler object will be able to see
information of state that any example handler object will be able to see
if it is using the same table.
if it is using the same table.
Please read the object definition in ha_example.h before reading the rest
Please read the object definition in ha_example.h before reading the rest
if this file.
if this file.
To get an idea of what occurs here is an example select that would do a
To get an idea of what occurs here is an example select that would do a
scan of an entire table:
scan of an entire table:
ha_example::store_lock
ha_example::store_lock
ha_example::external_lock
ha_example::external_lock
...
@@ -50,13 +50,13 @@
...
@@ -50,13 +50,13 @@
ha_example::rnd_next
ha_example::rnd_next
ha_example::extra
ha_example::extra
ENUM HA_EXTRA_NO_CACHE End cacheing of records (def)
ENUM HA_EXTRA_NO_CACHE End cacheing of records (def)
ha_example::external_lock
ha_example::external_lock
ha_example::extra
ha_example::extra
ENUM HA_EXTRA_RESET Reset database to after open
ENUM HA_EXTRA_RESET Reset database to after open
In the above example has 9 row called before rnd_next signalled that it was
In the above example has 9 row called before rnd_next signalled that it was
at the end of its data. In the above example the table was already opened
at the end of its data. In the above example the table was already opened
(or you would have seen a call to ha_example::open(). Calls to
(or you would have seen a call to ha_example::open(). Calls to
ha_example::extra() are hints as to what will be occuring to the request.
ha_example::extra() are hints as to what will be occuring to the request.
Happy coding!
Happy coding!
...
@@ -92,7 +92,7 @@ static byte* example_get_key(EXAMPLE_SHARE *share,uint *length,
...
@@ -92,7 +92,7 @@ static byte* example_get_key(EXAMPLE_SHARE *share,uint *length,
/*
/*
Example of simple lock controls. The "share" it creates is structure we will
Example of simple lock controls. The "share" it creates is structure we will
pass to each example handler. Do you have to have one of these? Well, you have
pass to each example handler. Do you have to have one of these? Well, you have
pieces that are used for locking, and they are needed to function.
pieces that are used for locking, and they are needed to function.
*/
*/
static
EXAMPLE_SHARE
*
get_share
(
const
char
*
table_name
,
TABLE
*
table
)
static
EXAMPLE_SHARE
*
get_share
(
const
char
*
table_name
,
TABLE
*
table
)
{
{
...
@@ -130,7 +130,7 @@ static EXAMPLE_SHARE *get_share(const char *table_name, TABLE *table)
...
@@ -130,7 +130,7 @@ static EXAMPLE_SHARE *get_share(const char *table_name, TABLE *table)
my_multi_malloc
(
MYF
(
MY_WME
|
MY_ZEROFILL
),
my_multi_malloc
(
MYF
(
MY_WME
|
MY_ZEROFILL
),
&
share
,
sizeof
(
*
share
),
&
share
,
sizeof
(
*
share
),
&
tmp_name
,
length
+
1
,
&
tmp_name
,
length
+
1
,
NullS
)))
NullS
)))
{
{
pthread_mutex_unlock
(
&
example_mutex
);
pthread_mutex_unlock
(
&
example_mutex
);
return
NULL
;
return
NULL
;
...
@@ -161,7 +161,7 @@ static EXAMPLE_SHARE *get_share(const char *table_name, TABLE *table)
...
@@ -161,7 +161,7 @@ static EXAMPLE_SHARE *get_share(const char *table_name, TABLE *table)
}
}
/*
/*
Free lock controls. We call this whenever we close a table. If the table had
Free lock controls. We call this whenever we close a table. If the table had
the last reference to the share then we free memory associated with it.
the last reference to the share then we free memory associated with it.
*/
*/
...
@@ -182,7 +182,7 @@ static int free_share(EXAMPLE_SHARE *share)
...
@@ -182,7 +182,7 @@ static int free_share(EXAMPLE_SHARE *share)
/*
/*
If frm_error() is called then we will use this to to find out what file extentions
If frm_error() is called then we will use this to to find out what file extentions
exist for the storage engine. This is also used by the default rename_table and
exist for the storage engine. This is also used by the default rename_table and
delete_table method in handler.cc.
delete_table method in handler.cc.
*/
*/
...
@@ -190,10 +190,10 @@ const char **ha_example::bas_ext() const
...
@@ -190,10 +190,10 @@ const char **ha_example::bas_ext() const
{
static
const
char
*
ext
[]
=
{
NullS
};
return
ext
;
}
{
static
const
char
*
ext
[]
=
{
NullS
};
return
ext
;
}
/*
/*
Used for opening tables. The name will be the name of the file.
Used for opening tables. The name will be the name of the file.
A table is opened when it needs to be opened. For instance
A table is opened when it needs to be opened. For instance
when a request comes in for a select on the table (tables are not
when a request comes in for a select on the table (tables are not
open and closed for each request, they are cached).
open and closed for each request, they are cached).
Called from handler.cc by handler::ha_open(). The server opens all tables by
Called from handler.cc by handler::ha_open(). The server opens all tables by
...
@@ -212,12 +212,12 @@ int ha_example::open(const char *name, int mode, uint test_if_locked)
...
@@ -212,12 +212,12 @@ int ha_example::open(const char *name, int mode, uint test_if_locked)
/*
/*
Closes a table. We call the free_share() function to free any resources
Closes a table. We call the free_share() function to free any resources
that we have allocated in the "shared" structure.
that we have allocated in the "shared" structure.
Called from sql_base.cc, sql_select.cc, and table.cc.
Called from sql_base.cc, sql_select.cc, and table.cc.
In sql_select.cc it is only used to close up temporary tables or during
In sql_select.cc it is only used to close up temporary tables or during
the process where a temporary table is converted over to being a
the process where a temporary table is converted over to being a
myisam table.
myisam table.
For sql_base.cc look at close_data_tables().
For sql_base.cc look at close_data_tables().
*/
*/
...
@@ -230,7 +230,7 @@ int ha_example::close(void)
...
@@ -230,7 +230,7 @@ int ha_example::close(void)
/*
/*
write_row() inserts a row. No extra() hint is given currently if a bulk load
write_row() inserts a row. No extra() hint is given currently if a bulk load
is happeneding. buf() is a byte array of data. You can use the field
is happeneding. buf() is a byte array of data. You can use the field
information to extract the data from the native byte array type.
information to extract the data from the native byte array type.
Example of this would be:
Example of this would be:
for (Field **field=table->field ; *field ; field++)
for (Field **field=table->field ; *field ; field++)
...
@@ -238,20 +238,20 @@ int ha_example::close(void)
...
@@ -238,20 +238,20 @@ int ha_example::close(void)
...
...
}
}
See ha_tina.cc for an example of extracting all of the data as strings.
See ha_tina.cc for an example of extracting all of the data as strings.
ha_berekly.cc has an example of how to store it intact by "packing" it
ha_berekly.cc has an example of how to store it intact by "packing" it
for ha_berkeley's own native storage type.
for ha_berkeley's own native storage type.
See the note for update_row() on auto_increments and timestamps. This
See the note for update_row() on auto_increments and timestamps. This
case also applied to write_row().
case also applied to write_row().
Called from item_sum.cc, item_sum.cc, sql_acl.cc, sql_insert.cc,
Called from item_sum.cc, item_sum.cc, sql_acl.cc, sql_insert.cc,
sql_insert.cc, sql_select.cc, sql_table.cc, sql_udf.cc, and sql_update.cc.
sql_insert.cc, sql_select.cc, sql_table.cc, sql_udf.cc, and sql_update.cc.
*/
*/
int
ha_example
::
write_row
(
byte
*
buf
)
int
ha_example
::
write_row
(
byte
*
buf
)
{
{
DBUG_ENTER
(
"ha_example::write_row"
);
DBUG_ENTER
(
"ha_example::write_row"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
...
@@ -274,7 +274,7 @@ int ha_example::update_row(const byte * old_data, byte * new_data)
...
@@ -274,7 +274,7 @@ int ha_example::update_row(const byte * old_data, byte * new_data)
{
{
DBUG_ENTER
(
"ha_example::update_row"
);
DBUG_ENTER
(
"ha_example::update_row"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
...
@@ -282,8 +282,8 @@ int ha_example::update_row(const byte * old_data, byte * new_data)
...
@@ -282,8 +282,8 @@ int ha_example::update_row(const byte * old_data, byte * new_data)
This will delete a row. buf will contain a copy of the row to be deleted.
This will delete a row. buf will contain a copy of the row to be deleted.
The server will call this right after the current row has been called (from
The server will call this right after the current row has been called (from
either a previous rnd_nexT() or index call).
either a previous rnd_nexT() or index call).
If you keep a pointer to the last row or can access a primary key it will
If you keep a pointer to the last row or can access a primary key it will
make doing the deletion quite a bit easier.
make doing the deletion quite a bit easier.
Keep in mind that the server does no guarentee consecutive deletions. ORDER BY
Keep in mind that the server does no guarentee consecutive deletions. ORDER BY
clauses can be used.
clauses can be used.
...
@@ -294,7 +294,7 @@ int ha_example::update_row(const byte * old_data, byte * new_data)
...
@@ -294,7 +294,7 @@ int ha_example::update_row(const byte * old_data, byte * new_data)
int
ha_example
::
delete_row
(
const
byte
*
buf
)
int
ha_example
::
delete_row
(
const
byte
*
buf
)
{
{
DBUG_ENTER
(
"ha_example::delete_row"
);
DBUG_ENTER
(
"ha_example::delete_row"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
...
@@ -309,7 +309,7 @@ int ha_example::index_read(byte * buf, const byte * key,
...
@@ -309,7 +309,7 @@ int ha_example::index_read(byte * buf, const byte * key,
__attribute__
((
unused
)))
__attribute__
((
unused
)))
{
{
DBUG_ENTER
(
"ha_example::index_read"
);
DBUG_ENTER
(
"ha_example::index_read"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
...
@@ -323,7 +323,7 @@ int ha_example::index_read_idx(byte * buf, uint index, const byte * key,
...
@@ -323,7 +323,7 @@ int ha_example::index_read_idx(byte * buf, uint index, const byte * key,
__attribute__
((
unused
)))
__attribute__
((
unused
)))
{
{
DBUG_ENTER
(
"ha_example::index_read_idx"
);
DBUG_ENTER
(
"ha_example::index_read_idx"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
...
@@ -333,7 +333,7 @@ int ha_example::index_read_idx(byte * buf, uint index, const byte * key,
...
@@ -333,7 +333,7 @@ int ha_example::index_read_idx(byte * buf, uint index, const byte * key,
int
ha_example
::
index_next
(
byte
*
buf
)
int
ha_example
::
index_next
(
byte
*
buf
)
{
{
DBUG_ENTER
(
"ha_example::index_next"
);
DBUG_ENTER
(
"ha_example::index_next"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
...
@@ -343,40 +343,40 @@ int ha_example::index_next(byte * buf)
...
@@ -343,40 +343,40 @@ int ha_example::index_next(byte * buf)
int
ha_example
::
index_prev
(
byte
*
buf
)
int
ha_example
::
index_prev
(
byte
*
buf
)
{
{
DBUG_ENTER
(
"ha_example::index_prev"
);
DBUG_ENTER
(
"ha_example::index_prev"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
/*
/*
index_first() asks for the first key in the index.
index_first() asks for the first key in the index.
Called from opt_range.cc, opt_sum.cc, sql_handler.cc,
Called from opt_range.cc, opt_sum.cc, sql_handler.cc,
and sql_select.cc.
and sql_select.cc.
*/
*/
int
ha_example
::
index_first
(
byte
*
buf
)
int
ha_example
::
index_first
(
byte
*
buf
)
{
{
DBUG_ENTER
(
"ha_example::index_first"
);
DBUG_ENTER
(
"ha_example::index_first"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
/*
/*
index_last() asks for the last key in the index.
index_last() asks for the last key in the index.
Called from opt_range.cc, opt_sum.cc, sql_handler.cc,
Called from opt_range.cc, opt_sum.cc, sql_handler.cc,
and sql_select.cc.
and sql_select.cc.
*/
*/
int
ha_example
::
index_last
(
byte
*
buf
)
int
ha_example
::
index_last
(
byte
*
buf
)
{
{
DBUG_ENTER
(
"ha_example::index_last"
);
DBUG_ENTER
(
"ha_example::index_last"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
/*
/*
rnd_init() is called when the system wants the storage engine to do a table
rnd_init() is called when the system wants the storage engine to do a table
scan.
scan.
See the example in the introduction at the top of this file to see when
See the example in the introduction at the top of this file to see when
rnd_init() is called.
rnd_init() is called.
Called from filesort.cc, records.cc, sql_handler.cc, sql_select.cc, sql_table.cc,
Called from filesort.cc, records.cc, sql_handler.cc, sql_select.cc, sql_table.cc,
...
@@ -385,11 +385,16 @@ int ha_example::index_last(byte * buf)
...
@@ -385,11 +385,16 @@ int ha_example::index_last(byte * buf)
int
ha_example
::
rnd_init
(
bool
scan
)
int
ha_example
::
rnd_init
(
bool
scan
)
{
{
DBUG_ENTER
(
"ha_example::rnd_init"
);
DBUG_ENTER
(
"ha_example::rnd_init"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
int
ha_example
::
rnd_end
()
{
DBUG_ENTER
(
"ha_example::rnd_end"
);
DBUG_RETURN
(
0
);
}
/*
/*
This is called for each row of the table scan. When you run out of records
This is called for each row of the table scan. When you run out of records
you should return HA_ERR_END_OF_FILE. Fill buff up with the row information.
you should return HA_ERR_END_OF_FILE. Fill buff up with the row information.
The Field structure for the table is the key to getting data into buf
The Field structure for the table is the key to getting data into buf
...
@@ -415,8 +420,8 @@ int ha_example::rnd_next(byte *buf)
...
@@ -415,8 +420,8 @@ int ha_example::rnd_next(byte *buf)
the size needed to store current_position. ref is just a byte array
the size needed to store current_position. ref is just a byte array
that the server will maintain. If you are using offsets to mark rows, then
that the server will maintain. If you are using offsets to mark rows, then
current_position should be the offset. If it is a primary key like in
current_position should be the offset. If it is a primary key like in
BDB, then it needs to be a primary key.
BDB, then it needs to be a primary key.
Called from filesort.cc, sql_select.cc, sql_delete.cc and sql_update.cc.
Called from filesort.cc, sql_select.cc, sql_delete.cc and sql_update.cc.
*/
*/
void
ha_example
::
position
(
const
byte
*
record
)
void
ha_example
::
position
(
const
byte
*
record
)
...
@@ -436,7 +441,7 @@ void ha_example::position(const byte *record)
...
@@ -436,7 +441,7 @@ void ha_example::position(const byte *record)
int
ha_example
::
rnd_pos
(
byte
*
buf
,
byte
*
pos
)
int
ha_example
::
rnd_pos
(
byte
*
buf
,
byte
*
pos
)
{
{
DBUG_ENTER
(
"ha_example::rnd_pos"
);
DBUG_ENTER
(
"ha_example::rnd_pos"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
...
@@ -449,9 +454,9 @@ int ha_example::rnd_pos(byte * buf, byte *pos)
...
@@ -449,9 +454,9 @@ int ha_example::rnd_pos(byte * buf, byte *pos)
if (records < 2)
if (records < 2)
records = 2;
records = 2;
The reason is that the server will optimize for cases of only a single
The reason is that the server will optimize for cases of only a single
record. If in a table scan you don't know the number of records
record. If in a table scan you don't know the number of records
it will probably be better to set records to two so you can return
it will probably be better to set records to two so you can return
as many records as you need.
as many records as you need.
Along with records a few more variables you may wish to set are:
Along with records a few more variables you may wish to set are:
records
records
deleted
deleted
...
@@ -518,9 +523,9 @@ int ha_example::reset(void)
...
@@ -518,9 +523,9 @@ int ha_example::reset(void)
/*
/*
Used to delete all rows in a table. Both for cases of truncate and
Used to delete all rows in a table. Both for cases of truncate and
for cases where the optimizer realizes that all rows will be
for cases where the optimizer realizes that all rows will be
removed as a result of a SQL statement.
removed as a result of a SQL statement.
Called from item_sum.cc by Item_func_group_concat::clear(),
Called from item_sum.cc by Item_func_group_concat::clear(),
Item_sum_count_distinct::clear(), and Item_func_group_concat::clear().
Item_sum_count_distinct::clear(), and Item_func_group_concat::clear().
Called from sql_delete.cc by mysql_delete().
Called from sql_delete.cc by mysql_delete().
Called from sql_select.cc by JOIN::reinit().
Called from sql_select.cc by JOIN::reinit().
...
@@ -529,12 +534,12 @@ int ha_example::reset(void)
...
@@ -529,12 +534,12 @@ int ha_example::reset(void)
int
ha_example
::
delete_all_rows
()
int
ha_example
::
delete_all_rows
()
{
{
DBUG_ENTER
(
"ha_example::delete_all_rows"
);
DBUG_ENTER
(
"ha_example::delete_all_rows"
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
/*
/*
First you should go read the section "locking functions for mysql" in
First you should go read the section "locking functions for mysql" in
lock.cc to understand this.
lock.cc to understand this.
This create a lock on the table. If you are implementing a storage engine
This create a lock on the table. If you are implementing a storage engine
that can handle transacations look at ha_berkely.cc to see how you will
that can handle transacations look at ha_berkely.cc to see how you will
...
@@ -564,7 +569,7 @@ int ha_example::external_lock(THD *thd, int lock_type)
...
@@ -564,7 +569,7 @@ int ha_example::external_lock(THD *thd, int lock_type)
lock (if we don't want to use MySQL table locks at all) or add locks
lock (if we don't want to use MySQL table locks at all) or add locks
for many tables (like we do when we are using a MERGE handler).
for many tables (like we do when we are using a MERGE handler).
Berkeley DB for example changes all WRITE locks to TL_WRITE_ALLOW_WRITE
Berkeley DB for example changes all WRITE locks to TL_WRITE_ALLOW_WRITE
(which signals that we are doing WRITES, but we are still allowing other
(which signals that we are doing WRITES, but we are still allowing other
reader's and writer's.
reader's and writer's.
...
@@ -591,9 +596,9 @@ THR_LOCK_DATA **ha_example::store_lock(THD *thd,
...
@@ -591,9 +596,9 @@ THR_LOCK_DATA **ha_example::store_lock(THD *thd,
}
}
/*
/*
Used to delete a table. By the time delete_table() has been called all
Used to delete a table. By the time delete_table() has been called all
opened references to this table will have been closed (and your globally
opened references to this table will have been closed (and your globally
shared references released. The variable name will just be the name of
shared references released. The variable name will just be the name of
the table. You will need to remove any files you have created at this point.
the table. You will need to remove any files you have created at this point.
If you do not implement this, the default delete_table() is called from
If you do not implement this, the default delete_table() is called from
...
@@ -623,10 +628,10 @@ int ha_example::delete_table(const char *name)
...
@@ -623,10 +628,10 @@ int ha_example::delete_table(const char *name)
int
ha_example
::
rename_table
(
const
char
*
from
,
const
char
*
to
)
int
ha_example
::
rename_table
(
const
char
*
from
,
const
char
*
to
)
{
{
DBUG_ENTER
(
"ha_example::rename_table "
);
DBUG_ENTER
(
"ha_example::rename_table "
);
DBUG_RETURN
(
HA_ERR_
NOT_IMPLEMENTE
D
);
DBUG_RETURN
(
HA_ERR_
WRONG_COMMAN
D
);
}
}
/*
/*
Given a starting key, and an ending key estimate the number of rows that
Given a starting key, and an ending key estimate the number of rows that
will exist between the two. end_key may be empty which in case determine
will exist between the two. end_key may be empty which in case determine
if start_key matches any rows.
if start_key matches any rows.
...
@@ -644,14 +649,14 @@ ha_rows ha_example::records_in_range(uint inx, key_range *min_key,
...
@@ -644,14 +649,14 @@ ha_rows ha_example::records_in_range(uint inx, key_range *min_key,
/*
/*
create() is called to create a database. The variable name will have the name
create() is called to create a database. The variable name will have the name
of the table. When create() is called you do not need to worry about opening
of the table. When create() is called you do not need to worry about opening
the table. Also, the FRM file will have already been created so adjusting
the table. Also, the FRM file will have already been created so adjusting
create_info will not do you any good. You can overwrite the frm file at this
create_info will not do you any good. You can overwrite the frm file at this
point if you wish to change the table definition, but there are no methods
point if you wish to change the table definition, but there are no methods
currently provided for doing that.
currently provided for doing that.
Called from handle.cc by ha_create_table().
Called from handle.cc by ha_create_table().
*/
*/
int
ha_example
::
create
(
const
char
*
name
,
TABLE
*
table_arg
,
int
ha_example
::
create
(
const
char
*
name
,
TABLE
*
table_arg
,
HA_CREATE_INFO
*
create_info
)
HA_CREATE_INFO
*
create_info
)
{
{
DBUG_ENTER
(
"ha_example::create"
);
DBUG_ENTER
(
"ha_example::create"
);
...
...
sql/examples/ha_example.h
View file @
9f45c9e3
...
@@ -14,7 +14,7 @@
...
@@ -14,7 +14,7 @@
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
/*
Please read ha_exmple.cc before reading this file.
Please read ha_exmple.cc before reading this file.
Please keep in mind that the example storage engine implements all methods
Please keep in mind that the example storage engine implements all methods
that are required to be implemented. handler.h has a full list of methods
that are required to be implemented. handler.h has a full list of methods
...
@@ -48,55 +48,68 @@ class ha_example: public handler
...
@@ -48,55 +48,68 @@ class ha_example: public handler
ha_example
(
TABLE
*
table
)
:
handler
(
table
)
ha_example
(
TABLE
*
table
)
:
handler
(
table
)
{
{
}
}
~
ha_example
()
~
ha_example
()
{
{
}
}
/* The name that will be used for display purposes */
/* The name that will be used for display purposes */
const
char
*
table_type
()
const
{
return
"EXAMPLE"
;
}
const
char
*
table_type
()
const
{
return
"EXAMPLE"
;
}
/* The name of the index type that will be used for display */
/*
const
char
*
index_type
(
uint
inx
)
{
return
"NONE"
;
}
The name of the index type that will be used for display
don't implement this method unless you really have indexes
*/
const
char
*
index_type
(
uint
inx
)
{
return
"HASH"
;
}
const
char
**
bas_ext
()
const
;
const
char
**
bas_ext
()
const
;
/*
/*
This is a list of flags that says what the storage engine
This is a list of flags that says what the storage engine
implements. The current table flags are documented in
implements. The current table flags are documented in
table_flags.
handler.h
*/
*/
ulong
table_flags
()
const
ulong
table_flags
()
const
{
{
return
0
;
return
0
;
}
}
/*
/*
This is a list of flags that says how the storage engine
This is a list of flags that says how the storage engine
implements indexes. The current index flags are documented in
implements indexes. The current index flags are documented in
handler.h. If you do not implement indexes, just return zero
handler.h. If you do not implement indexes, just return zero
here.
here.
*/
*/
ulong
index_flags
(
uint
inx
)
const
ulong
index_flags
(
uint
inx
,
uint
part
)
const
{
{
return
0
;
return
0
;
}
}
/*
/*
unireg.cc will call the following to make sure that the storage engine can
unireg.cc will call the following to make sure that the storage engine can
handle the data it is about to send.
handle the data it is about to send.
Return *real* limits of your storage engine here. MySQL will do
min(your_limits, MySQL_limits) automatically
There is no need to implement ..._key_... methods if you don't suport
indexes.
*/
*/
uint
max_record_length
()
const
{
return
HA_MAX_REC_LENGTH
;
}
uint
max_
supported_
record_length
()
const
{
return
HA_MAX_REC_LENGTH
;
}
uint
max_keys
()
const
{
return
0
;
}
uint
max_
supported_
keys
()
const
{
return
0
;
}
uint
max_key_parts
()
const
{
return
0
;
}
uint
max_
supported_
key_parts
()
const
{
return
0
;
}
uint
max_key_length
()
const
{
return
0
;
}
uint
max_
supported_
key_length
()
const
{
return
0
;
}
/*
/*
Called in test_quick_select to determine if indexes should be used.
Called in test_quick_select to determine if indexes should be used.
*/
*/
virtual
double
scan_time
()
{
return
(
double
)
(
records
+
deleted
)
/
20.0
+
10
;
}
virtual
double
scan_time
()
{
return
(
double
)
(
records
+
deleted
)
/
20.0
+
10
;
}
/*
/*
The next method will never be called if you do not implement indexes.
The next method will never be called if you do not implement indexes.
*/
*/
virtual
double
read_time
(
ha_rows
rows
)
{
return
(
double
)
rows
/
20.0
+
1
;
}
virtual
double
read_time
(
ha_rows
rows
)
{
return
(
double
)
rows
/
20.0
+
1
;
}
/*
/*
Everything below are methods that we implment in ha_example.cc.
Everything below are methods that we implment in ha_example.cc.
Most of these methods are not obligatory, skip them and
MySQL will treat them as not implemented
*/
*/
int
open
(
const
char
*
name
,
int
mode
,
uint
test_if_locked
);
int
open
(
const
char
*
name
,
int
mode
,
uint
test_if_locked
);
// required
int
close
(
void
);
int
close
(
void
);
// required
int
write_row
(
byte
*
buf
);
int
write_row
(
byte
*
buf
);
int
update_row
(
const
byte
*
old_data
,
byte
*
new_data
);
int
update_row
(
const
byte
*
old_data
,
byte
*
new_data
);
int
delete_row
(
const
byte
*
buf
);
int
delete_row
(
const
byte
*
buf
);
...
@@ -108,21 +121,32 @@ class ha_example: public handler
...
@@ -108,21 +121,32 @@ class ha_example: public handler
int
index_prev
(
byte
*
buf
);
int
index_prev
(
byte
*
buf
);
int
index_first
(
byte
*
buf
);
int
index_first
(
byte
*
buf
);
int
index_last
(
byte
*
buf
);
int
index_last
(
byte
*
buf
);
int
rnd_init
(
bool
scan
=
1
);
/*
int
rnd_next
(
byte
*
buf
);
unlike index_init(), rnd_init() can be called two times
int
rnd_pos
(
byte
*
buf
,
byte
*
pos
);
without rnd_end() in between (it only makes sense if scan=1).
void
position
(
const
byte
*
record
);
then the second call should prepare for the new table scan
void
info
(
uint
);
(e.g if rnd_init allocates the cursor, second call should
position it to the start of the table, no need to deallocate
and allocate it again
*/
int
rnd_init
(
bool
scan
);
//required
int
rnd_end
();
int
rnd_next
(
byte
*
buf
);
//required
int
rnd_pos
(
byte
*
buf
,
byte
*
pos
);
//required
void
position
(
const
byte
*
record
);
//required
void
info
(
uint
);
//required
int
extra
(
enum
ha_extra_function
operation
);
int
extra
(
enum
ha_extra_function
operation
);
int
reset
(
void
);
int
reset
(
void
);
int
external_lock
(
THD
*
thd
,
int
lock_type
);
int
external_lock
(
THD
*
thd
,
int
lock_type
);
//required
int
delete_all_rows
(
void
);
int
delete_all_rows
(
void
);
ha_rows
records_in_range
(
uint
inx
,
key_range
*
min_key
,
ha_rows
records_in_range
(
uint
inx
,
key_range
*
min_key
,
key_range
*
max_key
);
key_range
*
max_key
);
int
delete_table
(
const
char
*
from
);
int
delete_table
(
const
char
*
from
);
int
rename_table
(
const
char
*
from
,
const
char
*
to
);
int
rename_table
(
const
char
*
from
,
const
char
*
to
);
int
create
(
const
char
*
name
,
TABLE
*
form
,
HA_CREATE_INFO
*
create_info
);
int
create
(
const
char
*
name
,
TABLE
*
form
,
HA_CREATE_INFO
*
create_info
);
//required
THR_LOCK_DATA
**
store_lock
(
THD
*
thd
,
THR_LOCK_DATA
**
to
,
THR_LOCK_DATA
**
store_lock
(
THD
*
thd
,
THR_LOCK_DATA
**
to
,
enum
thr_lock_type
lock_type
);
enum
thr_lock_type
lock_type
);
//required
};
};
sql/ha_berkeley.cc
View file @
9f45c9e3
...
@@ -1583,7 +1583,7 @@ int ha_berkeley::index_last(byte * buf)
...
@@ -1583,7 +1583,7 @@ int ha_berkeley::index_last(byte * buf)
int
ha_berkeley
::
rnd_init
(
bool
scan
)
int
ha_berkeley
::
rnd_init
(
bool
scan
)
{
{
DBUG_ENTER
(
"rnd_init"
);
DBUG_ENTER
(
"rnd_init"
);
DBUG_ASSERT
(
active_index
==
MAX_KEY
);
//
DBUG_ASSERT(active_index==MAX_KEY);
current_row
.
flags
=
DB_DBT_REALLOC
;
current_row
.
flags
=
DB_DBT_REALLOC
;
DBUG_RETURN
(
index_init
(
primary_key
));
DBUG_RETURN
(
index_init
(
primary_key
));
}
}
...
...
sql/ha_berkeley.h
View file @
9f45c9e3
...
@@ -88,7 +88,7 @@ class ha_berkeley: public handler
...
@@ -88,7 +88,7 @@ class ha_berkeley: public handler
public:
public:
ha_berkeley
(
TABLE
*
table
)
:
handler
(
table
),
alloc_ptr
(
0
),
rec_buff
(
0
),
file
(
0
),
ha_berkeley
(
TABLE
*
table
)
:
handler
(
table
),
alloc_ptr
(
0
),
rec_buff
(
0
),
file
(
0
),
int_table_flags
(
HA_REC_NOT_IN_SEQ
|
HA_FAST_KEY_READ
|
int_table_flags
(
HA_REC_NOT_IN_SEQ
|
HA_FAST_KEY_READ
|
HA_NULL_IN_KEY
|
HA_
BLOB_KEY
|
HA_NOT_EXACT_COUNT
|
HA_NULL_IN_KEY
|
HA_
CAN_INDEX_BLOBS
|
HA_NOT_EXACT_COUNT
|
HA_PRIMARY_KEY_IN_READ_INDEX
|
HA_FILE_BASED
|
HA_PRIMARY_KEY_IN_READ_INDEX
|
HA_FILE_BASED
|
HA_AUTO_PART_KEY
|
HA_TABLE_SCAN_ON_INDEX
),
HA_AUTO_PART_KEY
|
HA_TABLE_SCAN_ON_INDEX
),
changed_rows
(
0
),
last_dup_key
((
uint
)
-
1
),
version
(
0
),
using_ignore
(
0
)
{}
changed_rows
(
0
),
last_dup_key
((
uint
)
-
1
),
version
(
0
),
using_ignore
(
0
)
{}
...
...
sql/sql_select.cc
View file @
9f45c9e3
...
@@ -3872,12 +3872,8 @@ JOIN::join_free(bool full)
...
@@ -3872,12 +3872,8 @@ JOIN::join_free(bool full)
{
{
for
(
tab
=
join_tab
,
end
=
tab
+
tables
;
tab
!=
end
;
tab
++
)
for
(
tab
=
join_tab
,
end
=
tab
+
tables
;
tab
!=
end
;
tab
++
)
{
{
if
(
tab
->
table
)
if
(
tab
->
table
&&
tab
->
table
->
file
->
inited
==
handler
::
RND
)
{
/* Don't free index if we are using read_record */
if
(
tab
->
table
->
file
->
inited
==
handler
::
RND
)
tab
->
table
->
file
->
ha_rnd_end
();
tab
->
table
->
file
->
ha_rnd_end
();
}
}
}
}
}
}
}
...
...
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