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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
42297969
Commit
42297969
authored
Oct 16, 2000
by
monty@donna.mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Automatic primary key for BDB tables
parent
9323e733
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
349 additions
and
143 deletions
+349
-143
BitKeeper/etc/logging_ok
BitKeeper/etc/logging_ok
+1
-1
Docs/manual.texi
Docs/manual.texi
+25
-9
sql/field.h
sql/field.h
+1
-1
sql/filesort.cc
sql/filesort.cc
+1
-1
sql/ha_berkeley.cc
sql/ha_berkeley.cc
+198
-69
sql/ha_berkeley.h
sql/ha_berkeley.h
+25
-11
sql/handler.h
sql/handler.h
+1
-0
sql/opt_range.cc
sql/opt_range.cc
+1
-0
sql/sql_base.cc
sql/sql_base.cc
+37
-11
sql/sql_select.cc
sql/sql_select.cc
+10
-0
sql/table.cc
sql/table.cc
+48
-39
sql/table.h
sql/table.h
+1
-1
No files found.
BitKeeper/etc/logging_ok
View file @
42297969
monty@
tik
.mysql.com
monty@
donna
.mysql.com
Docs/manual.texi
View file @
42297969
...
@@ -1793,16 +1793,20 @@ Big changes made in @strong{MySQL} Version 3.22.12.
...
@@ -1793,16 +1793,20 @@ Big changes made in @strong{MySQL} Version 3.22.12.
@item @strong{MyODBC} (uses ODBC SDK 2.5) --- Gamma
@item @strong{MyODBC} (uses ODBC SDK 2.5) --- Gamma
It seems to work well with some programs.
It seems to work well with some programs.
@item Replication -- Alpha
@item Replication -- Alpha
/ Beta
We are still working on replication, so don't expect this to be rock
We are still working on replication, so don't expect this to be rock
solid yet. On the other hand, some @strong{MySQL} users are already
solid yet. On the other hand, some @strong{MySQL} users are already
using this with good results.
using this with good results.
@item BDB Tables -- Alpha
@item BDB Tables -- Alpha
/ Beta
The Berkeley DB code is very stable, but we are still improving the interface
The Berkeley DB code is very stable, but we are still improving the interface
between @strong{MySQL} and BDB tables, so it will take some time before this
between @strong{MySQL} and BDB tables, so it will take some time before this
is as tested as the other table types.
is as tested as the other table types.
@item Automatic recovery of MyISAM tables - Alpha.
This only affects the new code that checks if the table was closed properly
on open and executes an automatic check/repair of the table if it wasn't.
@end table
@end table
MySQL AB provides e-mail support for paying customers, but the @strong{MySQL}
MySQL AB provides e-mail support for paying customers, but the @strong{MySQL}
...
@@ -7979,12 +7983,10 @@ you should also compile your code to be multi-threaded!
...
@@ -7979,12 +7983,10 @@ you should also compile your code to be multi-threaded!
@node Windows and BDB tables., Windows vs Unix, Windows compiling, Windows
@node Windows and BDB tables., Windows vs Unix, Windows compiling, Windows
@subsection Windows and BDB Tables
@subsection Windows and BDB Tables
We are working on removing the requirement that one must have a primary
We will shortly do a full test on the new BDB interface on Windows.
key in a BDB table. As soon as this is fixed we will throughly test the
When this is done we will start to release binary distributions (for
BDB interface by running the @strong{MySQL} benchmark and our internal
Windows and UNIX) of @strong{MySQL} that will include support for BDB
test suite on it. When the above is done we will start to release binary
tables.
distributions (for Windows and UNIX) of @strong{MySQL} that will include
support for BDB tables.
@cindex Windows, versus UNIX
@cindex Windows, versus UNIX
@cindex operating systems, Windows versus UNIX
@cindex operating systems, Windows versus UNIX
...
@@ -21876,13 +21878,22 @@ Some characteristic of @code{BDB} tables:
...
@@ -21876,13 +21878,22 @@ Some characteristic of @code{BDB} tables:
@itemize @bullet
@itemize @bullet
@item
@item
All @code{BDB} tables must have a primary key.
@strong{MySQL} requires a @code{PRIMARY KEY} in each BDB table to be
able to refer to previously read rows; If you don't create on,
@strong{MySQL} will create an maintain a hidden @code{PRIMARY KEY} for
you. The hidden key has a length of 5 bytes and is incremented for each
insert attempt.
@item
@item
If all columns you access in a @code{BDB} tables is part of the same index or
If all columns you access in a @code{BDB} tables is part of the same index or
part of the the primary key then @strong{MySQL} can execute the query
part of the the primary key then @strong{MySQL} can execute the query
without having to access the actual row. In a @code{MyISAM} table the
without having to access the actual row. In a @code{MyISAM} table the
above holds only if the columns are part of the same index.
above holds only if the columns are part of the same index.
@item
@item
The @code{PRIMARY KEY} will be faster than any other key, as the
@code{PRIMARY KEY} is stored together with the row data. As the other keys are
stored as the key data + the @code{PRIMARY KEY}, its important to keep the
@code{PRIMARY KEY} as short as possible to save disk and get better speed.
@item
@code{LOCK TABLES} works on @code{BDB} tables as with other tables. If
@code{LOCK TABLES} works on @code{BDB} tables as with other tables. If
you don't use @code{LOCK TABLE}, @strong{MYSQL} will issue an internal
you don't use @code{LOCK TABLE}, @strong{MYSQL} will issue an internal
multiple write lock on the table to ensure that the table will be
multiple write lock on the table to ensure that the table will be
...
@@ -37972,6 +37983,11 @@ though, so 3.23 is not released as a stable version yet.
...
@@ -37972,6 +37983,11 @@ though, so 3.23 is not released as a stable version yet.
@appendixsubsec Changes in release 3.23.26
@appendixsubsec Changes in release 3.23.26
@itemize @bullet
@itemize @bullet
@item
@item
If one don't create a @code{PRIMARY KEY} in a BDB table, a hidden
@code{PRIMARY KEY} will be created.
@item
Added read-only-key optimization to BDB tables.
@item
@code{LEFT JOIN} did in some case prefer a full table scan when one
@code{LEFT JOIN} did in some case prefer a full table scan when one
didn't have a @code{WHERE} clause.
didn't have a @code{WHERE} clause.
@item
@item
sql/field.h
View file @
42297969
...
@@ -44,7 +44,7 @@ public:
...
@@ -44,7 +44,7 @@ public:
uint8
null_bit
;
// And position to it
uint8
null_bit
;
// And position to it
struct
st_table
*
table
;
// Pointer for table
struct
st_table
*
table
;
// Pointer for table
ulong
query_id
;
// For quick test of used fields
ulong
query_id
;
// For quick test of used fields
key_map
key_start
,
part_of_key
;
//
Which keys a field is in
key_map
key_start
,
part_of_key
;
//
Key is part of these keys.
const
char
*
table_name
,
*
field_name
;
const
char
*
table_name
,
*
field_name
;
utype
unireg_check
;
utype
unireg_check
;
uint32
field_length
;
// Length of field
uint32
field_length
;
// Length of field
...
...
sql/filesort.cc
View file @
42297969
...
@@ -331,7 +331,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
...
@@ -331,7 +331,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
if
(
!
indexfile
&&
!
quick_select
)
if
(
!
indexfile
&&
!
quick_select
)
{
{
file
->
reset
();
// QQ; Shouldn't be needed
file
->
reset
();
// QQ; Shouldn't be needed
if
(
table
->
keyread
)
// QQ Can be removed after the reset
if
(
sort_form
->
key_read
)
// QQ Can be removed after the reset
file
->
extra
(
HA_EXTRA_KEYREAD
);
// QQ is removed
file
->
extra
(
HA_EXTRA_KEYREAD
);
// QQ is removed
next_pos
=
(
byte
*
)
0
;
/* Find records in sequence */
next_pos
=
(
byte
*
)
0
;
/* Find records in sequence */
file
->
rnd_init
();
file
->
rnd_init
();
...
...
sql/ha_berkeley.cc
View file @
42297969
...
@@ -21,13 +21,12 @@
...
@@ -21,13 +21,12 @@
- Don't automaticly pack all string keys (To do this we need to modify
- Don't automaticly pack all string keys (To do this we need to modify
CREATE TABLE so that one can use the pack_keys argument per key).
CREATE TABLE so that one can use the pack_keys argument per key).
- An argument to pack_key that we don't want compression.
- An argument to pack_key that we don't want compression.
- Interaction with LOCK TABLES (Monty will fix this)
- DB_DBT_USERMEN should be used for fixed length tables
- DB_DBT_USERMEN should be used for fixed length tables
We will need an updated Berkeley DB version for this.
We will need an updated Berkeley DB version for this.
- Killing threads that has got a 'deadlock'
- Killing threads that has got a 'deadlock'
- SHOW TABLE STATUS should give more information about the table.
- SHOW TABLE STATUS should give more information about the table.
- Get a more accurate count of the number of rows.
- Get a more accurate count of the number of rows.
- Introduce hidden primary keys for tables without a primary key
We could store the found number of rows when the table is scanned.
- We will need a manager thread that calls flush_logs, removes old
- We will need a manager thread that calls flush_logs, removes old
logs and makes checkpoints at given intervals.
logs and makes checkpoints at given intervals.
- When not using UPDATE IGNORE, don't make a sub transaction but abort
- When not using UPDATE IGNORE, don't make a sub transaction but abort
...
@@ -203,6 +202,14 @@ const char **ha_berkeley::bas_ext() const
...
@@ -203,6 +202,14 @@ const char **ha_berkeley::bas_ext() const
{
static
const
char
*
ext
[]
=
{
ha_berkeley_ext
,
NullS
};
return
ext
;
}
{
static
const
char
*
ext
[]
=
{
ha_berkeley_ext
,
NullS
};
return
ext
;
}
static
int
berkeley_cmp_hidden_key
(
const
DBT
*
new_key
,
const
DBT
*
saved_key
)
{
ulonglong
a
=
uint5korr
((
char
*
)
new_key
->
data
);
ulonglong
b
=
uint5korr
((
char
*
)
saved_key
->
data
);
return
a
<
b
?
-
1
:
(
a
>
b
?
1
:
0
);
}
static
int
static
int
berkeley_cmp_packed_key
(
const
DBT
*
new_key
,
const
DBT
*
saved_key
)
berkeley_cmp_packed_key
(
const
DBT
*
new_key
,
const
DBT
*
saved_key
)
{
{
...
@@ -232,6 +239,8 @@ berkeley_cmp_packed_key(const DBT *new_key, const DBT *saved_key)
...
@@ -232,6 +239,8 @@ berkeley_cmp_packed_key(const DBT *new_key, const DBT *saved_key)
}
}
/* The following is not yet used; Should be used for fixed length keys */
static
int
static
int
berkeley_cmp_fix_length_key
(
const
DBT
*
new_key
,
const
DBT
*
saved_key
)
berkeley_cmp_fix_length_key
(
const
DBT
*
new_key
,
const
DBT
*
saved_key
)
{
{
...
@@ -261,19 +270,30 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
...
@@ -261,19 +270,30 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
int
error
;
int
error
;
DBUG_ENTER
(
"ha_berkeley::open"
);
DBUG_ENTER
(
"ha_berkeley::open"
);
/* Open primary key */
hidden_primary_key
=
0
;
if
((
primary_key
=
table
->
primary_key
)
>=
MAX_KEY
)
{
// No primary key
primary_key
=
table
->
keys
;
fixed_length_primary_key
=
1
;
ref_length
=
hidden_primary_key
=
BDB_HIDDEN_PRIMARY_KEY_LENGTH
;
}
key_used_on_scan
=
primary_key
;
/* Need some extra memory in case of packed keys */
/* Need some extra memory in case of packed keys */
uint
max_key_length
=
table
->
max_key_length
+
MAX_REF_PARTS
*
2
;
uint
max_key_length
=
table
->
max_key_length
+
MAX_REF_PARTS
*
2
;
if
(
!
(
alloc_ptr
=
if
(
!
(
alloc_ptr
=
my_multi_malloc
(
MYF
(
MY_WME
),
my_multi_malloc
(
MYF
(
MY_WME
),
&
key_file
,
table
->
keys
*
sizeof
(
*
key_file
),
&
key_file
,
(
table
->
keys
+
1
)
*
sizeof
(
*
key_file
),
&
key_type
,
table
->
keys
*
sizeof
(
u_int32_t
),
&
key_type
,
(
table
->
keys
+
1
)
*
sizeof
(
u_int32_t
),
&
key_buff
,
max_key_length
,
&
key_buff
,
max_key_length
,
&
key_buff2
,
max_key_length
,
&
key_buff2
,
max_key_length
,
&
primary_key_buff
,
&
primary_key_buff
,
table
->
key_info
[
table
->
primary_key
].
key_length
,
(
hidden_primary_key
?
0
:
table
->
key_info
[
table
->
primary_key
].
key_length
),
NullS
)))
NullS
)))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
if
(
!
(
rec_buff
=
my_malloc
((
alloced_rec_buff_length
=
table
->
reclength
),
if
(
!
(
rec_buff
=
my_malloc
((
alloced_rec_buff_length
=
table
->
rec
_buff_
length
),
MYF
(
MY_WME
))))
MYF
(
MY_WME
))))
{
{
my_free
(
alloc_ptr
,
MYF
(
0
));
my_free
(
alloc_ptr
,
MYF
(
0
));
...
@@ -298,8 +318,9 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
...
@@ -298,8 +318,9 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
}
}
/* Open primary key */
file
->
set_bt_compare
(
file
,
file
->
set_bt_compare
(
file
,
berkeley_cmp_packed_key
);
(
hidden_primary_key
?
berkeley_cmp_hidden_key
:
berkeley_cmp_packed_key
));
if
((
error
=
(
file
->
open
(
file
,
fn_format
(
name_buff
,
name
,
""
,
ha_berkeley_ext
,
if
((
error
=
(
file
->
open
(
file
,
fn_format
(
name_buff
,
name
,
""
,
ha_berkeley_ext
,
2
|
4
),
2
|
4
),
"main"
,
DB_BTREE
,
open_mode
,
0
))))
"main"
,
DB_BTREE
,
open_mode
,
0
))))
...
@@ -314,26 +335,19 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
...
@@ -314,26 +335,19 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
info
(
HA_STATUS_NO_LOCK
|
HA_STATUS_VARIABLE
|
HA_STATUS_CONST
);
info
(
HA_STATUS_NO_LOCK
|
HA_STATUS_VARIABLE
|
HA_STATUS_CONST
);
transaction
=
0
;
transaction
=
0
;
cursor
=
0
;
cursor
=
0
;
key_read
=
0
;
fixed_length_row
=!
(
table
->
db_create_options
&
HA_OPTION_PACK_RECORD
);
fixed_length_row
=!
(
table
->
db_create_options
&
HA_OPTION_PACK_RECORD
);
/* Open other keys */
/* Open other keys */
bzero
((
char
*
)
key_file
,
sizeof
(
*
key_file
)
*
table
->
keys
);
bzero
((
char
*
)
key_file
,
sizeof
(
*
key_file
)
*
table
->
keys
);
if
((
key_used_on_scan
=
primary_key
=
table
->
primary_key
)
<
MAX_KEY
)
key_file
[
primary_key
]
=
file
;
key_file
[
primary_key
]
=
file
;
key_type
[
primary_key
]
=
DB_NOOVERWRITE
;
else
// No primary key
{
hidden_primary_key
=
1
;
if
(
!
share
->
primary_key_inited
)
update_auto_primary_key
();
}
bzero
((
char
*
)
&
current_row
,
sizeof
(
current_row
));
bzero
((
char
*
)
&
current_row
,
sizeof
(
current_row
));
DB
**
ptr
=
key_file
;
DB
**
ptr
=
key_file
;
for
(
uint
i
=
0
,
used_keys
=
0
;
i
<
table
->
keys
;
i
++
,
ptr
++
)
for
(
uint
i
=
0
,
used_keys
=
0
;
i
<
table
->
keys
;
i
++
,
ptr
++
)
{
{
char
part
[
7
];
char
part
[
7
];
key_type
[
i
]
=
table
->
key_info
[
i
].
flags
&
HA_NOSAME
?
DB_NOOVERWRITE
:
0
;
if
(
i
!=
primary_key
)
if
(
i
!=
primary_key
)
{
{
if
((
error
=
db_create
(
ptr
,
db_env
,
0
)))
if
((
error
=
db_create
(
ptr
,
db_env
,
0
)))
...
@@ -343,6 +357,7 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
...
@@ -343,6 +357,7 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
}
}
sprintf
(
part
,
"key%02d"
,
++
used_keys
);
sprintf
(
part
,
"key%02d"
,
++
used_keys
);
key_type
[
i
]
=
table
->
key_info
[
i
].
flags
&
HA_NOSAME
?
DB_NOOVERWRITE
:
0
;
(
*
ptr
)
->
set_bt_compare
(
*
ptr
,
berkeley_cmp_packed_key
);
(
*
ptr
)
->
set_bt_compare
(
*
ptr
,
berkeley_cmp_packed_key
);
if
(
!
(
table
->
key_info
[
i
].
flags
&
HA_NOSAME
))
if
(
!
(
table
->
key_info
[
i
].
flags
&
HA_NOSAME
))
(
*
ptr
)
->
set_flags
(
*
ptr
,
DB_DUP
);
(
*
ptr
)
->
set_flags
(
*
ptr
,
DB_DUP
);
...
@@ -355,28 +370,34 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
...
@@ -355,28 +370,34 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
}
}
}
}
}
}
/* Calculate pack_length of primary key */
if
(
!
hidden_primary_key
)
{
ref_length
=
0
;
KEY_PART_INFO
*
key_part
=
table
->
key_info
[
primary_key
].
key_part
;
KEY_PART_INFO
*
end
=
key_part
+
table
->
key_info
[
primary_key
].
key_parts
;
for
(
;
key_part
!=
end
;
key_part
++
)
ref_length
+=
key_part
->
field
->
max_packed_col_length
(
key_part
->
length
);
fixed_length_primary_key
=
(
ref_length
==
table
->
key_info
[
primary_key
].
key_length
);
}
else
{
if
(
!
share
->
primary_key_inited
)
update_auto_primary_key
();
}
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
void
ha_berkeley
::
initialize
(
void
)
{
/* Calculate pack_length of primary key */
ref_length
=
0
;
KEY_PART_INFO
*
key_part
=
table
->
key_info
[
primary_key
].
key_part
;
KEY_PART_INFO
*
end
=
key_part
+
table
->
key_info
[
primary_key
].
key_parts
;
for
(
;
key_part
!=
end
;
key_part
++
)
ref_length
+=
key_part
->
field
->
max_packed_col_length
(
key_part
->
length
);
fixed_length_primary_key
=
(
ref_length
==
table
->
key_info
[
primary_key
].
key_length
);
}
int
ha_berkeley
::
close
(
void
)
int
ha_berkeley
::
close
(
void
)
{
{
int
error
,
result
=
0
;
int
error
,
result
=
0
;
uint
keys
=
table
->
keys
+
test
(
hidden_primary_key
);
DBUG_ENTER
(
"ha_berkeley::close"
);
DBUG_ENTER
(
"ha_berkeley::close"
);
for
(
uint
i
=
0
;
i
<
table
->
keys
;
i
++
)
for
(
uint
i
=
0
;
i
<
keys
;
i
++
)
{
{
if
(
key_file
[
i
]
&&
(
error
=
key_file
[
i
]
->
close
(
key_file
[
i
],
0
)))
if
(
key_file
[
i
]
&&
(
error
=
key_file
[
i
]
->
close
(
key_file
[
i
],
0
)))
result
=
error
;
result
=
error
;
...
@@ -427,13 +448,20 @@ ulong ha_berkeley::max_row_length(const byte *buf)
...
@@ -427,13 +448,20 @@ ulong ha_berkeley::max_row_length(const byte *buf)
pre-allocated.
pre-allocated.
*/
*/
int
ha_berkeley
::
pack_row
(
DBT
*
row
,
const
byte
*
record
)
int
ha_berkeley
::
pack_row
(
DBT
*
row
,
const
byte
*
record
,
bool
new_row
)
{
{
bzero
((
char
*
)
row
,
sizeof
(
*
row
));
bzero
((
char
*
)
row
,
sizeof
(
*
row
));
if
(
fixed_length_row
)
if
(
fixed_length_row
)
{
{
row
->
data
=
(
void
*
)
record
;
row
->
data
=
(
void
*
)
record
;
row
->
size
=
table
->
reclength
;
row
->
size
=
table
->
reclength
+
hidden_primary_key
;
if
(
hidden_primary_key
)
{
if
(
new_row
)
get_auto_primary_key
(
current_ident
);
memcpy_fixed
((
char
*
)
record
+
table
->
reclength
,
(
char
*
)
current_ident
,
BDB_HIDDEN_PRIMARY_KEY_LENGTH
);
}
return
0
;
return
0
;
}
}
if
(
table
->
blob_fields
)
if
(
table
->
blob_fields
)
...
@@ -448,6 +476,15 @@ int ha_berkeley::pack_row(DBT *row, const byte *record)
...
@@ -448,6 +476,15 @@ int ha_berkeley::pack_row(DBT *row, const byte *record)
for
(
Field
**
field
=
table
->
field
;
*
field
;
field
++
)
for
(
Field
**
field
=
table
->
field
;
*
field
;
field
++
)
ptr
=
(
byte
*
)
(
*
field
)
->
pack
((
char
*
)
ptr
,
record
+
(
*
field
)
->
offset
());
ptr
=
(
byte
*
)
(
*
field
)
->
pack
((
char
*
)
ptr
,
record
+
(
*
field
)
->
offset
());
if
(
hidden_primary_key
)
{
if
(
new_row
)
get_auto_primary_key
(
current_ident
);
memcpy_fixed
((
char
*
)
ptr
,
(
char
*
)
current_ident
,
BDB_HIDDEN_PRIMARY_KEY_LENGTH
);
ptr
+=
BDB_HIDDEN_PRIMARY_KEY_LENGTH
;
}
row
->
data
=
rec_buff
;
row
->
data
=
rec_buff
;
row
->
size
=
(
size_t
)
(
ptr
-
rec_buff
);
row
->
size
=
(
size_t
)
(
ptr
-
rec_buff
);
return
0
;
return
0
;
...
@@ -457,7 +494,7 @@ int ha_berkeley::pack_row(DBT *row, const byte *record)
...
@@ -457,7 +494,7 @@ int ha_berkeley::pack_row(DBT *row, const byte *record)
void
ha_berkeley
::
unpack_row
(
char
*
record
,
DBT
*
row
)
void
ha_berkeley
::
unpack_row
(
char
*
record
,
DBT
*
row
)
{
{
if
(
fixed_length_row
)
if
(
fixed_length_row
)
memcpy
(
record
,
row
->
data
,
table
->
reclength
);
memcpy
(
record
,
(
char
*
)
row
->
data
,
table
->
reclength
+
hidden_primary_key
);
else
else
{
{
/* Copy null bits */
/* Copy null bits */
...
@@ -470,6 +507,37 @@ void ha_berkeley::unpack_row(char *record, DBT *row)
...
@@ -470,6 +507,37 @@ void ha_berkeley::unpack_row(char *record, DBT *row)
}
}
/* Store the key and the primary key into the row */
void
ha_berkeley
::
unpack_key
(
char
*
record
,
DBT
*
key
,
uint
index
)
{
KEY
*
key_info
=
table
->
key_info
+
index
;
KEY_PART_INFO
*
key_part
=
key_info
->
key_part
,
*
end
=
key_part
+
key_info
->
key_parts
;
char
*
pos
=
(
char
*
)
key
->
data
;
for
(
;
key_part
!=
end
;
key_part
++
)
{
if
(
key_part
->
null_bit
)
{
if
(
!*
pos
++
)
// Null value
{
/*
We don't need to reset the record data as we will not access it
if the null data is set
*/
record
[
key_part
->
null_offset
]
|=
key_part
->
null_bit
;
continue
;
}
record
[
key_part
->
null_offset
]
&=
~
key_part
->
null_bit
;
}
pos
=
(
char
*
)
key_part
->
field
->
unpack
(
record
+
key_part
->
field
->
offset
(),
pos
);
}
}
/*
/*
Create a packed key from from a row
Create a packed key from from a row
This will never fail as the key buffer is pre allocated.
This will never fail as the key buffer is pre allocated.
...
@@ -478,12 +546,20 @@ void ha_berkeley::unpack_row(char *record, DBT *row)
...
@@ -478,12 +546,20 @@ void ha_berkeley::unpack_row(char *record, DBT *row)
DBT
*
ha_berkeley
::
pack_key
(
DBT
*
key
,
uint
keynr
,
char
*
buff
,
DBT
*
ha_berkeley
::
pack_key
(
DBT
*
key
,
uint
keynr
,
char
*
buff
,
const
byte
*
record
)
const
byte
*
record
)
{
{
bzero
((
char
*
)
key
,
sizeof
(
*
key
));
if
(
hidden_primary_key
&&
keynr
==
primary_key
)
{
key
->
data
=
current_ident
;
key
->
size
=
BDB_HIDDEN_PRIMARY_KEY_LENGTH
;
return
key
;
}
KEY
*
key_info
=
table
->
key_info
+
keynr
;
KEY
*
key_info
=
table
->
key_info
+
keynr
;
KEY_PART_INFO
*
key_part
=
key_info
->
key_part
;
KEY_PART_INFO
*
key_part
=
key_info
->
key_part
;
KEY_PART_INFO
*
end
=
key_part
+
key_info
->
key_parts
;
KEY_PART_INFO
*
end
=
key_part
+
key_info
->
key_parts
;
DBUG_ENTER
(
"pack_key"
);
DBUG_ENTER
(
"pack_key"
);
bzero
((
char
*
)
key
,
sizeof
(
*
key
));
key
->
data
=
buff
;
key
->
data
=
buff
;
key
->
app_private
=
key_info
;
key
->
app_private
=
key_info
;
...
@@ -561,7 +637,7 @@ int ha_berkeley::write_row(byte * record)
...
@@ -561,7 +637,7 @@ int ha_berkeley::write_row(byte * record)
update_timestamp
(
record
+
table
->
time_stamp
-
1
);
update_timestamp
(
record
+
table
->
time_stamp
-
1
);
if
(
table
->
next_number_field
&&
record
==
table
->
record
[
0
])
if
(
table
->
next_number_field
&&
record
==
table
->
record
[
0
])
update_auto_increment
();
update_auto_increment
();
if
((
error
=
pack_row
(
&
row
,
record
)))
if
((
error
=
pack_row
(
&
row
,
record
,
1
)))
DBUG_RETURN
(
error
);
DBUG_RETURN
(
error
);
if
(
table
->
keys
==
1
)
if
(
table
->
keys
==
1
)
...
@@ -678,7 +754,7 @@ int ha_berkeley::update_primary_key(DB_TXN *trans, bool primary_key_changed,
...
@@ -678,7 +754,7 @@ int ha_berkeley::update_primary_key(DB_TXN *trans, bool primary_key_changed,
pack_key
(
&
old_key
,
primary_key
,
key_buff2
,
old_row
);
pack_key
(
&
old_key
,
primary_key
,
key_buff2
,
old_row
);
if
((
error
=
remove_key
(
trans
,
primary_key
,
old_row
,
(
DBT
*
)
0
,
&
old_key
)))
if
((
error
=
remove_key
(
trans
,
primary_key
,
old_row
,
(
DBT
*
)
0
,
&
old_key
)))
DBUG_RETURN
(
error
);
// This should always succeed
DBUG_RETURN
(
error
);
// This should always succeed
if
((
error
=
pack_row
(
&
row
,
new_row
)))
if
((
error
=
pack_row
(
&
row
,
new_row
,
0
)))
{
{
// Out of memory (this shouldn't happen!)
// Out of memory (this shouldn't happen!)
(
void
)
file
->
put
(
file
,
trans
,
&
old_key
,
&
row
,
(
void
)
file
->
put
(
file
,
trans
,
&
old_key
,
&
row
,
...
@@ -697,7 +773,7 @@ int ha_berkeley::update_primary_key(DB_TXN *trans, bool primary_key_changed,
...
@@ -697,7 +773,7 @@ int ha_berkeley::update_primary_key(DB_TXN *trans, bool primary_key_changed,
else
else
{
{
// Primary key didn't change; just update the row data
// Primary key didn't change; just update the row data
if
((
error
=
pack_row
(
&
row
,
new_row
)))
if
((
error
=
pack_row
(
&
row
,
new_row
,
0
)))
DBUG_RETURN
(
error
);
DBUG_RETURN
(
error
);
error
=
file
->
put
(
file
,
trans
,
prim_key
,
&
row
,
0
);
error
=
file
->
put
(
file
,
trans
,
prim_key
,
&
row
,
0
);
if
(
error
)
if
(
error
)
...
@@ -719,12 +795,24 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row)
...
@@ -719,12 +795,24 @@ int ha_berkeley::update_row(const byte * old_row, byte * new_row)
statistic_increment
(
ha_update_count
,
&
LOCK_status
);
statistic_increment
(
ha_update_count
,
&
LOCK_status
);
if
(
table
->
time_stamp
)
if
(
table
->
time_stamp
)
update_timestamp
(
new_row
+
table
->
time_stamp
-
1
);
update_timestamp
(
new_row
+
table
->
time_stamp
-
1
);
pack_key
(
&
prim_key
,
primary_key
,
key_buff
,
new_row
);
if
(
hidden_primary_key
)
if
((
primary_key_changed
=
key_cmp
(
primary_key
,
old_row
,
new_row
)))
{
pack_key
(
&
old_prim_key
,
primary_key
,
primary_key_buff
,
old_row
);
primary_key_changed
=
0
;
else
bzero
((
char
*
)
&
prim_key
,
sizeof
(
prim_key
));
prim_key
.
data
=
(
void
*
)
current_ident
;
prim_key
.
size
=
BDB_HIDDEN_PRIMARY_KEY_LENGTH
;
old_prim_key
=
prim_key
;
old_prim_key
=
prim_key
;
}
else
{
pack_key
(
&
prim_key
,
primary_key
,
key_buff
,
new_row
);
if
((
primary_key_changed
=
key_cmp
(
primary_key
,
old_row
,
new_row
)))
pack_key
(
&
old_prim_key
,
primary_key
,
primary_key_buff
,
old_row
);
else
old_prim_key
=
prim_key
;
}
LINT_INIT
(
error
);
LINT_INIT
(
error
);
for
(
uint
retry
=
0
;
retry
<
berkeley_trans_retry
;
retry
++
)
for
(
uint
retry
=
0
;
retry
<
berkeley_trans_retry
;
retry
++
)
...
@@ -869,9 +957,12 @@ int ha_berkeley::delete_row(const byte * record)
...
@@ -869,9 +957,12 @@ int ha_berkeley::delete_row(const byte * record)
DBUG_ENTER
(
"delete_row"
);
DBUG_ENTER
(
"delete_row"
);
statistic_increment
(
ha_delete_count
,
&
LOCK_status
);
statistic_increment
(
ha_delete_count
,
&
LOCK_status
);
if
((
error
=
pack_row
(
&
row
,
record
)))
if
((
error
=
pack_row
(
&
row
,
record
,
0
)))
DBUG_RETURN
((
error
));
DBUG_RETURN
((
error
));
pack_key
(
&
prim_key
,
primary_key
,
key_buff
,
record
);
pack_key
(
&
prim_key
,
primary_key
,
key_buff
,
record
);
if
(
hidden_primary_key
)
keys
|=
(
key_map
)
1
<<
primary_key
;
for
(
uint
retry
=
0
;
retry
<
berkeley_trans_retry
;
retry
++
)
for
(
uint
retry
=
0
;
retry
<
berkeley_trans_retry
;
retry
++
)
{
{
DB_TXN
*
sub_trans
;
DB_TXN
*
sub_trans
;
...
@@ -934,7 +1025,7 @@ int ha_berkeley::index_end()
...
@@ -934,7 +1025,7 @@ int ha_berkeley::index_end()
/* What to do after we have read a row based on an index */
/* What to do after we have read a row based on an index */
int
ha_berkeley
::
read_row
(
int
error
,
char
*
buf
,
uint
keynr
,
DBT
*
row
,
int
ha_berkeley
::
read_row
(
int
error
,
char
*
buf
,
uint
keynr
,
DBT
*
row
,
bool
read_next
)
DBT
*
found_key
,
bool
read_next
)
{
{
DBUG_ENTER
(
"read_row"
);
DBUG_ENTER
(
"read_row"
);
if
(
error
)
if
(
error
)
...
@@ -944,9 +1035,22 @@ int ha_berkeley::read_row(int error, char *buf, uint keynr, DBT *row,
...
@@ -944,9 +1035,22 @@ int ha_berkeley::read_row(int error, char *buf, uint keynr, DBT *row,
table
->
status
=
STATUS_NOT_FOUND
;
table
->
status
=
STATUS_NOT_FOUND
;
DBUG_RETURN
(
error
);
DBUG_RETURN
(
error
);
}
}
if
(
hidden_primary_key
)
memcpy_fixed
(
current_ident
,
(
char
*
)
row
->
data
+
row
->
size
-
BDB_HIDDEN_PRIMARY_KEY_LENGTH
,
BDB_HIDDEN_PRIMARY_KEY_LENGTH
);
table
->
status
=
0
;
if
(
keynr
!=
primary_key
)
if
(
keynr
!=
primary_key
)
{
{
/* We only found the primary key. Now we have to use this to find
the row data */
if
(
key_read
&&
found_key
)
{
unpack_key
(
buf
,
found_key
,
keynr
);
if
(
!
hidden_primary_key
)
unpack_key
(
buf
,
row
,
primary_key
);
DBUG_RETURN
(
0
);
}
DBT
key
;
DBT
key
;
bzero
((
char
*
)
&
key
,
sizeof
(
key
));
bzero
((
char
*
)
&
key
,
sizeof
(
key
));
key
.
data
=
key_buff2
;
key
.
data
=
key_buff2
;
...
@@ -963,7 +1067,6 @@ int ha_berkeley::read_row(int error, char *buf, uint keynr, DBT *row,
...
@@ -963,7 +1067,6 @@ int ha_berkeley::read_row(int error, char *buf, uint keynr, DBT *row,
row
=
&
current_row
;
row
=
&
current_row
;
}
}
unpack_row
(
buf
,
row
);
unpack_row
(
buf
,
row
);
table
->
status
=
0
;
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
...
@@ -980,7 +1083,7 @@ int ha_berkeley::index_read_idx(byte * buf, uint keynr, const byte * key,
...
@@ -980,7 +1083,7 @@ int ha_berkeley::index_read_idx(byte * buf, uint keynr, const byte * key,
pack_key
(
&
last_key
,
keynr
,
key_buff
,
key
,
pack_key
(
&
last_key
,
keynr
,
key_buff
,
key
,
key_len
),
key_len
),
&
current_row
,
0
),
&
current_row
,
0
),
buf
,
keynr
,
&
current_row
,
0
));
buf
,
keynr
,
&
current_row
,
&
last_key
,
0
));
}
}
...
@@ -999,7 +1102,7 @@ int ha_berkeley::index_read(byte * buf, const byte * key,
...
@@ -999,7 +1102,7 @@ int ha_berkeley::index_read(byte * buf, const byte * key,
key_buff
,
key_buff
,
key
,
key_len
),
key
,
key_len
),
&
row
,
DB_SET
),
&
row
,
DB_SET
),
buf
,
active_index
,
&
row
,
0
);
buf
,
active_index
,
&
row
,
(
DBT
*
)
0
,
0
);
}
}
else
else
{
{
...
@@ -1009,7 +1112,7 @@ int ha_berkeley::index_read(byte * buf, const byte * key,
...
@@ -1009,7 +1112,7 @@ int ha_berkeley::index_read(byte * buf, const byte * key,
memcpy
(
key_buff2
,
key_buff
,
last_key
.
size
);
memcpy
(
key_buff2
,
key_buff
,
last_key
.
size
);
((
KEY
*
)
last_key
.
app_private
)
->
handler
.
bdb_return_if_eq
=
-
1
;
((
KEY
*
)
last_key
.
app_private
)
->
handler
.
bdb_return_if_eq
=
-
1
;
error
=
read_row
(
cursor
->
c_get
(
cursor
,
&
last_key
,
&
row
,
DB_SET_RANGE
),
error
=
read_row
(
cursor
->
c_get
(
cursor
,
&
last_key
,
&
row
,
DB_SET_RANGE
),
buf
,
active_index
,
&
row
,
0
);
buf
,
active_index
,
&
row
,
(
DBT
*
)
0
,
0
);
((
KEY
*
)
last_key
.
app_private
)
->
handler
.
bdb_return_if_eq
=
0
;
((
KEY
*
)
last_key
.
app_private
)
->
handler
.
bdb_return_if_eq
=
0
;
if
(
!
error
&&
find_flag
==
HA_READ_KEY_EXACT
)
if
(
!
error
&&
find_flag
==
HA_READ_KEY_EXACT
)
{
{
...
@@ -1030,7 +1133,7 @@ int ha_berkeley::index_next(byte * buf)
...
@@ -1030,7 +1133,7 @@ int ha_berkeley::index_next(byte * buf)
statistic_increment
(
ha_read_next_count
,
&
LOCK_status
);
statistic_increment
(
ha_read_next_count
,
&
LOCK_status
);
bzero
((
char
*
)
&
row
,
sizeof
(
row
));
bzero
((
char
*
)
&
row
,
sizeof
(
row
));
DBUG_RETURN
(
read_row
(
cursor
->
c_get
(
cursor
,
&
last_key
,
&
row
,
DB_NEXT
),
DBUG_RETURN
(
read_row
(
cursor
->
c_get
(
cursor
,
&
last_key
,
&
row
,
DB_NEXT
),
buf
,
active_index
,
&
row
,
1
));
buf
,
active_index
,
&
row
,
&
last_key
,
1
));
}
}
int
ha_berkeley
::
index_next_same
(
byte
*
buf
,
const
byte
*
key
,
uint
keylen
)
int
ha_berkeley
::
index_next_same
(
byte
*
buf
,
const
byte
*
key
,
uint
keylen
)
...
@@ -1042,11 +1145,11 @@ int ha_berkeley::index_next_same(byte * buf, const byte *key, uint keylen)
...
@@ -1042,11 +1145,11 @@ int ha_berkeley::index_next_same(byte * buf, const byte *key, uint keylen)
bzero
((
char
*
)
&
row
,
sizeof
(
row
));
bzero
((
char
*
)
&
row
,
sizeof
(
row
));
if
(
keylen
==
table
->
key_info
[
active_index
].
key_length
)
if
(
keylen
==
table
->
key_info
[
active_index
].
key_length
)
error
=
read_row
(
cursor
->
c_get
(
cursor
,
&
last_key
,
&
row
,
DB_NEXT_DUP
),
error
=
read_row
(
cursor
->
c_get
(
cursor
,
&
last_key
,
&
row
,
DB_NEXT_DUP
),
buf
,
active_index
,
&
row
,
1
);
buf
,
active_index
,
&
row
,
&
last_key
,
1
);
else
else
{
{
error
=
read_row
(
cursor
->
c_get
(
cursor
,
&
last_key
,
&
row
,
DB_NEXT
),
error
=
read_row
(
cursor
->
c_get
(
cursor
,
&
last_key
,
&
row
,
DB_NEXT
),
buf
,
active_index
,
&
row
,
1
);
buf
,
active_index
,
&
row
,
&
last_key
,
1
);
if
(
!
error
&&
::
key_cmp
(
table
,
key
,
active_index
,
keylen
))
if
(
!
error
&&
::
key_cmp
(
table
,
key
,
active_index
,
keylen
))
error
=
HA_ERR_END_OF_FILE
;
error
=
HA_ERR_END_OF_FILE
;
}
}
...
@@ -1061,7 +1164,7 @@ int ha_berkeley::index_prev(byte * buf)
...
@@ -1061,7 +1164,7 @@ int ha_berkeley::index_prev(byte * buf)
statistic_increment
(
ha_read_prev_count
,
&
LOCK_status
);
statistic_increment
(
ha_read_prev_count
,
&
LOCK_status
);
bzero
((
char
*
)
&
row
,
sizeof
(
row
));
bzero
((
char
*
)
&
row
,
sizeof
(
row
));
DBUG_RETURN
(
read_row
(
cursor
->
c_get
(
cursor
,
&
last_key
,
&
row
,
DB_PREV
),
DBUG_RETURN
(
read_row
(
cursor
->
c_get
(
cursor
,
&
last_key
,
&
row
,
DB_PREV
),
buf
,
active_index
,
&
row
,
1
));
buf
,
active_index
,
&
row
,
&
last_key
,
1
));
}
}
...
@@ -1072,7 +1175,7 @@ int ha_berkeley::index_first(byte * buf)
...
@@ -1072,7 +1175,7 @@ int ha_berkeley::index_first(byte * buf)
statistic_increment
(
ha_read_first_count
,
&
LOCK_status
);
statistic_increment
(
ha_read_first_count
,
&
LOCK_status
);
bzero
((
char
*
)
&
row
,
sizeof
(
row
));
bzero
((
char
*
)
&
row
,
sizeof
(
row
));
DBUG_RETURN
(
read_row
(
cursor
->
c_get
(
cursor
,
&
last_key
,
&
row
,
DB_FIRST
),
DBUG_RETURN
(
read_row
(
cursor
->
c_get
(
cursor
,
&
last_key
,
&
row
,
DB_FIRST
),
buf
,
active_index
,
&
row
,
0
));
buf
,
active_index
,
&
row
,
&
last_key
,
0
));
}
}
int
ha_berkeley
::
index_last
(
byte
*
buf
)
int
ha_berkeley
::
index_last
(
byte
*
buf
)
...
@@ -1082,7 +1185,7 @@ int ha_berkeley::index_last(byte * buf)
...
@@ -1082,7 +1185,7 @@ int ha_berkeley::index_last(byte * buf)
statistic_increment
(
ha_read_last_count
,
&
LOCK_status
);
statistic_increment
(
ha_read_last_count
,
&
LOCK_status
);
bzero
((
char
*
)
&
row
,
sizeof
(
row
));
bzero
((
char
*
)
&
row
,
sizeof
(
row
));
DBUG_RETURN
(
read_row
(
cursor
->
c_get
(
cursor
,
&
last_key
,
&
row
,
DB_LAST
),
DBUG_RETURN
(
read_row
(
cursor
->
c_get
(
cursor
,
&
last_key
,
&
row
,
DB_LAST
),
buf
,
active_index
,
&
row
,
0
));
buf
,
active_index
,
&
row
,
&
last_key
,
0
));
}
}
int
ha_berkeley
::
rnd_init
(
bool
scan
)
int
ha_berkeley
::
rnd_init
(
bool
scan
)
...
@@ -1103,7 +1206,7 @@ int ha_berkeley::rnd_next(byte *buf)
...
@@ -1103,7 +1206,7 @@ int ha_berkeley::rnd_next(byte *buf)
statistic_increment
(
ha_read_rnd_next_count
,
&
LOCK_status
);
statistic_increment
(
ha_read_rnd_next_count
,
&
LOCK_status
);
bzero
((
char
*
)
&
row
,
sizeof
(
row
));
bzero
((
char
*
)
&
row
,
sizeof
(
row
));
DBUG_RETURN
(
read_row
(
cursor
->
c_get
(
cursor
,
&
last_key
,
&
row
,
DB_NEXT
),
DBUG_RETURN
(
read_row
(
cursor
->
c_get
(
cursor
,
&
last_key
,
&
row
,
DB_NEXT
),
buf
,
active_index
,
&
row
,
1
));
buf
,
active_index
,
&
row
,
&
last_key
,
1
));
}
}
...
@@ -1136,13 +1239,18 @@ int ha_berkeley::rnd_pos(byte * buf, byte *pos)
...
@@ -1136,13 +1239,18 @@ int ha_berkeley::rnd_pos(byte * buf, byte *pos)
return
read_row
(
file
->
get
(
file
,
transaction
,
return
read_row
(
file
->
get
(
file
,
transaction
,
get_pos
(
&
db_pos
,
pos
),
get_pos
(
&
db_pos
,
pos
),
&
current_row
,
0
),
&
current_row
,
0
),
buf
,
active_index
,
&
current_row
,
0
);
buf
,
active_index
,
&
current_row
,
(
DBT
*
)
0
,
0
);
}
}
void
ha_berkeley
::
position
(
const
byte
*
record
)
void
ha_berkeley
::
position
(
const
byte
*
record
)
{
{
DBT
key
;
DBT
key
;
pack_key
(
&
key
,
primary_key
,
ref
,
record
);
if
(
hidden_primary_key
)
{
memcpy_fixed
(
ref
,
(
char
*
)
current_ident
,
BDB_HIDDEN_PRIMARY_KEY_LENGTH
);
}
else
pack_key
(
&
key
,
primary_key
,
ref
,
record
);
}
}
...
@@ -1162,11 +1270,27 @@ void ha_berkeley::info(uint flag)
...
@@ -1162,11 +1270,27 @@ void ha_berkeley::info(uint flag)
int
ha_berkeley
::
extra
(
enum
ha_extra_function
operation
)
int
ha_berkeley
::
extra
(
enum
ha_extra_function
operation
)
{
{
switch
(
operation
)
{
case
HA_EXTRA_RESET
:
case
HA_EXTRA_RESET_STATE
:
key_read
=
0
;
break
;
case
HA_EXTRA_KEYREAD
:
key_read
=
1
;
// Query satisfied with key
break
;
case
HA_EXTRA_NO_KEYREAD
:
key_read
=
0
;
break
;
default:
break
;
}
return
0
;
return
0
;
}
}
int
ha_berkeley
::
reset
(
void
)
int
ha_berkeley
::
reset
(
void
)
{
{
key_read
=
0
;
// Reset to state after open
return
0
;
return
0
;
}
}
...
@@ -1280,6 +1404,7 @@ int ha_berkeley::create(const char *name, register TABLE *form,
...
@@ -1280,6 +1404,7 @@ int ha_berkeley::create(const char *name, register TABLE *form,
{
{
char
name_buff
[
FN_REFLEN
];
char
name_buff
[
FN_REFLEN
];
char
part
[
7
];
char
part
[
7
];
uint
index
=
1
;
DBUG_ENTER
(
"ha_berkeley::create"
);
DBUG_ENTER
(
"ha_berkeley::create"
);
fn_format
(
name_buff
,
name
,
""
,
ha_berkeley_ext
,
2
|
4
);
fn_format
(
name_buff
,
name
,
""
,
ha_berkeley_ext
,
2
|
4
);
...
@@ -1288,14 +1413,18 @@ int ha_berkeley::create(const char *name, register TABLE *form,
...
@@ -1288,14 +1413,18 @@ int ha_berkeley::create(const char *name, register TABLE *form,
if
(
create_sub_table
(
name_buff
,
"main"
,
DB_BTREE
,
0
))
if
(
create_sub_table
(
name_buff
,
"main"
,
DB_BTREE
,
0
))
DBUG_RETURN
(
1
);
DBUG_RETURN
(
1
);
primary_key
=
table
->
primary_key
;
/* Create the keys */
/* Create the keys */
for
(
uint
i
=
1
;
i
<
form
->
keys
;
i
++
)
for
(
uint
i
=
0
;
i
<
form
->
keys
;
i
++
)
{
{
sprintf
(
part
,
"key%02d"
,
i
);
if
(
i
!=
primary_key
)
if
(
create_sub_table
(
name_buff
,
part
,
DB_BTREE
,
{
(
table
->
key_info
[
i
].
flags
&
HA_NOSAME
)
?
0
:
sprintf
(
part
,
"key%02d"
,
index
++
);
DB_DUP
))
if
(
create_sub_table
(
name_buff
,
part
,
DB_BTREE
,
DBUG_RETURN
(
1
);
(
table
->
key_info
[
i
].
flags
&
HA_NOSAME
)
?
0
:
DB_DUP
))
DBUG_RETURN
(
1
);
}
}
}
/* Create the status block to save information from last status command */
/* Create the status block to save information from last status command */
...
@@ -1403,7 +1532,7 @@ static BDB_SHARE *get_share(const char *table_name)
...
@@ -1403,7 +1532,7 @@ static BDB_SHARE *get_share(const char *table_name)
return
0
;
return
0
;
}
}
thr_lock_init
(
&
share
->
lock
);
thr_lock_init
(
&
share
->
lock
);
pthread_mutex_init
(
&
share
->
mutex
);
pthread_mutex_init
(
&
share
->
mutex
,
NULL
);
}
}
}
}
share
->
use_count
++
;
share
->
use_count
++
;
...
@@ -1427,17 +1556,17 @@ static void free_share(BDB_SHARE *share)
...
@@ -1427,17 +1556,17 @@ static void free_share(BDB_SHARE *share)
void
ha_berkeley
::
update_auto_primary_key
()
void
ha_berkeley
::
update_auto_primary_key
()
{
{
(
void
)
extra
(
HA_EXTRA_KEYREAD
);
pthread_mutex_lock
(
&
share
->
mutex
);
pthread_mutex_lock
(
&
share
->
mutex
);
if
(
!
share
->
primary_key_inited
)
if
(
!
share
->
primary_key_inited
)
{
{
(
void
)
extra
(
HA_EXTRA_KEYREAD
);
index_init
(
primary_key
);
index_init
(
primary_key
);
if
(
!
index_last
(
table
->
record
[
1
]))
if
(
!
index_last
(
table
->
record
[
1
]))
share
->
auto_ident
=
current_ident
;
share
->
auto_ident
=
uint5korr
(
current_ident
)
;
index_end
();
index_end
();
(
void
)
extra
(
HA_EXTRA_NO_KEYREAD
);
}
}
pthread_mutex_unlock
(
&
share
->
mutex
);
pthread_mutex_unlock
(
&
share
->
mutex
);
(
void
)
extra
(
HA_EXTRA_NO_KEYREAD
);
}
}
#endif
/* HAVE_BERKELEY_DB */
#endif
/* HAVE_BERKELEY_DB */
sql/ha_berkeley.h
View file @
42297969
...
@@ -23,15 +23,18 @@
...
@@ -23,15 +23,18 @@
#include <db.h>
#include <db.h>
#define BDB_HIDDEN_PRIMARY_KEY_LENGTH 5
typedef
struct
st_berkeley_share
{
typedef
struct
st_berkeley_share
{
ulonglong
auto_ident
;
ulonglong
auto_ident
;
THR_LOCK
lock
;
THR_LOCK
lock
;
pthread_mutex_t
mutex
;
pthread_mutex_t
mutex
;
char
*
table_name
;
char
*
table_name
;
uint
table_name_length
,
use_count
;
uint
table_name_length
,
use_count
;
my_bool
inited
;
bool
primary_key_
inited
;
}
BDB_SHARE
;
}
BDB_SHARE
;
class
ha_berkeley
:
public
handler
class
ha_berkeley
:
public
handler
{
{
THR_LOCK_DATA
lock
;
THR_LOCK_DATA
lock
;
...
@@ -46,13 +49,15 @@ class ha_berkeley: public handler
...
@@ -46,13 +49,15 @@ class ha_berkeley: public handler
BDB_SHARE
*
share
;
BDB_SHARE
*
share
;
ulong
int_option_flag
;
ulong
int_option_flag
;
ulong
alloced_rec_buff_length
;
ulong
alloced_rec_buff_length
;
uint
primary_key
,
last_dup_key
;
uint
primary_key
,
last_dup_key
,
hidden_primary_key
;
bool
fixed_length_row
,
fixed_length_primary_key
,
hidden_primary_key
;
bool
fixed_length_row
,
fixed_length_primary_key
,
key_read
;
bool
fix_rec_buff_for_blob
(
ulong
length
);
bool
fix_rec_buff_for_blob
(
ulong
length
);
byte
current_ident
[
BDB_HIDDEN_PRIMARY_KEY_LENGTH
];
ulong
max_row_length
(
const
byte
*
buf
);
ulong
max_row_length
(
const
byte
*
buf
);
int
pack_row
(
DBT
*
row
,
const
byte
*
record
);
int
pack_row
(
DBT
*
row
,
const
byte
*
record
,
bool
new_row
);
void
unpack_row
(
char
*
record
,
DBT
*
row
);
void
unpack_row
(
char
*
record
,
DBT
*
row
);
void
ha_berkeley
::
unpack_key
(
char
*
record
,
DBT
*
key
,
uint
index
);
DBT
*
pack_key
(
DBT
*
key
,
uint
keynr
,
char
*
buff
,
const
byte
*
record
);
DBT
*
pack_key
(
DBT
*
key
,
uint
keynr
,
char
*
buff
,
const
byte
*
record
);
DBT
*
pack_key
(
DBT
*
key
,
uint
keynr
,
char
*
buff
,
const
byte
*
key_ptr
,
DBT
*
pack_key
(
DBT
*
key
,
uint
keynr
,
char
*
buff
,
const
byte
*
key_ptr
,
uint
key_length
);
uint
key_length
);
...
@@ -64,7 +69,7 @@ class ha_berkeley: public handler
...
@@ -64,7 +69,7 @@ class ha_berkeley: public handler
int
update_primary_key
(
DB_TXN
*
trans
,
bool
primary_key_changed
,
int
update_primary_key
(
DB_TXN
*
trans
,
bool
primary_key_changed
,
const
byte
*
old_row
,
const
byte
*
new_row
,
const
byte
*
old_row
,
const
byte
*
new_row
,
DBT
*
prim_key
);
DBT
*
prim_key
);
int
read_row
(
int
error
,
char
*
buf
,
uint
keynr
,
DBT
*
row
,
bool
);
int
read_row
(
int
error
,
char
*
buf
,
uint
keynr
,
DBT
*
row
,
DBT
*
key
,
bool
);
DBT
*
get_pos
(
DBT
*
to
,
byte
*
pos
);
DBT
*
get_pos
(
DBT
*
to
,
byte
*
pos
);
public:
public:
...
@@ -72,9 +77,8 @@ class ha_berkeley: public handler
...
@@ -72,9 +77,8 @@ class ha_berkeley: public handler
int_option_flag
(
HA_READ_NEXT
|
HA_READ_PREV
|
int_option_flag
(
HA_READ_NEXT
|
HA_READ_PREV
|
HA_REC_NOT_IN_SEQ
|
HA_REC_NOT_IN_SEQ
|
HA_KEYPOS_TO_RNDPOS
|
HA_READ_ORDER
|
HA_LASTKEY_ORDER
|
HA_KEYPOS_TO_RNDPOS
|
HA_READ_ORDER
|
HA_LASTKEY_ORDER
|
HA_LONGLONG_KEYS
|
HA_NULL_KEY
|
HA_LONGLONG_KEYS
|
HA_NULL_KEY
|
HA_HAVE_KEY_READ_ONLY
|
HA_BLOB_KEY
|
HA_BLOB_KEY
|
HA_NOT_EXACT_COUNT
|
HA_REQUIRE_PRIMARY_KEY
|
HA_NOT_EXACT_COUNT
|
HA_PRIMARY_KEY_IN_READ_INDEX
|
HA_DROP_BEFORE_CREATE
),
HA_PRIMARY_KEY_IN_READ_INDEX
|
HA_DROP_BEFORE_CREATE
),
last_dup_key
((
uint
)
-
1
)
last_dup_key
((
uint
)
-
1
)
{
{
...
@@ -84,14 +88,14 @@ class ha_berkeley: public handler
...
@@ -84,14 +88,14 @@ class ha_berkeley: public handler
const
char
**
bas_ext
()
const
;
const
char
**
bas_ext
()
const
;
ulong
option_flag
()
const
{
return
int_option_flag
;
}
ulong
option_flag
()
const
{
return
int_option_flag
;
}
uint
max_record_length
()
const
{
return
HA_MAX_REC_LENGTH
;
}
uint
max_record_length
()
const
{
return
HA_MAX_REC_LENGTH
;
}
uint
max_keys
()
const
{
return
MAX_KEY
;
}
uint
max_keys
()
const
{
return
MAX_KEY
-
1
;
}
uint
max_key_parts
()
const
{
return
MAX_REF_PARTS
;
}
uint
max_key_parts
()
const
{
return
MAX_REF_PARTS
;
}
uint
max_key_length
()
const
{
return
MAX_KEY_LENGTH
;
}
uint
max_key_length
()
const
{
return
MAX_KEY_LENGTH
;
}
uint
extra_rec_buf_length
()
{
return
BDB_HIDDEN_PRIMARY_KEY_LENGTH
;
}
bool
fast_key_read
()
{
return
1
;}
bool
fast_key_read
()
{
return
1
;}
bool
has_transactions
()
{
return
1
;}
bool
has_transactions
()
{
return
1
;}
int
open
(
const
char
*
name
,
int
mode
,
uint
test_if_locked
);
int
open
(
const
char
*
name
,
int
mode
,
uint
test_if_locked
);
void
initialize
(
void
);
int
close
(
void
);
int
close
(
void
);
double
scan_time
();
double
scan_time
();
int
write_row
(
byte
*
buf
);
int
write_row
(
byte
*
buf
);
...
@@ -129,6 +133,16 @@ class ha_berkeley: public handler
...
@@ -129,6 +133,16 @@ class ha_berkeley: public handler
int
delete_table
(
const
char
*
name
);
int
delete_table
(
const
char
*
name
);
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
);
void
update_auto_primary_key
();
inline
void
get_auto_primary_key
(
byte
*
to
)
{
ulonglong
tmp
;
pthread_mutex_lock
(
&
share
->
mutex
);
share
->
auto_ident
++
;
int5store
(
to
,
share
->
auto_ident
);
pthread_mutex_unlock
(
&
share
->
mutex
);
}
};
};
extern
bool
berkeley_skip
;
extern
bool
berkeley_skip
;
...
...
sql/handler.h
View file @
42297969
...
@@ -202,6 +202,7 @@ public:
...
@@ -202,6 +202,7 @@ public:
virtual
double
read_time
(
ha_rows
rows
)
{
return
rows
;
}
virtual
double
read_time
(
ha_rows
rows
)
{
return
rows
;
}
virtual
bool
fast_key_read
()
{
return
0
;}
virtual
bool
fast_key_read
()
{
return
0
;}
virtual
bool
has_transactions
(){
return
0
;}
virtual
bool
has_transactions
(){
return
0
;}
virtual
uint
extra_rec_buf_length
()
{
return
0
;
}
virtual
int
index_init
(
uint
idx
)
{
active_index
=
idx
;
return
0
;}
virtual
int
index_init
(
uint
idx
)
{
active_index
=
idx
;
return
0
;}
virtual
int
index_end
()
{
return
0
;
}
virtual
int
index_end
()
{
return
0
;
}
...
...
sql/opt_range.cc
View file @
42297969
...
@@ -2347,6 +2347,7 @@ bool QUICK_SELECT::unique_key_range()
...
@@ -2347,6 +2347,7 @@ bool QUICK_SELECT::unique_key_range()
QUICK_SELECT
*
get_quick_select_for_ref
(
TABLE
*
table
,
TABLE_REF
*
ref
)
QUICK_SELECT
*
get_quick_select_for_ref
(
TABLE
*
table
,
TABLE_REF
*
ref
)
{
{
table
->
file
->
index_end
();
// Remove old cursor
QUICK_SELECT
*
quick
=
new
QUICK_SELECT
(
table
,
ref
->
key
,
1
);
QUICK_SELECT
*
quick
=
new
QUICK_SELECT
(
table
,
ref
->
key
,
1
);
KEY
*
key_info
=
&
table
->
key_info
[
ref
->
key
];
KEY
*
key_info
=
&
table
->
key_info
[
ref
->
key
];
KEY_PART
*
key_part
;
KEY_PART
*
key_part
;
...
...
sql/sql_base.cc
View file @
42297969
...
@@ -1413,11 +1413,17 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
...
@@ -1413,11 +1413,17 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
if
(
field
->
query_id
!=
thd
->
query_id
)
if
(
field
->
query_id
!=
thd
->
query_id
)
{
{
field
->
query_id
=
thd
->
query_id
;
field
->
query_id
=
thd
->
query_id
;
field
->
table
->
used_fields
++
;
table
->
used_fields
++
;
if
(
field
->
part_of_key
)
{
if
(
!
(
field
->
part_of_key
&
table
->
ref_primary_key
))
table
->
used_keys
&=
field
->
part_of_key
;
}
else
table
->
used_keys
=
0
;
}
}
else
else
thd
->
dupp_field
=
field
;
thd
->
dupp_field
=
field
;
field
->
table
->
used_keys
&=
field
->
part_of_key
;
}
}
if
(
check_grants
&&
!
thd
->
master_access
&&
check_grant_column
(
thd
,
table
,
name
,
length
))
if
(
check_grants
&&
!
thd
->
master_access
&&
check_grant_column
(
thd
,
table
,
name
,
length
))
return
WRONG_GRANT
;
return
WRONG_GRANT
;
...
@@ -1659,19 +1665,19 @@ static bool
...
@@ -1659,19 +1665,19 @@ static bool
insert_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
const
char
*
table_name
,
insert_fields
(
THD
*
thd
,
TABLE_LIST
*
tables
,
const
char
*
table_name
,
List_iterator
<
Item
>
*
it
)
List_iterator
<
Item
>
*
it
)
{
{
TABLE_LIST
*
table
;
uint
found
;
uint
found
;
DBUG_ENTER
(
"insert_fields"
);
DBUG_ENTER
(
"insert_fields"
);
found
=
0
;
found
=
0
;
for
(
table
=
tables
;
table
;
table
=
table
->
next
)
for
(
;
tables
;
tables
=
tables
->
next
)
{
{
TABLE
*
table
=
tables
->
table
;
if
(
grant_option
&&
!
thd
->
master_access
&&
if
(
grant_option
&&
!
thd
->
master_access
&&
check_grant_all_columns
(
thd
,
SELECT_ACL
,
table
->
table
)
)
check_grant_all_columns
(
thd
,
SELECT_ACL
,
table
)
)
DBUG_RETURN
(
-
1
);
DBUG_RETURN
(
-
1
);
if
(
!
table_name
||
!
strcmp
(
table_name
,
table
->
name
))
if
(
!
table_name
||
!
strcmp
(
table_name
,
table
s
->
name
))
{
{
Field
**
ptr
=
table
->
table
->
field
,
*
field
;
Field
**
ptr
=
table
->
field
,
*
field
;
while
((
field
=
*
ptr
++
))
while
((
field
=
*
ptr
++
))
{
{
Item_field
*
item
=
new
Item_field
(
field
);
Item_field
*
item
=
new
Item_field
(
field
);
...
@@ -1682,10 +1688,17 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *table_name,
...
@@ -1682,10 +1688,17 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *table_name,
if
(
field
->
query_id
==
thd
->
query_id
)
if
(
field
->
query_id
==
thd
->
query_id
)
thd
->
dupp_field
=
field
;
thd
->
dupp_field
=
field
;
field
->
query_id
=
thd
->
query_id
;
field
->
query_id
=
thd
->
query_id
;
field
->
table
->
used_keys
&=
field
->
part_of_key
;
if
(
field
->
part_of_key
)
{
if
(
!
(
field
->
part_of_key
&
table
->
ref_primary_key
))
table
->
used_keys
&=
field
->
part_of_key
;
}
else
table
->
used_keys
=
0
;
}
}
/* All fields are used */
/* All fields are used */
table
->
table
->
used_fields
=
table
->
table
->
fields
;
table
->
used_fields
=
table
->
fields
;
}
}
}
}
if
(
!
found
)
if
(
!
found
)
...
@@ -1750,6 +1763,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -1750,6 +1763,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
// TODO: This could be optimized to use hashed names if t2 had a hash
// TODO: This could be optimized to use hashed names if t2 had a hash
for
(
j
=
0
;
j
<
t2
->
fields
;
j
++
)
for
(
j
=
0
;
j
<
t2
->
fields
;
j
++
)
{
{
key_map
tmp_map
;
if
(
!
my_strcasecmp
(
t1
->
field
[
i
]
->
field_name
,
if
(
!
my_strcasecmp
(
t1
->
field
[
i
]
->
field_name
,
t2
->
field
[
j
]
->
field_name
))
t2
->
field
[
j
]
->
field_name
))
{
{
...
@@ -1760,8 +1774,20 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
...
@@ -1760,8 +1774,20 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
tmp
->
fix_length_and_dec
();
// Update cmp_type
tmp
->
fix_length_and_dec
();
// Update cmp_type
tmp
->
const_item_cache
=
0
;
tmp
->
const_item_cache
=
0
;
cond_and
->
list
.
push_back
(
tmp
);
cond_and
->
list
.
push_back
(
tmp
);
t1
->
used_keys
&=
t1
->
field
[
i
]
->
part_of_key
;
if
((
tmp_map
=
t1
->
field
[
i
]
->
part_of_key
))
t2
->
used_keys
&=
t2
->
field
[
j
]
->
part_of_key
;
{
if
(
!
(
tmp_map
&
t1
->
ref_primary_key
))
t1
->
used_keys
&=
tmp_map
;
}
else
t1
->
used_keys
=
0
;
if
((
tmp_map
=
t2
->
field
[
j
]
->
part_of_key
))
{
if
(
!
(
tmp_map
&
t2
->
ref_primary_key
))
t2
->
used_keys
&=
tmp_map
;
}
else
t2
->
used_keys
=
0
;
break
;
break
;
}
}
}
}
...
...
sql/sql_select.cc
View file @
42297969
...
@@ -2352,6 +2352,11 @@ make_join_readinfo(JOIN *join,uint options)
...
@@ -2352,6 +2352,11 @@ make_join_readinfo(JOIN *join,uint options)
break
;
break
;
case
JT_EQ_REF
:
case
JT_EQ_REF
:
table
->
status
=
STATUS_NO_RECORD
;
table
->
status
=
STATUS_NO_RECORD
;
if
(
tab
->
select
)
{
delete
tab
->
select
->
quick
;
tab
->
select
->
quick
=
0
;
}
delete
tab
->
quick
;
delete
tab
->
quick
;
tab
->
quick
=
0
;
tab
->
quick
=
0
;
table
->
file
->
index_init
(
tab
->
ref
.
key
);
table
->
file
->
index_init
(
tab
->
ref
.
key
);
...
@@ -2365,6 +2370,11 @@ make_join_readinfo(JOIN *join,uint options)
...
@@ -2365,6 +2370,11 @@ make_join_readinfo(JOIN *join,uint options)
break
;
break
;
case
JT_REF
:
case
JT_REF
:
table
->
status
=
STATUS_NO_RECORD
;
table
->
status
=
STATUS_NO_RECORD
;
if
(
tab
->
select
)
{
delete
tab
->
select
->
quick
;
tab
->
select
->
quick
=
0
;
}
delete
tab
->
quick
;
delete
tab
->
quick
;
tab
->
quick
=
0
;
tab
->
quick
=
0
;
table
->
file
->
index_init
(
tab
->
ref
.
key
);
table
->
file
->
index_init
(
tab
->
ref
.
key
);
...
...
sql/table.cc
View file @
42297969
...
@@ -207,49 +207,29 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
...
@@ -207,49 +207,29 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
}
}
#endif
#endif
/* Allocate handler */
if
(
!
(
outparam
->
file
=
get_new_handler
(
outparam
,
outparam
->
db_type
)))
if
(
!
(
outparam
->
file
=
get_new_handler
(
outparam
,
outparam
->
db_type
)))
goto
err_not_open
;
goto
err_not_open
;
error
=
2
;
if
(
db_stat
)
{
int
err
;
if
((
err
=
(
outparam
->
file
->
ha_open
(
index_file
,
(
db_stat
&
HA_READ_ONLY
?
O_RDONLY
:
O_RDWR
),
(
db_stat
&
HA_OPEN_TEMPORARY
?
HA_OPEN_TMP_TABLE
:
((
db_stat
&
HA_WAIT_IF_LOCKED
)
||
(
specialflag
&
SPECIAL_WAIT_IF_LOCKED
))
?
HA_OPEN_WAIT_IF_LOCKED
:
(
db_stat
&
(
HA_ABORT_IF_LOCKED
|
HA_GET_INFO
))
?
HA_OPEN_ABORT_IF_LOCKED
:
HA_OPEN_IGNORE_IF_LOCKED
)
|
ha_open_flags
))))
{
/* Set a flag if the table is crashed and it can be auto. repaired */
outparam
->
crashed
=
(
err
==
HA_ERR_CRASHED
&&
outparam
->
file
->
auto_repair
()
&&
!
(
ha_open_flags
&
HA_OPEN_FOR_REPAIR
));
goto
err_not_open
;
/* purecov: inspected */
}
}
outparam
->
db_low_byte_first
=
outparam
->
file
->
low_byte_first
();
error
=
4
;
error
=
4
;
outparam
->
reginfo
.
lock_type
=
TL_UNLOCK
;
outparam
->
reginfo
.
lock_type
=
TL_UNLOCK
;
outparam
->
current_lock
=
F_UNLCK
;
outparam
->
current_lock
=
F_UNLCK
;
if
(
db_stat
&
HA_OPEN_KEYFILE
||
(
prgflag
&
DELAYED_OPEN
))
records
=
2
;
if
(
(
db_stat
&
HA_OPEN_KEYFILE
)
||
(
prgflag
&
DELAYED_OPEN
))
records
=
2
;
else
records
=
1
;
else
records
=
1
;
if
(
prgflag
&
(
READ_ALL
+
EXTRA_RECORD
))
records
++
;
if
(
prgflag
&
(
READ_ALL
+
EXTRA_RECORD
))
records
++
;
rec_buff_length
=
ALIGN_SIZE
(
outparam
->
reclength
+
1
);
/* QQ: TODO, remove the +1 from below */
rec_buff_length
=
ALIGN_SIZE
(
outparam
->
reclength
+
1
+
outparam
->
file
->
extra_rec_buf_length
());
if
(
!
(
outparam
->
record
[
0
]
=
(
byte
*
)
if
(
!
(
outparam
->
record
[
0
]
=
(
byte
*
)
(
record
=
(
char
*
)
alloc_root
(
&
outparam
->
mem_root
,
(
record
=
(
char
*
)
alloc_root
(
&
outparam
->
mem_root
,
rec_buff_length
*
records
))))
rec_buff_length
*
records
))))
goto
err
;
/* purecov: inspected */
goto
err
_not_open
;
/* purecov: inspected */
record
[
outparam
->
reclength
]
=
0
;
// For purify and ->c_ptr()
record
[
outparam
->
reclength
]
=
0
;
// For purify and ->c_ptr()
outparam
->
rec_buff_length
=
rec_buff_length
;
outparam
->
rec_buff_length
=
rec_buff_length
;
if
(
my_pread
(
file
,(
byte
*
)
record
,(
uint
)
outparam
->
reclength
,
if
(
my_pread
(
file
,(
byte
*
)
record
,(
uint
)
outparam
->
reclength
,
(
ulong
)
(
uint2korr
(
head
+
6
)
+
uint2korr
(
head
+
14
)),
(
ulong
)
(
uint2korr
(
head
+
6
)
+
uint2korr
(
head
+
14
)),
MYF
(
MY_NABP
)))
MYF
(
MY_NABP
)))
goto
err
;
/* purecov: inspected */
goto
err
_not_open
;
/* purecov: inspected */
for
(
i
=
0
;
i
<
records
;
i
++
,
record
+=
rec_buff_length
)
for
(
i
=
0
;
i
<
records
;
i
++
,
record
+=
rec_buff_length
)
{
{
outparam
->
record
[
i
]
=
(
byte
*
)
record
;
outparam
->
record
[
i
]
=
(
byte
*
)
record
;
...
@@ -265,12 +245,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
...
@@ -265,12 +245,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
}
}
VOID
(
my_seek
(
file
,
pos
,
MY_SEEK_SET
,
MYF
(
0
)));
VOID
(
my_seek
(
file
,
pos
,
MY_SEEK_SET
,
MYF
(
0
)));
if
(
my_read
(
file
,(
byte
*
)
head
,
288
,
MYF
(
MY_NABP
)))
goto
err
;
if
(
my_read
(
file
,(
byte
*
)
head
,
288
,
MYF
(
MY_NABP
)))
goto
err
_not_open
;
if
(
crypted
)
if
(
crypted
)
{
{
crypted
->
decode
((
char
*
)
head
+
256
,
288
-
256
);
crypted
->
decode
((
char
*
)
head
+
256
,
288
-
256
);
if
(
sint2korr
(
head
+
284
)
!=
0
)
// Should be 0
if
(
sint2korr
(
head
+
284
)
!=
0
)
// Should be 0
goto
err
;
// Wrong password
goto
err
_not_open
;
// Wrong password
}
}
outparam
->
fields
=
uint2korr
(
head
+
258
);
outparam
->
fields
=
uint2korr
(
head
+
258
);
...
@@ -292,13 +272,13 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
...
@@ -292,13 +272,13 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
(
outparam
->
fields
+
interval_parts
+
(
outparam
->
fields
+
interval_parts
+
keys
+
3
)
*
sizeof
(
my_string
)
+
keys
+
3
)
*
sizeof
(
my_string
)
+
(
n_length
+
int_length
)))))
(
n_length
+
int_length
)))))
goto
err
;
/* purecov: inspected */
goto
err
_not_open
;
/* purecov: inspected */
outparam
->
field
=
field_ptr
;
outparam
->
field
=
field_ptr
;
read_length
=
((
uint
)
(
outparam
->
fields
*
11
)
+
pos
+
read_length
=
((
uint
)
(
outparam
->
fields
*
11
)
+
pos
+
(
uint
)
(
n_length
+
int_length
));
(
uint
)
(
n_length
+
int_length
));
if
(
read_string
(
file
,(
gptr
*
)
&
disk_buff
,
read_length
))
if
(
read_string
(
file
,(
gptr
*
)
&
disk_buff
,
read_length
))
goto
err
;
/* purecov: inspected */
goto
err
_not_open
;
/* purecov: inspected */
if
(
crypted
)
if
(
crypted
)
{
{
crypted
->
decode
((
char
*
)
disk_buff
,
read_length
);
crypted
->
decode
((
char
*
)
disk_buff
,
read_length
);
...
@@ -321,6 +301,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
...
@@ -321,6 +301,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
if
(
keynames
)
if
(
keynames
)
fix_type_pointers
(
&
int_array
,
&
outparam
->
keynames
,
1
,
&
keynames
);
fix_type_pointers
(
&
int_array
,
&
outparam
->
keynames
,
1
,
&
keynames
);
VOID
(
my_close
(
file
,
MYF
(
MY_WME
)));
VOID
(
my_close
(
file
,
MYF
(
MY_WME
)));
file
=
-
1
;
record
=
(
char
*
)
outparam
->
record
[
0
]
-
1
;
/* Fieldstart = 1 */
record
=
(
char
*
)
outparam
->
record
[
0
]
-
1
;
/* Fieldstart = 1 */
if
(
null_field_first
)
if
(
null_field_first
)
...
@@ -426,7 +407,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
...
@@ -426,7 +407,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
(
uint
)
key_part
->
length
);
(
uint
)
key_part
->
length
);
#ifdef EXTRA_DEBUG
#ifdef EXTRA_DEBUG
if
(
key_part
->
fieldnr
>
outparam
->
fields
)
if
(
key_part
->
fieldnr
>
outparam
->
fields
)
goto
err
;
// sanity check
goto
err
_not_open
;
// sanity check
#endif
#endif
if
(
key_part
->
fieldnr
)
if
(
key_part
->
fieldnr
)
{
// Should always be true !
{
// Should always be true !
...
@@ -494,6 +475,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
...
@@ -494,6 +475,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
(
outparam
->
keys_in_use
&
((
key_map
)
1
<<
primary_key
)))
(
outparam
->
keys_in_use
&
((
key_map
)
1
<<
primary_key
)))
{
{
outparam
->
primary_key
=
primary_key
;
outparam
->
primary_key
=
primary_key
;
if
(
outparam
->
file
->
option_flag
()
&
HA_PRIMARY_KEY_IN_READ_INDEX
)
outparam
->
ref_primary_key
=
(
key_map
)
1
<<
primary_key
;
/*
If we are using an integer as the primary key then allow the user to
refer to it as '_rowid'
*/
if
(
outparam
->
key_info
[
primary_key
].
key_parts
==
1
)
if
(
outparam
->
key_info
[
primary_key
].
key_parts
==
1
)
{
{
Field
*
field
=
outparam
->
key_info
[
primary_key
].
key_part
[
0
].
field
;
Field
*
field
=
outparam
->
key_info
[
primary_key
].
key_part
[
0
].
field
;
...
@@ -505,6 +492,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
...
@@ -505,6 +492,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
outparam
->
primary_key
=
MAX_KEY
;
// we do not have a primary key
outparam
->
primary_key
=
MAX_KEY
;
// we do not have a primary key
}
}
x_free
((
gptr
)
disk_buff
);
x_free
((
gptr
)
disk_buff
);
disk_buff
=
0
;
if
(
new_field_pack_flag
<=
1
)
if
(
new_field_pack_flag
<=
1
)
{
/* Old file format with default null */
{
/* Old file format with default null */
uint
null_length
=
(
outparam
->
null_fields
+
7
)
/
8
;
uint
null_length
=
(
outparam
->
null_fields
+
7
)
/
8
;
...
@@ -523,7 +511,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
...
@@ -523,7 +511,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
(
Field_blob
**
)
alloc_root
(
&
outparam
->
mem_root
,
(
Field_blob
**
)
alloc_root
(
&
outparam
->
mem_root
,
(
uint
)
(
outparam
->
blob_fields
+
1
)
*
(
uint
)
(
outparam
->
blob_fields
+
1
)
*
sizeof
(
Field_blob
*
))))
sizeof
(
Field_blob
*
))))
goto
err
;
goto
err
_not_open
;
for
(
ptr
=
outparam
->
field
;
*
ptr
;
ptr
++
)
for
(
ptr
=
outparam
->
field
;
*
ptr
;
ptr
++
)
{
{
if
((
*
ptr
)
->
flags
&
BLOB_FLAG
)
if
((
*
ptr
)
->
flags
&
BLOB_FLAG
)
...
@@ -535,22 +523,43 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
...
@@ -535,22 +523,43 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
outparam
->
blob_field
=
outparam
->
blob_field
=
(
Field_blob
**
)
(
outparam
->
field
+
outparam
->
fields
);
// Point at null ptr
(
Field_blob
**
)
(
outparam
->
field
+
outparam
->
fields
);
// Point at null ptr
/* The table struct is now initialzed; Open the table */
error
=
2
;
if
(
db_stat
)
{
int
err
;
if
((
err
=
(
outparam
->
file
->
ha_open
(
index_file
,
(
db_stat
&
HA_READ_ONLY
?
O_RDONLY
:
O_RDWR
),
(
db_stat
&
HA_OPEN_TEMPORARY
?
HA_OPEN_TMP_TABLE
:
((
db_stat
&
HA_WAIT_IF_LOCKED
)
||
(
specialflag
&
SPECIAL_WAIT_IF_LOCKED
))
?
HA_OPEN_WAIT_IF_LOCKED
:
(
db_stat
&
(
HA_ABORT_IF_LOCKED
|
HA_GET_INFO
))
?
HA_OPEN_ABORT_IF_LOCKED
:
HA_OPEN_IGNORE_IF_LOCKED
)
|
ha_open_flags
))))
{
/* Set a flag if the table is crashed and it can be auto. repaired */
outparam
->
crashed
=
(
err
==
HA_ERR_CRASHED
&&
outparam
->
file
->
auto_repair
()
&&
!
(
ha_open_flags
&
HA_OPEN_FOR_REPAIR
));
goto
err_not_open
;
/* purecov: inspected */
}
}
outparam
->
db_low_byte_first
=
outparam
->
file
->
low_byte_first
();
my_pthread_setspecific_ptr
(
THR_MALLOC
,
old_root
);
my_pthread_setspecific_ptr
(
THR_MALLOC
,
old_root
);
opened_tables
++
;
opened_tables
++
;
#ifndef DBUG_OFF
#ifndef DBUG_OFF
if
(
use_hash
)
if
(
use_hash
)
(
void
)
hash_check
(
&
outparam
->
name_hash
);
(
void
)
hash_check
(
&
outparam
->
name_hash
);
#endif
#endif
if
(
db_stat
)
outparam
->
file
->
initialize
();
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
err:
if
(
outparam
->
file
&&
db_stat
)
(
void
)
outparam
->
file
->
close
();
err_not_open:
err_not_open:
x_free
((
gptr
)
disk_buff
);
x_free
((
gptr
)
disk_buff
);
VOID
(
my_close
(
file
,
MYF
(
MY_WME
)));
if
(
file
>
0
)
VOID
(
my_close
(
file
,
MYF
(
MY_WME
)));
err_end:
/* Here when no file */
err_end:
/* Here when no file */
delete
crypted
;
delete
crypted
;
...
...
sql/table.h
View file @
42297969
...
@@ -113,7 +113,7 @@ struct st_table {
...
@@ -113,7 +113,7 @@ struct st_table {
byte
*
record_pointers
;
/* If sorted in memory */
byte
*
record_pointers
;
/* If sorted in memory */
ha_rows
found_records
;
/* How many records in sort */
ha_rows
found_records
;
/* How many records in sort */
ORDER
*
group
;
ORDER
*
group
;
key_map
quick_keys
,
used_keys
;
key_map
quick_keys
,
used_keys
,
ref_primary_key
;
ha_rows
quick_rows
[
MAX_KEY
];
ha_rows
quick_rows
[
MAX_KEY
];
uint
quick_key_parts
[
MAX_KEY
];
uint
quick_key_parts
[
MAX_KEY
];
key_part_map
const_key_parts
[
MAX_KEY
];
key_part_map
const_key_parts
[
MAX_KEY
];
...
...
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