Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-5.0
into sanja.is.com.ua:/home/bell/mysql/bk/work-repl-5.0 sql/item.cc: Auto merged sql/item_func.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_select.cc: Auto merged
This commit is contained in:
commit
592ee68568
@ -2379,6 +2379,8 @@ void usage()
|
||||
|
||||
#include <help_end.h>
|
||||
|
||||
#include <help_end.h>
|
||||
|
||||
|
||||
static my_bool
|
||||
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||
|
@ -1809,6 +1809,18 @@ static my_bool my_realloc_str(NET *net, ulong length)
|
||||
}
|
||||
|
||||
|
||||
/* Clear possible error statee of struct NET */
|
||||
|
||||
static void net_clear_error(NET *net)
|
||||
{
|
||||
if (net->last_errno)
|
||||
{
|
||||
net->last_errno= 0;
|
||||
net->last_error[0]= '\0';
|
||||
strmov(net->sqlstate, not_error_sqlstate);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Set statement error code, sqlstate, and error message
|
||||
from given errcode and sqlstate.
|
||||
@ -2499,6 +2511,11 @@ int cli_stmt_execute(MYSQL_STMT *stmt)
|
||||
set_stmt_error(stmt, CR_PARAMS_NOT_BOUND, unknown_sqlstate);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (stmt->mysql->status != MYSQL_STATUS_READY)
|
||||
{
|
||||
set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
net_clear(net); /* Sets net->write_pos */
|
||||
/* Reserve place for null-marker bytes */
|
||||
@ -4858,6 +4875,11 @@ my_bool STDCALL mysql_stmt_close(MYSQL_STMT *stmt)
|
||||
if (mysql)
|
||||
{
|
||||
mysql->stmts= list_delete(mysql->stmts, &stmt->list);
|
||||
/*
|
||||
Clear NET error state: if the following commands come through
|
||||
successfully, connection will still be usable for other commands.
|
||||
*/
|
||||
net_clear_error(&mysql->net);
|
||||
if ((int) stmt->state > (int) MYSQL_STMT_INIT_DONE)
|
||||
{
|
||||
char buff[MYSQL_STMT_HEADER]; /* 4 bytes - stmt id */
|
||||
|
@ -194,8 +194,8 @@ MY_LOG_DIR="$MYSQL_TEST_DIR/var/log"
|
||||
#
|
||||
# Set LD_LIBRARY_PATH if we are using shared libraries
|
||||
#
|
||||
LD_LIBRARY_PATH="$BASEDIR/lib:$BASEDIR/libmysql/.libs:$LD_LIBRARY_PATH"
|
||||
DYLD_LIBRARY_PATH="$BASEDIR/lib:$BASEDIR/libmysql/.libs:$DYLD_LIBRARY_PATH"
|
||||
LD_LIBRARY_PATH="$BASEDIR/lib:$BASEDIR/libmysql/.libs:$BASEDIR/zlib/.libs:$LD_LIBRARY_PATH"
|
||||
DYLD_LIBRARY_PATH="$BASEDIR/lib:$BASEDIR/libmysql/.libs:$BASEDIR/zlib/.libs:$DYLD_LIBRARY_PATH"
|
||||
export LD_LIBRARY_PATH DYLD_LIBRARY_PATH
|
||||
|
||||
#
|
||||
@ -692,6 +692,7 @@ then
|
||||
fi
|
||||
|
||||
MYSQL_CLIENT_TEST="$MYSQL_CLIENT_TEST --no-defaults --testcase --user=root --socket=$MASTER_MYSOCK --port=$MYSQL_TCP_PORT --silent"
|
||||
MYSQL_DUMP="$MYSQL_DUMP --no-defaults -uroot --socket=$MASTER_MYSOCK --password=$DBPASSWD $EXTRA_MYSQLDUMP_OPT"
|
||||
MYSQL_BINLOG="$MYSQL_BINLOG --no-defaults --local-load=$MYSQL_TMP_DIR --character-sets-dir=$CHARSETSDIR $EXTRA_MYSQLBINLOG_OPT"
|
||||
MYSQL_FIX_SYSTEM_TABLES="$MYSQL_FIX_SYSTEM_TABLES --no-defaults --host=localhost --port=$MASTER_MYPORT --socket=$MASTER_MYSOCK --user=root --password=$DBPASSWD --basedir=$BASEDIR --bindir=$CLIENT_BINDIR --verbose"
|
||||
MYSQL="$MYSQL --host=localhost --port=$MASTER_MYPORT --socket=$MASTER_MYSOCK --user=root --password=$DBPASSWD"
|
||||
@ -1151,8 +1152,7 @@ start_master()
|
||||
fi
|
||||
if [ -n "$EXTRA_MASTER_MYSQLD_TRACE" ]
|
||||
then
|
||||
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT \
|
||||
$EXTRA_MASTER_MYSQLD_TRACE$1"
|
||||
CURR_MASTER_MYSQLD_TRACE="$EXTRA_MASTER_MYSQLD_TRACE$1"
|
||||
fi
|
||||
if [ -z "$DO_BENCH" ]
|
||||
then
|
||||
@ -1177,7 +1177,7 @@ start_master()
|
||||
$MASTER_40_ARGS \
|
||||
$SMALL_SERVER \
|
||||
$EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT \
|
||||
$NOT_FIRST_MASTER_EXTRA_OPTS"
|
||||
$NOT_FIRST_MASTER_EXTRA_OPTS $CURR_MASTER_MYSQLD_TRACE"
|
||||
else
|
||||
master_args="--no-defaults --log-bin=$MYSQL_TEST_DIR/var/log/master-bin$1 \
|
||||
--server-id=$id --rpl-recovery-rank=1 \
|
||||
|
@ -655,9 +655,9 @@ insert into t1 (a,b) values (1,2),(1,3),(2,5);
|
||||
select a, 0.1*0+1 r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2=1;
|
||||
a r2 r1
|
||||
1 1.0 2
|
||||
select a, rand()*0+1 r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2=1;
|
||||
select a, round(rand(100)*10) r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2<=2;
|
||||
a r2 r1
|
||||
1 1 2
|
||||
1 2 2
|
||||
select a,sum(b) from t1 where a=1 group by c;
|
||||
a sum(b)
|
||||
1 5
|
||||
|
@ -355,3 +355,13 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t3 ref a a 44 const,const 6 Using where
|
||||
1 SIMPLE t1 ref heap_idx heap_idx 22 const 7 Using where
|
||||
drop table t1, t2, t3;
|
||||
create temporary table t1 ( a int, index (a) ) engine=memory;
|
||||
insert into t1 values (1),(2),(3),(4),(5);
|
||||
select a from t1 where a in (1,3);
|
||||
a
|
||||
1
|
||||
3
|
||||
explain select a from t1 where a in (1,3);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range a a 5 NULL 2 Using where
|
||||
drop table t1;
|
||||
|
@ -2666,7 +2666,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c5' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c6' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c7' at row 1
|
||||
Note 1265 Data truncated for column 'c12' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c12' at row 1
|
||||
execute my_select ;
|
||||
c1 127
|
||||
@ -2717,7 +2716,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c5' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c6' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c7' at row 1
|
||||
Note 1265 Data truncated for column 'c12' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c12' at row 1
|
||||
execute my_select ;
|
||||
c1 -128
|
||||
|
@ -2649,7 +2649,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c5' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c6' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c7' at row 1
|
||||
Note 1265 Data truncated for column 'c12' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c12' at row 1
|
||||
execute my_select ;
|
||||
c1 127
|
||||
@ -2700,7 +2699,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c5' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c6' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c7' at row 1
|
||||
Note 1265 Data truncated for column 'c12' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c12' at row 1
|
||||
execute my_select ;
|
||||
c1 -128
|
||||
|
@ -2650,7 +2650,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c5' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c6' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c7' at row 1
|
||||
Note 1265 Data truncated for column 'c12' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c12' at row 1
|
||||
execute my_select ;
|
||||
c1 127
|
||||
@ -2701,7 +2700,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c5' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c6' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c7' at row 1
|
||||
Note 1265 Data truncated for column 'c12' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c12' at row 1
|
||||
execute my_select ;
|
||||
c1 -128
|
||||
|
@ -2586,7 +2586,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c5' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c6' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c7' at row 1
|
||||
Note 1265 Data truncated for column 'c12' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c12' at row 1
|
||||
execute my_select ;
|
||||
c1 127
|
||||
@ -2637,7 +2636,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c5' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c6' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c7' at row 1
|
||||
Note 1265 Data truncated for column 'c12' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c12' at row 1
|
||||
execute my_select ;
|
||||
c1 -128
|
||||
@ -5597,7 +5595,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c5' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c6' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c7' at row 1
|
||||
Note 1265 Data truncated for column 'c12' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c12' at row 1
|
||||
execute my_select ;
|
||||
c1 127
|
||||
@ -5648,7 +5645,6 @@ Warning 1264 Out of range value adjusted for column 'c4' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c5' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c6' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c7' at row 1
|
||||
Note 1265 Data truncated for column 'c12' at row 1
|
||||
Warning 1264 Out of range value adjusted for column 'c12' at row 1
|
||||
execute my_select ;
|
||||
c1 -128
|
||||
|
@ -1433,7 +1433,7 @@ Note 1003 (select `test`.`t1`.`s1` AS `s1` from `test`.`t1`)
|
||||
s1
|
||||
tttt
|
||||
drop table t1;
|
||||
create table t1 (s1 char(5) not null, index s1(s1));
|
||||
create table t1 (s1 char(5), index s1(s1));
|
||||
create table t2 (s1 char(5), index s1(s1));
|
||||
insert into t1 values ('a1'),('a2'),('a3');
|
||||
insert into t2 values ('a1'),('a2');
|
||||
@ -1459,25 +1459,25 @@ a2 1
|
||||
a3 1
|
||||
explain extended select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 index NULL s1 5 NULL 3 Using index
|
||||
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
|
||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`s1` AS `s1`,not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL)))) AS `s1 NOT IN (SELECT s1 FROM t2)` from `test`.`t1`
|
||||
explain extended select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 index NULL s1 5 NULL 3 Using index
|
||||
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
|
||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`s1` AS `s1`,<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL))) AS `s1 = ANY (SELECT s1 FROM t2)` from `test`.`t1`
|
||||
explain extended select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 index NULL s1 5 NULL 3 Using index
|
||||
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
|
||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`s1` AS `s1`,not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL)))) AS `s1 <> ALL (SELECT s1 FROM t2)` from `test`.`t1`
|
||||
explain extended select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 index NULL s1 5 NULL 3 Using index
|
||||
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
|
||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 1 Using index; Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`s1` AS `s1`,not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where (`test`.`t2`.`s1` < _latin1'a2'))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1`
|
||||
@ -2133,34 +2133,6 @@ SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1
|
||||
c
|
||||
Oceania
|
||||
drop table t1;
|
||||
CREATE TABLE t1 ( f1 BIGINT );
|
||||
INSERT INTO t1 SET f1= NULL;
|
||||
INSERT INTO t1 SET f1= 1;
|
||||
CREATE TABLE t2 ( f1 BIGINT );
|
||||
SELECT f1 FROM t1
|
||||
WHERE f1 <> ALL ( SELECT f1 FROM t2 );
|
||||
f1
|
||||
NULL
|
||||
1
|
||||
INSERT INTO t2 VALUES (1), (2);
|
||||
SELECT f1 FROM t1
|
||||
WHERE f1 <> ALL ( SELECT f1 FROM t2 WHERE f1 > 2 );
|
||||
f1
|
||||
NULL
|
||||
1
|
||||
SELECT f1 FROM t1
|
||||
WHERE f1 <> ALL ( SELECT f1 FROM t2 WHERE f1 > 2
|
||||
UNION
|
||||
SELECT f1 FROM t2 WHERE f1 > 3);
|
||||
f1
|
||||
NULL
|
||||
1
|
||||
SELECT f1 FROM t1
|
||||
WHERE f1 <> ALL ( SELECT SUM(f1) AS sf1 FROM t2 HAVING sf1 > 10000);
|
||||
f1
|
||||
NULL
|
||||
1
|
||||
drop table t1,t2;
|
||||
create table t1 (a1 int);
|
||||
create table t2 (b1 int);
|
||||
select * from t1 where a2 > any(select b1 from t2);
|
||||
|
@ -113,8 +113,8 @@ select @a:=0;
|
||||
select @a, @a:=@a+count(*), count(*), @a from t1 group by i;
|
||||
@a @a:=@a+count(*) count(*) @a
|
||||
0 1 1 0
|
||||
0 3 2 0
|
||||
0 6 3 0
|
||||
0 2 2 0
|
||||
0 3 3 0
|
||||
select @a:=0;
|
||||
@a:=0
|
||||
0
|
||||
|
@ -480,7 +480,8 @@ drop table t1;
|
||||
create table t1 (a integer, b integer, c integer);
|
||||
insert into t1 (a,b) values (1,2),(1,3),(2,5);
|
||||
select a, 0.1*0+1 r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2=1;
|
||||
select a, rand()*0+1 r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2=1;
|
||||
# rand(100)*10 will be < 2 only for the first row (of 6)
|
||||
select a, round(rand(100)*10) r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2<=2;
|
||||
select a,sum(b) from t1 where a=1 group by c;
|
||||
select a*sum(b) from t1 where a=1 group by c;
|
||||
select sum(a)*sum(b) from t1 where a=1 group by c;
|
||||
|
@ -251,3 +251,9 @@ explain select * from t1 ignore key(btree_idx), t3 where t1.name='matt' and t3.a
|
||||
|
||||
drop table t1, t2, t3;
|
||||
|
||||
# Fix for BUG#8371: wrong rec_per_key value for hash index on temporary table
|
||||
create temporary table t1 ( a int, index (a) ) engine=memory;
|
||||
insert into t1 values (1),(2),(3),(4),(5);
|
||||
select a from t1 where a in (1,3);
|
||||
explain select a from t1 where a in (1,3);
|
||||
drop table t1;
|
||||
|
@ -894,7 +894,7 @@ drop table t1;
|
||||
#
|
||||
# IN optimisation test results
|
||||
#
|
||||
create table t1 (s1 char(5) not null, index s1(s1));
|
||||
create table t1 (s1 char(5), index s1(s1));
|
||||
create table t2 (s1 char(5), index s1(s1));
|
||||
insert into t1 values ('a1'),('a2'),('a3');
|
||||
insert into t2 values ('a1'),('a2');
|
||||
@ -1392,34 +1392,6 @@ INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','M
|
||||
SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200);
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test cases for bug #7351:
|
||||
# quantified predicate with subquery returning empty result set
|
||||
#
|
||||
|
||||
CREATE TABLE t1 ( f1 BIGINT );
|
||||
INSERT INTO t1 SET f1= NULL;
|
||||
INSERT INTO t1 SET f1= 1;
|
||||
CREATE TABLE t2 ( f1 BIGINT );
|
||||
|
||||
SELECT f1 FROM t1
|
||||
WHERE f1 <> ALL ( SELECT f1 FROM t2 );
|
||||
|
||||
INSERT INTO t2 VALUES (1), (2);
|
||||
|
||||
SELECT f1 FROM t1
|
||||
WHERE f1 <> ALL ( SELECT f1 FROM t2 WHERE f1 > 2 );
|
||||
|
||||
SELECT f1 FROM t1
|
||||
WHERE f1 <> ALL ( SELECT f1 FROM t2 WHERE f1 > 2
|
||||
UNION
|
||||
SELECT f1 FROM t2 WHERE f1 > 3);
|
||||
|
||||
SELECT f1 FROM t1
|
||||
WHERE f1 <> ALL ( SELECT SUM(f1) AS sf1 FROM t2 HAVING sf1 > 10000);
|
||||
|
||||
drop table t1,t2;
|
||||
|
||||
#
|
||||
# Test for BUG#7885: Server crash when 'any' subselect compared to
|
||||
# non-existant field.
|
||||
|
@ -45,7 +45,7 @@ int my_rename(const char *from, const char *to, myf MyFlags)
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_RENAME)
|
||||
#ifdef __WIN__
|
||||
#if defined(__WIN__) || defined(__NETWARE__)
|
||||
/*
|
||||
On windows we can't rename over an existing file:
|
||||
Remove any conflicting files:
|
||||
|
@ -85,7 +85,7 @@ FastScheduler::activateSendPacked()
|
||||
void
|
||||
FastScheduler::doJob()
|
||||
{
|
||||
Uint32 init_loopCount = 0;
|
||||
Uint32 loopCount = 0;
|
||||
Uint32 TminLoops = getBOccupancy() + EXTRA_SIGNALS_PER_DO_JOB;
|
||||
Uint32 TloopMax = (Uint32)globalData.loopMax;
|
||||
if (TminLoops < TloopMax) {
|
||||
@ -94,10 +94,9 @@ FastScheduler::doJob()
|
||||
if (TloopMax < MIN_NUMBER_OF_SIG_PER_DO_JOB) {
|
||||
TloopMax = MIN_NUMBER_OF_SIG_PER_DO_JOB;
|
||||
}//if
|
||||
register Signal* signal = getVMSignals();
|
||||
register Uint32 tHighPrio= globalData.highestAvailablePrio;
|
||||
do{
|
||||
Uint32 loopCount = init_loopCount;
|
||||
register Uint32 tHighPrio = globalData.highestAvailablePrio;
|
||||
register Signal* signal = getVMSignals();
|
||||
while ((tHighPrio < LEVEL_IDLE) && (loopCount < TloopMax)) {
|
||||
// signal->garbage_register();
|
||||
// To ensure we find bugs quickly
|
||||
@ -155,24 +154,27 @@ FastScheduler::doJob()
|
||||
}//if
|
||||
loopCount++;
|
||||
}//while
|
||||
if (globalData.sendPackedActivated == 1) {
|
||||
Uint32 t1 = theDoJobTotalCounter;
|
||||
Uint32 t2 = theDoJobCallCounter;
|
||||
t1 += (loopCount - init_loopCount);
|
||||
t2++;
|
||||
theDoJobTotalCounter = t1;
|
||||
theDoJobCallCounter = t2;
|
||||
if (t2 == 8192) {
|
||||
reportDoJobStatistics(t1 >> 13);
|
||||
theDoJobCallCounter = 0;
|
||||
theDoJobTotalCounter = 0;
|
||||
}//if
|
||||
}//if
|
||||
init_loopCount = loopCount;
|
||||
sendPacked();
|
||||
tHighPrio = globalData.highestAvailablePrio;
|
||||
if(getBOccupancy() > MAX_OCCUPANCY)
|
||||
{
|
||||
if(loopCount != TloopMax)
|
||||
abort();
|
||||
assert( loopCount == TloopMax );
|
||||
TloopMax += 512;
|
||||
}
|
||||
} while ((getBOccupancy() > MAX_OCCUPANCY) ||
|
||||
((init_loopCount < TloopMax) &&
|
||||
(globalData.highestAvailablePrio < LEVEL_IDLE)));
|
||||
((loopCount < TloopMax) &&
|
||||
(tHighPrio < LEVEL_IDLE)));
|
||||
|
||||
theDoJobCallCounter ++;
|
||||
theDoJobTotalCounter += loopCount;
|
||||
if (theDoJobCallCounter == 8192) {
|
||||
reportDoJobStatistics(theDoJobTotalCounter >> 13);
|
||||
theDoJobCallCounter = 0;
|
||||
theDoJobTotalCounter = 0;
|
||||
}//if
|
||||
|
||||
}//FastScheduler::doJob()
|
||||
|
||||
void FastScheduler::sendPacked()
|
||||
|
@ -192,7 +192,7 @@ void install_db(char *datadir)
|
||||
char error[PATH_MAX];
|
||||
|
||||
// input file
|
||||
snprintf(input, PATH_MAX, "%s/bin/init_db.sql", base_dir);
|
||||
snprintf(input, PATH_MAX, "%s/bin/test_db.sql", base_dir);
|
||||
snprintf(output, PATH_MAX, "%s/install.out", datadir);
|
||||
snprintf(error, PATH_MAX, "%s/install.err", datadir);
|
||||
|
||||
@ -1160,7 +1160,8 @@ void setup(char *file)
|
||||
setenv("MASTER_MYPORT", "9306", 1);
|
||||
setenv("SLAVE_MYPORT", "9307", 1);
|
||||
setenv("MYSQL_TCP_PORT", "3306", 1);
|
||||
|
||||
snprintf(file_path, PATH_MAX*2, "%s/mysql_client_test --no-defaults --testcase--user=root --port=%u ", bin_dir, master_port);
|
||||
setenv("MYSQL_CLIENT_TEST",file_path,1);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
86
sql/field.cc
86
sql/field.cc
@ -149,7 +149,7 @@ bool Field::check_int(const char *str, int length, const char *int_end,
|
||||
truncation.
|
||||
|
||||
SYNOPSIS
|
||||
Field::check_overflow()
|
||||
Field::warn_if_overflow()
|
||||
op_result decimal library return code (E_DEC_* see include/decimal.h)
|
||||
|
||||
RETURN
|
||||
@ -157,19 +157,22 @@ bool Field::check_int(const char *str, int length, const char *int_end,
|
||||
0 no error or some other errors except overflow
|
||||
*/
|
||||
|
||||
int Field::check_overflow(int op_result)
|
||||
int Field::warn_if_overflow(int op_result)
|
||||
{
|
||||
if (op_result == E_DEC_OVERFLOW)
|
||||
{
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
return 1;
|
||||
}
|
||||
else if (op_result == E_DEC_TRUNCATED)
|
||||
if (op_result == E_DEC_TRUNCATED)
|
||||
{
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
|
||||
/* we return 1 only in case of EFL */
|
||||
/* We return 0 here as this is not a critical issue */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef NOT_USED
|
||||
static bool test_if_real(const char *str,int length, CHARSET_INFO *cs)
|
||||
{
|
||||
@ -507,7 +510,7 @@ longlong Field::convert_decimal2longlong(const my_decimal *val,
|
||||
i= 0;
|
||||
*err= 1;
|
||||
}
|
||||
else if (check_overflow(my_decimal2int(E_DEC_ERROR &
|
||||
else if (warn_if_overflow(my_decimal2int(E_DEC_ERROR &
|
||||
~E_DEC_OVERFLOW & ~E_DEC_TRUNCATED,
|
||||
val, TRUE, &i)))
|
||||
{
|
||||
@ -515,7 +518,7 @@ longlong Field::convert_decimal2longlong(const my_decimal *val,
|
||||
*err= 1;
|
||||
}
|
||||
}
|
||||
else if (check_overflow(my_decimal2int(E_DEC_ERROR &
|
||||
else if (warn_if_overflow(my_decimal2int(E_DEC_ERROR &
|
||||
~E_DEC_OVERFLOW & ~E_DEC_TRUNCATED,
|
||||
val, FALSE, &i)))
|
||||
{
|
||||
@ -616,7 +619,7 @@ int Field_str::store_decimal(const my_decimal *d)
|
||||
{
|
||||
double val;
|
||||
/* TODO: use decimal2string? */
|
||||
int err= check_overflow(my_decimal2double(E_DEC_FATAL_ERROR &
|
||||
int err= warn_if_overflow(my_decimal2double(E_DEC_FATAL_ERROR &
|
||||
~E_DEC_OVERFLOW, d, &val));
|
||||
return err | store(val);
|
||||
}
|
||||
@ -1552,12 +1555,17 @@ void Field_new_decimal::set_value_on_overflow(my_decimal *decimal_value,
|
||||
checks if decimal_value fits into field size.
|
||||
if it does, stores the decimal in the buffer using binary format.
|
||||
Otherwise sets maximal number that can be stored in the field.
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
1 error
|
||||
*/
|
||||
|
||||
bool Field_new_decimal::store_value(const my_decimal *decimal_value)
|
||||
{
|
||||
DBUG_ENTER("Field_new_decimal::store_value");
|
||||
my_decimal *dec= (my_decimal*)decimal_value;
|
||||
int error= 0;
|
||||
DBUG_ENTER("Field_new_decimal::store_value");
|
||||
DBUG_EXECUTE("enter", print_decimal(dec););
|
||||
|
||||
/* check that we do not try to write negative value in unsigned field */
|
||||
@ -1565,16 +1573,18 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value)
|
||||
{
|
||||
DBUG_PRINT("info", ("unsigned overflow"));
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||
error= 1;
|
||||
dec= &decimal_zero;
|
||||
}
|
||||
DBUG_PRINT("info", ("saving with precision %d, scale: %d",
|
||||
(int)field_length, (int)decimals()));
|
||||
DBUG_EXECUTE("info", print_decimal(dec););
|
||||
|
||||
if (check_overflow(my_decimal2binary(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
|
||||
dec, ptr,
|
||||
field_length,
|
||||
decimals())))
|
||||
if (warn_if_overflow(my_decimal2binary(E_DEC_FATAL_ERROR &
|
||||
~E_DEC_OVERFLOW,
|
||||
dec, ptr,
|
||||
field_length,
|
||||
decimals())))
|
||||
{
|
||||
my_decimal buff;
|
||||
DBUG_PRINT("info", ("overflow"));
|
||||
@ -1584,20 +1594,20 @@ bool Field_new_decimal::store_value(const my_decimal *decimal_value)
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
DBUG_EXECUTE("info", print_decimal_buff(dec, ptr, bin_size););
|
||||
DBUG_RETURN(0);
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
int Field_new_decimal::store(const char *from, uint length,
|
||||
CHARSET_INFO *charset)
|
||||
{
|
||||
DBUG_ENTER("Field_new_decimal::store(char*)");
|
||||
int err;
|
||||
my_decimal decimal_value;
|
||||
DBUG_ENTER("Field_new_decimal::store(char*)");
|
||||
|
||||
switch ((err= str2my_decimal(E_DEC_FATAL_ERROR &
|
||||
~(E_DEC_OVERFLOW | E_DEC_BAD_NUM),
|
||||
from, length, charset, &decimal_value)))
|
||||
{
|
||||
from, length, charset, &decimal_value))) {
|
||||
case E_DEC_TRUNCATED:
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
|
||||
break;
|
||||
@ -1624,9 +1634,11 @@ int Field_new_decimal::store(const char *from, uint length,
|
||||
int Field_new_decimal::store(double nr)
|
||||
{
|
||||
my_decimal decimal_value;
|
||||
int err= double2my_decimal(E_DEC_FATAL_ERROR &
|
||||
~E_DEC_OVERFLOW, nr,
|
||||
&decimal_value);
|
||||
int err;
|
||||
DBUG_ENTER("Field_new_decimal::store(double)");
|
||||
|
||||
err= double2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW, nr,
|
||||
&decimal_value);
|
||||
/*
|
||||
TODO: fix following when double2my_decimal when double2decimal
|
||||
will return E_DEC_TRUNCATED always correctly
|
||||
@ -1638,10 +1650,18 @@ int Field_new_decimal::store(double nr)
|
||||
if (nr2 != nr)
|
||||
err= E_DEC_TRUNCATED;
|
||||
}
|
||||
if (check_overflow(err))
|
||||
set_value_on_overflow(&decimal_value, decimal_value.sign());
|
||||
store_value(&decimal_value);
|
||||
return err;
|
||||
if (err)
|
||||
{
|
||||
if (check_overflow(err))
|
||||
set_value_on_overflow(&decimal_value, decimal_value.sign());
|
||||
/* Only issue a warning if store_value doesn't issue an warning */
|
||||
table->in_use->got_warning= 0;
|
||||
}
|
||||
if (store_value(&decimal_value))
|
||||
err= 1;
|
||||
else if (err && !table->in_use->got_warning)
|
||||
err= warn_if_overflow(err);
|
||||
DBUG_RETURN(err);
|
||||
}
|
||||
|
||||
|
||||
@ -1649,10 +1669,19 @@ int Field_new_decimal::store(longlong nr)
|
||||
{
|
||||
my_decimal decimal_value;
|
||||
int err;
|
||||
if ((err= check_overflow(int2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
|
||||
nr, unsigned_flag, &decimal_value))))
|
||||
set_value_on_overflow(&decimal_value, decimal_value.sign());
|
||||
store_value(&decimal_value);
|
||||
|
||||
if ((err= int2my_decimal(E_DEC_FATAL_ERROR & ~E_DEC_OVERFLOW,
|
||||
nr, unsigned_flag, &decimal_value)))
|
||||
{
|
||||
if (check_overflow(err))
|
||||
set_value_on_overflow(&decimal_value, decimal_value.sign());
|
||||
/* Only issue a warning if store_value doesn't issue an warning */
|
||||
table->in_use->got_warning= 0;
|
||||
}
|
||||
if (store_value(&decimal_value))
|
||||
err= 1;
|
||||
else if (err && !table->in_use->got_warning)
|
||||
err= warn_if_overflow(err);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -1694,7 +1723,7 @@ my_decimal* Field_new_decimal::val_decimal(my_decimal *decimal_value)
|
||||
|
||||
|
||||
String *Field_new_decimal::val_str(String *val_buffer,
|
||||
String *val_ptr __attribute__((unused)))
|
||||
String *val_ptr __attribute__((unused)))
|
||||
{
|
||||
my_decimal decimal_value;
|
||||
int fixed_precision= (zerofill ?
|
||||
@ -1728,6 +1757,7 @@ void Field_new_decimal::sql_type(String &str) const
|
||||
add_zerofill_and_unsigned(str);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** tiny int
|
||||
****************************************************************************/
|
||||
|
@ -290,7 +290,11 @@ public:
|
||||
int cuted_increment);
|
||||
void set_datetime_warning(const uint level, const uint code,
|
||||
double nr, timestamp_type ts_type);
|
||||
int check_overflow(int op_result);
|
||||
inline bool check_overflow(int op_result)
|
||||
{
|
||||
return (op_result == E_DEC_OVERFLOW);
|
||||
}
|
||||
int warn_if_overflow(int op_result);
|
||||
virtual field_cast_enum field_cast_type()= 0;
|
||||
bool field_cast_compatible(field_cast_enum type);
|
||||
/* maximum possible display length */
|
||||
|
@ -60,8 +60,7 @@ int ha_heap::open(const char *name, int mode, uint test_if_locked)
|
||||
{
|
||||
/* Initialize variables for the opened table */
|
||||
set_keys_for_scanning();
|
||||
if (table->s->tmp_table == NO_TMP_TABLE)
|
||||
update_key_stats();
|
||||
update_key_stats();
|
||||
}
|
||||
return (file ? 0 : 1);
|
||||
}
|
||||
@ -104,6 +103,8 @@ void ha_heap::update_key_stats()
|
||||
for (uint i= 0; i < table->s->keys; i++)
|
||||
{
|
||||
KEY *key=table->key_info+i;
|
||||
if (!key->rec_per_key)
|
||||
continue;
|
||||
if (key->algorithm != HA_KEY_ALG_BTREE)
|
||||
{
|
||||
ha_rows hash_buckets= file->s->keydef[i].hash_buckets;
|
||||
@ -124,8 +125,8 @@ int ha_heap::write_row(byte * buf)
|
||||
if (table->next_number_field && buf == table->record[0])
|
||||
update_auto_increment();
|
||||
res= heap_write(file,buf);
|
||||
if (!res && table->s->tmp_table == NO_TMP_TABLE &&
|
||||
++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
|
||||
if (!res && (++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
|
||||
file->s->records))
|
||||
update_key_stats();
|
||||
return res;
|
||||
}
|
||||
@ -137,8 +138,8 @@ int ha_heap::update_row(const byte * old_data, byte * new_data)
|
||||
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
|
||||
table->timestamp_field->set_time();
|
||||
res= heap_update(file,old_data,new_data);
|
||||
if (!res && table->s->tmp_table == NO_TMP_TABLE &&
|
||||
++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
|
||||
if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
|
||||
file->s->records)
|
||||
update_key_stats();
|
||||
return res;
|
||||
}
|
||||
|
52
sql/item.cc
52
sql/item.cc
@ -542,6 +542,58 @@ void Item_splocal::print(String *str)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Move SUM items out from item tree and replace with reference
|
||||
|
||||
SYNOPSIS
|
||||
split_sum_func2()
|
||||
thd Thread handler
|
||||
ref_pointer_array Pointer to array of reference fields
|
||||
fields All fields in select
|
||||
ref Pointer to item
|
||||
|
||||
NOTES
|
||||
This is from split_sum_func2() for items that should be split
|
||||
|
||||
All found SUM items are added FIRST in the fields list and
|
||||
we replace the item with a reference.
|
||||
|
||||
thd->fatal_error() may be called if we are out of memory
|
||||
*/
|
||||
|
||||
|
||||
void Item::split_sum_func2(THD *thd, Item **ref_pointer_array,
|
||||
List<Item> &fields, Item **ref)
|
||||
{
|
||||
if (type() != SUM_FUNC_ITEM && with_sum_func)
|
||||
{
|
||||
/* Will split complicated items and ignore simple ones */
|
||||
split_sum_func(thd, ref_pointer_array, fields);
|
||||
}
|
||||
else if ((type() == SUM_FUNC_ITEM ||
|
||||
(used_tables() & ~PARAM_TABLE_BIT)) &&
|
||||
type() != REF_ITEM)
|
||||
{
|
||||
/*
|
||||
Replace item with a reference so that we can easily calculate
|
||||
it (in case of sum functions) or copy it (in case of fields)
|
||||
|
||||
The test above is to ensure we don't do a reference for things
|
||||
that are constants (PARAM_TABLE_BIT is in effect a constant)
|
||||
or already referenced (for example an item in HAVING)
|
||||
*/
|
||||
uint el= fields.elements;
|
||||
Item *new_item;
|
||||
ref_pointer_array[el]= this;
|
||||
if (!(new_item= new Item_ref(ref_pointer_array + el, 0, name)))
|
||||
return; // fatal_error is set
|
||||
fields.push_front(this);
|
||||
ref_pointer_array[el]= this;
|
||||
thd->change_item_tree(ref, new_item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Aggregate two collations together taking
|
||||
into account their coercibility (aka derivation):
|
||||
|
@ -334,6 +334,9 @@ public:
|
||||
virtual void update_used_tables() {}
|
||||
virtual void split_sum_func(THD *thd, Item **ref_pointer_array,
|
||||
List<Item> &fields) {}
|
||||
/* Called for items that really have to be split */
|
||||
void split_sum_func2(THD *thd, Item **ref_pointer_array, List<Item> &fields,
|
||||
Item **ref);
|
||||
virtual bool get_date(TIME *ltime,uint fuzzydate);
|
||||
virtual bool get_time(TIME *ltime);
|
||||
virtual bool get_date_result(TIME *ltime,uint fuzzydate)
|
||||
|
@ -704,13 +704,12 @@ longlong Item_in_optimizer::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
cache->store(args[0]);
|
||||
longlong tmp= args[1]->val_int_result();
|
||||
if (cache->null_value)
|
||||
{
|
||||
if (tmp)
|
||||
null_value= 1;
|
||||
null_value= 1;
|
||||
return 0;
|
||||
}
|
||||
longlong tmp= args[1]->val_int_result();
|
||||
null_value= args[1]->null_value;
|
||||
return tmp;
|
||||
}
|
||||
@ -2349,10 +2348,10 @@ Item *Item_cond::transform(Item_transformer transformer, byte *arg)
|
||||
Move SUM items out from item tree and replace with reference
|
||||
|
||||
SYNOPSIS
|
||||
split_sum_func()
|
||||
thd Thread handler
|
||||
ref_pointer_array Pointer to array of reference fields
|
||||
fields All fields in select
|
||||
split_sum_func()
|
||||
thd Thread handler
|
||||
ref_pointer_array Pointer to array of reference fields
|
||||
fields All fields in select
|
||||
|
||||
NOTES
|
||||
This function is run on all expression (SELECT list, WHERE, HAVING etc)
|
||||
@ -2362,16 +2361,6 @@ Item *Item_cond::transform(Item_transformer transformer, byte *arg)
|
||||
so that we can easily find and calculate them.
|
||||
(Calculation done by update_sum_func() and copy_sum_funcs() in
|
||||
sql_select.cc)
|
||||
|
||||
All found SUM items are added FIRST in the fields list and
|
||||
we replace the item with a reference.
|
||||
|
||||
We also replace all functions without side effects (like RAND() or UDF's)
|
||||
that uses columns as arguments.
|
||||
For functions with side effects, we just remember any fields referred
|
||||
by the function to ensure that we get a copy of the field value for the
|
||||
first accepted row. This ensures that we can do things like
|
||||
SELECT a*SUM(b) FROM t1 WHERE a=1
|
||||
*/
|
||||
|
||||
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
|
||||
@ -2379,37 +2368,8 @@ void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
|
||||
{
|
||||
List_iterator<Item> li(list);
|
||||
Item *item;
|
||||
used_tables_cache=0;
|
||||
const_item_cache=1;
|
||||
while ((item=li++))
|
||||
{
|
||||
/* with_sum_func is set for items that contains a SUM expression */
|
||||
if (item->type() != SUM_FUNC_ITEM &&
|
||||
(item->with_sum_func ||
|
||||
(item->used_tables() & PSEUDO_TABLE_BITS)))
|
||||
item->split_sum_func(thd, ref_pointer_array, fields);
|
||||
else if (item->type() == SUM_FUNC_ITEM ||
|
||||
(item->used_tables() && item->type() != REF_ITEM))
|
||||
{
|
||||
/*
|
||||
Replace item with a reference so that we can easily calculate
|
||||
it (in case of sum functions) or copy it (in case of fields)
|
||||
|
||||
The test above is to ensure we don't do a reference for things
|
||||
that are constants or are not yet calculated as in:
|
||||
SELECT RAND() as r1, SUM(a) as r2 FROM t1 HAVING r1 > 1 AND r2 > 0
|
||||
*/
|
||||
Item **ref= li.ref();
|
||||
uint el= fields.elements;
|
||||
ref_pointer_array[el]= item;
|
||||
Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name);
|
||||
fields.push_front(item);
|
||||
thd->change_item_tree(ref, new_item);
|
||||
}
|
||||
item->update_used_tables();
|
||||
used_tables_cache|=item->used_tables();
|
||||
const_item_cache&=item->const_item();
|
||||
}
|
||||
while ((item= li++))
|
||||
item->split_sum_func2(thd, ref_pointer_array, fields, li.ref());
|
||||
}
|
||||
|
||||
|
||||
|
@ -401,27 +401,14 @@ Item *Item_func::transform(Item_transformer transformer, byte *argument)
|
||||
}
|
||||
|
||||
|
||||
/* See comments in Item_cmp_func::split_sum_func() */
|
||||
|
||||
void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
|
||||
List<Item> &fields)
|
||||
{
|
||||
Item **arg, **arg_end;
|
||||
for (arg= args, arg_end= args+arg_count; arg != arg_end ; arg++)
|
||||
{
|
||||
Item *item=* arg;
|
||||
if (item->type() != SUM_FUNC_ITEM &&
|
||||
(item->with_sum_func ||
|
||||
(item->used_tables() & PSEUDO_TABLE_BITS)))
|
||||
item->split_sum_func(thd, ref_pointer_array, fields);
|
||||
else if (item->type() == SUM_FUNC_ITEM ||
|
||||
(item->used_tables() && item->type() != REF_ITEM))
|
||||
{
|
||||
uint el= fields.elements;
|
||||
ref_pointer_array[el]= item;
|
||||
Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name);
|
||||
fields.push_front(item);
|
||||
thd->change_item_tree(arg, new_item);
|
||||
}
|
||||
}
|
||||
(*arg)->split_sum_func2(thd, ref_pointer_array, fields, arg);
|
||||
}
|
||||
|
||||
|
||||
|
@ -90,24 +90,10 @@ void Item_row::split_sum_func(THD *thd, Item **ref_pointer_array,
|
||||
{
|
||||
Item **arg, **arg_end;
|
||||
for (arg= items, arg_end= items+arg_count; arg != arg_end ; arg++)
|
||||
{
|
||||
Item *item= *arg;
|
||||
if (item->type() != SUM_FUNC_ITEM &&
|
||||
(item->with_sum_func ||
|
||||
(item->used_tables() & PSEUDO_TABLE_BITS)))
|
||||
item->split_sum_func(thd, ref_pointer_array, fields);
|
||||
else if (item->type() == SUM_FUNC_ITEM ||
|
||||
(item->used_tables() && item->type() != REF_ITEM))
|
||||
{
|
||||
uint el= fields.elements;
|
||||
ref_pointer_array[el]= *arg;
|
||||
Item *new_item= new Item_ref(ref_pointer_array + el, 0, (*arg)->name);
|
||||
fields.push_front(*arg);
|
||||
thd->change_item_tree(arg, new_item);
|
||||
}
|
||||
}
|
||||
(*arg)->split_sum_func2(thd, ref_pointer_array, fields, arg);
|
||||
}
|
||||
|
||||
|
||||
void Item_row::update_used_tables()
|
||||
{
|
||||
used_tables_cache= 0;
|
||||
|
@ -1778,19 +1778,7 @@ String *Item_func_elt::val_str(String *str)
|
||||
void Item_func_make_set::split_sum_func(THD *thd, Item **ref_pointer_array,
|
||||
List<Item> &fields)
|
||||
{
|
||||
if (item->type() != SUM_FUNC_ITEM &&
|
||||
(item->with_sum_func ||
|
||||
(item->used_tables() & PSEUDO_TABLE_BITS)))
|
||||
item->split_sum_func(thd, ref_pointer_array, fields);
|
||||
else if (item->type() == SUM_FUNC_ITEM ||
|
||||
(item->used_tables() && item->type() != REF_ITEM))
|
||||
{
|
||||
uint el= fields.elements;
|
||||
ref_pointer_array[el]= item;
|
||||
Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name);
|
||||
fields.push_front(item);
|
||||
thd->change_item_tree(&item, new_item);
|
||||
}
|
||||
item->split_sum_func2(thd, ref_pointer_array, fields, &item);
|
||||
Item_str_func::split_sum_func(thd, ref_pointer_array, fields);
|
||||
}
|
||||
|
||||
|
@ -889,8 +889,10 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
ref_pointer_array,
|
||||
(char *)"<ref>",
|
||||
this->full_name()));
|
||||
#ifdef CORRECT_BUT_TOO_SLOW_TO_BE_USABLE
|
||||
if (!abort_on_null && left_expr->maybe_null)
|
||||
item= new Item_cond_or(new Item_func_isnull(left_expr), item);
|
||||
#endif
|
||||
/*
|
||||
AND and comparison functions can't be changed during fix_fields()
|
||||
we can assign select_lex->having here, and pass 0 as last
|
||||
@ -944,8 +946,10 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
goto err;
|
||||
item= new Item_cond_or(item,
|
||||
new Item_func_isnull(orig_item));
|
||||
#ifdef CORRECT_BUT_TOO_SLOW_TO_BE_USABLE
|
||||
if (left_expr->maybe_null)
|
||||
item= new Item_cond_or(new Item_func_isnull(left_expr), item);
|
||||
#endif
|
||||
}
|
||||
item->name= (char *)in_additional_cond;
|
||||
/*
|
||||
@ -975,8 +979,10 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
new Item_null_helper(this, item,
|
||||
(char *)"<no matter>",
|
||||
(char *)"<result>"));
|
||||
#ifdef CORRECT_BUT_TOO_SLOW_TO_BE_USABLE
|
||||
if (!abort_on_null && left_expr->maybe_null)
|
||||
item= new Item_cond_or(new Item_func_isnull(left_expr), item);
|
||||
#endif
|
||||
select_lex->having= join->having= item;
|
||||
select_lex->having_fix_field= 1;
|
||||
/*
|
||||
|
@ -3302,12 +3302,14 @@ default_service_handling(char **argv,
|
||||
|
||||
if (Service.got_service_option(argv, "install"))
|
||||
{
|
||||
Service.Install(1, servicename, displayname, path_and_service, account_name);
|
||||
Service.Install(1, servicename, displayname, path_and_service,
|
||||
account_name);
|
||||
return 0;
|
||||
}
|
||||
if (Service.got_service_option(argv, "install-manual"))
|
||||
{
|
||||
Service.Install(0, servicename, displayname, path_and_service, account_name);
|
||||
Service.Install(0, servicename, displayname, path_and_service,
|
||||
account_name);
|
||||
return 0;
|
||||
}
|
||||
if (Service.got_service_option(argv, "remove"))
|
||||
@ -3327,7 +3329,7 @@ int main(int argc, char **argv)
|
||||
application PID e.g.: MySQLShutdown1890; MySQLShutdown2342
|
||||
*/
|
||||
int10_to_str((int) GetCurrentProcessId(),strmov(shutdown_event_name,
|
||||
"MySQLShutdown"), 10);
|
||||
"MySQLShutdown"), 10);
|
||||
|
||||
/* Must be initialized early for comparison of service name */
|
||||
system_charset_info= &my_charset_utf8_general_ci;
|
||||
@ -3361,7 +3363,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
else if (argc == 3) /* install or remove any optional service */
|
||||
{
|
||||
if (!default_service_handling(argv, argv[2], argv[2], file_path, "", NULL))
|
||||
if (!default_service_handling(argv, argv[2], argv[2], file_path, "",
|
||||
NULL))
|
||||
return 0;
|
||||
if (Service.IsService(argv[2]))
|
||||
{
|
||||
@ -3388,24 +3391,20 @@ int main(int argc, char **argv)
|
||||
--defaults-file=file, but that was not enforced in 4.1, so we don't
|
||||
enforce it here.)
|
||||
*/
|
||||
char *extra_opt= NULL;
|
||||
char *account_name = NULL;
|
||||
const char *extra_opt= NullS;
|
||||
const char *account_name = NullS;
|
||||
int index;
|
||||
for (index = 3; index < argc; index++)
|
||||
{
|
||||
if (strncmp(argv[index], "--local-service", 15) == 0)
|
||||
{
|
||||
account_name=(char*)malloc(27);
|
||||
strmov(account_name, "NT AUTHORITY\\LocalService\0");
|
||||
}
|
||||
if (!strcmp(argv[index], "--local-service"))
|
||||
account_name= "NT AUTHORITY\\LocalService";
|
||||
else
|
||||
{
|
||||
extra_opt= argv[index];
|
||||
}
|
||||
}
|
||||
|
||||
if (argc != 5 || account_name)
|
||||
if (!default_service_handling(argv, argv[2], argv[2], file_path, extra_opt, account_name))
|
||||
if (argc == 4 || account_name)
|
||||
if (!default_service_handling(argv, argv[2], argv[2], file_path,
|
||||
extra_opt, account_name))
|
||||
return 0;
|
||||
}
|
||||
else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME))
|
||||
|
@ -48,8 +48,9 @@ class NTService
|
||||
|
||||
|
||||
//service install / un-install
|
||||
BOOL Install(int startType,LPCSTR szInternName,LPCSTR szDisplayName,LPCSTR szFullPath,
|
||||
LPCSTR szAccountName=NULL,LPCSTR szPassword=NULL);
|
||||
BOOL Install(int startType,LPCSTR szInternName,LPCSTR szDisplayName,
|
||||
LPCSTR szFullPath, LPCSTR szAccountName=NULL,
|
||||
LPCSTR szPassword=NULL);
|
||||
BOOL SeekStatus(LPCSTR szInternName, int OperationType);
|
||||
BOOL Remove(LPCSTR szInternName);
|
||||
BOOL IsService(LPCSTR ServiceName);
|
||||
|
@ -1027,6 +1027,7 @@ public:
|
||||
bool charset_is_system_charset, charset_is_collation_connection;
|
||||
bool slow_command;
|
||||
bool no_trans_update, abort_on_warning;
|
||||
bool got_warning; /* Set on call to push_warning() */
|
||||
longlong row_count_func; /* For the ROW_COUNT() function */
|
||||
sp_rcontext *spcont; // SP runtime context
|
||||
sp_cache *sp_proc_cache;
|
||||
|
@ -108,6 +108,7 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
|
||||
|
||||
if (thd->query_id != thd->warn_id)
|
||||
mysql_reset_errors(thd);
|
||||
thd->got_warning= 1;
|
||||
if (thd->spcont &&
|
||||
thd->spcont->find_handler(code,
|
||||
((int) level >=
|
||||
|
@ -140,15 +140,6 @@ public:
|
||||
delete *prev;
|
||||
*prev=node;
|
||||
}
|
||||
inline void *pop(void)
|
||||
{
|
||||
if (first == &end_of_list) return 0;
|
||||
list_node *tmp=first;
|
||||
first=first->next;
|
||||
if (!--elements)
|
||||
last= &first;
|
||||
return tmp->info;
|
||||
}
|
||||
inline void concat(base_list *list)
|
||||
{
|
||||
if (!list->is_empty())
|
||||
@ -158,6 +149,15 @@ public:
|
||||
elements+= list->elements;
|
||||
}
|
||||
}
|
||||
inline void *pop(void)
|
||||
{
|
||||
if (first == &end_of_list) return 0;
|
||||
list_node *tmp=first;
|
||||
first=first->next;
|
||||
if (!--elements)
|
||||
last= &first;
|
||||
return tmp->info;
|
||||
}
|
||||
inline void disjoin(base_list *list)
|
||||
{
|
||||
list_node **prev= &first;
|
||||
|
@ -1313,7 +1313,7 @@ enum enum_mysql_completiontype {
|
||||
SAVEPOINT_NAME_ROLLBACK=2,
|
||||
SAVEPOINT_NAME_RELEASE=4,
|
||||
COMMIT_AND_CHAIN=6,
|
||||
ROLLBACK_AND_CHAIN=7,
|
||||
ROLLBACK_AND_CHAIN=7
|
||||
};
|
||||
|
||||
int mysql_endtrans(THD *thd, enum enum_mysql_completiontype completion,
|
||||
|
@ -8247,6 +8247,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
||||
keyinfo->key_length=(uint16) reclength;
|
||||
keyinfo->name= (char*) "distinct_key";
|
||||
keyinfo->algorithm= HA_KEY_ALG_UNDEF;
|
||||
keyinfo->rec_per_key=0;
|
||||
if (null_pack_length)
|
||||
{
|
||||
key_part_info->null_bit=0;
|
||||
@ -11843,6 +11844,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
|
||||
res_selected_fields.empty();
|
||||
res_all_fields.empty();
|
||||
List_iterator_fast<Item> itr(res_all_fields);
|
||||
List<Item> extra_funcs;
|
||||
uint i, border= all_fields.elements - elements;
|
||||
DBUG_ENTER("setup_copy_fields");
|
||||
|
||||
@ -11904,7 +11906,12 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
|
||||
*/
|
||||
if (!(pos=new Item_copy_string(pos)))
|
||||
goto err;
|
||||
if (param->copy_funcs.push_back(pos))
|
||||
if (i < border) // HAVING, ORDER and GROUP BY
|
||||
{
|
||||
if (extra_funcs.push_back(pos))
|
||||
goto err;
|
||||
}
|
||||
else if (param->copy_funcs.push_back(pos))
|
||||
goto err;
|
||||
}
|
||||
res_all_fields.push_back(pos);
|
||||
@ -11916,6 +11923,12 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
|
||||
for (i= 0; i < border; i++)
|
||||
itr++;
|
||||
itr.sublist(res_selected_fields, elements);
|
||||
/*
|
||||
Put elements from HAVING, ORDER BY and GROUP BY last to ensure that any
|
||||
reference used in these will resolve to a item that is already calculated
|
||||
*/
|
||||
param->copy_funcs.concat(&extra_funcs);
|
||||
|
||||
DBUG_RETURN(0);
|
||||
|
||||
err:
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <my_global.h>
|
||||
#include <my_sys.h>
|
||||
#include <mysql.h>
|
||||
#include <errmsg.h>
|
||||
#include <my_getopt.h>
|
||||
#include <m_string.h>
|
||||
|
||||
@ -12512,6 +12513,77 @@ static void test_bug6761(void)
|
||||
}
|
||||
|
||||
|
||||
/* Bug#8330 - mysql_stmt_execute crashes (libmysql) */
|
||||
|
||||
static void test_bug8330()
|
||||
{
|
||||
const char *stmt_text;
|
||||
MYSQL_STMT *stmt[2];
|
||||
int i, rc;
|
||||
char *query= "select a,b from t1 where a=?";
|
||||
MYSQL_BIND bind[2];
|
||||
long lval[2];
|
||||
|
||||
myheader("test_bug8330");
|
||||
|
||||
stmt_text= "drop table if exists t1";
|
||||
/* in case some previos test failed */
|
||||
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
|
||||
myquery(rc);
|
||||
stmt_text= "create table t1 (a int, b int)";
|
||||
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
|
||||
myquery(rc);
|
||||
|
||||
bzero(bind, sizeof(bind));
|
||||
for (i=0; i < 2; i++)
|
||||
{
|
||||
stmt[i]= mysql_stmt_init(mysql);
|
||||
rc= mysql_stmt_prepare(stmt[i], query, strlen(query));
|
||||
check_execute(stmt[i], rc);
|
||||
|
||||
bind[i].buffer_type= MYSQL_TYPE_LONG;
|
||||
bind[i].buffer= (void*) &lval[i];
|
||||
bind[i].is_null= 0;
|
||||
mysql_stmt_bind_param(stmt[i], &bind[i]);
|
||||
}
|
||||
|
||||
rc= mysql_stmt_execute(stmt[0]);
|
||||
check_execute(stmt[0], rc);
|
||||
|
||||
rc= mysql_stmt_execute(stmt[1]);
|
||||
DIE_UNLESS(rc && mysql_stmt_errno(stmt[1]) == CR_COMMANDS_OUT_OF_SYNC);
|
||||
rc= mysql_stmt_execute(stmt[0]);
|
||||
check_execute(stmt[0], rc);
|
||||
|
||||
mysql_stmt_close(stmt[0]);
|
||||
mysql_stmt_close(stmt[1]);
|
||||
|
||||
stmt_text= "drop table t1";
|
||||
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
|
||||
myquery(rc);
|
||||
}
|
||||
|
||||
|
||||
/* Bug#7990 - mysql_stmt_close doesn't reset mysql->net.last_error */
|
||||
|
||||
static void test_bug7990()
|
||||
{
|
||||
MYSQL_STMT *stmt;
|
||||
int rc;
|
||||
myheader("test_bug7990");
|
||||
|
||||
stmt= mysql_stmt_init(mysql);
|
||||
rc= mysql_stmt_prepare(stmt, "foo", 3);
|
||||
/*
|
||||
XXX: the fact that we store errno both in STMT and in
|
||||
MYSQL is not documented and is subject to change in 5.0
|
||||
*/
|
||||
DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql));
|
||||
mysql_stmt_close(stmt);
|
||||
DIE_UNLESS(!mysql_errno(mysql));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Read and parse arguments and MySQL options from my.cnf
|
||||
*/
|
||||
@ -12730,6 +12802,8 @@ static struct my_tests_st my_tests[]= {
|
||||
{ "test_cursors_with_union", test_cursors_with_union },
|
||||
{ "test_truncation", test_truncation },
|
||||
{ "test_truncation_option", test_truncation_option },
|
||||
{ "test_bug8330", test_bug8330 },
|
||||
{ "test_bug7990", test_bug7990 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user