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
de1572d6
Commit
de1572d6
authored
Jan 25, 2007
by
svoj@mysql.com/april.(none)
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql.com:/home/svoj/devel/bk/mysql-5.0
into mysql.com:/home/svoj/devel/mysql/merge/mysql-5.0-engines
parents
cb6c5f7e
ea7fe60f
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
162 additions
and
89 deletions
+162
-89
include/thr_lock.h
include/thr_lock.h
+1
-0
myisam/mi_create.c
myisam/mi_create.c
+7
-6
myisam/mi_dynrec.c
myisam/mi_dynrec.c
+2
-2
myisam/mi_locking.c
myisam/mi_locking.c
+9
-0
myisam/mi_open.c
myisam/mi_open.c
+15
-1
myisam/mi_update.c
myisam/mi_update.c
+2
-1
myisam/mi_write.c
myisam/mi_write.c
+1
-1
myisam/myisamdef.h
myisam/myisamdef.h
+1
-0
mysql-test/r/myisam.result
mysql-test/r/myisam.result
+21
-0
mysql-test/t/myisam.test
mysql-test/t/myisam.test
+27
-0
mysys/thr_lock.c
mysys/thr_lock.c
+10
-2
sql/sql_update.cc
sql/sql_update.cc
+64
-76
sql/table.cc
sql/table.cc
+2
-0
No files found.
include/thr_lock.h
View file @
de1572d6
...
...
@@ -121,6 +121,7 @@ typedef struct st_thr_lock {
void
(
*
get_status
)(
void
*
,
int
);
/* When one gets a lock */
void
(
*
copy_status
)(
void
*
,
void
*
);
void
(
*
update_status
)(
void
*
);
/* Before release of write */
void
(
*
restore_status
)(
void
*
);
/* Before release of read */
my_bool
(
*
check_status
)(
void
*
);
}
THR_LOCK
;
...
...
myisam/mi_create.c
View file @
de1572d6
...
...
@@ -815,18 +815,19 @@ uint mi_get_pointer_length(ulonglong file_length, uint def)
if
(
file_length
)
/* If not default */
{
#ifdef NOT_YET_READY_FOR_8_BYTE_POINTERS
if
(
file_length
>=
(
longlong
)
1
<<
56
)
if
(
file_length
>=
ULL
(
1
)
<<
56
)
def
=
8
;
else
#endif
if
(
file_length
>=
(
longlong
)
1
<<
48
)
if
(
file_length
>=
ULL
(
1
)
<<
48
)
def
=
7
;
if
(
file_length
>=
(
longlong
)
1
<<
40
)
else
if
(
file_length
>=
ULL
(
1
)
<<
40
)
def
=
6
;
else
if
(
file_length
>=
(
longlong
)
1
<<
32
)
else
if
(
file_length
>=
ULL
(
1
)
<<
32
)
def
=
5
;
else
if
(
file_length
>=
(
1L
<<
24
)
)
else
if
(
file_length
>=
ULL
(
1
)
<<
24
)
def
=
4
;
else
if
(
file_length
>=
(
1L
<<
16
)
)
else
if
(
file_length
>=
ULL
(
1
)
<<
16
)
def
=
3
;
else
def
=
2
;
...
...
myisam/mi_dynrec.c
View file @
de1572d6
...
...
@@ -80,7 +80,7 @@ int _mi_write_blob_record(MI_INFO *info, const byte *record)
#endif
if
(
!
(
rec_buff
=
(
byte
*
)
my_alloca
(
reclength
)))
{
my_errno
=
ENOMEM
;
my_errno
=
HA_ERR_OUT_OF_MEM
;
/* purecov: inspected */
return
(
-
1
);
}
reclength2
=
_mi_rec_pack
(
info
,
rec_buff
+
ALIGN_SIZE
(
MI_MAX_DYN_BLOCK_HEADER
),
...
...
@@ -114,7 +114,7 @@ int _mi_update_blob_record(MI_INFO *info, my_off_t pos, const byte *record)
#endif
if
(
!
(
rec_buff
=
(
byte
*
)
my_alloca
(
reclength
)))
{
my_errno
=
ENOMEM
;
my_errno
=
HA_ERR_OUT_OF_MEM
;
/* purecov: inspected */
return
(
-
1
);
}
reclength
=
_mi_rec_pack
(
info
,
rec_buff
+
ALIGN_SIZE
(
MI_MAX_DYN_BLOCK_HEADER
),
...
...
myisam/mi_locking.c
View file @
de1572d6
...
...
@@ -325,6 +325,15 @@ void mi_update_status(void* param)
}
}
void
mi_restore_status
(
void
*
param
)
{
MI_INFO
*
info
=
(
MI_INFO
*
)
param
;
info
->
state
=
&
info
->
s
->
state
.
state
;
info
->
append_insert_at_end
=
0
;
}
void
mi_copy_status
(
void
*
to
,
void
*
from
)
{
((
MI_INFO
*
)
to
)
->
state
=
&
((
MI_INFO
*
)
from
)
->
save_state
;
...
...
myisam/mi_open.c
View file @
de1572d6
...
...
@@ -322,7 +322,13 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
for
(
j
=
0
;
j
<
share
->
keyinfo
[
i
].
keysegs
;
j
++
,
pos
++
)
{
disk_pos
=
mi_keyseg_read
(
disk_pos
,
pos
);
if
(
pos
->
flag
&
HA_BLOB_PART
&&
!
(
share
->
options
&
(
HA_OPTION_COMPRESS_RECORD
|
HA_OPTION_PACK_RECORD
)))
{
my_errno
=
HA_ERR_CRASHED
;
goto
err
;
}
if
(
pos
->
type
==
HA_KEYTYPE_TEXT
||
pos
->
type
==
HA_KEYTYPE_VARTEXT1
||
pos
->
type
==
HA_KEYTYPE_VARTEXT2
)
...
...
@@ -440,6 +446,13 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
offset
+=
share
->
rec
[
i
].
length
;
}
share
->
rec
[
i
].
type
=
(
int
)
FIELD_LAST
;
/* End marker */
if
(
offset
>
share
->
base
.
reclength
)
{
/* purecov: begin inspected */
my_errno
=
HA_ERR_CRASHED
;
goto
err
;
/* purecov: end */
}
if
(
!
lock_error
)
{
...
...
@@ -504,6 +517,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
share
->
lock
.
get_status
=
mi_get_status
;
share
->
lock
.
copy_status
=
mi_copy_status
;
share
->
lock
.
update_status
=
mi_update_status
;
share
->
lock
.
restore_status
=
mi_restore_status
;
share
->
lock
.
check_status
=
mi_check_status
;
}
}
...
...
myisam/mi_update.c
View file @
de1572d6
...
...
@@ -196,7 +196,8 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec)
save_errno
=
my_errno
;
if
(
changed
)
key_changed
|=
HA_STATE_CHANGED
;
if
(
my_errno
==
HA_ERR_FOUND_DUPP_KEY
||
my_errno
==
HA_ERR_RECORD_FILE_FULL
)
if
(
my_errno
==
HA_ERR_FOUND_DUPP_KEY
||
my_errno
==
HA_ERR_OUT_OF_MEM
||
my_errno
==
HA_ERR_RECORD_FILE_FULL
)
{
info
->
errkey
=
(
int
)
i
;
flag
=
0
;
...
...
myisam/mi_write.c
View file @
de1572d6
...
...
@@ -168,7 +168,7 @@ int mi_write(MI_INFO *info, byte *record)
err:
save_errno
=
my_errno
;
if
(
my_errno
==
HA_ERR_FOUND_DUPP_KEY
||
my_errno
==
HA_ERR_RECORD_FILE_FULL
||
my_errno
==
HA_ERR_NULL_IN_SPATIAL
)
my_errno
==
HA_ERR_NULL_IN_SPATIAL
||
my_errno
==
HA_ERR_OUT_OF_MEM
)
{
if
(
info
->
bulk_insert
)
{
...
...
myisam/myisamdef.h
View file @
de1572d6
...
...
@@ -731,6 +731,7 @@ int mi_unique_comp(MI_UNIQUEDEF *def, const byte *a, const byte *b,
my_bool
null_are_equal
);
void
mi_get_status
(
void
*
param
,
int
concurrent_insert
);
void
mi_update_status
(
void
*
param
);
void
mi_restore_status
(
void
*
param
);
void
mi_copy_status
(
void
*
to
,
void
*
from
);
my_bool
mi_check_status
(
void
*
param
);
void
mi_disable_non_unique_index
(
MI_INFO
*
info
,
ha_rows
rows
);
...
...
mysql-test/r/myisam.result
View file @
de1572d6
...
...
@@ -922,6 +922,27 @@ SET @@myisam_repair_threads=1;
SHOW VARIABLES LIKE 'myisam_repair%';
Variable_name Value
myisam_repair_threads 1
CREATE TABLE t1(a VARCHAR(16));
INSERT INTO t1 VALUES('aaaaaaaa'),(NULL);
UPDATE t1 AS ta1, t1 AS ta2 SET ta1.a='aaaaaaaaaaaaaaaa';
SELECT * FROM t1;
a
aaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaa
DROP TABLE t1;
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES(1),(2);
UPDATE t1,t1 AS t2 SET t1.a=t1.a+2 WHERE t1.a=t2.a-1;
SELECT * FROM t1 ORDER BY a;
a
2
3
DROP TABLE t1;
CREATE TABLE t1 (c1 TEXT) AVG_ROW_LENGTH=70100 MAX_ROWS=4100100100;
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MyISAM 10 Dynamic X X X 72057594037927935 X X X X X X latin1_swedish_ci X max_rows=4100100100 avg_row_length=70100
DROP TABLE t1;
End of 4.1 tests
set storage_engine=MyISAM;
drop table if exists t1,t2,t3;
...
...
mysql-test/t/myisam.test
View file @
de1572d6
...
...
@@ -847,6 +847,33 @@ DROP TABLE t1;
SET
@@
myisam_repair_threads
=
1
;
SHOW
VARIABLES
LIKE
'myisam_repair%'
;
#
# BUG#21310 - Trees in SQL causing a "crashed" table with MyISAM storage
# engine
#
# A simplified test case that reflect crashed table issue.
CREATE
TABLE
t1
(
a
VARCHAR
(
16
));
INSERT
INTO
t1
VALUES
(
'aaaaaaaa'
),(
NULL
);
UPDATE
t1
AS
ta1
,
t1
AS
ta2
SET
ta1
.
a
=
'aaaaaaaaaaaaaaaa'
;
SELECT
*
FROM
t1
;
DROP
TABLE
t1
;
# A test case that reflect wrong result set.
CREATE
TABLE
t1
(
a
INT
);
INSERT
INTO
t1
VALUES
(
1
),(
2
);
UPDATE
t1
,
t1
AS
t2
SET
t1
.
a
=
t1
.
a
+
2
WHERE
t1
.
a
=
t2
.
a
-
1
;
SELECT
*
FROM
t1
ORDER
BY
a
;
DROP
TABLE
t1
;
#
# Bug#24607 - MyISAM pointer size determined incorrectly
#
CREATE
TABLE
t1
(
c1
TEXT
)
AVG_ROW_LENGTH
=
70100
MAX_ROWS
=
4100100100
;
--
replace_column
5
X
6
X
7
X
9
X
10
X
11
X
12
X
13
X
14
X
16
X
SHOW
TABLE
STATUS
LIKE
't1'
;
DROP
TABLE
t1
;
--
echo
End
of
4.1
tests
...
...
mysys/thr_lock.c
View file @
de1572d6
...
...
@@ -757,8 +757,16 @@ void thr_unlock(THR_LOCK_DATA *data)
}
else
lock
->
write
.
last
=
data
->
prev
;
if
(
lock_type
>=
TL_WRITE_CONCURRENT_INSERT
&&
lock
->
update_status
)
if
(
lock_type
>=
TL_WRITE_CONCURRENT_INSERT
)
{
if
(
lock
->
update_status
)
(
*
lock
->
update_status
)(
data
->
status_param
);
}
else
{
if
(
lock
->
restore_status
)
(
*
lock
->
restore_status
)(
data
->
status_param
);
}
if
(
lock_type
==
TL_READ_NO_INSERT
)
lock
->
read_no_write_count
--
;
data
->
type
=
TL_UNLOCK
;
/* Mark unlocked */
...
...
sql/sql_update.cc
View file @
de1572d6
...
...
@@ -24,8 +24,6 @@
#include "sp_head.h"
#include "sql_trigger.h"
static
bool
safe_update_on_fly
(
JOIN_TAB
*
join_tab
,
List
<
Item
>
*
fields
);
/* Return 0 if row hasn't changed */
static
bool
compare_record
(
TABLE
*
table
,
query_id_t
query_id
)
...
...
@@ -1040,27 +1038,73 @@ int multi_update::prepare(List<Item> ¬_used_values,
for
(
i
=
0
;
i
<
table_count
;
i
++
)
set_if_bigger
(
max_fields
,
fields_for_table
[
i
]
->
elements
);
copy_field
=
new
Copy_field
[
max_fields
];
DBUG_RETURN
(
thd
->
is_fatal_error
!=
0
);
}
/*
Mark all copies of tables that are updates to ensure that
init_read_record() will not try to enable a cache on them
The problem is that for queries like
/*
Check if table is safe to update on fly
UPDATE t1, t1 AS t2 SET t1.b=t2.c WHERE t1.a=t2.a;
SYNOPSIS
safe_update_on_fly()
thd Thread handler
join_tab How table is used in join
all_tables List of tables
fields Fields that are updated
the row buffer may contain things that doesn't match what is on disk
which will cause an error when reading a row.
(This issue is mostly relevent for MyISAM tables)
*/
for
(
table_ref
=
leaves
;
table_ref
;
table_ref
=
table_ref
->
next_leaf
)
{
TABLE
*
table
=
table_ref
->
table
;
if
((
tables_to_update
&
table
->
map
)
&&
unique_table
(
thd
,
table_ref
,
update_tables
))
table
->
no_cache
=
1
;
// Disable row cache
NOTES
We can update the first table in join on the fly if we know that
a row in this table will never be read twice. This is true under
the following conditions:
- We are doing a table scan and the data is in a separate file (MyISAM) or
if we don't update a clustered key.
- We are doing a range scan and we don't update the scan key or
the primary key for a clustered table handler.
- Table is not joined to itself.
When checking for above cases we also should take into account that
BEFORE UPDATE trigger potentially may change value of any field in row
being updated.
WARNING
This code is a bit dependent of how make_join_readinfo() works.
RETURN
0 Not safe to update
1 Safe to update
*/
static
bool
safe_update_on_fly
(
THD
*
thd
,
JOIN_TAB
*
join_tab
,
TABLE_LIST
*
table_ref
,
TABLE_LIST
*
all_tables
,
List
<
Item
>
*
fields
)
{
TABLE
*
table
=
join_tab
->
table
;
if
(
unique_table
(
thd
,
table_ref
,
all_tables
))
return
0
;
switch
(
join_tab
->
type
)
{
case
JT_SYSTEM
:
case
JT_CONST
:
case
JT_EQ_REF
:
return
TRUE
;
// At most one matching row
case
JT_REF
:
case
JT_REF_OR_NULL
:
return
!
is_key_used
(
table
,
join_tab
->
ref
.
key
,
*
fields
);
case
JT_ALL
:
/* If range search on index */
if
(
join_tab
->
quick
)
return
!
join_tab
->
quick
->
is_keys_used
(
fields
);
/* If scanning in clustered key */
if
((
table
->
file
->
table_flags
()
&
HA_PRIMARY_KEY_IN_READ_INDEX
)
&&
table
->
s
->
primary_key
<
MAX_KEY
)
return
!
is_key_used
(
table
,
table
->
s
->
primary_key
,
*
fields
);
return
TRUE
;
default:
break
;
// Avoid compler warning
}
DBUG_RETURN
(
thd
->
is_fatal_error
!=
0
)
;
return
FALSE
;
}
...
...
@@ -1098,7 +1142,8 @@ multi_update::initialize_tables(JOIN *join)
table
->
file
->
extra
(
HA_EXTRA_IGNORE_DUP_KEY
);
if
(
table
==
main_table
)
// First table in join
{
if
(
safe_update_on_fly
(
join
->
join_tab
,
&
temp_fields
))
if
(
safe_update_on_fly
(
thd
,
join
->
join_tab
,
table_ref
,
all_tables
,
&
temp_fields
))
{
table_to_update
=
main_table
;
// Update table on the fly
continue
;
...
...
@@ -1149,63 +1194,6 @@ multi_update::initialize_tables(JOIN *join)
DBUG_RETURN
(
0
);
}
/*
Check if table is safe to update on fly
SYNOPSIS
safe_update_on_fly
join_tab How table is used in join
fields Fields that are updated
NOTES
We can update the first table in join on the fly if we know that
a row in this table will never be read twice. This is true under
the following conditions:
- We are doing a table scan and the data is in a separate file (MyISAM) or
if we don't update a clustered key.
- We are doing a range scan and we don't update the scan key or
the primary key for a clustered table handler.
When checking for above cases we also should take into account that
BEFORE UPDATE trigger potentially may change value of any field in row
being updated.
WARNING
This code is a bit dependent of how make_join_readinfo() works.
RETURN
0 Not safe to update
1 Safe to update
*/
static
bool
safe_update_on_fly
(
JOIN_TAB
*
join_tab
,
List
<
Item
>
*
fields
)
{
TABLE
*
table
=
join_tab
->
table
;
switch
(
join_tab
->
type
)
{
case
JT_SYSTEM
:
case
JT_CONST
:
case
JT_EQ_REF
:
return
TRUE
;
// At most one matching row
case
JT_REF
:
case
JT_REF_OR_NULL
:
return
!
is_key_used
(
table
,
join_tab
->
ref
.
key
,
*
fields
);
case
JT_ALL
:
/* If range search on index */
if
(
join_tab
->
quick
)
return
!
join_tab
->
quick
->
is_keys_used
(
fields
);
/* If scanning in clustered key */
if
((
table
->
file
->
table_flags
()
&
HA_PRIMARY_KEY_IN_READ_INDEX
)
&&
table
->
s
->
primary_key
<
MAX_KEY
)
return
!
is_key_used
(
table
,
table
->
s
->
primary_key
,
*
fields
);
return
TRUE
;
default:
break
;
// Avoid compler warning
}
return
FALSE
;
}
multi_update
::~
multi_update
()
{
...
...
sql/table.cc
View file @
de1572d6
...
...
@@ -452,6 +452,8 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
memcpy
(
comment_pos
,
disk_buff
+
read_length
-
com_length
,
com_length
);
fix_type_pointers
(
&
int_array
,
&
share
->
fieldnames
,
1
,
&
names
);
if
(
share
->
fieldnames
.
count
!=
share
->
fields
)
goto
err
;
fix_type_pointers
(
&
int_array
,
share
->
intervals
,
interval_count
,
&
names
);
...
...
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