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
eecf716a
Commit
eecf716a
authored
Feb 20, 2009
by
Patrick Crews
Browse files
Options
Browse Files
Download
Plain Diff
automerge
parents
ac46e344
c02752a0
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
380 additions
and
48 deletions
+380
-48
mysql-test/include/wait_show_condition.inc
mysql-test/include/wait_show_condition.inc
+78
-0
mysql-test/r/innodb_bug42419.result
mysql-test/r/innodb_bug42419.result
+17
-0
mysql-test/r/mysqlbinlog.result
mysql-test/r/mysqlbinlog.result
+10
-0
mysql-test/r/row.result
mysql-test/r/row.result
+14
-0
mysql-test/t/innodb_bug42419.test
mysql-test/t/innodb_bug42419.test
+77
-0
mysql-test/t/mysqlbinlog.test
mysql-test/t/mysqlbinlog.test
+20
-0
mysql-test/t/row.test
mysql-test/t/row.test
+18
-0
sql/item.cc
sql/item.cc
+43
-34
sql/item.h
sql/item.h
+2
-0
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+12
-1
sql/log_event.cc
sql/log_event.cc
+1
-1
sql/sql_select.cc
sql/sql_select.cc
+24
-12
tests/mysql_client_test.c
tests/mysql_client_test.c
+64
-0
No files found.
mysql-test/include/wait_show_condition.inc
0 → 100644
View file @
eecf716a
# include/wait_show_condition.inc
#
# SUMMARY
#
# Waits until the show statement ($show_statement) has at least within one of
# the rows of the result set for the field ($field) a value which fulfils
# a condition ($condition), or the operation times out.
#
#
# USAGE
#
# let $show_statement= SHOW PROCESSLIST;
# let $field= State;
# let $condition= = 'Updating';
# --source include/wait_show_condition.inc
#
# OR
#
# let $wait_timeout= 60; # Override default of 30 seconds with 60.
# let $show_statement= SHOW PROCESSLIST;
# let $field= State;
# let $condition= = 'Updating';
# --source include/wait_show_condition.inc
#
# Please do not use this use routine if you can replace the SHOW statement
# with a select. In such a case include/wait_condition.inc is recommended.
#
# Created: 2009-02-18 mleich
#
let
$max_run_time
=
30
;
if
(
$wait_timeout
)
{
let
$max_run_time
=
$wait_timeout
;
}
# Reset $wait_timeout so that its value won't be used on subsequent
# calls, and default will be used instead.
let
$wait_timeout
=
0
;
# The smallest timespan till UNIX_TIMESTAMP() gets incremented is ~0 seconds.
# We add one second to avoid the case that somebody measures timespans on a
# real clock with fractions of seconds, detects that n seconds are sufficient,
# assigns n to this routine and suffers because he sometimes gets n - 1
# seconds in reality.
inc
$max_run_time
;
let
$found
=
0
;
let
$max_end_time
=
`SELECT UNIX_TIMESTAMP() + $max_run_time`
;
while
(
`SELECT UNIX_TIMESTAMP() <= $max_end_time AND $found = 0`
)
{
# Sleep a bit to avoid too heavy load.
real_sleep
0.2
;
let
$rowno
=
1
;
let
$process_result
=
1
;
while
(
`SELECT $process_result = 1 AND $found = 0`
)
{
let
$field_value
=
query_get_value
(
$show_statement
,
$field
,
$rowno
);
if
(
`SELECT '$field_value' $condition`
)
{
let
$found
=
1
;
}
if
(
`SELECT '$field_value' = 'No such row'`
)
{
# We are behind the last row of the result set.
let
$process_result
=
0
;
}
inc
$rowno
;
}
}
if
(
!
$found
)
{
echo
# Timeout in include/wait_show_condition.inc for $wait_condition;
echo
# show_statement : $show_statement;
echo
# field : $field;
echo
# condition : $condition;
echo
# max_run_time : $max_run_time;
}
mysql-test/r/innodb_bug42419.result
0 → 100644
View file @
eecf716a
CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b INT) ENGINE = InnoDB;
INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
COMMIT;
SET AUTOCOMMIT = 0;
CREATE TEMPORARY TABLE t1_tmp ( b INT );
INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 3;
INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 2;
SET AUTOCOMMIT = 0;
CREATE TEMPORARY TABLE t2_tmp ( a int, new_a int );
INSERT INTO t2_tmp VALUES (1,51),(2,52),(3,53);
UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 1;
UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 2;
INSERT INTO t1_tmp (b) SELECT b FROM t1 WHERE a = 1;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
Reap the server message for connection user2 UPDATE t1 ...
UPDATE t1 SET a = (SELECT new_a FROM t2_tmp WHERE t2_tmp.a = t1.a) WHERE a = 3;
DROP TABLE t1;
mysql-test/r/mysqlbinlog.result
View file @
eecf716a
...
@@ -369,4 +369,14 @@ drop table t1;
...
@@ -369,4 +369,14 @@ drop table t1;
1
1
drop table t1;
drop table t1;
shell> mysqlbinlog std_data/corrupt-relay-bin.000624 > var/tmp/bug31793.sql
shell> mysqlbinlog std_data/corrupt-relay-bin.000624 > var/tmp/bug31793.sql
set @@global.server_id= 4294967295;
reset master;
select
(@a:=load_file("MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug37313.binlog"))
is not null;
(@a:=load_file("MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug37313.binlog"))
is not null
1
*** Unsigned server_id 4294967295 is found: 1 ***
set @@global.server_id= 1;
End of 5.0 tests
End of 5.0 tests
mysql-test/r/row.result
View file @
eecf716a
...
@@ -443,3 +443,17 @@ SELECT ROW(a, 1) IN (SELECT SUM(b), 3) FROM t1 GROUP BY a;
...
@@ -443,3 +443,17 @@ SELECT ROW(a, 1) IN (SELECT SUM(b), 3) FROM t1 GROUP BY a;
ROW(a, 1) IN (SELECT SUM(b), 3)
ROW(a, 1) IN (SELECT SUM(b), 3)
0
0
DROP TABLE t1;
DROP TABLE t1;
create table t1 (a varchar(200),
b int unsigned not null primary key auto_increment)
default character set 'utf8';
create table t2 (c varchar(200),
d int unsigned not null primary key auto_increment)
default character set 'latin1';
insert into t1 (a) values('abc');
insert into t2 (c) values('abc');
select * from t1,t2 where (a,b) = (c,d);
a b c d
abc 1 abc 1
select host,user from mysql.user where (host,user) = ('localhost','test');
host user
drop table t1,t2;
mysql-test/t/innodb_bug42419.test
0 → 100644
View file @
eecf716a
#
# Testcase for InnoDB
# Bug#42419 Server crash with "Pure virtual method called" on two concurrent connections
#
--
source
include
/
have_innodb
.
inc
let
$innodb_lock_wait_timeout
=
query_get_value
(
SHOW
VARIABLES
LIKE
'innodb_lock_wait_timeout%'
,
Value
,
1
);
if
(
`SELECT $innodb_lock_wait_timeout < 10`
)
{
--
echo
# innodb_lock_wait_timeout must be >= 10 seconds
--
echo
# so that this test can work all time fine on an overloaded testing box
SHOW
VARIABLES
LIKE
'innodb_lock_wait_timeout'
;
exit
;
}
# Save the initial number of concurrent sessions
--
source
include
/
count_sessions
.
inc
# First session
connection
default
;
--
enable_warnings
CREATE
TABLE
t1
(
a
INT
AUTO_INCREMENT
PRIMARY
KEY
,
b
INT
)
ENGINE
=
InnoDB
;
INSERT
INTO
t1
VALUES
(
1
,
1
),(
2
,
2
),(
3
,
3
);
COMMIT
;
SET
AUTOCOMMIT
=
0
;
CREATE
TEMPORARY
TABLE
t1_tmp
(
b
INT
);
INSERT
INTO
t1_tmp
(
b
)
SELECT
b
FROM
t1
WHERE
a
=
3
;
INSERT
INTO
t1_tmp
(
b
)
SELECT
b
FROM
t1
WHERE
a
=
2
;
# Second session
connect
(
user2
,
localhost
,
root
,,,
$MASTER_MYPORT
,
$MASTER_MYSOCK
);
SET
AUTOCOMMIT
=
0
;
CREATE
TEMPORARY
TABLE
t2_tmp
(
a
int
,
new_a
int
);
INSERT
INTO
t2_tmp
VALUES
(
1
,
51
),(
2
,
52
),(
3
,
53
);
UPDATE
t1
SET
a
=
(
SELECT
new_a
FROM
t2_tmp
WHERE
t2_tmp
.
a
=
t1
.
a
)
WHERE
a
=
1
;
send
UPDATE
t1
SET
a
=
(
SELECT
new_a
FROM
t2_tmp
WHERE
t2_tmp
.
a
=
t1
.
a
)
WHERE
a
=
2
;
# The last update will wait for a lock held by the first session
# First session
connection
default
;
# Poll till the UPDATE of the second session waits for lock
let
$show_statement
=
SHOW
PROCESSLIST
;
let
$field
=
State
;
let
$condition
=
=
'Updating'
;
--
source
include
/
wait_show_condition
.
inc
# If the testing box is overloadeded and innodb_lock_wait_timeout is too small
# we might get here ER_LOCK_WAIT_TIMEOUT.
--
error
ER_LOCK_DEADLOCK
INSERT
INTO
t1_tmp
(
b
)
SELECT
b
FROM
t1
WHERE
a
=
1
;
# Second session
connection
user2
;
--
echo
Reap
the
server
message
for
connection
user2
UPDATE
t1
...
reap
;
# The server crashed when executing this UPDATE or the succeeding SQL command.
UPDATE
t1
SET
a
=
(
SELECT
new_a
FROM
t2_tmp
WHERE
t2_tmp
.
a
=
t1
.
a
)
WHERE
a
=
3
;
connection
default
;
disconnect
user2
;
DROP
TABLE
t1
;
# Wait till all disconnects are completed
--
source
include
/
wait_until_count_sessions
.
inc
mysql-test/t/mysqlbinlog.test
View file @
eecf716a
...
@@ -272,4 +272,24 @@ echo shell> mysqlbinlog std_data/corrupt-relay-bin.000624 > var/tmp/bug31793.sql
...
@@ -272,4 +272,24 @@ echo shell> mysqlbinlog std_data/corrupt-relay-bin.000624 > var/tmp/bug31793.sql
error
1
;
error
1
;
exec
$MYSQL_BINLOG
$MYSQL_TEST_DIR
/
std_data
/
corrupt
-
relay
-
bin
.
000624
>
$MYSQLTEST_VARDIR
/
tmp
/
bug31793
.
sql
;
exec
$MYSQL_BINLOG
$MYSQL_TEST_DIR
/
std_data
/
corrupt
-
relay
-
bin
.
000624
>
$MYSQLTEST_VARDIR
/
tmp
/
bug31793
.
sql
;
#
# Bug #37313 BINLOG Contains Incorrect server id
#
let
$save_server_id
=
`select @@global.server_id`
;
let
$s_id_max
=
`select (1 << 32) - 1`
;
eval
set
@@
global
.
server_id
=
$s_id_max
;
reset
master
;
--
exec
$MYSQL_BINLOG
$MYSQLTEST_VARDIR
/
log
/
master
-
bin
.
000001
>
$MYSQLTEST_VARDIR
/
tmp
/
mysqlbinlog_bug37313
.
binlog
--
replace_result
$MYSQLTEST_VARDIR
MYSQLTEST_VARDIR
eval
select
(
@
a
:=
load_file
(
"
$MYSQLTEST_VARDIR
/tmp/mysqlbinlog_bug37313.binlog"
))
is
not
null
;
let
$s_id_unsigned
=
`select @a like "%server id $s_id_max%" /* must return 1 */`
;
echo
***
Unsigned
server_id
$s_id_max
is
found
:
$s_id_unsigned
***
;
eval
set
@@
global
.
server_id
=
$save_server_id
;
--
remove_file
$MYSQLTEST_VARDIR
/
tmp
/
mysqlbinlog_bug37313
.
binlog
--
echo
End
of
5.0
tests
--
echo
End
of
5.0
tests
mysql-test/t/row.test
View file @
eecf716a
...
@@ -237,3 +237,21 @@ SELECT ROW(a, 1) IN (SELECT SUM(b), 1) FROM t1 GROUP BY a;
...
@@ -237,3 +237,21 @@ SELECT ROW(a, 1) IN (SELECT SUM(b), 1) FROM t1 GROUP BY a;
SELECT
ROW
(
a
,
1
)
IN
(
SELECT
SUM
(
b
),
3
)
FROM
t1
GROUP
BY
a
;
SELECT
ROW
(
a
,
1
)
IN
(
SELECT
SUM
(
b
),
3
)
FROM
t1
GROUP
BY
a
;
DROP
TABLE
t1
;
DROP
TABLE
t1
;
#
# Bug#37601 Cast Is Not Done On Row Comparison
#
create
table
t1
(
a
varchar
(
200
),
b
int
unsigned
not
null
primary
key
auto_increment
)
default
character
set
'utf8'
;
create
table
t2
(
c
varchar
(
200
),
d
int
unsigned
not
null
primary
key
auto_increment
)
default
character
set
'latin1'
;
insert
into
t1
(
a
)
values
(
'abc'
);
insert
into
t2
(
c
)
values
(
'abc'
);
select
*
from
t1
,
t2
where
(
a
,
b
)
=
(
c
,
d
);
select
host
,
user
from
mysql
.
user
where
(
host
,
user
)
=
(
'localhost'
,
'test'
);
drop
table
t1
,
t2
;
sql/item.cc
View file @
eecf716a
...
@@ -1608,42 +1608,11 @@ bool agg_item_collations_for_comparison(DTCollation &c, const char *fname,
...
@@ -1608,42 +1608,11 @@ bool agg_item_collations_for_comparison(DTCollation &c, const char *fname,
}
}
/*
Collect arguments' character sets together.
We allow to apply automatic character set conversion in some cases.
The conditions when conversion is possible are:
- arguments A and B have different charsets
- A wins according to coercibility rules
(i.e. a column is stronger than a string constant,
an explicit COLLATE clause is stronger than a column)
- character set of A is either superset for character set of B,
or B is a string constant which can be converted into the
character set of A without data loss.
If all of the above is true, then it's possible to convert
B into the character set of A, and then compare according
to the collation of A.
For functions with more than two arguments:
collect(A,B,C) ::= collect(collect(A,B),C)
Since this function calls THD::change_item_tree() on the passed Item **
pointers, it is necessary to pass the original Item **'s, not copies.
Otherwise their values will not be properly restored (see BUG#20769).
If the items are not consecutive (eg. args[2] and args[5]), use the
item_sep argument, ie.
agg_item_charsets(coll, fname, &args[2], 2, flags, 3)
*/
bool
agg_item_set_converter
(
DTCollation
&
coll
,
const
char
*
fname
,
bool
agg_item_charsets
(
DTCollation
&
coll
,
const
char
*
fname
,
Item
**
args
,
uint
nargs
,
uint
flags
,
int
item_sep
)
Item
**
args
,
uint
nargs
,
uint
flags
,
int
item_sep
)
{
{
Item
**
arg
,
*
safe_args
[
2
];
Item
**
arg
,
*
safe_args
[
2
];
if
(
agg_item_collations
(
coll
,
fname
,
args
,
nargs
,
flags
,
item_sep
))
return
TRUE
;
/*
/*
For better error reporting: save the first and the second argument.
For better error reporting: save the first and the second argument.
...
@@ -1724,6 +1693,46 @@ bool agg_item_charsets(DTCollation &coll, const char *fname,
...
@@ -1724,6 +1693,46 @@ bool agg_item_charsets(DTCollation &coll, const char *fname,
}
}
/*
Collect arguments' character sets together.
We allow to apply automatic character set conversion in some cases.
The conditions when conversion is possible are:
- arguments A and B have different charsets
- A wins according to coercibility rules
(i.e. a column is stronger than a string constant,
an explicit COLLATE clause is stronger than a column)
- character set of A is either superset for character set of B,
or B is a string constant which can be converted into the
character set of A without data loss.
If all of the above is true, then it's possible to convert
B into the character set of A, and then compare according
to the collation of A.
For functions with more than two arguments:
collect(A,B,C) ::= collect(collect(A,B),C)
Since this function calls THD::change_item_tree() on the passed Item **
pointers, it is necessary to pass the original Item **'s, not copies.
Otherwise their values will not be properly restored (see BUG#20769).
If the items are not consecutive (eg. args[2] and args[5]), use the
item_sep argument, ie.
agg_item_charsets(coll, fname, &args[2], 2, flags, 3)
*/
bool
agg_item_charsets
(
DTCollation
&
coll
,
const
char
*
fname
,
Item
**
args
,
uint
nargs
,
uint
flags
,
int
item_sep
)
{
if
(
agg_item_collations
(
coll
,
fname
,
args
,
nargs
,
flags
,
item_sep
))
return
TRUE
;
return
agg_item_set_converter
(
coll
,
fname
,
args
,
nargs
,
flags
,
item_sep
);
}
void
Item_ident_for_show
::
make_field
(
Send_field
*
tmp_field
)
void
Item_ident_for_show
::
make_field
(
Send_field
*
tmp_field
)
{
{
tmp_field
->
table_name
=
tmp_field
->
org_table_name
=
table_name
;
tmp_field
->
table_name
=
tmp_field
->
org_table_name
=
table_name
;
...
@@ -3010,7 +3019,7 @@ bool Item_param::convert_str_value(THD *thd)
...
@@ -3010,7 +3019,7 @@ bool Item_param::convert_str_value(THD *thd)
str_value
.
set_charset
(
value
.
cs_info
.
final_character_set_of_str_value
);
str_value
.
set_charset
(
value
.
cs_info
.
final_character_set_of_str_value
);
/* Here str_value is guaranteed to be in final_character_set_of_str_value */
/* Here str_value is guaranteed to be in final_character_set_of_str_value */
max_length
=
str_value
.
length
()
;
max_length
=
str_value
.
numchars
()
*
str_value
.
charset
()
->
mbmaxlen
;
decimals
=
0
;
decimals
=
0
;
/*
/*
str_value_ptr is returned from val_str(). It must be not alloced
str_value_ptr is returned from val_str(). It must be not alloced
...
...
sql/item.h
View file @
eecf716a
...
@@ -1169,6 +1169,8 @@ bool agg_item_collations(DTCollation &c, const char *name,
...
@@ -1169,6 +1169,8 @@ bool agg_item_collations(DTCollation &c, const char *name,
Item
**
items
,
uint
nitems
,
uint
flags
,
int
item_sep
);
Item
**
items
,
uint
nitems
,
uint
flags
,
int
item_sep
);
bool
agg_item_collations_for_comparison
(
DTCollation
&
c
,
const
char
*
name
,
bool
agg_item_collations_for_comparison
(
DTCollation
&
c
,
const
char
*
name
,
Item
**
items
,
uint
nitems
,
uint
flags
);
Item
**
items
,
uint
nitems
,
uint
flags
);
bool
agg_item_set_converter
(
DTCollation
&
coll
,
const
char
*
fname
,
Item
**
args
,
uint
nargs
,
uint
flags
,
int
item_sep
);
bool
agg_item_charsets
(
DTCollation
&
c
,
const
char
*
name
,
bool
agg_item_charsets
(
DTCollation
&
c
,
const
char
*
name
,
Item
**
items
,
uint
nitems
,
uint
flags
,
int
item_sep
);
Item
**
items
,
uint
nitems
,
uint
flags
,
int
item_sep
);
...
...
sql/item_cmpfunc.cc
View file @
eecf716a
...
@@ -490,7 +490,8 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
...
@@ -490,7 +490,8 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
my_error
(
ER_OPERAND_COLUMNS
,
MYF
(
0
),
(
*
a
)
->
element_index
(
i
)
->
cols
());
my_error
(
ER_OPERAND_COLUMNS
,
MYF
(
0
),
(
*
a
)
->
element_index
(
i
)
->
cols
());
return
1
;
return
1
;
}
}
comparators
[
i
].
set_cmp_func
(
owner
,
(
*
a
)
->
addr
(
i
),
(
*
b
)
->
addr
(
i
));
if
(
comparators
[
i
].
set_cmp_func
(
owner
,
(
*
a
)
->
addr
(
i
),
(
*
b
)
->
addr
(
i
)))
return
1
;
}
}
break
;
break
;
}
}
...
@@ -835,6 +836,16 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
...
@@ -835,6 +836,16 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
get_value_func
=
&
get_time_value
;
get_value_func
=
&
get_time_value
;
return
0
;
return
0
;
}
}
else
if
(
type
==
STRING_RESULT
&&
(
*
a
)
->
result_type
()
==
STRING_RESULT
&&
(
*
b
)
->
result_type
()
==
STRING_RESULT
)
{
DTCollation
coll
;
coll
.
set
((
*
a
)
->
collation
.
collation
);
if
(
agg_item_set_converter
(
coll
,
owner_arg
->
func_name
(),
b
,
1
,
MY_COLL_CMP_CONV
,
1
))
return
1
;
}
return
set_compare_func
(
owner_arg
,
type
);
return
set_compare_func
(
owner_arg
,
type
);
}
}
...
...
sql/log_event.cc
View file @
eecf716a
...
@@ -976,7 +976,7 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info)
...
@@ -976,7 +976,7 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info)
fputc
(
'#'
,
file
);
fputc
(
'#'
,
file
);
print_timestamp
(
file
);
print_timestamp
(
file
);
fprintf
(
file
,
" server id %
d
end_log_pos %s "
,
server_id
,
fprintf
(
file
,
" server id %
lu
end_log_pos %s "
,
server_id
,
llstr
(
log_pos
,
llbuff
));
llstr
(
log_pos
,
llbuff
));
/* mysqlbinlog --hexdump */
/* mysqlbinlog --hexdump */
...
...
sql/sql_select.cc
View file @
eecf716a
...
@@ -2373,11 +2373,12 @@ typedef struct st_sargable_param
...
@@ -2373,11 +2373,12 @@ typedef struct st_sargable_param
*/
*/
static
bool
static
bool
make_join_statistics
(
JOIN
*
join
,
TABLE_LIST
*
tables
,
COND
*
conds
,
make_join_statistics
(
JOIN
*
join
,
TABLE_LIST
*
tables
_arg
,
COND
*
conds
,
DYNAMIC_ARRAY
*
keyuse_array
)
DYNAMIC_ARRAY
*
keyuse_array
)
{
{
int
error
;
int
error
;
TABLE
*
table
;
TABLE
*
table
;
TABLE_LIST
*
tables
=
tables_arg
;
uint
i
,
table_count
,
const_count
,
key
;
uint
i
,
table_count
,
const_count
,
key
;
table_map
found_const_table_map
,
all_table_map
,
found_ref
,
refs
;
table_map
found_const_table_map
,
all_table_map
,
found_ref
,
refs
;
key_map
const_ref
,
eq_part
;
key_map
const_ref
,
eq_part
;
...
@@ -2415,10 +2416,10 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
...
@@ -2415,10 +2416,10 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
table_vector
[
i
]
=
s
->
table
=
table
=
tables
->
table
;
table_vector
[
i
]
=
s
->
table
=
table
=
tables
->
table
;
table
->
pos_in_table_list
=
tables
;
table
->
pos_in_table_list
=
tables
;
error
=
table
->
file
->
info
(
HA_STATUS_VARIABLE
|
HA_STATUS_NO_LOCK
);
error
=
table
->
file
->
info
(
HA_STATUS_VARIABLE
|
HA_STATUS_NO_LOCK
);
if
(
error
)
if
(
error
)
{
{
table
->
file
->
print_error
(
error
,
MYF
(
0
));
table
->
file
->
print_error
(
error
,
MYF
(
0
));
DBUG_RETURN
(
1
)
;
goto
error
;
}
}
table
->
quick_keys
.
clear_all
();
table
->
quick_keys
.
clear_all
();
table
->
reginfo
.
join_tab
=
s
;
table
->
reginfo
.
join_tab
=
s
;
...
@@ -2503,7 +2504,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
...
@@ -2503,7 +2504,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
{
{
join
->
tables
=
0
;
// Don't use join->table
join
->
tables
=
0
;
// Don't use join->table
my_message
(
ER_WRONG_OUTER_JOIN
,
ER
(
ER_WRONG_OUTER_JOIN
),
MYF
(
0
));
my_message
(
ER_WRONG_OUTER_JOIN
,
ER
(
ER_WRONG_OUTER_JOIN
),
MYF
(
0
));
DBUG_RETURN
(
1
)
;
goto
error
;
}
}
s
->
key_dependent
=
s
->
dependent
;
s
->
key_dependent
=
s
->
dependent
;
}
}
...
@@ -2513,7 +2514,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
...
@@ -2513,7 +2514,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
if
(
update_ref_and_keys
(
join
->
thd
,
keyuse_array
,
stat
,
join
->
tables
,
if
(
update_ref_and_keys
(
join
->
thd
,
keyuse_array
,
stat
,
join
->
tables
,
conds
,
join
->
cond_equal
,
conds
,
join
->
cond_equal
,
~
outer_join
,
join
->
select_lex
,
&
sargables
))
~
outer_join
,
join
->
select_lex
,
&
sargables
))
DBUG_RETURN
(
1
)
;
goto
error
;
/* Read tables with 0 or 1 rows (system tables) */
/* Read tables with 0 or 1 rows (system tables) */
join
->
const_table_map
=
0
;
join
->
const_table_map
=
0
;
...
@@ -2529,7 +2530,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
...
@@ -2529,7 +2530,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
if
((
tmp
=
join_read_const_table
(
s
,
p_pos
)))
if
((
tmp
=
join_read_const_table
(
s
,
p_pos
)))
{
{
if
(
tmp
>
0
)
if
(
tmp
>
0
)
DBUG_RETURN
(
1
);
// Fatal error
goto
error
;
// Fatal error
}
}
else
else
found_const_table_map
|=
s
->
table
->
map
;
found_const_table_map
|=
s
->
table
->
map
;
...
@@ -2601,7 +2602,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
...
@@ -2601,7 +2602,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
if
((
tmp
=
join_read_const_table
(
s
,
join
->
positions
+
const_count
-
1
)))
if
((
tmp
=
join_read_const_table
(
s
,
join
->
positions
+
const_count
-
1
)))
{
{
if
(
tmp
>
0
)
if
(
tmp
>
0
)
DBUG_RETURN
(
1
)
;
// Fatal error
goto
error
;
// Fatal error
}
}
else
else
found_const_table_map
|=
table
->
map
;
found_const_table_map
|=
table
->
map
;
...
@@ -2650,12 +2651,12 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
...
@@ -2650,12 +2651,12 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
set_position
(
join
,
const_count
++
,
s
,
start_keyuse
);
set_position
(
join
,
const_count
++
,
s
,
start_keyuse
);
if
(
create_ref_for_key
(
join
,
s
,
start_keyuse
,
if
(
create_ref_for_key
(
join
,
s
,
start_keyuse
,
found_const_table_map
))
found_const_table_map
))
DBUG_RETURN
(
1
)
;
goto
error
;
if
((
tmp
=
join_read_const_table
(
s
,
if
((
tmp
=
join_read_const_table
(
s
,
join
->
positions
+
const_count
-
1
)))
join
->
positions
+
const_count
-
1
)))
{
{
if
(
tmp
>
0
)
if
(
tmp
>
0
)
DBUG_RETURN
(
1
)
;
// Fatal error
goto
error
;
// Fatal error
}
}
else
else
found_const_table_map
|=
table
->
map
;
found_const_table_map
|=
table
->
map
;
...
@@ -2732,7 +2733,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
...
@@ -2732,7 +2733,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
*
s
->
on_expr_ref
?
*
s
->
on_expr_ref
:
conds
,
*
s
->
on_expr_ref
?
*
s
->
on_expr_ref
:
conds
,
1
,
&
error
);
1
,
&
error
);
if
(
!
select
)
if
(
!
select
)
DBUG_RETURN
(
1
)
;
goto
error
;
records
=
get_quick_record_count
(
join
->
thd
,
select
,
s
->
table
,
records
=
get_quick_record_count
(
join
->
thd
,
select
,
s
->
table
,
&
s
->
const_keys
,
join
->
row_limit
);
&
s
->
const_keys
,
join
->
row_limit
);
s
->
quick
=
select
->
quick
;
s
->
quick
=
select
->
quick
;
...
@@ -2778,7 +2779,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
...
@@ -2778,7 +2779,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
{
{
optimize_keyuse
(
join
,
keyuse_array
);
optimize_keyuse
(
join
,
keyuse_array
);
if
(
choose_plan
(
join
,
all_table_map
&
~
join
->
const_table_map
))
if
(
choose_plan
(
join
,
all_table_map
&
~
join
->
const_table_map
))
DBUG_RETURN
(
TRUE
)
;
goto
error
;
}
}
else
else
{
{
...
@@ -2788,6 +2789,17 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
...
@@ -2788,6 +2789,17 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
}
}
/* Generate an execution plan from the found optimal join order. */
/* Generate an execution plan from the found optimal join order. */
DBUG_RETURN
(
join
->
thd
->
killed
||
get_best_combination
(
join
));
DBUG_RETURN
(
join
->
thd
->
killed
||
get_best_combination
(
join
));
error:
/*
Need to clean up join_tab from TABLEs in case of error.
They won't get cleaned up by JOIN::cleanup() because JOIN::join_tab
may not be assigned yet by this function (which is building join_tab).
Dangling TABLE::reginfo.join_tab may cause part_of_refkey to choke.
*/
for
(
tables
=
tables_arg
;
tables
;
tables
=
tables
->
next_leaf
)
tables
->
table
->
reginfo
.
join_tab
=
NULL
;
DBUG_RETURN
(
1
);
}
}
...
...
tests/mysql_client_test.c
View file @
eecf716a
...
@@ -16410,6 +16410,69 @@ static void test_bug36326()
...
@@ -16410,6 +16410,69 @@ static void test_bug36326()
#endif
#endif
/**
Bug#41078: With CURSOR_TYPE_READ_ONLY mysql_stmt_fetch() returns short
string value.
*/
static
void
test_bug41078
(
void
)
{
uint
rc
;
MYSQL_STMT
*
stmt
=
0
;
MYSQL_BIND
param
,
result
;
ulong
cursor_type
=
CURSOR_TYPE_READ_ONLY
;
ulong
len
;
char
str
[
64
];
const
char
param_str
[]
=
"abcdefghijklmn"
;
my_bool
is_null
,
error
;
DBUG_ENTER
(
"test_bug41078"
);
rc
=
mysql_query
(
mysql
,
"SET NAMES UTF8"
);
myquery
(
rc
);
stmt
=
mysql_simple_prepare
(
mysql
,
"SELECT ?"
);
check_stmt
(
stmt
);
verify_param_count
(
stmt
,
1
);
rc
=
mysql_stmt_attr_set
(
stmt
,
STMT_ATTR_CURSOR_TYPE
,
&
cursor_type
);
check_execute
(
stmt
,
rc
);
bzero
(
&
param
,
sizeof
(
param
));
param
.
buffer_type
=
MYSQL_TYPE_STRING
;
param
.
buffer
=
(
void
*
)
param_str
;
len
=
sizeof
(
param_str
)
-
1
;
param
.
length
=
&
len
;
rc
=
mysql_stmt_bind_param
(
stmt
,
&
param
);
check_execute
(
stmt
,
rc
);
rc
=
mysql_stmt_execute
(
stmt
);
check_execute
(
stmt
,
rc
);
bzero
(
&
result
,
sizeof
(
result
));
result
.
buffer_type
=
MYSQL_TYPE_STRING
;
result
.
buffer
=
str
;
result
.
buffer_length
=
sizeof
(
str
);
result
.
is_null
=
&
is_null
;
result
.
length
=
&
len
;
result
.
error
=
&
error
;
rc
=
mysql_stmt_bind_result
(
stmt
,
&
result
);
check_execute
(
stmt
,
rc
);
rc
=
mysql_stmt_store_result
(
stmt
);
check_execute
(
stmt
,
rc
);
rc
=
mysql_stmt_fetch
(
stmt
);
check_execute
(
stmt
,
rc
);
DIE_UNLESS
(
len
==
sizeof
(
param_str
)
-
1
&&
!
strcmp
(
str
,
param_str
));
mysql_stmt_close
(
stmt
);
DBUG_VOID_RETURN
;
}
/*
/*
Read and parse arguments and MySQL options from my.cnf
Read and parse arguments and MySQL options from my.cnf
...
@@ -16713,6 +16776,7 @@ static struct my_tests_st my_tests[]= {
...
@@ -16713,6 +16776,7 @@ static struct my_tests_st my_tests[]= {
#ifdef HAVE_QUERY_CACHE
#ifdef HAVE_QUERY_CACHE
{
"test_bug36326"
,
test_bug36326
},
{
"test_bug36326"
,
test_bug36326
},
#endif
#endif
{
"test_bug41078"
,
test_bug41078
},
{
0
,
0
}
{
0
,
0
}
};
};
...
...
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