Merge 5.3 -> 5.5

This commit is contained in:
Sergey Petrunya 2012-06-20 15:01:28 +04:00
commit 8c762965d3
24 changed files with 556 additions and 116 deletions

View File

@ -9012,8 +9012,12 @@ int main(int argc, char **argv)
command->abort_on_error= (command->expected_errors.count == 0 &&
abort_on_error);
/* delimiter needs to be executed so we can continue to parse */
ok_to_do= cur_block->ok || command->type == Q_DELIMITER;
/*
some commmands need to be executed or at least parsed unconditionally,
because they change the grammar.
*/
ok_to_do= cur_block->ok || command->type == Q_DELIMITER
|| command->type == Q_PERL;
/*
Some commands need to be "done" the first time if they may get
re-iterated over in a true context. This can only happen if there's
@ -9024,8 +9028,7 @@ int main(int argc, char **argv)
if (command->type == Q_SOURCE ||
command->type == Q_ERROR ||
command->type == Q_WRITE_FILE ||
command->type == Q_APPEND_FILE ||
command->type == Q_PERL)
command->type == Q_APPEND_FILE)
{
for (struct st_block *stb= cur_block-1; stb >= block_stack; stb--)
{

View File

@ -148,9 +148,10 @@ typedef struct st_key_cache
ulonglong param_partitions; /* number of the key cache partitions */
my_bool key_cache_inited; /* <=> key cache has been created */
my_bool can_be_used; /* usage of cache for read/write is allowed */
my_bool in_init; /* Set to 1 in MySQL during init/resize */
my_bool in_init; /* set to 1 in MySQL during init/resize */
uint partitions; /* actual number of partitions */
size_t key_cache_mem_size; /* specified size of the cache memory */
pthread_mutex_t op_lock; /* to serialize operations like 'resize' */
} KEY_CACHE;

View File

@ -1682,7 +1682,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and `test`.`t2`.`b`)
Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t2`.`b` <> 0))
SELECT t.b, t.c, t1.a
FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
WHERE t.b AND t.c = t1.a;
@ -1713,7 +1713,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t2` left join `test`.`t3` on((`test`.`t3`.`b` = `test`.`t2`.`a`)) where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and `test`.`t2`.`b`)
Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t2` left join `test`.`t3` on((`test`.`t3`.`b` = `test`.`t2`.`a`)) where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t2`.`b` <> 0))
SELECT t.b, t.c, t1.a
FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
WHERE t.b AND t.c = t1.a;

View File

@ -789,3 +789,13 @@ DROP TABLE t1;
# End of test BUG#13012483
#
End of 5.1 tests
#
# LP bug#992380 Crash when creating PS for a query with
# subquery in WHERE (see also mysql bug#13012483)
#
CREATE TABLE t1 (a INT);
PREPARE s FROM "SELECT 1 FROM t1 WHERE 1 < ALL (SELECT @:= (1 IN (SELECT 1 FROM t1)) FROM t1)";
EXECUTE s;
1
DROP TABLE t1;
# End of 5.3 tests

View File

@ -279,3 +279,44 @@ NULL
SELECT GREATEST(1.5E+2,1.3E+2,NULL) FROM DUAL;
GREATEST(1.5E+2,1.3E+2,NULL)
NULL
create table t1 (a int);
insert into t1 values (1), (100), (0), (NULL);
select not a from t1;
not a
0
0
1
NULL
explain extended select not a from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00
Warnings:
Note 1003 select (`test`.`t1`.`a` = 0) AS `not a` from `test`.`t1`
select * from t1 where not a;
a
0
explain extended select * from t1 where not a;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = 0)
select not (a+0) from t1;
not (a+0)
0
0
1
NULL
explain extended select not (a+0) from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00
Warnings:
Note 1003 select (not((`test`.`t1`.`a` + 0))) AS `not (a+0)` from `test`.`t1`
select * from t1 where not (a+0);
a
0
explain extended select * from t1 where not (a+0);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (not((`test`.`t1`.`a` + 0)))
drop table t1;

View File

@ -0,0 +1 @@
# Done

View File

@ -321,7 +321,7 @@ select * from t1 where not(NULL or a);
a
explain select * from t1 where not(NULL and a);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 21 Using where; Using index
1 SIMPLE t1 ref a a 5 const 1 Using index
select * from t1 where not(NULL and a);
a
0
@ -502,5 +502,5 @@ explain extended select a, not(not(a)), not(a <= 2 and not(a)), not(a not like "
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 range a a 5 NULL 4 100.00 Using where; Using index
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,(`test`.`t1`.`a` <> 0) AS `not(not(a))`,((`test`.`t1`.`a` > 2) or `test`.`t1`.`a`) AS `not(a <= 2 and not(a))`,(`test`.`t1`.`a` like '1') AS `not(a not like "1")`,(`test`.`t1`.`a` in (1,2)) AS `not (a not in (1,2))`,(`test`.`t1`.`a` = 2) AS `not(a != 2)` from `test`.`t1` where (`test`.`t1`.`a` <> 0) having (`test`.`t1`.`a` <> 0)
Note 1003 select `test`.`t1`.`a` AS `a`,(`test`.`t1`.`a` <> 0) AS `not(not(a))`,((`test`.`t1`.`a` > 2) or (`test`.`t1`.`a` <> 0)) AS `not(a <= 2 and not(a))`,(`test`.`t1`.`a` like '1') AS `not(a not like "1")`,(`test`.`t1`.`a` in (1,2)) AS `not (a not in (1,2))`,(`test`.`t1`.`a` = 2) AS `not(a != 2)` from `test`.`t1` where (`test`.`t1`.`a` <> 0) having (`test`.`t1`.`a` <> 0)
drop table t1;

View File

@ -255,15 +255,15 @@ deallocate prepare StMt1;
deallocate prepare Stmt1;
ERROR HY000: Unknown prepared statement handler (Stmt1) given to DEALLOCATE PREPARE
set names utf8;
prepare `Ăź` from 'select 1234';
execute `Ăź` ;
prepare `ü` from 'select 1234';
execute `ü` ;
1234
1234
set names latin1;
execute `ü`;
execute `ü`;
1234
1234
deallocate prepare `ü`;
deallocate prepare `ü`;
set names default;
create table t1 (a varchar(10)) charset=utf8;
insert into t1 (a) values ('yahoo');
@ -3055,6 +3055,62 @@ DEALLOCATE PREPARE stmt;
DROP TABLE t1;
End of 5.1 tests.
#
# LP bug#1001500 Crash on the second execution of the PS for
# a query with degenerated conjunctive condition
# (see also mysql bug#12582849)
#
CREATE TABLE t1 (
pk INTEGER AUTO_INCREMENT,
col_int_nokey INTEGER,
col_int_key INTEGER,
col_varchar_key VARCHAR(1),
col_varchar_nokey VARCHAR(1),
PRIMARY KEY (pk),
KEY (col_int_key),
KEY (col_varchar_key, col_int_key)
);
INSERT INTO t1 (
col_int_key, col_int_nokey,
col_varchar_key, col_varchar_nokey
) VALUES
(4, 2, 'v', 'v'),
(62, 150, 'v', 'v');
CREATE TABLE t2 (
pk INTEGER AUTO_INCREMENT,
col_int_nokey INTEGER,
col_int_key INTEGER,
col_varchar_key VARCHAR(1),
col_varchar_nokey VARCHAR(1),
PRIMARY KEY (pk),
KEY (col_int_key),
KEY (col_varchar_key, col_int_key)
);
INSERT INTO t2 (
col_int_key, col_int_nokey,
col_varchar_key, col_varchar_nokey
) VALUES
(8, NULL, 'x', 'x'),
(7, 8, 'd', 'd');
PREPARE stmt FROM '
SELECT
( SELECT MAX( SQ1_alias2 .col_int_nokey ) AS SQ1_field1
FROM ( t2 AS SQ1_alias1 RIGHT JOIN t1 AS SQ1_alias2
ON ( SQ1_alias2.col_varchar_key = SQ1_alias1.col_varchar_nokey )
)
WHERE SQ1_alias2.pk < alias1.col_int_nokey OR alias1.pk
) AS field1
FROM ( t1 AS alias1 JOIN t2 AS alias2 ON alias2.pk )
GROUP BY field1
';
EXECUTE stmt;
field1
150
EXECUTE stmt;
field1
150
DEALLOCATE PREPARE stmt;
DROP TABLE t1, t2;
#
# WL#4435: Support OUT-parameters in prepared statements.
@ -4044,3 +4100,4 @@ c1 c2 count(c3)
2012-03-01 01:00:00 3 1
2012-03-01 02:00:00 3 1
DEALLOCATE PREPARE s1;
# End of 5.3 tests

View File

@ -209,8 +209,8 @@ WHERE t1.f1 AND alias2.f10
ORDER BY field1 ;
field1
Warnings:
Warning 1292 Truncated incorrect INTEGER value: 'f'
Warning 1292 Truncated incorrect INTEGER value: 'd'
Warning 1292 Truncated incorrect DOUBLE value: 'f'
Warning 1292 Truncated incorrect DOUBLE value: 'd'
set optimizer_switch=@tmp_optimizer_switch;
drop table t1,t2;
#

View File

@ -454,6 +454,13 @@ SELECT (@v:=a) <> (@v:=1) FROM t1;
(@v:=a) <> (@v:=1)
1
DROP TABLE t1;
CREATE TABLE t1(a int);
INSERT INTO t1 VALUES (1), (2);
SELECT DISTINCT @a:=MIN(t1.a) FROM t1, t1 AS t2
GROUP BY @b:=(SELECT COUNT(*) > t2.a);
@a:=MIN(t1.a)
1
DROP TABLE t1;
End of 5.1 tests
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(f1 INT AUTO_INCREMENT, PRIMARY KEY(f1));

View File

@ -4324,13 +4324,13 @@ MM
ZZ
ZZ
Warnings:
Warning 1292 Truncated incorrect INTEGER value: 'VV'
Warning 1292 Truncated incorrect DOUBLE value: 'VV'
EXPLAIN EXTENDED
SELECT * FROM v1 WHERE a > 'JJ' OR a AND a = 'VV';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 range a a 13 NULL 4 100.00 Using where; Using index
Warnings:
Warning 1292 Truncated incorrect INTEGER value: 'VV'
Warning 1292 Truncated incorrect DOUBLE value: 'VV'
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > 'JJ')
DROP VIEW v1;
DROP TABLE t1;

View File

@ -577,3 +577,14 @@ DROP TABLE t1;
--echo #
--echo End of 5.1 tests
--echo #
--echo # LP bug#992380 Crash when creating PS for a query with
--echo # subquery in WHERE (see also mysql bug#13012483)
--echo #
CREATE TABLE t1 (a INT);
PREPARE s FROM "SELECT 1 FROM t1 WHERE 1 < ALL (SELECT @:= (1 IN (SELECT 1 FROM t1)) FROM t1)";
EXECUTE s;
DROP TABLE t1;
--echo # End of 5.3 tests

View File

@ -160,3 +160,23 @@ SELECT LEAST(1.1,1.2,NULL,1.0) FROM DUAL;
SELECT GREATEST(1.5E+2,1.3E+2,NULL) FROM DUAL;
# End of 4.1 tests
#
# test of replacing NOT <field>
#
create table t1 (a int);
insert into t1 values (1), (100), (0), (NULL);
select not a from t1;
explain extended select not a from t1;
select * from t1 where not a;
explain extended select * from t1 where not a;
select not (a+0) from t1;
explain extended select not (a+0) from t1;
select * from t1 where not (a+0);
explain extended select * from t1 where not (a+0);
drop table t1;

View File

@ -0,0 +1,17 @@
#
# MDEV-256 lp:995501 - mysqltest attempts to parse Perl code inside a block
# with false condition, gets confused and throws wrong errors
#
let $run = 0;
if ($run)
{
--perl
foreach (1)
{
print "In perl\n";
}
EOF
SELECT 1;
}
--echo # Done

View File

@ -279,11 +279,11 @@ deallocate prepare Stmt1;
# also check that statement names are in right charset.
set names utf8;
prepare `Ăź` from 'select 1234';
execute `Ăź` ;
prepare `ü` from 'select 1234';
execute `ü` ;
set names latin1;
execute `ü`;
deallocate prepare `ü`;
execute `ü`;
deallocate prepare `ü`;
set names default;
@ -3124,6 +3124,71 @@ DROP TABLE t1;
--echo
--echo End of 5.1 tests.
--echo #
--echo # LP bug#1001500 Crash on the second execution of the PS for
--echo # a query with degenerated conjunctive condition
--echo # (see also mysql bug#12582849)
--echo #
CREATE TABLE t1 (
pk INTEGER AUTO_INCREMENT,
col_int_nokey INTEGER,
col_int_key INTEGER,
col_varchar_key VARCHAR(1),
col_varchar_nokey VARCHAR(1),
PRIMARY KEY (pk),
KEY (col_int_key),
KEY (col_varchar_key, col_int_key)
);
INSERT INTO t1 (
col_int_key, col_int_nokey,
col_varchar_key, col_varchar_nokey
) VALUES
(4, 2, 'v', 'v'),
(62, 150, 'v', 'v');
CREATE TABLE t2 (
pk INTEGER AUTO_INCREMENT,
col_int_nokey INTEGER,
col_int_key INTEGER,
col_varchar_key VARCHAR(1),
col_varchar_nokey VARCHAR(1),
PRIMARY KEY (pk),
KEY (col_int_key),
KEY (col_varchar_key, col_int_key)
);
INSERT INTO t2 (
col_int_key, col_int_nokey,
col_varchar_key, col_varchar_nokey
) VALUES
(8, NULL, 'x', 'x'),
(7, 8, 'd', 'd');
PREPARE stmt FROM '
SELECT
( SELECT MAX( SQ1_alias2 .col_int_nokey ) AS SQ1_field1
FROM ( t2 AS SQ1_alias1 RIGHT JOIN t1 AS SQ1_alias2
ON ( SQ1_alias2.col_varchar_key = SQ1_alias1.col_varchar_nokey )
)
WHERE SQ1_alias2.pk < alias1.col_int_nokey OR alias1.pk
) AS field1
FROM ( t1 AS alias1 JOIN t2 AS alias2 ON alias2.pk )
GROUP BY field1
';
EXECUTE stmt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
DROP TABLE t1, t2;
###########################################################################
--echo
@ -3596,3 +3661,5 @@ GROUP BY c1, c2;
EXECUTE s1;
DEALLOCATE PREPARE s1;
--echo # End of 5.3 tests

View File

@ -363,6 +363,17 @@ SELECT (@v:=a) <> (@v:=1) FROM t1;
DROP TABLE t1;
#
# LP BUG#1001506 Crash on a query with GROUP BY and user variables
# MySQL Bug #11764372 57197: EVEN MORE USER VARIABLE CRASHING FUN
#
CREATE TABLE t1(a int);
INSERT INTO t1 VALUES (1), (2);
SELECT DISTINCT @a:=MIN(t1.a) FROM t1, t1 AS t2
GROUP BY @b:=(SELECT COUNT(*) > t2.a);
DROP TABLE t1;
--echo End of 5.1 tests
#

View File

@ -5821,6 +5821,111 @@ static KEY_CACHE_FUNCS partitioned_key_cache_funcs =
******************************************************************************/
static
int repartition_key_cache_internal(KEY_CACHE *keycache,
uint key_cache_block_size, size_t use_mem,
uint division_limit, uint age_threshold,
uint partitions, my_bool use_op_lock);
/*
Initialize a key cache : internal
SYNOPSIS
init_key_cache_internal()
keycache pointer to the key cache to be initialized
key_cache_block_size size of blocks to keep cached data
use_mem total memory to use for cache buffers/structures
division_limit division limit (may be zero)
age_threshold age threshold (may be zero)
partitions number of partitions in the key cache
use_op_lock if TRUE use keycache->op_lock, otherwise - ignore it
DESCRIPTION
The function performs the actions required from init_key_cache().
It has an additional parameter: use_op_lock. When the parameter
is TRUE than the function initializes keycache->op_lock if needed,
then locks it, and unlocks it before the return. Otherwise the actions
with the lock are omitted.
RETURN VALUE
total number of blocks in key cache partitions, if successful,
<= 0 - otherwise.
NOTES
if keycache->key_cache_inited != 0 we assume that the memory
for the control block of the key cache has been already allocated.
*/
static
int init_key_cache_internal(KEY_CACHE *keycache, uint key_cache_block_size,
size_t use_mem, uint division_limit,
uint age_threshold, uint partitions,
my_bool use_op_lock)
{
void *keycache_cb;
int blocks;
if (keycache->key_cache_inited)
{
if (use_op_lock)
pthread_mutex_lock(&keycache->op_lock);
keycache_cb= keycache->keycache_cb;
}
else
{
if (partitions == 0)
{
if (!(keycache_cb= (void *) my_malloc(sizeof(SIMPLE_KEY_CACHE_CB),
MYF(0))))
return 0;
((SIMPLE_KEY_CACHE_CB *) keycache_cb)->key_cache_inited= 0;
keycache->key_cache_type= SIMPLE_KEY_CACHE;
keycache->interface_funcs= &simple_key_cache_funcs;
}
else
{
if (!(keycache_cb= (void *) my_malloc(sizeof(PARTITIONED_KEY_CACHE_CB),
MYF(0))))
return 0;
((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->key_cache_inited= 0;
keycache->key_cache_type= PARTITIONED_KEY_CACHE;
keycache->interface_funcs= &partitioned_key_cache_funcs;
}
/*
Initialize op_lock if it's not initialized before.
The mutex may have been initialized before if we are being called
from repartition_key_cache_internal().
*/
if (use_op_lock)
pthread_mutex_init(&keycache->op_lock, MY_MUTEX_INIT_FAST);
keycache->keycache_cb= keycache_cb;
keycache->key_cache_inited= 1;
if (use_op_lock)
pthread_mutex_lock(&keycache->op_lock);
}
if (partitions != 0)
{
((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->partitions= partitions;
}
keycache->can_be_used= 0;
blocks= keycache->interface_funcs->init(keycache_cb, key_cache_block_size,
use_mem, division_limit,
age_threshold);
keycache->partitions= partitions ?
((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->partitions :
0;
DBUG_ASSERT(partitions <= MAX_KEY_CACHE_PARTITIONS);
keycache->key_cache_mem_size=
keycache->partitions ?
((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->key_cache_mem_size :
((SIMPLE_KEY_CACHE_CB *) keycache_cb)->key_cache_mem_size;
if (blocks > 0)
keycache->can_be_used= 1;
if (use_op_lock)
pthread_mutex_unlock(&keycache->op_lock);
return blocks;
}
/*
Initialize a key cache
@ -5845,16 +5950,15 @@ static KEY_CACHE_FUNCS partitioned_key_cache_funcs =
age_threshold determine the initial values of those characteristics of
the key cache that are used for midpoint insertion strategy. The parameter
use_mem specifies the total amount of memory to be allocated for the
key cache buffers and for all auxiliary structures.
key cache buffers and for all auxiliary structures.
The function calls init_key_cache_internal() to perform all these actions
with the last parameter set to TRUE.
RETURN VALUE
total number of blocks in key cache partitions, if successful,
<= 0 - otherwise.
NOTES
if keycache->key_cache_inited != 0 we assume that the memory
for the control block of the key cache has been already allocated.
It's assumed that no two threads call this function simultaneously
referring to the same key cache handle.
*/
@ -5863,53 +5967,8 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
size_t use_mem, uint division_limit,
uint age_threshold, uint partitions)
{
void *keycache_cb;
int blocks;
if (keycache->key_cache_inited)
keycache_cb= keycache->keycache_cb;
else
{
if (partitions == 0)
{
if (!(keycache_cb= (void *) my_malloc(sizeof(SIMPLE_KEY_CACHE_CB),
MYF(0))))
return 0;
((SIMPLE_KEY_CACHE_CB *) keycache_cb)->key_cache_inited= 0;
keycache->key_cache_type= SIMPLE_KEY_CACHE;
keycache->interface_funcs= &simple_key_cache_funcs;
}
else
{
if (!(keycache_cb= (void *) my_malloc(sizeof(PARTITIONED_KEY_CACHE_CB),
MYF(0))))
return 0;
((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->key_cache_inited= 0;
keycache->key_cache_type= PARTITIONED_KEY_CACHE;
keycache->interface_funcs= &partitioned_key_cache_funcs;
}
keycache->keycache_cb= keycache_cb;
keycache->key_cache_inited= 1;
}
if (partitions != 0)
{
((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->partitions= partitions;
}
keycache->can_be_used= 0;
blocks= keycache->interface_funcs->init(keycache_cb, key_cache_block_size,
use_mem, division_limit,
age_threshold);
keycache->partitions= partitions ?
((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->partitions :
0;
DBUG_ASSERT(partitions <= MAX_KEY_CACHE_PARTITIONS);
keycache->key_cache_mem_size=
keycache->partitions ?
((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->key_cache_mem_size :
((SIMPLE_KEY_CACHE_CB *) keycache_cb)->key_cache_mem_size;
if (blocks > 0)
keycache->can_be_used= 1;
return blocks;
return init_key_cache_internal(keycache, key_cache_block_size, use_mem,
division_limit, age_threshold, partitions, 1);
}
@ -5953,11 +6012,13 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
int blocks= -1;
if (keycache->key_cache_inited)
{
pthread_mutex_lock(&keycache->op_lock);
if ((uint) keycache->param_partitions != keycache->partitions && use_mem)
blocks= repartition_key_cache(keycache,
key_cache_block_size, use_mem,
division_limit, age_threshold,
(uint) keycache->param_partitions);
blocks= repartition_key_cache_internal(keycache,
key_cache_block_size, use_mem,
division_limit, age_threshold,
(uint) keycache->param_partitions,
0);
else
{
blocks= keycache->interface_funcs->resize(keycache->keycache_cb,
@ -5976,6 +6037,7 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
((SIMPLE_KEY_CACHE_CB *)(keycache->keycache_cb))->key_cache_mem_size;
keycache->can_be_used= (blocks >= 0);
pthread_mutex_unlock(&keycache->op_lock);
}
return blocks;
}
@ -6009,10 +6071,57 @@ void change_key_cache_param(KEY_CACHE *keycache, uint division_limit,
{
if (keycache->key_cache_inited)
{
pthread_mutex_lock(&keycache->op_lock);
keycache->interface_funcs->change_param(keycache->keycache_cb,
division_limit,
age_threshold);
age_threshold);
pthread_mutex_unlock(&keycache->op_lock);
}
}
/*
Destroy a key cache : internal
SYNOPSIS
end_key_cache_internal()
keycache pointer to the key cache to be destroyed
cleanup <=> complete free
use_op_lock if TRUE use keycache->op_lock, otherwise - ignore it
DESCRIPTION
The function performs the actions required from end_key_cache().
It has an additional parameter: use_op_lock. When the parameter
is TRUE than the function destroys keycache->op_lock if cleanup is true.
Otherwise the action with the lock is omitted.
RETURN VALUE
none
*/
static
void end_key_cache_internal(KEY_CACHE *keycache, my_bool cleanup,
my_bool use_op_lock)
{
if (keycache->key_cache_inited)
{
keycache->interface_funcs->end(keycache->keycache_cb, cleanup);
if (cleanup)
{
if (keycache->keycache_cb)
{
my_free(keycache->keycache_cb);
keycache->keycache_cb= 0;
}
/*
We do not destroy op_lock if we are going to reuse the same key cache.
This happens if we are called from repartition_key_cache_internal().
*/
if (use_op_lock)
pthread_mutex_destroy(&keycache->op_lock);
keycache->key_cache_inited= 0;
}
keycache->can_be_used= 0;
}
}
@ -6030,6 +6139,8 @@ void change_key_cache_param(KEY_CACHE *keycache, uint division_limit,
auxiliary structures used by the key cache keycache. If the value
of the parameter cleanup is TRUE then all resources used by the key
cache are to be freed.
The function calls end_key_cache_internal() to perform all these actions
with the last parameter set to TRUE.
RETURN VALUE
none
@ -6037,20 +6148,7 @@ void change_key_cache_param(KEY_CACHE *keycache, uint division_limit,
void end_key_cache(KEY_CACHE *keycache, my_bool cleanup)
{
if (keycache->key_cache_inited)
{
keycache->interface_funcs->end(keycache->keycache_cb, cleanup);
if (cleanup)
{
if (keycache->keycache_cb)
{
my_free(keycache->keycache_cb);
keycache->keycache_cb= 0;
}
keycache->key_cache_inited= 0;
}
keycache->can_be_used= 0;
}
end_key_cache_internal(keycache, cleanup, 1);
}
@ -6098,7 +6196,7 @@ uchar *key_cache_read(KEY_CACHE *keycache,
uchar *buff, uint length,
uint block_length, int return_buffer)
{
if (keycache->key_cache_inited && keycache->can_be_used)
if (keycache->can_be_used)
return keycache->interface_funcs->read(keycache->keycache_cb,
file, filepos, level,
buff, length,
@ -6150,7 +6248,7 @@ int key_cache_insert(KEY_CACHE *keycache,
File file, my_off_t filepos, int level,
uchar *buff, uint length)
{
if (keycache->key_cache_inited && keycache->can_be_used)
if (keycache->can_be_used)
return keycache->interface_funcs->insert(keycache->keycache_cb,
file, filepos, level,
buff, length);
@ -6205,7 +6303,7 @@ int key_cache_write(KEY_CACHE *keycache,
uchar *buff, uint length,
uint block_length, int force_write)
{
if (keycache->key_cache_inited && keycache->can_be_used)
if (keycache->can_be_used)
return keycache->interface_funcs->write(keycache->keycache_cb,
file, file_extra,
filepos, level,
@ -6257,7 +6355,7 @@ int flush_key_blocks(KEY_CACHE *keycache,
int file, void *file_extra,
enum flush_type type)
{
if (keycache->key_cache_inited)
if (keycache->can_be_used)
return keycache->interface_funcs->flush(keycache->keycache_cb,
file, file_extra, type);
return 0;
@ -6289,13 +6387,15 @@ int reset_key_cache_counters(const char *name __attribute__((unused)),
KEY_CACHE *keycache,
void *unused __attribute__((unused)))
{
int rc= 0;
if (keycache->key_cache_inited)
{
return keycache->interface_funcs->reset_counters(name,
keycache->keycache_cb);
pthread_mutex_lock(&keycache->op_lock);
rc= keycache->interface_funcs->reset_counters(name,
keycache->keycache_cb);
pthread_mutex_unlock(&keycache->op_lock);
}
return 0;
return rc;
}
@ -6325,11 +6425,63 @@ void get_key_cache_statistics(KEY_CACHE *keycache, uint partition_no,
{
if (keycache->key_cache_inited)
{
pthread_mutex_lock(&keycache->op_lock);
keycache->interface_funcs->get_stats(keycache->keycache_cb,
partition_no, key_cache_stats);
pthread_mutex_unlock(&keycache->op_lock);
}
}
/*
Repartition a key cache : internal
SYNOPSIS
repartition_key_cache_internal()
keycache pointer to the key cache to be repartitioned
key_cache_block_size size of blocks to keep cached data
use_mem total memory to use for the new key cache
division_limit new division limit (if not zero)
age_threshold new age threshold (if not zero)
partitions new number of partitions in the key cache
use_op_lock if TRUE use keycache->op_lock, otherwise - ignore it
DESCRIPTION
The function performs the actions required from repartition_key_cache().
It has an additional parameter: use_op_lock. When the parameter
is TRUE then the function locks keycache->op_lock at start and
unlocks it before the return. Otherwise the actions with the lock
are omitted.
RETURN VALUE
number of blocks in the key cache, if successful,
0 - otherwise.
*/
static
int repartition_key_cache_internal(KEY_CACHE *keycache,
uint key_cache_block_size, size_t use_mem,
uint division_limit, uint age_threshold,
uint partitions, my_bool use_op_lock)
{
uint blocks= -1;
if (keycache->key_cache_inited)
{
if (use_op_lock)
pthread_mutex_lock(&keycache->op_lock);
keycache->interface_funcs->resize(keycache->keycache_cb,
key_cache_block_size, 0,
division_limit, age_threshold);
end_key_cache_internal(keycache, 1, 0);
blocks= init_key_cache_internal(keycache, key_cache_block_size, use_mem,
division_limit, age_threshold, partitions,
0);
if (use_op_lock)
pthread_mutex_unlock(&keycache->op_lock);
}
return blocks;
}
/*
Repartition a key cache
@ -6353,16 +6505,14 @@ void get_key_cache_statistics(KEY_CACHE *keycache, uint partition_no,
that are used for midpoint insertion strategy. The parameter use_mem
specifies the total amount of memory to be allocated for the new key
cache buffers and for all auxiliary structures.
The function calls repartition_key_cache_internal() to perform all these
actions with the last parameter set to TRUE.
RETURN VALUE
number of blocks in the key cache, if successful,
0 - otherwise.
NOTES
The function does not block the calls and executions of other functions
from the key cache interface. However it assumes that the calls of
resize_key_cache itself are serialized.
Currently the function is called when the value of the variable
key_cache_partitions is being reset for the key cache keycache.
*/
@ -6371,16 +6521,8 @@ int repartition_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
size_t use_mem, uint division_limit,
uint age_threshold, uint partitions)
{
uint blocks= -1;
if (keycache->key_cache_inited)
{
keycache->interface_funcs->resize(keycache->keycache_cb,
key_cache_block_size, 0,
division_limit, age_threshold);
end_key_cache(keycache, 1);
blocks= init_key_cache(keycache, key_cache_block_size, use_mem,
division_limit, age_threshold, partitions);
}
return blocks;
return repartition_key_cache_internal(keycache, key_cache_block_size, use_mem,
division_limit, age_threshold,
partitions, 1);
}

View File

@ -1504,6 +1504,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
}
if (args[1]->maybe_null)
maybe_null=1;
with_subselect= 1;
with_sum_func= with_sum_func || args[1]->with_sum_func;
with_field= with_field || args[1]->with_field;
used_tables_cache|= args[1]->used_tables();
@ -4256,6 +4257,22 @@ Item_cond::fix_fields(THD *thd, Item **ref)
if (abort_on_null)
item->top_level_item();
/*
replace degraded condition:
was: <field>
become: <field> = 1
*/
if (item->type() == FIELD_ITEM)
{
Query_arena backup, *arena;
Item *new_item;
arena= thd->activate_stmt_arena_if_needed(&backup);
if ((new_item= new Item_func_ne(item, new Item_int(0, 1))))
li.replace(item= new_item);
if (arena)
thd->restore_active_arena(arena, &backup);
}
// item can be substituted in fix_fields
if ((!item->fixed &&
item->fix_fields(thd, li.ref())) ||
@ -4940,6 +4957,7 @@ Item_func_regex::fix_fields(THD *thd, Item **ref)
return TRUE; /* purecov: inspected */
with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func;
with_field= args[0]->with_field || args[1]->with_field;
with_subselect|= args[0]->with_subselect | args[1]->with_subselect;
max_length= 1;
decimals= 0;
@ -5309,6 +5327,28 @@ Item *Item_func_not::neg_transformer(THD *thd) /* NOT(x) -> x */
}
bool Item_func_not::fix_fields(THD *thd, Item **ref)
{
if (args[0]->type() == FIELD_ITEM)
{
/* replace "NOT <field>" with "<filed> == 0" */
Query_arena backup, *arena;
Item *new_item;
bool rc= TRUE;
arena= thd->activate_stmt_arena_if_needed(&backup);
if ((new_item= new Item_func_eq(args[0], new Item_int(0, 1))))
{
new_item->name= name;
rc= (*ref= new_item)->fix_fields(thd, ref);
}
if (arena)
thd->restore_active_arena(arena, &backup);
return rc;
}
return Item_func::fix_fields(thd, ref);
}
Item *Item_bool_rowready_func2::neg_transformer(THD *thd)
{
Item *item= negated_item();
@ -5739,6 +5779,7 @@ bool Item_equal::fix_fields(THD *thd, Item **ref)
used_tables_cache|= item->used_tables();
tmp_table_map= item->not_null_tables();
not_null_tables_cache|= tmp_table_map;
DBUG_ASSERT(!item->with_sum_func && !item->with_subselect);
if (item->maybe_null)
maybe_null= 1;
if (!item->get_item_equal())

View File

@ -442,6 +442,7 @@ public:
enum Functype functype() const { return NOT_FUNC; }
const char *func_name() const { return "not"; }
Item *neg_transformer(THD *thd);
bool fix_fields(THD *, Item **);
virtual void print(String *str, enum_query_type query_type);
};
@ -508,6 +509,8 @@ public:
longlong val_int();
enum Functype functype() const { return NOT_ALL_FUNC; }
const char *func_name() const { return "<not>"; }
bool fix_fields(THD *thd, Item **ref)
{return Item_func::fix_fields(thd, ref);}
virtual void print(String *str, enum_query_type query_type);
void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };

View File

@ -3338,6 +3338,7 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
func->maybe_null=1;
func->with_sum_func= func->with_sum_func || item->with_sum_func;
func->with_field= func->with_field || item->with_field;
func->with_subselect|= item->with_subselect;
used_tables_cache|=item->used_tables();
const_item_cache&=item->const_item();
f_args.arg_type[i]=item->result_type();

View File

@ -95,6 +95,7 @@ bool Item_row::fix_fields(THD *thd, Item **ref)
maybe_null|= item->maybe_null;
with_sum_func= with_sum_func || item->with_sum_func;
with_field= with_field || item->with_field;
with_subselect|= item->with_subselect;
}
fixed= 1;
return FALSE;

View File

@ -1135,6 +1135,7 @@ Item_sum_num::fix_fields(THD *thd, Item **ref)
if (args[i]->fix_fields(thd, args + i) || args[i]->check_cols(1))
return TRUE;
set_if_bigger(decimals, args[i]->decimals);
with_subselect|= args[i]->with_subselect;
}
result_field=0;
max_length=float_length(decimals);
@ -1165,6 +1166,7 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
(item= args[0])->check_cols(1))
return TRUE;
decimals=item->decimals;
with_subselect= args[0]->with_subselect;
switch (hybrid_type= item->result_type()) {
case INT_RESULT:
@ -3319,6 +3321,7 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref)
args[i]->fix_fields(thd, args + i)) ||
args[i]->check_cols(1))
return TRUE;
with_subselect|= args[i]->with_subselect;
}
/* skip charset aggregation for order columns */

View File

@ -3525,7 +3525,8 @@ public:
if (copy_field) /* Fix for Intel compiler */
{
delete [] copy_field;
save_copy_field= copy_field= 0;
save_copy_field= copy_field= NULL;
save_copy_field_end= copy_field_end= NULL;
}
}
};

View File

@ -20296,6 +20296,8 @@ copy_fields(TMP_TABLE_PARAM *param)
Copy_field *ptr=param->copy_field;
Copy_field *end=param->copy_field_end;
DBUG_ASSERT((ptr != NULL && end >= ptr) || (ptr == NULL && end == NULL));
for (; ptr != end; ptr++)
(*ptr->do_copy)(ptr);