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
54c147a1
Commit
54c147a1
authored
Jan 03, 2007
by
istruewing@chilla.local
Browse files
Options
Browse Files
Download
Plain Diff
Merge bk-internal.mysql.com:/home/bk/mysql-5.1
into chilla.local:/home/mydev/mysql-5.1-axmrg
parents
60a3f102
de87e317
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
124 additions
and
80 deletions
+124
-80
include/thr_lock.h
include/thr_lock.h
+1
-0
mysql-test/r/myisam.result
mysql-test/r/myisam.result
+16
-0
mysql-test/t/myisam.test
mysql-test/t/myisam.test
+18
-0
mysys/thr_lock.c
mysys/thr_lock.c
+10
-2
sql/sql_update.cc
sql/sql_update.cc
+61
-74
sql/table.cc
sql/table.cc
+2
-0
storage/myisam/mi_dynrec.c
storage/myisam/mi_dynrec.c
+2
-2
storage/myisam/mi_locking.c
storage/myisam/mi_locking.c
+9
-0
storage/myisam/mi_open.c
storage/myisam/mi_open.c
+1
-0
storage/myisam/mi_update.c
storage/myisam/mi_update.c
+2
-1
storage/myisam/mi_write.c
storage/myisam/mi_write.c
+1
-1
storage/myisam/myisamdef.h
storage/myisam/myisamdef.h
+1
-0
No files found.
include/thr_lock.h
View file @
54c147a1
...
@@ -121,6 +121,7 @@ typedef struct st_thr_lock {
...
@@ -121,6 +121,7 @@ typedef struct st_thr_lock {
void
(
*
get_status
)(
void
*
,
int
);
/* When one gets a lock */
void
(
*
get_status
)(
void
*
,
int
);
/* When one gets a lock */
void
(
*
copy_status
)(
void
*
,
void
*
);
void
(
*
copy_status
)(
void
*
,
void
*
);
void
(
*
update_status
)(
void
*
);
/* Before release of write */
void
(
*
update_status
)(
void
*
);
/* Before release of write */
void
(
*
restore_status
)(
void
*
);
/* Before release of read */
my_bool
(
*
check_status
)(
void
*
);
my_bool
(
*
check_status
)(
void
*
);
}
THR_LOCK
;
}
THR_LOCK
;
...
...
mysql-test/r/myisam.result
View file @
54c147a1
...
@@ -1603,6 +1603,22 @@ select * from t1;
...
@@ -1603,6 +1603,22 @@ select * from t1;
a
a
42
42
drop table t1;
drop table t1;
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;
End of 4.1 tests
End of 4.1 tests
create table t1 (c1 int) engine=myisam pack_keys=0;
create table t1 (c1 int) engine=myisam pack_keys=0;
create table t2 (c1 int) engine=myisam pack_keys=1;
create table t2 (c1 int) engine=myisam pack_keys=1;
...
...
mysql-test/t/myisam.test
View file @
54c147a1
...
@@ -977,6 +977,24 @@ connection default;
...
@@ -977,6 +977,24 @@ connection default;
select
*
from
t1
;
select
*
from
t1
;
drop
table
t1
;
drop
table
t1
;
#
# 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
;
--
echo
End
of
4.1
tests
--
echo
End
of
4.1
tests
#
#
...
...
mysys/thr_lock.c
View file @
54c147a1
...
@@ -757,8 +757,16 @@ void thr_unlock(THR_LOCK_DATA *data)
...
@@ -757,8 +757,16 @@ void thr_unlock(THR_LOCK_DATA *data)
}
}
else
else
lock
->
write
.
last
=
data
->
prev
;
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
);
(
*
lock
->
update_status
)(
data
->
status_param
);
}
else
{
if
(
lock
->
restore_status
)
(
*
lock
->
restore_status
)(
data
->
status_param
);
}
if
(
lock_type
==
TL_READ_NO_INSERT
)
if
(
lock_type
==
TL_READ_NO_INSERT
)
lock
->
read_no_write_count
--
;
lock
->
read_no_write_count
--
;
data
->
type
=
TL_UNLOCK
;
/* Mark unlocked */
data
->
type
=
TL_UNLOCK
;
/* Mark unlocked */
...
...
sql/sql_update.cc
View file @
54c147a1
...
@@ -24,8 +24,6 @@
...
@@ -24,8 +24,6 @@
#include "sp_head.h"
#include "sp_head.h"
#include "sql_trigger.h"
#include "sql_trigger.h"
static
bool
safe_update_on_fly
(
JOIN_TAB
*
join_tab
);
/* Return 0 if row hasn't changed */
/* Return 0 if row hasn't changed */
static
bool
compare_record
(
TABLE
*
table
)
static
bool
compare_record
(
TABLE
*
table
)
...
@@ -1160,27 +1158,71 @@ int multi_update::prepare(List<Item> ¬_used_values,
...
@@ -1160,27 +1158,71 @@ int multi_update::prepare(List<Item> ¬_used_values,
for
(
i
=
0
;
i
<
table_count
;
i
++
)
for
(
i
=
0
;
i
<
table_count
;
i
++
)
set_if_bigger
(
max_fields
,
fields_for_table
[
i
]
->
elements
);
set_if_bigger
(
max_fields
,
fields_for_table
[
i
]
->
elements
);
copy_field
=
new
Copy_field
[
max_fields
];
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
the row buffer may contain things that doesn't match what is on disk
NOTES
which will cause an error when reading a row.
We can update the first table in join on the fly if we know that
(This issue is mostly relevent for MyISAM tables)
a row in this table will never be read twice. This is true under
*/
the following conditions:
for
(
table_ref
=
leaves
;
table_ref
;
table_ref
=
table_ref
->
next_leaf
)
{
- We are doing a table scan and the data is in a separate file (MyISAM) or
TABLE
*
table
=
table_ref
->
table
;
if we don't update a clustered key.
if
((
tables_to_update
&
table
->
map
)
&&
unique_table
(
thd
,
table_ref
,
update_tables
))
- We are doing a range scan and we don't update the scan key or
table
->
no_cache
=
1
;
// Disable row cache
the primary key for a clustered table handler.
- Table is not joined to itself.
This function gets information about fields to be updated from
the TABLE::write_set bitmap.
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
)
{
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
,
table
->
write_set
);
case
JT_ALL
:
/* If range search on index */
if
(
join_tab
->
quick
)
return
!
join_tab
->
quick
->
is_keys_used
(
table
->
write_set
);
/* If scanning in clustered key */
if
((
table
->
file
->
ha_table_flags
()
&
HA_PRIMARY_KEY_IN_READ_INDEX
)
&&
table
->
s
->
primary_key
<
MAX_KEY
)
return
!
is_key_used
(
table
,
table
->
s
->
primary_key
,
table
->
write_set
);
return
TRUE
;
default:
break
;
// Avoid compler warning
}
}
DBUG_RETURN
(
thd
->
is_fatal_error
!=
0
);
return
FALSE
;
}
}
...
@@ -1220,7 +1262,7 @@ multi_update::initialize_tables(JOIN *join)
...
@@ -1220,7 +1262,7 @@ multi_update::initialize_tables(JOIN *join)
table
->
file
->
extra
(
HA_EXTRA_IGNORE_DUP_KEY
);
table
->
file
->
extra
(
HA_EXTRA_IGNORE_DUP_KEY
);
if
(
table
==
main_table
)
// First table in join
if
(
table
==
main_table
)
// First table in join
{
{
if
(
safe_update_on_fly
(
join
->
join_tab
))
if
(
safe_update_on_fly
(
thd
,
join
->
join_tab
,
table_ref
,
all_tables
))
{
{
table_to_update
=
main_table
;
// Update table on the fly
table_to_update
=
main_table
;
// Update table on the fly
continue
;
continue
;
...
@@ -1272,61 +1314,6 @@ multi_update::initialize_tables(JOIN *join)
...
@@ -1272,61 +1314,6 @@ multi_update::initialize_tables(JOIN *join)
DBUG_RETURN
(
0
);
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
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.
This function gets information about fields to be updated from
the TABLE::write_set bitmap.
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
)
{
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
,
table
->
write_set
);
case
JT_ALL
:
/* If range search on index */
if
(
join_tab
->
quick
)
return
!
join_tab
->
quick
->
is_keys_used
(
table
->
write_set
);
/* If scanning in clustered key */
if
((
table
->
file
->
ha_table_flags
()
&
HA_PRIMARY_KEY_IN_READ_INDEX
)
&&
table
->
s
->
primary_key
<
MAX_KEY
)
return
!
is_key_used
(
table
,
table
->
s
->
primary_key
,
table
->
write_set
);
return
TRUE
;
default:
break
;
// Avoid compler warning
}
return
FALSE
;
}
multi_update
::~
multi_update
()
multi_update
::~
multi_update
()
{
{
...
...
sql/table.cc
View file @
54c147a1
...
@@ -785,6 +785,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
...
@@ -785,6 +785,8 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
memcpy
(
comment_pos
,
disk_buff
+
read_length
-
com_length
,
com_length
);
memcpy
(
comment_pos
,
disk_buff
+
read_length
-
com_length
,
com_length
);
fix_type_pointers
(
&
interval_array
,
&
share
->
fieldnames
,
1
,
&
names
);
fix_type_pointers
(
&
interval_array
,
&
share
->
fieldnames
,
1
,
&
names
);
if
(
share
->
fieldnames
.
count
!=
share
->
fields
)
goto
err
;
fix_type_pointers
(
&
interval_array
,
share
->
intervals
,
interval_count
,
fix_type_pointers
(
&
interval_array
,
share
->
intervals
,
interval_count
,
&
names
);
&
names
);
...
...
storage/myisam/mi_dynrec.c
View file @
54c147a1
...
@@ -254,7 +254,7 @@ int _mi_write_blob_record(MI_INFO *info, const byte *record)
...
@@ -254,7 +254,7 @@ int _mi_write_blob_record(MI_INFO *info, const byte *record)
#endif
#endif
if
(
!
(
rec_buff
=
(
byte
*
)
my_alloca
(
reclength
)))
if
(
!
(
rec_buff
=
(
byte
*
)
my_alloca
(
reclength
)))
{
{
my_errno
=
ENOMEM
;
my_errno
=
HA_ERR_OUT_OF_MEM
;
/* purecov: inspected */
return
(
-
1
);
return
(
-
1
);
}
}
reclength2
=
_mi_rec_pack
(
info
,
rec_buff
+
ALIGN_SIZE
(
MI_MAX_DYN_BLOCK_HEADER
),
reclength2
=
_mi_rec_pack
(
info
,
rec_buff
+
ALIGN_SIZE
(
MI_MAX_DYN_BLOCK_HEADER
),
...
@@ -288,7 +288,7 @@ int _mi_update_blob_record(MI_INFO *info, my_off_t pos, const byte *record)
...
@@ -288,7 +288,7 @@ int _mi_update_blob_record(MI_INFO *info, my_off_t pos, const byte *record)
#endif
#endif
if
(
!
(
rec_buff
=
(
byte
*
)
my_alloca
(
reclength
)))
if
(
!
(
rec_buff
=
(
byte
*
)
my_alloca
(
reclength
)))
{
{
my_errno
=
ENOMEM
;
my_errno
=
HA_ERR_OUT_OF_MEM
;
/* purecov: inspected */
return
(
-
1
);
return
(
-
1
);
}
}
reclength
=
_mi_rec_pack
(
info
,
rec_buff
+
ALIGN_SIZE
(
MI_MAX_DYN_BLOCK_HEADER
),
reclength
=
_mi_rec_pack
(
info
,
rec_buff
+
ALIGN_SIZE
(
MI_MAX_DYN_BLOCK_HEADER
),
...
...
storage/myisam/mi_locking.c
View file @
54c147a1
...
@@ -338,6 +338,15 @@ void mi_update_status(void* param)
...
@@ -338,6 +338,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
)
void
mi_copy_status
(
void
*
to
,
void
*
from
)
{
{
((
MI_INFO
*
)
to
)
->
state
=
&
((
MI_INFO
*
)
from
)
->
save_state
;
((
MI_INFO
*
)
to
)
->
state
=
&
((
MI_INFO
*
)
from
)
->
save_state
;
...
...
storage/myisam/mi_open.c
View file @
54c147a1
...
@@ -518,6 +518,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
...
@@ -518,6 +518,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
share
->
lock
.
get_status
=
mi_get_status
;
share
->
lock
.
get_status
=
mi_get_status
;
share
->
lock
.
copy_status
=
mi_copy_status
;
share
->
lock
.
copy_status
=
mi_copy_status
;
share
->
lock
.
update_status
=
mi_update_status
;
share
->
lock
.
update_status
=
mi_update_status
;
share
->
lock
.
restore_status
=
mi_restore_status
;
share
->
lock
.
check_status
=
mi_check_status
;
share
->
lock
.
check_status
=
mi_check_status
;
}
}
}
}
...
...
storage/myisam/mi_update.c
View file @
54c147a1
...
@@ -196,7 +196,8 @@ err:
...
@@ -196,7 +196,8 @@ err:
save_errno
=
my_errno
;
save_errno
=
my_errno
;
if
(
changed
)
if
(
changed
)
key_changed
|=
HA_STATE_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
;
info
->
errkey
=
(
int
)
i
;
flag
=
0
;
flag
=
0
;
...
...
storage/myisam/mi_write.c
View file @
54c147a1
...
@@ -180,7 +180,7 @@ int mi_write(MI_INFO *info, byte *record)
...
@@ -180,7 +180,7 @@ int mi_write(MI_INFO *info, byte *record)
err:
err:
save_errno
=
my_errno
;
save_errno
=
my_errno
;
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_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
)
if
(
info
->
bulk_insert
)
{
{
...
...
storage/myisam/myisamdef.h
View file @
54c147a1
...
@@ -753,6 +753,7 @@ int mi_unique_comp(MI_UNIQUEDEF *def, const byte *a, const byte *b,
...
@@ -753,6 +753,7 @@ int mi_unique_comp(MI_UNIQUEDEF *def, const byte *a, const byte *b,
my_bool
null_are_equal
);
my_bool
null_are_equal
);
void
mi_get_status
(
void
*
param
,
int
concurrent_insert
);
void
mi_get_status
(
void
*
param
,
int
concurrent_insert
);
void
mi_update_status
(
void
*
param
);
void
mi_update_status
(
void
*
param
);
void
mi_restore_status
(
void
*
param
);
void
mi_copy_status
(
void
*
to
,
void
*
from
);
void
mi_copy_status
(
void
*
to
,
void
*
from
);
my_bool
mi_check_status
(
void
*
param
);
my_bool
mi_check_status
(
void
*
param
);
void
mi_disable_non_unique_index
(
MI_INFO
*
info
,
ha_rows
rows
);
void
mi_disable_non_unique_index
(
MI_INFO
*
info
,
ha_rows
rows
);
...
...
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