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
2e2d1df9
Commit
2e2d1df9
authored
Nov 29, 2002
by
unknown
Browse files
Options
Browse Files
Download
Plain Diff
Merge work:/my/mysql-4.0 into mashka.mysql.fi:/home/my/mysql-4.0
sql/sql_yacc.yy: Auto merged
parents
df1af612
7908c8d4
Changes
29
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
773 additions
and
633 deletions
+773
-633
heap/_check.c
heap/_check.c
+54
-3
heap/hp_delete.c
heap/hp_delete.c
+4
-0
heap/hp_scan.c
heap/hp_scan.c
+1
-0
heap/hp_update.c
heap/hp_update.c
+4
-0
heap/hp_write.c
heap/hp_write.c
+5
-0
include/my_base.h
include/my_base.h
+2
-1
isam/extra.c
isam/extra.c
+6
-0
myisam/mi_check.c
myisam/mi_check.c
+6
-6
myisam/mi_extra.c
myisam/mi_extra.c
+4
-0
myisam/sort.c
myisam/sort.c
+12
-10
myisammrg/myrg_extra.c
myisammrg/myrg_extra.c
+2
-1
mysql-test/r/multi_update.result
mysql-test/r/multi_update.result
+19
-29
mysql-test/t/multi_update.test
mysql-test/t/multi_update.test
+21
-29
mysys/mf_iocache.c
mysys/mf_iocache.c
+2
-0
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+4
-4
sql/mysql_priv.h
sql/mysql_priv.h
+19
-1
sql/sql_base.cc
sql/sql_base.cc
+11
-6
sql/sql_class.h
sql/sql_class.h
+31
-32
sql/sql_delete.cc
sql/sql_delete.cc
+32
-35
sql/sql_insert.cc
sql/sql_insert.cc
+6
-18
sql/sql_olap.cc
sql/sql_olap.cc
+2
-2
sql/sql_parse.cc
sql/sql_parse.cc
+17
-62
sql/sql_select.cc
sql/sql_select.cc
+78
-7
sql/sql_select.h
sql/sql_select.h
+1
-0
sql/sql_union.cc
sql/sql_union.cc
+11
-8
sql/sql_update.cc
sql/sql_update.cc
+401
-367
sql/sql_yacc.yy
sql/sql_yacc.yy
+6
-5
sql/table.h
sql/table.h
+10
-6
sql/uniques.cc
sql/uniques.cc
+2
-1
No files found.
heap/_check.c
View file @
2e2d1df9
...
...
@@ -21,19 +21,70 @@
static
int
check_one_key
(
HP_KEYDEF
*
keydef
,
uint
keynr
,
ulong
records
,
ulong
blength
,
my_bool
print_status
);
/* Returns 0 if the HEAP is ok */
/*
Check if keys and rows are ok in a heap table
SYNOPSIS
heap_check_heap()
info Table handler
print_status Prints some extra status
NOTES
Doesn't change the state of the table handler
RETURN VALUES
0 ok
1 error
*/
int
heap_check_heap
(
HP_INFO
*
info
,
my_bool
print_status
)
{
int
error
;
uint
key
;
ulong
records
=
0
,
deleted
=
0
,
pos
,
next_block
;
HP_SHARE
*
share
=
info
->
s
;
DBUG_ENTER
(
"heap_check_keys"
);
HP_INFO
save_info
=
*
info
;
/* Needed because scan_init */
DBUG_ENTER
(
"heap_check_heap"
);
for
(
error
=
key
=
0
;
key
<
share
->
keys
;
key
++
)
for
(
error
=
key
=
0
;
key
<
share
->
keys
;
key
++
)
error
|=
check_one_key
(
share
->
keydef
+
key
,
key
,
share
->
records
,
share
->
blength
,
print_status
);
/*
This is basicly the same code as in hp_scan, but we repeat it here to
get shorter DBUG log file.
*/
for
(
pos
=
next_block
=
0
;
;
pos
++
)
{
if
(
pos
<
next_block
)
{
info
->
current_ptr
+=
share
->
block
.
recbuffer
;
}
else
{
next_block
+=
share
->
block
.
records_in_block
;
if
(
next_block
>=
share
->
records
+
share
->
deleted
)
{
next_block
=
share
->
records
+
share
->
deleted
;
if
(
pos
>=
next_block
)
break
;
/* End of file */
}
}
_hp_find_record
(
info
,
pos
);
if
(
!
info
->
current_ptr
[
share
->
reclength
])
deleted
++
;
else
records
++
;
}
if
(
records
!=
share
->
records
||
deleted
!=
share
->
deleted
)
{
DBUG_PRINT
(
"error"
,(
"Found rows: %lu (%lu) deleted %lu (%lu)"
,
records
,
share
->
records
,
deleted
,
share
->
deleted
));
error
=
1
;
}
*
info
=
save_info
;
DBUG_RETURN
(
error
);
}
...
...
heap/hp_delete.c
View file @
2e2d1df9
...
...
@@ -48,6 +48,10 @@ int heap_delete(HP_INFO *info, const byte *record)
pos
[
share
->
reclength
]
=
0
;
/* Record deleted */
share
->
deleted
++
;
info
->
current_hash_ptr
=
0
;
#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
DBUG_EXECUTE
(
"check_heap"
,
heap_check_heap
(
info
,
0
););
#endif
DBUG_RETURN
(
0
);
err:
if
(
++
(
share
->
records
)
==
share
->
blength
)
...
...
heap/hp_scan.c
View file @
2e2d1df9
...
...
@@ -62,6 +62,7 @@ int heap_scan(register HP_INFO *info, byte *record)
}
if
(
!
info
->
current_ptr
[
share
->
reclength
])
{
DBUG_PRINT
(
"warning"
,(
"Found deleted record"
));
info
->
update
=
HA_STATE_PREV_FOUND
|
HA_STATE_NEXT_FOUND
;
DBUG_RETURN
(
my_errno
=
HA_ERR_RECORD_DELETED
);
}
...
...
heap/hp_update.c
View file @
2e2d1df9
...
...
@@ -46,6 +46,10 @@ int heap_update(HP_INFO *info, const byte *old, const byte *heap_new)
memcpy
(
pos
,
heap_new
,(
size_t
)
share
->
reclength
);
if
(
++
(
share
->
records
)
==
share
->
blength
)
share
->
blength
+=
share
->
blength
;
#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
DBUG_EXECUTE
(
"check_heap"
,
heap_check_heap
(
info
,
0
););
#endif
DBUG_RETURN
(
0
);
err:
...
...
heap/hp_write.c
View file @
2e2d1df9
...
...
@@ -60,7 +60,11 @@ int heap_write(HP_INFO *info, const byte *record)
info
->
current_ptr
=
pos
;
info
->
current_hash_ptr
=
0
;
info
->
update
|=
HA_STATE_AKTIV
;
#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
DBUG_EXECUTE
(
"check_heap"
,
heap_check_heap
(
info
,
0
););
#endif
DBUG_RETURN
(
0
);
err:
DBUG_PRINT
(
"info"
,(
"Duplicate key: %d"
,
key
));
info
->
errkey
=
key
;
...
...
@@ -74,6 +78,7 @@ int heap_write(HP_INFO *info, const byte *record)
*
((
byte
**
)
pos
)
=
share
->
del_link
;
share
->
del_link
=
pos
;
pos
[
share
->
reclength
]
=
0
;
/* Record deleted */
DBUG_RETURN
(
my_errno
);
}
/* heap_write */
...
...
include/my_base.h
View file @
2e2d1df9
...
...
@@ -109,7 +109,8 @@ enum ha_extra_function {
HA_EXTRA_BULK_INSERT_BEGIN
,
HA_EXTRA_BULK_INSERT_FLUSH
,
/* Flush one index */
HA_EXTRA_BULK_INSERT_END
,
HA_EXTRA_PREPARE_FOR_DELETE
HA_EXTRA_PREPARE_FOR_DELETE
,
HA_EXTRA_PREPARE_FOR_UPDATE
/* Remove read cache if problems */
};
/* The following is parameter to ha_panic() */
...
...
isam/extra.c
View file @
2e2d1df9
...
...
@@ -123,6 +123,7 @@ int nisam_extra(N_INFO *info, enum ha_extra_function function)
}
#endif
if
(
!
(
info
->
opt_flag
&
(
READ_CACHE_USED
|
WRITE_CACHE_USED
)))
{
if
(
!
(
init_io_cache
(
&
info
->
rec_cache
,
info
->
dfile
,
0
,
WRITE_CACHE
,
info
->
s
->
state
.
data_file_length
,
(
pbool
)
(
info
->
lock_type
!=
F_UNLCK
),
...
...
@@ -131,7 +132,12 @@ int nisam_extra(N_INFO *info, enum ha_extra_function function)
info
->
opt_flag
|=
WRITE_CACHE_USED
;
info
->
update
&=
~
HA_STATE_ROW_CHANGED
;
}
}
break
;
case
HA_EXTRA_PREPARE_FOR_UPDATE
:
if
(
info
->
s
->
data_file_type
!=
DYNAMIC_RECORD
)
break
;
/* Remove read/write cache if dynamic rows */
case
HA_EXTRA_NO_CACHE
:
if
(
info
->
opt_flag
&
(
READ_CACHE_USED
|
WRITE_CACHE_USED
))
{
...
...
myisam/mi_check.c
View file @
2e2d1df9
...
...
@@ -2329,13 +2329,13 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
for
(
i
=
0
;
i
<
sort_info
.
total_keys
;
i
++
)
{
sort_param
[
i
].
read_cache
=
param
->
read_cache
;
/*
two approaches: the same amount of memory for each thread
or the memory for the same number of keys for each thread...
In the second one all the threads will fill their sort_buffers
(and call write_keys) at the same time, putting more stress on i/o.
*/
sort_param
[
i
].
sortbuff_size
=
/*
two approaches: the same amount of memory for each thread
or the memory for the same number of keys for each thread...
In the second one all the threads will fill their sort_buffers
(and call write_keys) at the same time, putting more stress on i/o.
*/
#ifndef USING_SECOND_APPROACH
param
->
sort_buffer_length
/
sort_info
.
total_keys
;
#else
...
...
myisam/mi_extra.c
View file @
2e2d1df9
...
...
@@ -165,6 +165,10 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
HA_STATE_EXTEND_BLOCK
);
}
break
;
case
HA_EXTRA_PREPARE_FOR_UPDATE
:
if
(
info
->
s
->
data_file_type
!=
DYNAMIC_RECORD
)
break
;
/* Remove read/write cache if dynamic rows */
case
HA_EXTRA_NO_CACHE
:
if
(
info
->
opt_flag
&
(
READ_CACHE_USED
|
WRITE_CACHE_USED
))
{
...
...
myisam/sort.c
View file @
2e2d1df9
...
...
@@ -344,7 +344,6 @@ pthread_handler_decl(thr_find_all_keys,arg)
mi_check_print_error
(
info
->
sort_info
->
param
,
"Sort buffer to small"
);
/* purecov: tested */
goto
err
;
/* purecov: tested */
}
// (*info->lock_in_memory)(info->sort_info->param);/* Everything is allocated */
if
(
info
->
sort_info
->
param
->
testflag
&
T_VERBOSE
)
printf
(
"Key %d - Allocating buffer for %d keys
\n
"
,
info
->
key
+
1
,
keys
);
...
...
@@ -424,9 +423,9 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
byte
*
mergebuf
=
0
;
LINT_INIT
(
length
);
for
(
i
=
0
,
sinfo
=
sort_param
;
i
<
sort_info
->
total_keys
;
i
++
,
rec_per_key_part
+=
sinfo
->
keyinfo
->
keysegs
,
sinfo
++
)
for
(
i
=
0
,
sinfo
=
sort_param
;
i
<
sort_info
->
total_keys
;
i
++
,
rec_per_key_part
+=
sinfo
->
keyinfo
->
keysegs
,
sinfo
++
)
{
if
(
!
sinfo
->
sort_keys
)
{
...
...
@@ -452,15 +451,18 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
}
}
my_free
((
gptr
)
sinfo
->
sort_keys
,
MYF
(
0
));
my_free
(
mi_get_rec_buff_ptr
(
info
,
sinfo
->
rec_buff
),
MYF
(
MY_ALLOW_ZERO_PTR
));
my_free
(
mi_get_rec_buff_ptr
(
info
,
sinfo
->
rec_buff
),
MYF
(
MY_ALLOW_ZERO_PTR
));
sinfo
->
sort_keys
=
0
;
}
for
(
i
=
0
,
sinfo
=
sort_param
;
i
<
sort_info
->
total_keys
;
i
++
,
delete_dynamic
(
&
sinfo
->
buffpek
),
close_cached_file
(
&
sinfo
->
tempfile
),
close_cached_file
(
&
sinfo
->
tempfile_for_exceptions
),
sinfo
++
)
for
(
i
=
0
,
sinfo
=
sort_param
;
i
<
sort_info
->
total_keys
;
i
++
,
delete_dynamic
(
&
sinfo
->
buffpek
),
close_cached_file
(
&
sinfo
->
tempfile
),
close_cached_file
(
&
sinfo
->
tempfile_for_exceptions
),
sinfo
++
)
{
if
(
got_error
)
continue
;
...
...
myisammrg/myrg_extra.c
View file @
2e2d1df9
...
...
@@ -38,7 +38,8 @@ int myrg_extra(MYRG_INFO *info,enum ha_extra_function function,
}
else
{
if
(
function
==
HA_EXTRA_NO_CACHE
||
function
==
HA_EXTRA_RESET
)
if
(
function
==
HA_EXTRA_NO_CACHE
||
function
==
HA_EXTRA_RESET
||
function
==
HA_EXTRA_PREPARE_FOR_UPDATE
)
info
->
cache_in_use
=
0
;
if
(
function
==
HA_EXTRA_RESET
||
function
==
HA_EXTRA_RESET_STATE
)
{
...
...
mysql-test/r/multi_update.result
View file @
2e2d1df9
...
...
@@ -20,7 +20,7 @@ count(*)
10
select count(*) from t2 where t = "bbb";
count(*)
1
0
5
0
select count(*) from t2 where id2 > 90;
count(*)
50
...
...
@@ -70,71 +70,61 @@ create table t1(id1 int not null primary key, t varchar(100)) pack_keys = 1;
create table t2(id2 int not null, t varchar(100), index(id2)) pack_keys = 1;
delete t1 from t1,t2 where t1.id1 = t2.id2 and t1.id1 > 500;
drop table t1,t2;
DROP TABLE IF EXISTS a,b,c;
CREATE TABLE a (
CREATE TABLE t1 (
id int(11) NOT NULL default '0',
name varchar(10) default NULL,
PRIMARY KEY (id)
) TYPE=MyISAM;
INSERT INTO
a
VALUES (1,'aaa'),(2,'aaa'),(3,'aaa');
CREATE TABLE
b
(
INSERT INTO
t1
VALUES (1,'aaa'),(2,'aaa'),(3,'aaa');
CREATE TABLE
t2
(
id int(11) NOT NULL default '0',
name varchar(10) default NULL,
PRIMARY KEY (id)
) TYPE=MyISAM;
INSERT INTO
b
VALUES (2,'bbb'),(3,'bbb'),(4,'bbb');
CREATE TABLE
c
(
INSERT INTO
t2
VALUES (2,'bbb'),(3,'bbb'),(4,'bbb');
CREATE TABLE
t3
(
id int(11) NOT NULL default '0',
mydate datetime default NULL,
PRIMARY KEY (id)
) TYPE=MyISAM;
INSERT INTO
c
VALUES (1,'2002-02-04 00:00:00'),(3,'2002-05-12 00:00:00'),(5,'2002-05-12 00:00:00'),(6,'2002-06-22
INSERT INTO
t3
VALUES (1,'2002-02-04 00:00:00'),(3,'2002-05-12 00:00:00'),(5,'2002-05-12 00:00:00'),(6,'2002-06-22
00:00:00'),(7,'2002-07-22 00:00:00');
delete a,b,c from a,b,c
where to_days(now())-to_days(c.mydate)>=30
and c.id=a.id and c.id=b.id;
select * from c;
delete t1,t2,t3 from t1,t2,t3 where to_days(now())-to_days(t3.mydate)>=30 and t3.id=t1.id and t3.id=t2.id;
select * from t3;
id mydate
1 2002-02-04 00:00:00
5 2002-05-12 00:00:00
6 2002-06-22 00:00:00
7 2002-07-22 00:00:00
DROP TABLE IF EXISTS a,b,c;
drop table if exists parent, child;
CREATE TABLE IF NOT EXISTS `parent` (
DROP TABLE IF EXISTS t1,t2,t3;
CREATE TABLE IF NOT EXISTS `t1` (
`id` int(11) NOT NULL auto_increment,
`tst` text,
`tst1` text,
PRIMARY KEY (`id`)
) TYPE=MyISAM;
CREATE TABLE IF NOT EXISTS `
child
` (
CREATE TABLE IF NOT EXISTS `
t2
` (
`ID` int(11) NOT NULL auto_increment,
`ParId` int(11) default NULL,
`tst` text,
`tst1` text,
PRIMARY KEY (`ID`),
KEY `IX_ParId_
child
` (`ParId`),
FOREIGN KEY (`ParId`) REFERENCES `t
est.parent
` (`id`)
KEY `IX_ParId_
t2
` (`ParId`),
FOREIGN KEY (`ParId`) REFERENCES `t
1
` (`id`)
) TYPE=MyISAM;
INSERT INTO parent(tst,tst1)
VALUES("MySQL","MySQL AB"), ("MSSQL","Microsoft"), ("ORACLE","ORACLE");
INSERT INTO child(ParId)
VALUES(1), (2), (3);
select * from child;
INSERT INTO t1(tst,tst1) VALUES("MySQL","MySQL AB"), ("MSSQL","Microsoft"), ("ORACLE","ORACLE");
INSERT INTO t2(ParId) VALUES(1), (2), (3);
select * from t2;
ID ParId tst tst1
1 1 NULL NULL
2 2 NULL NULL
3 3 NULL NULL
UPDATE child, parent
SET child.tst = parent.tst,
child.tst1 = parent.tst1
WHERE child.ParId = parent.Id;
select * from child;
UPDATE t2, t1 SET t2.tst = t1.tst, t2.tst1 = t1.tst1 WHERE t2.ParId = t1.Id;
select * from t2;
ID ParId tst tst1
1 1 MySQL MySQL AB
2 2 MSSQL Microsoft
3 3 ORACLE ORACLE
drop table parent, child;
drop table if exists t1, t2 ;
create table t1 (n numeric(10));
create table t2 (n numeric(10));
...
...
mysql-test/t/multi_update.test
View file @
2e2d1df9
...
...
@@ -80,67 +80,59 @@ while ($1)
enable_query_log
;
delete
t1
from
t1
,
t2
where
t1
.
id1
=
t2
.
id2
and
t1
.
id1
>
500
;
drop
table
t1
,
t2
;
DROP
TABLE
IF
EXISTS
a
,
b
,
c
;
CREATE
TABLE
a
(
CREATE
TABLE
t1
(
id
int
(
11
)
NOT
NULL
default
'0'
,
name
varchar
(
10
)
default
NULL
,
PRIMARY
KEY
(
id
)
)
TYPE
=
MyISAM
;
INSERT
INTO
a
VALUES
(
1
,
'aaa'
),(
2
,
'aaa'
),(
3
,
'aaa'
);
CREATE
TABLE
b
(
INSERT
INTO
t1
VALUES
(
1
,
'aaa'
),(
2
,
'aaa'
),(
3
,
'aaa'
);
CREATE
TABLE
t2
(
id
int
(
11
)
NOT
NULL
default
'0'
,
name
varchar
(
10
)
default
NULL
,
PRIMARY
KEY
(
id
)
)
TYPE
=
MyISAM
;
INSERT
INTO
b
VALUES
(
2
,
'bbb'
),(
3
,
'bbb'
),(
4
,
'bbb'
);
CREATE
TABLE
c
(
INSERT
INTO
t2
VALUES
(
2
,
'bbb'
),(
3
,
'bbb'
),(
4
,
'bbb'
);
CREATE
TABLE
t3
(
id
int
(
11
)
NOT
NULL
default
'0'
,
mydate
datetime
default
NULL
,
PRIMARY
KEY
(
id
)
)
TYPE
=
MyISAM
;
INSERT
INTO
c
VALUES
(
1
,
'2002-02-04 00:00:00'
),(
3
,
'2002-05-12 00:00:00'
),(
5
,
'2002-05-12 00:00:00'
),(
6
,
'2002-06-22
INSERT
INTO
t3
VALUES
(
1
,
'2002-02-04 00:00:00'
),(
3
,
'2002-05-12 00:00:00'
),(
5
,
'2002-05-12 00:00:00'
),(
6
,
'2002-06-22
00:00:00'
),(
7
,
'2002-07-22 00:00:00'
);
delete
a
,
b
,
c
from
a
,
b
,
c
where
to_days
(
now
())
-
to_days
(
c
.
mydate
)
>=
30
and
c
.
id
=
a
.
id
and
c
.
id
=
b
.
id
;
select
*
from
c
;
DROP
TABLE
IF
EXISTS
a
,
b
,
c
;
drop
table
if
exists
parent
,
child
;
CREATE
TABLE
IF
NOT
EXISTS
`parent`
(
delete
t1
,
t2
,
t3
from
t1
,
t2
,
t3
where
to_days
(
now
())
-
to_days
(
t3
.
mydate
)
>=
30
and
t3
.
id
=
t1
.
id
and
t3
.
id
=
t2
.
id
;
select
*
from
t3
;
DROP
TABLE
IF
EXISTS
t1
,
t2
,
t3
;
CREATE
TABLE
IF
NOT
EXISTS
`t1`
(
`id`
int
(
11
)
NOT
NULL
auto_increment
,
`tst`
text
,
`tst1`
text
,
PRIMARY
KEY
(
`id`
)
)
TYPE
=
MyISAM
;
CREATE
TABLE
IF
NOT
EXISTS
`
child
`
(
CREATE
TABLE
IF
NOT
EXISTS
`
t2
`
(
`ID`
int
(
11
)
NOT
NULL
auto_increment
,
`ParId`
int
(
11
)
default
NULL
,
`tst`
text
,
`tst1`
text
,
PRIMARY
KEY
(
`ID`
),
KEY
`IX_ParId_
child
`
(
`ParId`
),
FOREIGN
KEY
(
`ParId`
)
REFERENCES
`t
est.parent
`
(
`id`
)
KEY
`IX_ParId_
t2
`
(
`ParId`
),
FOREIGN
KEY
(
`ParId`
)
REFERENCES
`t
1
`
(
`id`
)
)
TYPE
=
MyISAM
;
INSERT
INTO
parent
(
tst
,
tst1
)
VALUES
(
"MySQL"
,
"MySQL AB"
),
(
"MSSQL"
,
"Microsoft"
),
(
"ORACLE"
,
"ORACLE"
);
INSERT
INTO
child
(
ParId
)
VALUES
(
1
),
(
2
),
(
3
);
INSERT
INTO
t1
(
tst
,
tst1
)
VALUES
(
"MySQL"
,
"MySQL AB"
),
(
"MSSQL"
,
"Microsoft"
),
(
"ORACLE"
,
"ORACLE"
);
select
*
from
child
;
INSERT
INTO
t2
(
ParId
)
VALUES
(
1
),
(
2
),
(
3
)
;
UPDATE
child
,
parent
SET
child
.
tst
=
parent
.
tst
,
child
.
tst1
=
parent
.
tst1
WHERE
child
.
ParId
=
parent
.
Id
;
select
*
from
t2
;
select
*
from
chil
d
;
UPDATE
t2
,
t1
SET
t2
.
tst
=
t1
.
tst
,
t2
.
tst1
=
t1
.
tst1
WHERE
t2
.
ParId
=
t1
.
I
d
;
select
*
from
t2
;
drop
table
parent
,
child
;
drop
table
if
exists
t1
,
t2
;
create
table
t1
(
n
numeric
(
10
));
create
table
t2
(
n
numeric
(
10
));
insert
into
t2
values
(
1
),(
2
),(
4
),(
8
),(
16
),(
32
);
...
...
mysys/mf_iocache.c
View file @
2e2d1df9
...
...
@@ -445,6 +445,8 @@ void init_io_cache_share(IO_CACHE *info, IO_CACHE_SHARE *s, uint num_threads)
s
->
active
=
0
;
/* to catch errors */
info
->
share
=
s
;
info
->
read_function
=
_my_b_read_r
;
/* Ensure that the code doesn't use pointer to the IO_CACHE object */
info
->
current_pos
=
info
->
current_end
=
0
;
}
/*
...
...
sql/item_cmpfunc.cc
View file @
2e2d1df9
...
...
@@ -1658,7 +1658,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const
i
-=
u
;
}
if
(
i
<
0
)
return
true
;
return
1
;
register
const
int
v
=
plm1
-
i
;
turboShift
=
u
-
v
;
...
...
@@ -1675,7 +1675,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const
}
j
+=
shift
;
}
return
false
;
return
0
;
}
else
{
...
...
@@ -1689,7 +1689,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const
i
-=
u
;
}
if
(
i
<
0
)
return
true
;
return
1
;
register
const
int
v
=
plm1
-
i
;
turboShift
=
u
-
v
;
...
...
@@ -1706,7 +1706,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const
}
j
+=
shift
;
}
return
false
;
return
0
;
}
}
...
...
sql/mysql_priv.h
View file @
2e2d1df9
...
...
@@ -242,6 +242,20 @@ typedef struct st_sql_list {
uint
elements
;
byte
*
first
;
byte
**
next
;
inline
void
empty
()
{
elements
=
0
;
first
=
0
;
next
=
&
first
;
}
inline
void
link_in_list
(
byte
*
element
,
byte
**
next_ptr
)
{
elements
++
;
(
*
next
)
=
element
;
next
=
next_ptr
;
*
next
=
0
;
}
}
SQL_LIST
;
...
...
@@ -415,6 +429,10 @@ int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields,
List
<
Item
>
&
values
,
COND
*
conds
,
ORDER
*
order
,
ha_rows
limit
,
enum
enum_duplicates
handle_duplicates
);
int
mysql_multi_update
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Item
>
*
fields
,
List
<
Item
>
*
values
,
COND
*
conds
,
ulong
options
,
enum
enum_duplicates
handle_duplicates
);
int
mysql_insert
(
THD
*
thd
,
TABLE_LIST
*
table
,
List
<
Item
>
&
fields
,
List
<
List_item
>
&
values
,
enum_duplicates
flag
);
void
kill_delayed_threads
(
void
);
...
...
@@ -498,7 +516,7 @@ TABLE_LIST *add_table_to_list(Table_ident *table,LEX_STRING *alias,
void
set_lock_for_tables
(
thr_lock_type
lock_type
);
void
add_join_on
(
TABLE_LIST
*
b
,
Item
*
expr
);
void
add_join_natural
(
TABLE_LIST
*
a
,
TABLE_LIST
*
b
);
bool
add_proc_to_list
(
Item
*
item
);
bool
add_proc_to_list
(
THD
*
thd
,
Item
*
item
);
TABLE
*
unlink_open_table
(
THD
*
thd
,
TABLE
*
list
,
TABLE
*
find
);
SQL_SELECT
*
make_select
(
TABLE
*
head
,
table_map
const_tables
,
...
...
sql/sql_base.cc
View file @
2e2d1df9
...
...
@@ -1942,8 +1942,8 @@ static key_map get_key_map_from_key_list(TABLE *table,
}
/****************************************************************************
**
This just drops in all fields instead of current '*' field
**
Returns pointer to last inserted field if ok
This just drops in all fields instead of current '*' field
Returns pointer to last inserted field if ok
****************************************************************************/
bool
...
...
@@ -1957,21 +1957,26 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
for
(;
tables
;
tables
=
tables
->
next
)
{
TABLE
*
table
=
tables
->
table
;
if
(
grant_option
&&
!
thd
->
master_access
&&
check_grant_all_columns
(
thd
,
SELECT_ACL
,
table
)
)
DBUG_RETURN
(
-
1
);
if
(
!
table_name
||
(
!
strcmp
(
table_name
,
tables
->
alias
)
&&
(
!
db_name
||
!
strcmp
(
tables
->
db
,
db_name
))))
{
/* Ensure that we have access right to all columns */
if
(
grant_option
&&
!
thd
->
master_access
&&
check_grant_all_columns
(
thd
,
SELECT_ACL
,
table
)
)
DBUG_RETURN
(
-
1
);
Field
**
ptr
=
table
->
field
,
*
field
;
thd
->
used_tables
|=
table
->
map
;
while
((
field
=
*
ptr
++
))
{
Item_field
*
item
=
new
Item_field
(
field
);
if
(
!
found
++
)
(
void
)
it
->
replace
(
item
);
(
void
)
it
->
replace
(
item
);
// Replace '*'
else
it
->
after
(
item
);
/*
Mark if field used before in this select.
Used by 'insert' to verify if a field name is used twice
*/
if
(
field
->
query_id
==
thd
->
query_id
)
thd
->
dupp_field
=
field
;
field
->
query_id
=
thd
->
query_id
;
...
...
sql/sql_class.h
View file @
2e2d1df9
...
...
@@ -592,7 +592,7 @@ class select_result :public Sql_alloc {
virtual
int
prepare
(
List
<
Item
>
&
list
)
{
return
0
;
}
virtual
bool
send_fields
(
List
<
Item
>
&
list
,
uint
flag
)
=
0
;
virtual
bool
send_data
(
List
<
Item
>
&
items
)
=
0
;
virtual
void
initialize_tables
(
JOIN
*
join
=
0
)
{
}
virtual
bool
initialize_tables
(
JOIN
*
join
=
0
)
{
return
0
;
}
virtual
void
send_error
(
uint
errcode
,
const
char
*
err
)
{
::
send_error
(
&
thd
->
net
,
errcode
,
err
);
...
...
@@ -656,10 +656,10 @@ class select_insert :public select_result {
List
<
Item
>
*
fields
;
ulonglong
last_insert_id
;
COPY_INFO
info
;
uint
save_time_stamp
;
select_insert
(
TABLE
*
table_par
,
List
<
Item
>
*
fields_par
,
enum_duplicates
duplic
)
:
table
(
table_par
),
fields
(
fields_par
),
last_insert_id
(
0
),
save_time_stamp
(
0
)
{
:
table
(
table_par
),
fields
(
fields_par
),
last_insert_id
(
0
)
{
bzero
((
char
*
)
&
info
,
sizeof
(
info
));
info
.
handle_duplicates
=
duplic
;
}
...
...
@@ -703,8 +703,8 @@ class select_union :public select_result {
public:
TABLE
*
table
;
COPY_INFO
info
;
uint
save_time_stamp
;
TMP_TABLE_PARAM
*
tmp_table_param
;
bool
not_describe
;
select_union
(
TABLE
*
table_par
);
~
select_union
();
...
...
@@ -814,37 +814,36 @@ class Unique :public Sql_alloc
bool
send_fields
(
List
<
Item
>
&
list
,
uint
flag
)
{
return
0
;
}
bool
send_data
(
List
<
Item
>
&
items
);
void
initialize_tables
(
JOIN
*
join
);
bool
initialize_tables
(
JOIN
*
join
);
void
send_error
(
uint
errcode
,
const
char
*
err
);
int
do_deletes
(
bool
from_send_error
);
bool
send_eof
();
};
class
multi_update
:
public
select_result
{
TABLE_LIST
*
update_tables
,
*
table_being_updated
;
// Unique **tempfiles;
COPY_INFO
*
infos
;
TABLE
**
tmp_tables
;
THD
*
thd
;
ha_rows
updated
,
found
;
List
<
Item
>
fields
;
List
<
Item
>
**
fields_by_tables
;
enum
enum_duplicates
dupl
;
uint
num_of_tables
,
num_fields
,
num_updated
,
*
save_time_stamps
,
*
field_sequence
;
int
error
;
bool
do_update
,
not_trans_safe
;
public:
multi_update
(
THD
*
thd_arg
,
TABLE_LIST
*
ut
,
List
<
Item
>
&
fs
,
enum
enum_duplicates
handle_duplicates
,
uint
num
);
~
multi_update
();
int
prepare
(
List
<
Item
>
&
list
);
bool
send_fields
(
List
<
Item
>
&
list
,
uint
flag
)
{
return
0
;
}
bool
send_data
(
List
<
Item
>
&
items
);
void
initialize_tables
(
JOIN
*
join
);
void
send_error
(
uint
errcode
,
const
char
*
err
);
int
do_updates
(
bool
from_send_error
);
bool
send_eof
();
};
class
multi_update
:
public
select_result
{
TABLE_LIST
*
all_tables
,
*
update_tables
,
*
table_being_updated
;
THD
*
thd
;
TABLE
**
tmp_tables
,
*
main_table
;
TMP_TABLE_PARAM
*
tmp_table_param
;
ha_rows
updated
,
found
;
List
<
Item
>
*
fields
,
*
values
;
List
<
Item
>
**
fields_for_table
,
**
values_for_table
;
uint
table_count
;
Copy_field
*
copy_field
;
enum
enum_duplicates
handle_duplicates
;
bool
do_update
,
trans_safe
,
transactional_tables
,
log_delayed
;
public:
multi_update
(
THD
*
thd_arg
,
TABLE_LIST
*
ut
,
List
<
Item
>
*
fields
,
List
<
Item
>
*
values
,
enum_duplicates
handle_duplicates
);
~
multi_update
();
int
prepare
(
List
<
Item
>
&
list
);
bool
send_fields
(
List
<
Item
>
&
list
,
uint
flag
)
{
return
0
;
}
bool
send_data
(
List
<
Item
>
&
items
);
bool
initialize_tables
(
JOIN
*
join
);
void
send_error
(
uint
errcode
,
const
char
*
err
);
int
do_updates
(
bool
from_send_error
);
bool
send_eof
();
};
sql/sql_delete.cc
View file @
2e2d1df9
...
...
@@ -213,12 +213,13 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
extern
"C"
int
refposcmp2
(
void
*
arg
,
const
void
*
a
,
const
void
*
b
)
{
/* arg is a pointer to file->ref_length */
return
memcmp
(
a
,
b
,
*
(
int
*
)
arg
);
}
multi_delete
::
multi_delete
(
THD
*
thd_arg
,
TABLE_LIST
*
dt
,
uint
num_of_tables_arg
)
:
delete_tables
(
dt
),
thd
(
thd_arg
),
deleted
(
0
),
:
delete_tables
(
dt
),
thd
(
thd_arg
),
deleted
(
0
),
num_of_tables
(
num_of_tables_arg
),
error
(
0
),
do_delete
(
0
),
transactional_tables
(
0
),
log_delayed
(
0
),
normal_tables
(
0
)
{
...
...
@@ -230,31 +231,22 @@ int
multi_delete
::
prepare
(
List
<
Item
>
&
values
)
{
DBUG_ENTER
(
"multi_delete::prepare"
);
do_delete
=
true
;
do_delete
=
1
;
thd
->
proc_info
=
"deleting from main table"
;
if
(
thd
->
options
&
OPTION_SAFE_UPDATES
)
{
TABLE_LIST
*
table_ref
;
for
(
table_ref
=
delete_tables
;
table_ref
;
table_ref
=
table_ref
->
next
)
{
TABLE
*
table
=
table_ref
->
table
;
if
((
thd
->
options
&
OPTION_SAFE_UPDATES
)
&&
!
table
->
quick_keys
)
{
my_error
(
ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE
,
MYF
(
0
));
DBUG_RETURN
(
1
);
}
}
}
DBUG_RETURN
(
0
);
}
void
bool
multi_delete
::
initialize_tables
(
JOIN
*
join
)
{
int
counter
=
0
;
TABLE_LIST
*
walk
;
Unique
**
tempfiles_ptr
;
DBUG_ENTER
(
"initialize_tables"
);
if
((
thd
->
options
&
OPTION_SAFE_UPDATES
)
&&
error_if_full_join
(
join
))
DBUG_RETURN
(
1
);
table_map
tables_to_delete_from
=
0
;
for
(
walk
=
delete_tables
;
walk
;
walk
=
walk
->
next
)
tables_to_delete_from
|=
walk
->
table
->
map
;
...
...
@@ -268,9 +260,10 @@ multi_delete::initialize_tables(JOIN *join)
{
/* We are going to delete from this table */
TABLE
*
tbl
=
walk
->
table
=
tab
->
table
;
walk
=
walk
->
next
;
/* Don't use KEYREAD optimization on this table */
tbl
->
no_keyread
=
1
;
walk
=
walk
->
next
;
tbl
->
used_keys
=
0
;
if
(
tbl
->
file
->
has_transactions
())
log_delayed
=
transactional_tables
=
1
;
else
if
(
tbl
->
tmp_table
!=
NO_TMP_TABLE
)
...
...
@@ -280,19 +273,17 @@ multi_delete::initialize_tables(JOIN *join)
}
}
walk
=
delete_tables
;
walk
->
table
->
used_keys
=
0
;
for
(
walk
=
walk
->
next
;
walk
;
walk
=
walk
->
next
,
counter
++
)
tempfiles_ptr
=
tempfiles
;
for
(
walk
=
walk
->
next
;
walk
;
walk
=
walk
->
next
)
{
tables_to_delete_from
|=
walk
->
table
->
map
;
TABLE
*
table
=
walk
->
table
;
/* Don't use key read with MULTI-TABLE-DELETE */
table
->
used_keys
=
0
;
tempfiles
[
counter
]
=
new
Unique
(
refposcmp2
,
(
void
*
)
&
table
->
file
->
ref_length
,
table
->
file
->
ref_length
,
MEM_STRIP_BUF_SIZE
);
*
tempfiles_ptr
++=
new
Unique
(
refposcmp2
,
(
void
*
)
&
table
->
file
->
ref_length
,
table
->
file
->
ref_length
,
MEM_STRIP_BUF_SIZE
);
}
init_ftfuncs
(
thd
,
1
);
DBUG_RETURN
(
thd
->
fatal_error
!=
0
);
}
...
...
@@ -307,7 +298,7 @@ multi_delete::~multi_delete()
t
->
no_keyread
=
0
;
}
for
(
uint
counter
=
0
;
counter
<
num_of_tables
-
1
;
counter
++
)
for
(
uint
counter
=
0
;
counter
<
num_of_tables
-
1
;
counter
++
)
{
if
(
tempfiles
[
counter
])
delete
tempfiles
[
counter
];
...
...
@@ -414,7 +405,7 @@ int multi_delete::do_deletes(bool from_send_error)
else
table_being_deleted
=
delete_tables
;
do_delete
=
false
;
do_delete
=
0
;
for
(
table_being_deleted
=
table_being_deleted
->
next
;
table_being_deleted
;
table_being_deleted
=
table_being_deleted
->
next
,
counter
++
)
...
...
@@ -468,7 +459,7 @@ bool multi_delete::send_eof()
was a non-transaction-safe table involved, since
modifications in it cannot be rolled back.
*/
if
(
deleted
)
if
(
deleted
&&
(
error
<=
0
||
normal_tables
)
)
{
mysql_update_log
.
write
(
thd
,
thd
->
query
,
thd
->
query_length
);
if
(
mysql_bin_log
.
is_open
())
...
...
@@ -478,11 +469,17 @@ bool multi_delete::send_eof()
if
(
mysql_bin_log
.
write
(
&
qinfo
)
&&
!
normal_tables
)
local_error
=
1
;
// Log write failed: roll back the SQL statement
}
/* Commit or rollback the current SQL statement */
VOID
(
ha_autocommit_or_rollback
(
thd
,
local_error
>
0
));
query_cache_invalidate3
(
thd
,
delete_tables
,
1
);
if
(
!
log_delayed
)
thd
->
options
|=
OPTION_STATUS_NO_TRANS_UPDATE
;
}
/* Commit or rollback the current SQL statement */
if
(
transactional_tables
)
if
(
ha_autocommit_or_rollback
(
thd
,
local_error
>
0
))
local_error
=
1
;
if
(
deleted
)
query_cache_invalidate3
(
thd
,
delete_tables
,
1
);
if
(
local_error
)
::
send_error
(
&
thd
->
net
);
else
...
...
sql/sql_insert.cc
View file @
2e2d1df9
...
...
@@ -41,7 +41,8 @@ static void unlink_blobs(register TABLE *table);
/*
Check if insert fields are correct
Resets form->time_stamp if a timestamp value is set
Updates table->time_stamp to point to timestamp field or 0, depending on
if timestamp should be updated or not.
*/
static
int
...
...
@@ -87,11 +88,12 @@ check_insert_fields(THD *thd,TABLE *table,List<Item> &fields,
my_error
(
ER_FIELD_SPECIFIED_TWICE
,
MYF
(
0
),
thd
->
dupp_field
->
field_name
);
return
-
1
;
}
table
->
time_stamp
=
0
;
if
(
table
->
timestamp_field
&&
// Don't set timestamp if used
table
->
timestamp_field
->
query_id
=
=
thd
->
query_id
)
table
->
time_stamp
=
0
;
// This should be saved
table
->
timestamp_field
->
query_id
!
=
thd
->
query_id
)
table
->
time_stamp
=
table
->
timestamp_field
->
offset
()
+
1
;
}
// For the values we need select_priv
// For the values we need select_priv
table
->
grant
.
want_privilege
=
(
SELECT_ACL
&
~
table
->
grant
.
privilege
);
return
0
;
}
...
...
@@ -105,7 +107,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
!
(
thd
->
master_access
&
SUPER_ACL
));
bool
transactional_table
,
log_delayed
,
bulk_insert
=
0
;
uint
value_count
;
uint
save_time_stamp
;
ulong
counter
=
1
;
ulonglong
id
;
COPY_INFO
info
;
...
...
@@ -150,14 +151,10 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
DBUG_RETURN
(
-
1
);
thd
->
proc_info
=
"init"
;
thd
->
used_tables
=
0
;
save_time_stamp
=
table
->
time_stamp
;
values
=
its
++
;
if
(
check_insert_fields
(
thd
,
table
,
fields
,
*
values
,
1
)
||
setup_tables
(
table_list
)
||
setup_fields
(
thd
,
table_list
,
*
values
,
0
,
0
,
0
))
{
table
->
time_stamp
=
save_time_stamp
;
goto
abort
;
}
value_count
=
values
->
elements
;
while
((
values
=
its
++
))
{
...
...
@@ -167,14 +164,10 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
my_printf_error
(
ER_WRONG_VALUE_COUNT_ON_ROW
,
ER
(
ER_WRONG_VALUE_COUNT_ON_ROW
),
MYF
(
0
),
counter
);
table
->
time_stamp
=
save_time_stamp
;
goto
abort
;
}
if
(
setup_fields
(
thd
,
table_list
,
*
values
,
0
,
0
,
0
))
{
table
->
time_stamp
=
save_time_stamp
;
goto
abort
;
}
}
its
.
rewind
();
/*
...
...
@@ -333,7 +326,6 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
}
}
thd
->
proc_info
=
"end"
;
table
->
time_stamp
=
save_time_stamp
;
// Restore auto timestamp ptr
table
->
next_number_field
=
0
;
thd
->
count_cuted_fields
=
0
;
thd
->
next_insert_id
=
0
;
// Reset this if wrongly used
...
...
@@ -1287,7 +1279,6 @@ select_insert::prepare(List<Item> &values)
{
DBUG_ENTER
(
"select_insert::prepare"
);
save_time_stamp
=
table
->
time_stamp
;
if
(
check_insert_fields
(
thd
,
table
,
*
fields
,
values
,
1
))
DBUG_RETURN
(
1
);
...
...
@@ -1308,8 +1299,6 @@ select_insert::~select_insert()
{
if
(
table
)
{
if
(
save_time_stamp
)
table
->
time_stamp
=
save_time_stamp
;
table
->
next_number_field
=
0
;
table
->
file
->
extra
(
HA_EXTRA_RESET
);
}
...
...
@@ -1412,7 +1401,6 @@ select_create::prepare(List<Item> &values)
/* First field to copy */
field
=
table
->
field
+
table
->
fields
-
values
.
elements
;
save_time_stamp
=
table
->
time_stamp
;
if
(
table
->
timestamp_field
)
// Don't set timestamp if used
{
table
->
timestamp_field
->
set_time
();
...
...
sql/sql_olap.cc
View file @
2e2d1df9
...
...
@@ -75,7 +75,7 @@ static int make_new_olap_select(LEX *lex, SELECT_LEX *select_lex, List<Item> new
!
strcmp
(((
Item_field
*
)
new_item
)
->
table_name
,
iif
->
table_name
)
&&
!
strcmp
(((
Item_field
*
)
new_item
)
->
field_name
,
iif
->
field_name
))
{
not_found
=
false
;
not_found
=
0
;
((
Item_field
*
)
new_item
)
->
db_name
=
iif
->
db_name
;
Item_field
*
new_one
=
new
Item_field
(
iif
->
db_name
,
iif
->
table_name
,
iif
->
field_name
);
privlist
.
push_back
(
new_one
);
...
...
@@ -151,7 +151,7 @@ int handle_olaps(LEX *lex, SELECT_LEX *select_lex)
if
(
cursor
->
do_redirect
)
{
cursor
->
table
=
((
TABLE_LIST
*
)
cursor
->
table
)
->
table
;
cursor
->
do_redirect
=
false
;
cursor
->
do_redirect
=
0
;
}
}
...
...
sql/sql_parse.cc
View file @
2e2d1df9
...
...
@@ -422,7 +422,7 @@ static bool check_mqh(THD *thd, uint check_command)
}
static
void
reset_mqh
(
THD
*
thd
,
LEX_USER
*
lu
,
bool
get_them
=
false
)
static
void
reset_mqh
(
THD
*
thd
,
LEX_USER
*
lu
,
bool
get_them
=
0
)
{
(
void
)
pthread_mutex_lock
(
&
LOCK_user_conn
);
...
...
@@ -1826,61 +1826,29 @@ mysql_execute_command(void)
select_lex
->
select_limit
,
lex
->
duplicates
);
}
else
else
{
multi_update
*
result
;
uint
table_count
;
TABLE_LIST
*
auxi
;
const
char
*
msg
=
0
;
lex
->
sql_command
=
SQLCOM_MULTI_UPDATE
;
for
(
auxi
=
(
TABLE_LIST
*
)
tables
,
table_count
=
0
;
auxi
;
auxi
=
auxi
->
next
)
table_count
++
;
const
char
*
msg
=
0
;
lex
->
sql_command
=
SQLCOM_MULTI_UPDATE
;
if
(
select_lex
->
order_list
.
elements
)
msg
=
"ORDER BY"
;
else
if
(
select_lex
->
select_limit
&&
select_lex
->
select_limit
!=
HA_POS_ERROR
)
msg
=
"LIMIT"
;
if
(
msg
)
{
net_printf
(
&
thd
->
net
,
ER_WRONG_USAGE
,
"UPDATE"
,
msg
);
res
=
1
;
break
;
}
tables
->
grant
.
want_privilege
=
(
SELECT_ACL
&
~
tables
->
grant
.
privilege
);
if
((
res
=
open_and_lock_tables
(
thd
,
tables
)))
break
;
thd
->
select_limit
=
HA_POS_ERROR
;
if
(
!
setup_fields
(
thd
,
tables
,
select_lex
->
item_list
,
1
,
0
,
0
)
&&
!
setup_fields
(
thd
,
tables
,
lex
->
value_list
,
0
,
0
,
0
)
&&
!
thd
->
fatal_error
&&
(
result
=
new
multi_update
(
thd
,
tables
,
select_lex
->
item_list
,
lex
->
duplicates
,
table_count
)))
{
List
<
Item
>
total_list
;
List_iterator
<
Item
>
field_list
(
select_lex
->
item_list
);
List_iterator
<
Item
>
value_list
(
lex
->
value_list
);
Item
*
item
;
while
((
item
=
field_list
++
))
total_list
.
push_back
(
item
);
while
((
item
=
value_list
++
))
total_list
.
push_back
(
item
);
res
=
mysql_select
(
thd
,
tables
,
total_list
,
select_lex
->
where
,
(
ORDER
*
)
NULL
,(
ORDER
*
)
NULL
,(
Item
*
)
NULL
,
(
ORDER
*
)
NULL
,
select_lex
->
options
|
thd
->
options
|
SELECT_NO_JOIN_CACHE
,
result
);
delete
result
;
}
else
res
=
-
1
;
// Error is not sent
close_thread_tables
(
thd
);
res
=
mysql_multi_update
(
thd
,
tables
,
&
select_lex
->
item_list
,
&
lex
->
value_list
,
select_lex
->
where
,
select_lex
->
options
,
lex
->
duplicates
);
}
break
;
break
;
case
SQLCOM_INSERT
:
if
(
check_access
(
thd
,
INSERT_ACL
,
tables
->
db
,
&
tables
->
grant
.
privilege
))
goto
error
;
/* purecov: inspected */
...
...
@@ -2741,11 +2709,8 @@ mysql_init_select(LEX *lex)
select_lex
->
olap
=
UNSPECIFIED_OLAP_TYPE
;
lex
->
exchange
=
0
;
lex
->
proc_list
.
first
=
0
;
select_lex
->
order_list
.
elements
=
select_lex
->
group_list
.
elements
=
0
;
select_lex
->
order_list
.
first
=
0
;
select_lex
->
order_list
.
next
=
(
byte
**
)
&
select_lex
->
order_list
.
first
;
select_lex
->
group_list
.
first
=
0
;
select_lex
->
group_list
.
next
=
(
byte
**
)
&
select_lex
->
group_list
.
first
;
select_lex
->
order_list
.
empty
();
select_lex
->
group_list
.
empty
();
select_lex
->
next
=
(
SELECT_LEX
*
)
NULL
;
}
...
...
@@ -2818,16 +2783,6 @@ mysql_parse(THD *thd,char *inBuf,uint length)
}
inline
static
void
link_in_list
(
SQL_LIST
*
list
,
byte
*
element
,
byte
**
next
)
{
list
->
elements
++
;
(
*
list
->
next
)
=
element
;
list
->
next
=
next
;
*
next
=
0
;
}
/*****************************************************************************
** Store field definition for create
** Return 0 if ok
...
...
@@ -3102,7 +3057,7 @@ void store_position_for_column(const char *name)
}
bool
add_proc_to_list
(
Item
*
item
)
add_proc_to_list
(
THD
*
thd
,
Item
*
item
)
{
ORDER
*
order
;
Item
**
item_ptr
;
...
...
@@ -3113,7 +3068,7 @@ add_proc_to_list(Item *item)
*
item_ptr
=
item
;
order
->
item
=
item_ptr
;
order
->
free_me
=
0
;
link_in_list
(
&
current_lex
->
proc_list
,
(
byte
*
)
order
,(
byte
**
)
&
order
->
next
);
thd
->
lex
.
proc_list
.
link_in_list
(
(
byte
*
)
order
,(
byte
**
)
&
order
->
next
);
return
0
;
}
...
...
@@ -3167,7 +3122,7 @@ bool add_to_list(SQL_LIST &list,Item *item,bool asc)
order
->
asc
=
asc
;
order
->
free_me
=
0
;
order
->
used
=
0
;
li
nk_in_list
(
&
list
,
(
byte
*
)
order
,(
byte
**
)
&
order
->
next
);
li
st
.
link_in_list
(
(
byte
*
)
order
,(
byte
**
)
&
order
->
next
);
DBUG_RETURN
(
0
);
}
...
...
@@ -3248,7 +3203,7 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
}
}
}
link_in_list
(
&
thd
->
lex
.
select
->
table_list
,
(
byte
*
)
ptr
,(
byte
**
)
&
ptr
->
next
);
thd
->
lex
.
select
->
table_list
.
link_in_list
(
(
byte
*
)
ptr
,(
byte
**
)
&
ptr
->
next
);
DBUG_RETURN
(
ptr
);
}
...
...
sql/sql_select.cc
View file @
2e2d1df9
...
...
@@ -437,7 +437,8 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
if
(
make_join_statistics
(
&
join
,
tables
,
conds
,
&
keyuse
)
||
thd
->
fatal_error
)
goto
err
;
thd
->
proc_info
=
"preparing"
;
result
->
initialize_tables
(
&
join
);
if
(
result
->
initialize_tables
(
&
join
))
goto
err
;
if
(
join
.
const_table_map
!=
join
.
found_const_table_map
&&
!
(
select_options
&
SELECT_DESCRIBE
))
{
...
...
@@ -2721,6 +2722,38 @@ make_join_readinfo(JOIN *join,uint options)
}
/*
Give error if we some tables are done with a full join
SYNOPSIS
error_if_full_join()
join Join condition
USAGE
This is used by multi_table_update and multi_table_delete when running
in safe mode
RETURN VALUES
0 ok
1 Error (full join used)
*/
bool
error_if_full_join
(
JOIN
*
join
)
{
for
(
JOIN_TAB
*
tab
=
join
->
join_tab
,
*
end
=
join
->
join_tab
+
join
->
tables
;
tab
<
end
;
tab
++
)
{
if
(
tab
->
type
==
JT_ALL
&&
!
tab
->
select
->
quick
)
{
my_error
(
ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE
,
MYF
(
0
));
return
(
1
);
}
}
return
(
0
);
}
static
void
join_free
(
JOIN
*
join
)
{
...
...
@@ -3401,12 +3434,34 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
/****************************************************************************
Create a temp table according to a field list.
Set distinct if duplicates could be removed
Given fields field pointers are changed to point at tmp_table
for send_fields
Create internal temporary table
****************************************************************************/
/*
Create field for temporary table
SYNOPSIS
create_tmp_field()
thd Thread handler
table Temporary table
item Item to create a field for
type Type of item (normally item->type)
copy_func If set and item is a function, store copy of item
in this array
group 1 if we are going to do a relative group by on result
modify_item 1 if item->result_field should point to new item.
This is relevent for how fill_record() is going to
work:
If modify_item is 1 then fill_record() will update
the record in the original table.
If modify_item is 0 then fill_record() will update
the temporary table
RETURN
0 on error
new_created field
*/
Field
*
create_tmp_field
(
THD
*
thd
,
TABLE
*
table
,
Item
*
item
,
Item
::
Type
type
,
Item_result_field
***
copy_func
,
Field
**
from_field
,
bool
group
,
bool
modify_item
)
...
...
@@ -3515,6 +3570,13 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
}
/*
Create a temp table according to a field list.
Set distinct if duplicates could be removed
Given fields field pointers are changed to point at tmp_table
for send_fields
*/
TABLE
*
create_tmp_table
(
THD
*
thd
,
TMP_TABLE_PARAM
*
param
,
List
<
Item
>
&
fields
,
ORDER
*
group
,
bool
distinct
,
bool
save_sum_fields
,
...
...
@@ -3675,9 +3737,19 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
}
else
{
/*
The last parameter to create_tmp_field() is a bit tricky:
We need to set it to 0 in union, to get fill_record() to modify the
temporary table.
We need to set it to 1 on multi-table-update and in select to
write rows to the temporary table.
We here distinguish between UNION and multi-table-updates by the fact
that in the later case group is set to the row pointer.
*/
Field
*
new_field
=
create_tmp_field
(
thd
,
table
,
item
,
type
,
&
copy_func
,
tmp_from_field
,
group
!=
0
,
not_all_columns
);
not_all_columns
||
group
!=
0
);
if
(
!
new_field
)
{
if
(
thd
->
fatal_error
)
...
...
@@ -3991,7 +4063,6 @@ static bool open_tmp_table(TABLE *table)
table
->
db_stat
=
0
;
return
(
1
);
}
/* VOID(ha_lock(table,F_WRLCK)); */
/* Single thread table */
(
void
)
table
->
file
->
extra
(
HA_EXTRA_QUICK
);
/* Faster */
return
(
0
);
}
...
...
sql/sql_select.h
View file @
2e2d1df9
...
...
@@ -301,3 +301,4 @@ class store_key_const_item :public store_key_item
};
bool
cp_buffer_from_ref
(
TABLE_REF
*
ref
);
bool
error_if_full_join
(
JOIN
*
join
);
sql/sql_union.cc
View file @
2e2d1df9
...
...
@@ -33,7 +33,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
TABLE
*
table
;
int
describe
=
(
lex
->
select_lex
.
options
&
SELECT_DESCRIBE
)
?
1
:
0
;
int
res
;
bool
found_rows_for_union
=
false
;
bool
found_rows_for_union
=
0
;
TABLE_LIST
result_table_list
;
TABLE_LIST
*
first_table
=
(
TABLE_LIST
*
)
lex
->
select_lex
.
table_list
.
first
;
TMP_TABLE_PARAM
tmp_table_param
;
...
...
@@ -53,7 +53,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
if
(
cursor
->
do_redirect
)
// False if CUBE/ROLLUP
{
cursor
->
table
=
((
TABLE_LIST
*
)
cursor
->
table
)
->
table
;
cursor
->
do_redirect
=
false
;
cursor
->
do_redirect
=
0
;
}
}
}
...
...
@@ -138,7 +138,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
res
=
-
1
;
goto
exit
;
}
union_result
->
save_time_stamp
=
!
describe
;
union_result
->
not_describe
=
!
describe
;
union_result
->
tmp_table_param
=&
tmp_table_param
;
for
(
sl
=
&
lex
->
select_lex
;
sl
;
sl
=
sl
->
next
)
{
...
...
@@ -150,14 +150,17 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
if
(
thd
->
select_limit
==
HA_POS_ERROR
)
sl
->
options
&=
~
OPTION_FOUND_ROWS
;
res
=
mysql_select
(
thd
,
(
describe
&&
sl
->
linkage
==
NOT_A_SELECT
)
?
first_table
:
(
TABLE_LIST
*
)
sl
->
table_list
.
first
,
res
=
mysql_select
(
thd
,
(
describe
&&
sl
->
linkage
==
NOT_A_SELECT
)
?
first_table
:
(
TABLE_LIST
*
)
sl
->
table_list
.
first
,
sl
->
item_list
,
sl
->
where
,
(
sl
->
braces
)
?
(
ORDER
*
)
sl
->
order_list
.
first
:
(
ORDER
*
)
0
,
(
sl
->
braces
)
?
(
ORDER
*
)
sl
->
order_list
.
first
:
(
ORDER
*
)
0
,
(
ORDER
*
)
sl
->
group_list
.
first
,
sl
->
having
,
(
ORDER
*
)
NULL
,
sl
->
options
|
thd
->
options
|
SELECT_NO_UNLOCK
|
((
describe
)
?
SELECT_DESCRIBE
:
0
),
sl
->
options
|
thd
->
options
|
SELECT_NO_UNLOCK
|
((
describe
)
?
SELECT_DESCRIBE
:
0
),
union_result
);
if
(
res
)
goto
exit
;
...
...
@@ -226,7 +229,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
***************************************************************************/
select_union
::
select_union
(
TABLE
*
table_par
)
:
table
(
table_par
)
:
table
(
table_par
),
not_describe
(
0
)
{
bzero
((
char
*
)
&
info
,
sizeof
(
info
));
/*
...
...
@@ -243,7 +246,7 @@ select_union::~select_union()
int
select_union
::
prepare
(
List
<
Item
>
&
list
)
{
if
(
save_time_stamp
&&
list
.
elements
!=
table
->
fields
)
if
(
not_describe
&&
list
.
elements
!=
table
->
fields
)
{
my_message
(
ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT
,
ER
(
ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT
),
MYF
(
0
));
...
...
sql/sql_update.cc
View file @
2e2d1df9
This diff is collapsed.
Click to expand it.
sql/sql_yacc.yy
View file @
2e2d1df9
...
...
@@ -1451,9 +1451,9 @@ select:
select_init { Lex->sql_command=SQLCOM_SELECT; };
select_init:
SELECT_SYM select_part2 { Select->braces=
false
; } opt_union
SELECT_SYM select_part2 { Select->braces=
0
; } opt_union
|
'(' SELECT_SYM select_part2 ')' { Select->braces=
true
;} union_opt;
'(' SELECT_SYM select_part2 ')' { Select->braces=
1
;} union_opt;
select_part2:
...
...
@@ -2366,7 +2366,7 @@ procedure_clause:
lex->proc_list.elements=0;
lex->proc_list.first=0;
lex->proc_list.next= (byte**) &lex->proc_list.first;
if (add_proc_to_list(new Item_field(NULL,NULL,$2.str)))
if (add_proc_to_list(
lex->thd,
new Item_field(NULL,NULL,$2.str)))
YYABORT;
current_thd->safe_to_cache_query=0;
}
...
...
@@ -2384,10 +2384,11 @@ procedure_list2:
procedure_item:
remember_name expr
{
if (add_proc_to_list($2))
LEX *lex= Lex;
if (add_proc_to_list(lex->thd, $2))
YYABORT;
if (!$2->name)
$2->set_name($1,(uint) ((char*)
L
ex->tok_end - $1));
$2->set_name($1,(uint) ((char*)
l
ex->tok_end - $1));
};
opt_into:
...
...
sql/table.h
View file @
2e2d1df9
...
...
@@ -117,18 +117,22 @@ struct st_table {
table_map
map
;
/* ID bit of table (1,2,4,8,16...) */
ulong
version
,
flush_version
;
uchar
*
null_flags
;
IO_CACHE
*
io_cache
;
/* If sorted trough file*/
byte
*
record_pointers
;
/* If sorted in memory */
ha_rows
found_records
;
/* How many records in sort */
IO_CACHE
*
io_cache
;
/* If sorted trough file*/
byte
*
record_pointers
;
/* If sorted in memory */
ha_rows
found_records
;
/* How many records in sort */
ORDER
*
group
;
ha_rows
quick_rows
[
MAX_KEY
];
uint
quick_key_parts
[
MAX_KEY
];
key_part_map
const_key_parts
[
MAX_KEY
];
ulong
query_id
;
uint
temp_pool_slot
;
union
/* Temporary variables */
{
uint
temp_pool_slot
;
/* Used by intern temp tables */
struct
st_table_list
*
pos_in_table_list
;
};
THD
*
in_use
;
/* Which thread uses this */
THD
*
in_use
;
/* Which thread uses this */
struct
st_table
*
next
,
*
prev
;
};
...
...
@@ -148,10 +152,10 @@ typedef struct st_table_list
GRANT_INFO
grant
;
thr_lock_type
lock_type
;
uint
outer_join
;
/* Which join type */
uint
shared
;
/* Used in union or in multi-upd */
uint32
db_length
,
real_name_length
;
bool
straight
;
/* optimize with prev table */
bool
updating
;
/* for replicate-do/ignore table */
bool
shared
;
/* Used twice in union */
bool
do_redirect
;
/* To get the struct in UNION's */
}
TABLE_LIST
;
...
...
sql/uniques.cc
View file @
2e2d1df9
...
...
@@ -53,7 +53,8 @@ Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg,
:
max_in_memory_size
(
max_in_memory_size_arg
),
elements
(
0
)
{
my_b_clear
(
&
file
);
init_tree
(
&
tree
,
max_in_memory_size
/
16
,
0
,
size
,
comp_func
,
0
,
NULL
,
comp_func_fixed_arg
);
init_tree
(
&
tree
,
max_in_memory_size
/
16
,
0
,
size
,
comp_func
,
0
,
NULL
,
comp_func_fixed_arg
);
/* If the following fail's the next add will also fail */
my_init_dynamic_array
(
&
file_ptrs
,
sizeof
(
BUFFPEK
),
16
,
16
);
max_elements
=
max_in_memory_size
/
ALIGN_SIZE
(
sizeof
(
TREE_ELEMENT
)
+
size
);
...
...
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