Commit 2d90fe51 authored by matthias@three.local.lan's avatar matthias@three.local.lan

Merge mleich@bk-internal.mysql.com:/home/bk/mysql-4.1

into three.local.lan:/home/matthias/Arbeit/mysql-4.1/src
parents ddd43987 bf72f5da
......@@ -943,3 +943,5 @@ ac_available_languages_fragment
libmysqld/ha_archive.cc
libmysqld/ha_example.cc
libmysqld/ha_tina.cc
analyse.test
client/mysqladmin.c
......@@ -11,7 +11,7 @@ $opt_distribution=$opt_user=$opt_config_env=$opt_config_extra_env="";
$opt_dbd_options=$opt_perl_options=$opt_config_options=$opt_make_options=$opt_suffix="";
$opt_tmp=$opt_version_suffix="";
$opt_bundled_zlib=$opt_help=$opt_delete=$opt_debug=$opt_stage=$opt_no_test=$opt_no_perl=$opt_one_error=$opt_with_low_memory=$opt_fast_benchmark=$opt_static_client=$opt_static_server=$opt_static_perl=$opt_sur=$opt_with_small_disk=$opt_local_perl=$opt_tcpip=$opt_build_thread=$opt_use_old_distribution=$opt_enable_shared=$opt_no_crash_me=$opt_no_strip=$opt_with_archive=$opt_with_cluster=$opt_with_debug=$opt_no_benchmark=$opt_no_mysqltest=$opt_without_embedded=$opt_readline=0;
$opt_innodb=$opt_bdb=$opt_raid=$opt_libwrap=$opt_clearlogs=0;
$opt_embedded_test=$opt_ps_test=$opt_innodb=$opt_bdb=$opt_raid=$opt_libwrap=$opt_clearlogs=0;
GetOptions(
"bdb",
......@@ -25,6 +25,7 @@ GetOptions(
"delete",
"distribution=s",
"enable-shared",
"embedded-test",
"fast-benchmark",
"help|Information",
"innodb",
......@@ -40,6 +41,7 @@ GetOptions(
"one-error",
"perl-files=s",
"perl-options=s",
"ps-test",
"raid",
"readline",
"stage=i",
......@@ -274,6 +276,7 @@ if ($opt_stage <= 1)
$opt_config_options.= " --with-libedit";
}
$opt_config_options.= " --with-embedded-server" unless ($opt_without_embedded);
$opt_embedded_test= 0 if ($opt_without_embedded);
$opt_config_options.= " --with-archive-storage-engine" if ($opt_with_archive);
$opt_config_options.= " --with-ndbcluster" if ($opt_with_cluster);
......@@ -376,13 +379,29 @@ $ENV{"LD_LIBRARY_PATH"}= ("$test_dir/lib" .
if ($opt_stage <= 5 && !$opt_no_test && !$opt_no_mysqltest)
{
my $flags= "";
my $force= "";
$flags.= " --with-ndbcluster" if ($opt_with_cluster);
$flags.= " --force" if (!$opt_one_error);
log_timestamp();
info("Running test suite");
system("mkdir $bench_tmpdir") if (! -d $bench_tmpdir);
safe_cd("${test_dir}/mysql-test");
check_system("./mysql-test-run $flags --tmpdir=$bench_tmpdir --master_port=$mysql_tcp_port --slave_port=$slave_port --ndbcluster_port=$ndbcluster_port --manager-port=$manager_port --no-manager --sleep=10", "tests were successful");
if ($opt_ps_test)
{
log_timestamp();
info("Running test suite using prepared statements");
check_system("./mysql-test-run $flags --ps-protocol --tmpdir=$bench_tmpdir --master_port=$mysql_tcp_port --slave_port=$slave_port --ndbcluster_port=$ndbcluster_port --manager-port=$manager_port --no-manager --sleep=10", "tests were successful");
}
if ($opt_embedded_test)
{
log_timestamp();
info("Running embedded server test suite");
# Embedded server and NDB don't jive
$flags=~ s/ --with-ndbcluster//;
check_system("./mysql-test-run $flags --embedded-server --tmpdir=$bench_tmpdir --master_port=$mysql_tcp_port --slave_port=$slave_port --manager-port=$manager_port --no-manager --sleep=10", "tests were successful");
}
# 'mysql-test-run' writes its own final message for log evaluation.
}
......@@ -528,6 +547,9 @@ Delete the distribution file.
--distribution=<distribution_file>
Name of the MySQL source distribution file.
--embedded-test
Run the test suite against the embedded server
--enable-shared
Compile with shared libraries
......@@ -576,6 +598,9 @@ Compile and install the given perl modules.
--perl-options=<options>
Build Perl modules with the additional options
--ps-test
Run an additional test run, using prepared statements
--raid
Compile with RAID support
......
......@@ -394,10 +394,19 @@ os_file_lock(
lk.l_start = lk.l_len = 0;
if (fcntl(fd, F_SETLK, &lk) == -1) {
fprintf(stderr,
"InnoDB: Unable to lock %s, error: %d", name, errno);
"InnoDB: Unable to lock %s, error: %d\n", name, errno);
if (errno == EAGAIN || errno == EACCES) {
fprintf(stderr,
"InnoDB: Check that you do not already have another mysqld process\n"
"InnoDB: using the same InnoDB data or log files.\n");
}
close(fd);
return(-1);
}
return(0);
}
#endif /* USE_FILE_LOCK */
......
......@@ -4413,6 +4413,12 @@ mysql_stmt_data_seek(MYSQL_STMT *stmt, my_ulonglong row)
for (; tmp && row; --row, tmp= tmp->next)
;
stmt->data_cursor= tmp;
if (!row && tmp)
{
/* Rewind the counter */
stmt->read_row_func= stmt_read_row_buffered;
stmt->state= MYSQL_STMT_EXECUTE_DONE;
}
DBUG_VOID_RETURN;
}
......
......@@ -155,7 +155,7 @@ static void _ftb_parse_query(FTB *ftb, byte **start, byte *end,
ftbw=(FTB_WORD *)alloc_root(&ftb->mem_root,
sizeof(FTB_WORD) +
(param.trunc ? MI_MAX_KEY_BUFF :
w.len+extra));
w.len*ftb->charset->mbmaxlen+extra));
ftbw->len=w.len+1;
ftbw->flags=0;
ftbw->off=0;
......
-- NDB Cluster -- Management Client --
---------------------------------------------------------------------------
NDB Cluster -- Management Client -- Help
---------------------------------------------------------------------------
HELP Print help text
HELP SHOW Help for SHOW command
HELP DEBUG Help for debug compiled version
SHOW Print information about cluster
START BACKUP Start backup
ABORT BACKUP <backup id> Abort backup
SHUTDOWN Shutdown all processes in cluster and quit
CLUSTERLOG ON [<severity>] ... Enable Cluster logging
CLUSTERLOG OFF [<severity>] ... Disable Cluster logging
CLUSTERLOG TOGGLE [<severity>] ... Toggle severity filter on/off
CLUSTERLOG INFO Print cluster log information
<id> START Start DB node (started with -n)
<id> RESTART [-n] [-i] Restart DB node
<id> STOP Stop DB node
ENTER SINGLE USER MODE <api-node> Enter single user mode
EXIT SINGLE USER MODE Exit single user mode
<id> STATUS Print status
<id> CLUSTERLOG {<category>=<level>}+ Set log level for cluster log
PURGE STALE SESSIONS Reset reserved nodeid's in the mgmt server
CONNECT [<connectstring>] Connect to management server (reconnect if already connected)
QUIT Quit management client
<severity> = ALERT | CRITICAL | ERROR | WARNING | INFO | DEBUG
<category> = STARTUP | SHUTDOWN | STATISTICS | CHECKPOINT | NODERESTART | CONNECTION | INFO | ERROR | GREP | DEBUG | BACKUP
<level> = 0 - 15
<id> = ALL | Any database node id
Connected to Management Server at: localhost:1186
Node 1: started (Version 4.1.8)
Node 2: started (Version 4.1.8)
Node 1: started (Version 4.1.8)
Node 2: started (Version 4.1.8)
Executing CLUSTERLOG on node 1 OK!
Executing CLUSTERLOG on node 2 OK!
Executing CLUSTERLOG on node 1 OK!
Executing CLUSTERLOG on node 2 OK!
Executing CLUSTERLOG on node 1 OK!
Executing CLUSTERLOG on node 2 OK!
Executing CLUSTERLOG on node 1 OK!
Executing CLUSTERLOG on node 2 OK!
Executing CLUSTERLOG on node 1 OK!
Executing CLUSTERLOG on node 2 OK!
Executing CLUSTERLOG on node 1 OK!
Executing CLUSTERLOG on node 2 OK!
Executing CLUSTERLOG on node 1 OK!
Executing CLUSTERLOG on node 2 OK!
Executing CLUSTERLOG on node 1 OK!
Executing CLUSTERLOG on node 2 OK!
Cluster logging is disabled
Cluster logging is enabled.
Cluster logging is disabled
ALL disabled
ALL enabled
help
all status
1 status
2 status
all clusterlog connection=8
all clusterlog startup=7
all clusterlog checkpoint=7
all clusterlog noderestart=15
all clusterlog statistics=7
all clusterlog error=7
all clusterlog info=7
all clusterlog backup=15
clusterlog off
clusterlog toggle
clusterlog off
clusterlog off all
clusterlog on all
......@@ -47,6 +47,7 @@ fi
pidfile=ndbcluster.pid
cfgfile=Ndb.cfg
test_ndb=
stop_ndb=
initial_ndb=
status_ndb=
......@@ -59,6 +60,9 @@ ndb_imem=24M
while test $# -gt 0; do
case "$1" in
--test)
test_ndb=1
;;
--stop)
stop_ndb=1
;;
......@@ -67,8 +71,7 @@ while test $# -gt 0; do
initial_ndb=1
;;
--debug*)
f=`echo "$1" | sed -e "s;--debug=;;"`
flags_ndb="$flags_ndb $f"
flags_ndb="$flags_ndb $1"
;;
--status)
status_ndb=1
......@@ -232,7 +235,7 @@ status_ndbcluster
status_ndbcluster() {
# Start management client
echo "show" | $exec_mgmtclient
$exec_mgmtclient -e show
}
stop_default_ndbcluster() {
......@@ -241,7 +244,7 @@ stop_default_ndbcluster() {
exec_mgmtclient="$exec_mgmtclient --try-reconnect=1"
echo "shutdown" | $exec_mgmtclient 2>&1 | cat > /dev/null
$exec_mgmtclient -e shutdown 2>&1 | cat > /dev/null
if [ -f "$fs_ndb/$pidfile" ] ; then
kill_pids=`cat "$fs_ndb/$pidfile"`
......@@ -276,6 +279,44 @@ if [ -f "$fs_ndb/$pidfile" ] ; then
fi
}
initialize_ndb_test ()
{
fs_result=$fs_ndb/r
rm -rf $fs_result
mkdir $fs_result
echo ------------------
echo starting ndb tests
echo ------------------
}
do_ndb_test ()
{
test_name=$1
clusterlog=$fs_ndb/ndb_3_cluster.log
test_log_result=$fs_result/${test_name}_log.result
test_log_reject=$fs_result/${test_name}_log.reject
test_result=$fs_result/${test_name}.result
test_reject=$fs_result/${test_name}.reject
clean_log='s/.*\[MgmSrvr\]//'
cat $clusterlog ndb/${test_name}_log.result | sed -e $clean_log > $test_log_result
cp ndb/${test_name}.result $test_result
cat ndb/${test_name}.test | $exec_mgmtclient > $test_reject
cat $clusterlog | sed -e $clean_log > $test_log_reject
t="pass"
diff -C 5 $test_result $test_reject || t="fail"
printf "ndb_mgm output %20s [%s]\n" $test_name $t
t="pass"
diff -C 5 $test_log_result $test_log_reject || t="fail"
printf "clusterlog output %20s [%s]\n" $test_name $t
}
if [ $status_ndb ] ; then
status_ndbcluster
exit 0
......@@ -287,4 +328,15 @@ else
start_default_ndbcluster
fi
if [ $test_ndb ] ; then
initialize_ndb_test
all_tests=`ls ndb/*.test | sed "s#ndb/##" | sed "s#.test##"`
for a in $all_tests ; do
do_ndb_test $a
done
echo ------------------
echo shutting down cluster
stop_default_ndbcluster
fi
exit 0
-- NDB Cluster -- Management Client --
Connected to Management Server at: localhost:1186
ALL disabled
Cluster logging is enabled.
ALERT enabled
Executing CLUSTERLOG on node 1 OK!
Executing CLUSTERLOG on node 2 OK!
Node 1 is being restarted.
Executing CLUSTERLOG on node 1 OK!
Executing CLUSTERLOG on node 2 OK!
Node 1 is being restarted.
ALL enabled
clusterlog off all
clusterlog on
clusterlog on alert
all clusterlog connection=0
sleep 1
1 restart
sleep 5
all clusterlog connection=8
sleep 1
1 restart
sleep 5
clusterlog on all
ALERT -- Node 2: Network partitioning - arbitration required
ALERT -- Node 2: Arbitration won - positive reply from node 3
ALERT -- Node 2: Node 1 has failed. The Node state at failure was 0
ALERT -- Node 2: Node failure of 1 DBLQH completed
ALERT -- Node 2: Node failure of 1 DBDICT completed
ALERT -- Node 2: Node failure of 1 DBDIH completed
ALERT -- Node 2: Node failure of 1 DBTC completed
ALERT -- Node 2: Node 2 completed failure of Node 1
ALERT -- Node 2: All nodes completed failure of Node 1
ALERT -- Node 3: Node 1 Disconnected
ALERT -- Node 2: Node 1 Disconnected
ALERT -- Node 2: Network partitioning - arbitration required
ALERT -- Node 2: Arbitration won - positive reply from node 3
ALERT -- Node 2: Node 1 has failed. The Node state at failure was 0
ALERT -- Node 2: Node failure of 1 DBLQH completed
ALERT -- Node 2: Node failure of 1 DBDICT completed
ALERT -- Node 2: Node failure of 1 DBDIH completed
ALERT -- Node 2: Node failure of 1 DBTC completed
ALERT -- Node 2: Node 2 completed failure of Node 1
ALERT -- Node 2: All nodes completed failure of Node 1
......@@ -471,3 +471,14 @@ select @var is null, @var is not null, @var;
execute stmt using @var, @var, @var;
? is null ? is not null ?
1 0 NULL
create table t1 (pnum char(3));
create table t2 (pnum char(3));
prepare stmt from "select pnum from t2 having pnum in (select 'p1' from t1)";
execute stmt;
pnum
execute stmt;
pnum
execute stmt;
pnum
deallocate prepare stmt;
drop table t1, t2;
......@@ -314,57 +314,57 @@ insert into t2 values (1),(2);
insert into t3 values (1,1),(2,2);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 2 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 2 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 2 9 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t1 HEAP 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 2 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
insert into t1 values (3),(4);
insert into t2 values (3),(4);
insert into t3 values (3,3),(4,4);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 4 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 4 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 4 9 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t1 HEAP 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 4 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
insert into t1 values (5);
insert into t2 values (5);
insert into t3 values (5,5);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 5 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 5 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 5 9 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t1 HEAP 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 5 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
delete from t1 where a=3;
delete from t2 where b=3;
delete from t3 where a=3;
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 4 5 # # # 5 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 4 5 # # # 5 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 4 9 # # # 9 NULL NULL NULL NULL latin1_swedish_ci NULL
t1 HEAP 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 4 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
delete from t1;
delete from t2;
delete from t3;
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 0 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 0 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 0 9 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t1 HEAP 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 0 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
insert into t1 values (5);
insert into t2 values (5);
insert into t3 values (5,5);
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 1 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 1 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 1 9 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t1 HEAP 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 1 # # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
delete from t1 where a=5;
delete from t2 where b=5;
delete from t3 where a=5;
show table status;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 HEAP 9 Fixed 0 5 # # # 5 NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 0 5 # # # 5 NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 0 9 # # # 9 NULL NULL NULL NULL latin1_swedish_ci NULL
t1 HEAP 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t2 HEAP 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
t3 HEAP 9 Fixed 0 # # # # # NULL NULL NULL NULL latin1_swedish_ci NULL
drop table t1, t2, t3;
create database mysqltest;
show create database mysqltest;
......
......@@ -269,7 +269,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 3
Warnings:
Note 1003 select test.t3.a AS `a` from test.t3 where (test.t3.a >= (select min(test.t2.b) from test.t2))
Note 1003 select test.t3.a AS `a` from test.t3 where <nop>((test.t3.a >= (select min(test.t2.b) from test.t2)))
select * from t3 where a >= all (select b from t2);
a
7
......@@ -1488,6 +1488,71 @@ id select_type table type possible_keys key key_len ref rows Extra
2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
Warnings:
Note 1003 select test.t3.a AS `a` from test.t3 where <not>((test.t3.a < (select max(test.t2.b) from test.t2)))
select * from t3 where a >= some (select b from t2);
a
6
7
3
explain extended select * from t3 where a >= some (select b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
Warnings:
Note 1003 select test.t3.a AS `a` from test.t3 where <nop>((test.t3.a >= (select min(test.t2.b) from test.t2)))
select * from t3 where a >= all (select b from t2 group by 1);
a
6
7
3
explain extended select * from t3 where a >= all (select b from t2 group by 1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
Warnings:
Note 1003 select test.t3.a AS `a` from test.t3 where <not>((test.t3.a < <max>(select test.t2.b AS `b` from test.t2 group by test.t2.b)))
select * from t3 where a >= some (select b from t2 group by 1);
a
6
7
3
explain extended select * from t3 where a >= some (select b from t2 group by 1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
Warnings:
Note 1003 select test.t3.a AS `a` from test.t3 where <nop>((test.t3.a >= <min>(select test.t2.b AS `b` from test.t2 group by test.t2.b)))
select * from t3 where NULL >= any (select b from t2);
a
explain extended select * from t3 where NULL >= any (select b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
Warnings:
Note 1003 select test.t3.a AS `a` from test.t3
select * from t3 where NULL >= any (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= any (select b from t2 group by 1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
Warnings:
Note 1003 select test.t3.a AS `a` from test.t3
select * from t3 where NULL >= some (select b from t2);
a
explain extended select * from t3 where NULL >= some (select b from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
Warnings:
Note 1003 select test.t3.a AS `a` from test.t3
select * from t3 where NULL >= some (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= some (select b from t2 group by 1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
Warnings:
Note 1003 select test.t3.a AS `a` from test.t3
insert into t2 values (2,2), (2,1), (3,3), (3,1);
select * from t3 where a > all (select max(b) from t2 group by a);
a
......@@ -2031,3 +2096,12 @@ insert into t1 values (20,15);
select * from t1 where (('a',null) <=> (select 'a',s2 from t1 where s1 = 0));
s1 s2
drop table t1;
create table t1 (s1 int);
insert into t1 values (1),(null);
select * from t1 where s1 < all (select s1 from t1);
s1
select s1, s1 < all (select s1 from t1) from t1;
s1 s1 < all (select s1 from t1)
1 0
NULL NULL
drop table t1;
......@@ -471,3 +471,17 @@ execute stmt using @var, @var, @var;
set @var=null;
select @var is null, @var is not null, @var;
execute stmt using @var, @var, @var;
#
# Bug#6873 "PS, having with subquery, crash during execute"
# check that if we modify having subtree, we update JOIN->having pointer
#
create table t1 (pnum char(3));
create table t2 (pnum char(3));
prepare stmt from "select pnum from t2 having pnum in (select 'p1' from t1)";
execute stmt;
execute stmt;
execute stmt;
deallocate prepare stmt;
drop table t1, t2;
......@@ -228,37 +228,37 @@ CREATE TABLE t3 (
insert into t1 values (1),(2);
insert into t2 values (1),(2);
insert into t3 values (1,1),(2,2);
--replace_column 7 # 8 # 9 #
--replace_column 6 # 7 # 8 # 9 #
show table status;
insert into t1 values (3),(4);
insert into t2 values (3),(4);
insert into t3 values (3,3),(4,4);
--replace_column 7 # 8 # 9 #
--replace_column 6 # 7 # 8 # 9 #
show table status;
insert into t1 values (5);
insert into t2 values (5);
insert into t3 values (5,5);
--replace_column 7 # 8 # 9 #
--replace_column 6 # 7 # 8 # 9 #
show table status;
delete from t1 where a=3;
delete from t2 where b=3;
delete from t3 where a=3;
--replace_column 7 # 8 # 9 #
--replace_column 6 # 7 # 8 # 9 # 10 #
show table status;
delete from t1;
delete from t2;
delete from t3;
--replace_column 7 # 8 # 9 #
--replace_column 6 # 7 # 8 # 9 #
show table status;
insert into t1 values (5);
insert into t2 values (5);
insert into t3 values (5,5);
--replace_column 7 # 8 # 9 #
--replace_column 6 # 7 # 8 # 9 #
show table status;
delete from t1 where a=5;
delete from t2 where b=5;
delete from t3 where a=5;
--replace_column 7 # 8 # 9 #
--replace_column 6 # 7 # 8 # 9 # 10 #
show table status;
drop table t1, t2, t3;
......
......@@ -911,7 +911,20 @@ create table t3 (a int);
insert into t3 values (6),(7),(3);
select * from t3 where a >= all (select b from t2);
explain extended select * from t3 where a >= all (select b from t2);
select * from t3 where a >= some (select b from t2);
explain extended select * from t3 where a >= some (select b from t2);
select * from t3 where a >= all (select b from t2 group by 1);
explain extended select * from t3 where a >= all (select b from t2 group by 1);
select * from t3 where a >= some (select b from t2 group by 1);
explain extended select * from t3 where a >= some (select b from t2 group by 1);
select * from t3 where NULL >= any (select b from t2);
explain extended select * from t3 where NULL >= any (select b from t2);
select * from t3 where NULL >= any (select b from t2 group by 1);
explain extended select * from t3 where NULL >= any (select b from t2 group by 1);
select * from t3 where NULL >= some (select b from t2);
explain extended select * from t3 where NULL >= some (select b from t2);
select * from t3 where NULL >= some (select b from t2 group by 1);
explain extended select * from t3 where NULL >= some (select b from t2 group by 1);
#
# optimized static ALL/ANY with grouping
#
......@@ -1336,3 +1349,12 @@ create table t1 (s1 int,s2 int);
insert into t1 values (20,15);
select * from t1 where (('a',null) <=> (select 'a',s2 from t1 where s1 = 0));
drop table t1;
#
# ALL/ANY with NULL
#
create table t1 (s1 int);
insert into t1 values (1),(null);
select * from t1 where s1 < all (select s1 from t1);
select s1, s1 < all (select s1 from t1) from t1;
drop table t1;
......@@ -48,6 +48,11 @@ public:
static const EventRepLogLevelMatrix matrix[];
static const Uint32 matrixSize;
static int
EventLoggerBase::event_lookup(int eventType,
LogLevel::EventCategory &cat,
Uint32 &threshold,
Logger::LoggerLevel &severity);
};
/**
......
......@@ -73,7 +73,7 @@ public:
/**
* Note level is valid as 0-15
*/
void setLogLevel(EventCategory ec, Uint32 level = 7);
int setLogLevel(EventCategory ec, Uint32 level = 7);
/**
* Get the loglevel (0-15) for a category
......@@ -119,10 +119,14 @@ LogLevel::clear(){
}
inline
void
int
LogLevel::setLogLevel(EventCategory ec, Uint32 level){
assert(ec >= 0 && (Uint32) ec < LOGLEVEL_CATEGORIES);
logLevelData[ec] = (Uint8)level;
if (ec >= 0 && (Uint32) ec < LOGLEVEL_CATEGORIES)
{
logLevelData[ec] = (Uint8)level;
return 0;
}
return 1;
}
inline
......
......@@ -1342,27 +1342,41 @@ operator<<(NdbOut& out, const LogLevel & ll)
return out;
}
void
EventLogger::log(int eventType, const Uint32* theData, NodeId nodeId,
const LogLevel* ll)
int
EventLoggerBase::event_lookup(int eventType,
LogLevel::EventCategory &cat,
Uint32 &threshold,
Logger::LoggerLevel &severity)
{
Uint32 threshold = 0;
Logger::LoggerLevel severity = Logger::LL_WARNING;
LogLevel::EventCategory cat= LogLevel::llInvalid;
for(unsigned i = 0; i<EventLoggerBase::matrixSize; i++){
if(EventLoggerBase::matrix[i].eventType == eventType){
cat = EventLoggerBase::matrix[i].eventCategory;
threshold = EventLoggerBase::matrix[i].threshold;
severity = EventLoggerBase::matrix[i].severity;
break;
return 0;
}
}
return 1;
}
void
EventLogger::log(int eventType, const Uint32* theData, NodeId nodeId,
const LogLevel* ll)
{
Uint32 threshold = 0;
Logger::LoggerLevel severity = Logger::LL_WARNING;
LogLevel::EventCategory cat= LogLevel::llInvalid;
DBUG_ENTER("EventLogger::log");
DBUG_PRINT("enter",("eventType=%d, nodeid=%d", eventType, nodeId));
if (cat == LogLevel::llInvalid)
return;
if (EventLoggerBase::event_lookup(eventType,cat,threshold,severity))
DBUG_VOID_RETURN;
Uint32 set = ll?ll->getLogLevel(cat) : m_logLevel.getLogLevel(cat);
DBUG_PRINT("info",("threshold=%d, set=%d", threshold, set));
if (ll)
DBUG_PRINT("info",("m_logLevel.getLogLevel=%d", m_logLevel.getLogLevel(cat)));
if (threshold <= set){
switch (severity){
case Logger::LL_ALERT:
......@@ -1401,6 +1415,7 @@ EventLogger::log(int eventType, const Uint32* theData, NodeId nodeId,
break;
}
} // if (..
DBUG_VOID_RETURN;
}
int
......
......@@ -22,7 +22,7 @@
extern "C"
int
Ndb_getInAddr(struct in_addr * dst, const char *address) {
DBUG_ENTER("Ndb_getInAddr");
// DBUG_ENTER("Ndb_getInAddr");
{
int tmp_errno;
struct hostent tmp_hostent, *hp;
......@@ -33,7 +33,7 @@ Ndb_getInAddr(struct in_addr * dst, const char *address) {
{
memcpy(dst, hp->h_addr, min(sizeof(*dst), (size_t) hp->h_length));
my_gethostbyname_r_free();
DBUG_RETURN(0);
return 0; //DBUG_RETURN(0);
}
my_gethostbyname_r_free();
}
......@@ -47,11 +47,11 @@ Ndb_getInAddr(struct in_addr * dst, const char *address) {
#endif
)
{
DBUG_RETURN(0);
return 0; //DBUG_RETURN(0);
}
DBUG_PRINT("error",("inet_addr(%s) - %d - %s",
address, errno, strerror(errno)));
DBUG_RETURN(-1);
// DBUG_PRINT("error",("inet_addr(%s) - %d - %s",
// address, errno, strerror(errno)));
return -1; //DBUG_RETURN(-1);
}
#if 0
......
......@@ -193,21 +193,11 @@ void Cmvmi::execEVENT_REP(Signal* signal)
/**
* If entry is not found
*/
Uint32 threshold = 16;
LogLevel::EventCategory eventCategory = (LogLevel::EventCategory)0;
for(unsigned int i = 0; i< EventLoggerBase::matrixSize; i++){
if(EventLoggerBase::matrix[i].eventType == eventType){
eventCategory = EventLoggerBase::matrix[i].eventCategory;
threshold = EventLoggerBase::matrix[i].threshold;
break;
}
}
if(threshold > 15){
// No entry found in matrix (or event that should never be printed)
Uint32 threshold;
LogLevel::EventCategory eventCategory;
Logger::LoggerLevel severity;
if (EventLoggerBase::event_lookup(eventType,eventCategory,threshold,severity))
return;
}
SubscriberPtr ptr;
for(subscribers.first(ptr); ptr.i != RNIL; subscribers.next(ptr)){
......@@ -225,14 +215,15 @@ void Cmvmi::execEVENT_REP(Signal* signal)
// Print the event info
g_eventLogger.log(eventReport->getEventType(), signal->theData);
return;
}//execEVENT_REP()
void
Cmvmi::execEVENT_SUBSCRIBE_REQ(Signal * signal){
EventSubscribeReq * subReq = (EventSubscribeReq *)&signal->theData[0];
SubscriberPtr ptr;
jamEntry();
DBUG_ENTER("Cmvmi::execEVENT_SUBSCRIBE_REQ");
/**
* Search for subcription
......@@ -269,11 +260,13 @@ Cmvmi::execEVENT_SUBSCRIBE_REQ(Signal * signal){
category = (LogLevel::EventCategory)(subReq->theData[i] >> 16);
level = subReq->theData[i] & 0xFFFF;
ptr.p->logLevel.setLogLevel(category, level);
DBUG_PRINT("info",("entry %d: level=%d, category= %d", i, level, category));
}
}
signal->theData[0] = ptr.i;
sendSignal(ptr.p->blockRef, GSN_EVENT_SUBSCRIBE_CONF, signal, 1, JBB);
DBUG_VOID_RETURN;
}
void
......
......@@ -1102,15 +1102,18 @@ ndb_mgm_set_loglevel_clusterlog(NdbMgmHandle handle, int nodeId,
"set cluster loglevel", &args);
CHECK_REPLY(reply, -1);
DBUG_ENTER("ndb_mgm_set_loglevel_clusterlog");
DBUG_PRINT("enter",("node=%d, category=%d, level=%d", nodeId, cat, level));
BaseString result;
reply->get("result", result);
if(strcmp(result.c_str(), "Ok") != 0) {
SET_ERROR(handle, EINVAL, result.c_str());
delete reply;
return -1;
DBUG_RETURN(-1);
}
delete reply;
return 0;
DBUG_RETURN(0);
}
extern "C"
......
......@@ -499,7 +499,8 @@ CommandInterpreter::execute_impl(const char *_line)
line = my_strdup(_line,MYF(MY_WME));
My_auto_ptr<char> ptr(line);
if (emptyString(line)) {
if (emptyString(line) ||
line[0] == '#') {
DBUG_RETURN(true);
}
......@@ -516,6 +517,11 @@ CommandInterpreter::execute_impl(const char *_line)
executeConnect(allAfterFirstToken);
DBUG_RETURN(true);
}
else if (strcasecmp(firstToken, "SLEEP") == 0) {
if (allAfterFirstToken)
sleep(atoi(allAfterFirstToken));
DBUG_RETURN(true);
}
else if((strcasecmp(firstToken, "QUIT") == 0 ||
strcasecmp(firstToken, "EXIT") == 0 ||
strcasecmp(firstToken, "BYE") == 0) &&
......
......@@ -153,7 +153,7 @@ MgmtSrvr::logLevelThreadRun()
* Handle started nodes
*/
EventSubscribeReq req;
req = m_statisticsListner.m_clients[0].m_logLevel;
req = m_event_listner[0].m_logLevel;
req.blockRef = _ownReference;
SetLogLevelOrd ord;
......@@ -409,7 +409,7 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server,
_ownReference(0),
theSignalIdleList(NULL),
theWaitState(WAIT_SUBSCRIBE_CONF),
m_statisticsListner(this)
m_event_listner(this)
{
DBUG_ENTER("MgmtSrvr::MgmtSrvr");
......@@ -547,16 +547,18 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server,
}
}
// Setup clusterlog as client[0] in m_event_listner
{
MgmStatService::StatListener se;
Ndb_mgmd_event_service::Event_listener se;
se.m_socket = -1;
for(size_t t = 0; t<LogLevel::LOGLEVEL_CATEGORIES; t++){
se.m_logLevel.setLogLevel((LogLevel::EventCategory)t, 7);
}
se.m_logLevel.setLogLevel(LogLevel::llError, 15);
se.m_logLevel.setLogLevel(LogLevel::llConnection, 8);
se.m_logLevel.setLogLevel(LogLevel::llBackup, 15);
m_statisticsListner.m_clients.push_back(se);
m_statisticsListner.m_logLevel = se.m_logLevel;
m_event_listner.m_clients.push_back(se);
m_event_listner.m_logLevel = se.m_logLevel;
}
DBUG_VOID_RETURN;
......@@ -2071,21 +2073,18 @@ MgmtSrvr::handleStopReply(NodeId nodeId, Uint32 errCode)
void
MgmtSrvr::handleStatus(NodeId nodeId, bool alive)
{
DBUG_ENTER("MgmtSrvr::handleStatus");
Uint32 theData[25];
theData[1] = nodeId;
if (alive) {
m_started_nodes.push_back(nodeId);
Uint32 theData[25];
theData[0] = EventReport::Connected;
theData[1] = nodeId;
eventReport(_ownNodeId, theData);
} else {
handleStopReply(nodeId, 0);
Uint32 theData[25];
theData[0] = EventReport::Disconnected;
theData[1] = nodeId;
eventReport(_ownNodeId, theData);
}
eventReport(_ownNodeId, theData);
DBUG_VOID_RETURN;
}
//****************************************************************************
......@@ -2106,8 +2105,11 @@ void
MgmtSrvr::nodeStatusNotification(void* mgmSrv, Uint32 nodeId,
bool alive, bool nfComplete)
{
DBUG_ENTER("MgmtSrvr::nodeStatusNotification");
DBUG_PRINT("enter",("nodeid= %d, alive= %d, nfComplete= %d", nodeId, alive, nfComplete));
if(!(!alive && nfComplete))
((MgmtSrvr*)mgmSrv)->handleStatus(nodeId, alive);
DBUG_VOID_RETURN;
}
enum ndb_mgm_node_type
......@@ -2294,8 +2296,9 @@ MgmtSrvr::alloc_node_id(NodeId * nodeId,
if (found_matching_type)
if (found_free_node)
error_string.appfmt("Connection done from wrong host ip %s.",
inet_ntoa(((struct sockaddr_in *)
(client_addr))->sin_addr));
(client_addr)?
inet_ntoa(((struct sockaddr_in *)
(client_addr))->sin_addr):"");
else
error_string.appfmt("No free node id found for %s.",
type_string.c_str());
......@@ -2386,8 +2389,8 @@ MgmtSrvr::eventReport(NodeId nodeId, const Uint32 * theData)
EventReport::EventType type = eventReport->getEventType();
// Log event
g_EventLogger.log(type, theData, nodeId,
&m_statisticsListner.m_clients[0].m_logLevel);
m_statisticsListner.log(type, theData, nodeId);
&m_event_listner[0].m_logLevel);
m_event_listner.log(type, theData, nodeId);
}
/***************************************************************************
......@@ -2740,5 +2743,5 @@ template bool SignalQueue::waitFor<SigMatch>(Vector<SigMatch>&, SigMatch*&, NdbA
#endif
template class MutexVector<unsigned short>;
template class MutexVector<MgmStatService::StatListener>;
template class MutexVector<Ndb_mgmd_event_service::Event_listener>;
template class MutexVector<EventSubscribeReq>;
......@@ -43,27 +43,30 @@ class Config;
class SetLogLevelOrd;
class SocketServer;
class MgmStatService : public EventLoggerBase
class Ndb_mgmd_event_service : public EventLoggerBase
{
friend class MgmtSrvr;
public:
struct StatListener : public EventLoggerBase {
struct Event_listener : public EventLoggerBase {
NDB_SOCKET_TYPE m_socket;
};
private:
class MgmtSrvr * m_mgmsrv;
MutexVector<StatListener> m_clients;
MutexVector<Event_listener> m_clients;
public:
MgmStatService(class MgmtSrvr * m) : m_clients(5) {
Ndb_mgmd_event_service(class MgmtSrvr * m) : m_clients(5) {
m_mgmsrv = m;
}
void add_listener(const StatListener&);
void add_listener(const Event_listener&);
void log(int eventType, const Uint32* theData, NodeId nodeId);
void stopSessions();
void stop_sessions();
Event_listener& operator[](unsigned i) { return m_clients[i]; }
const Event_listener& operator[](unsigned i) const { return m_clients[i]; }
};
/**
......@@ -732,8 +735,8 @@ private:
LogLevel m_nodeLogLevel[MAX_NODES];
enum ndb_mgm_node_type nodeTypes[MAX_NODES];
friend class MgmApiSession;
friend class MgmStatService;
MgmStatService m_statisticsListner;
friend class Ndb_mgmd_event_service;
Ndb_mgmd_event_service m_event_listner;
/**
* Handles the thread wich upon a 'Node is started' event will
......
......@@ -208,12 +208,12 @@ ParserRow<MgmApiSession> commands[] = {
MGM_CMD("set loglevel", &MgmApiSession::setLogLevel, ""),
MGM_ARG("node", Int, Mandatory, "Node"),
MGM_ARG("category", String, Mandatory, "Event category"),
MGM_ARG("category", Int, Mandatory, "Event category"),
MGM_ARG("level", Int, Mandatory, "Log level (0-15)"),
MGM_CMD("set cluster loglevel", &MgmApiSession::setClusterLogLevel, ""),
MGM_ARG("node", Int, Mandatory, "Node"),
MGM_ARG("category", String, Mandatory, "Event category"),
MGM_ARG("category", Int, Mandatory, "Event category"),
MGM_ARG("level", Int, Mandatory, "Log level (0-15)"),
MGM_CMD("set logfilter", &MgmApiSession::setLogFilter, ""),
......@@ -781,20 +781,35 @@ MgmApiSession::bye(Parser<MgmApiSession>::Context &,
void
MgmApiSession::setClusterLogLevel(Parser<MgmApiSession>::Context &,
Properties const &args) {
Uint32 node, level, category;
const char *reply= "set cluster loglevel reply";
Uint32 node, level, cat;
BaseString errorString;
SetLogLevelOrd logLevel;
int result;
DBUG_ENTER("MgmApiSession::setClusterLogLevel");
args.get("node", &node);
args.get("category", &category);
args.get("category", &cat);
args.get("level", &level);
DBUG_PRINT("enter",("node=%d, category=%d, level=%d", node, cat, level));
/* XXX should use constants for this value */
if(level > 15) {
m_output->println("set cluster loglevel reply");
m_output->println("result: Invalid loglevel");
m_output->println(reply);
m_output->println("result: Invalid loglevel %d", level);
m_output->println("");
return;
DBUG_VOID_RETURN;
}
LogLevel::EventCategory category=
(LogLevel::EventCategory)(cat-(int)CFG_MIN_LOGLEVEL);
if (m_mgmsrv.m_event_listner[0].m_logLevel.setLogLevel(category,level))
{
m_output->println(reply);
m_output->println("result: Invalid category %d", category);
m_output->println("");
DBUG_VOID_RETURN;
}
EventSubscribeReq req;
......@@ -802,10 +817,11 @@ MgmApiSession::setClusterLogLevel(Parser<MgmApiSession>::Context &,
req.noOfEntries = 1;
req.theData[0] = (category << 16) | level;
m_mgmsrv.m_log_level_requests.push_back(req);
m_output->println("set cluster loglevel reply");
m_output->println(reply);
m_output->println("result: Ok");
m_output->println("");
DBUG_VOID_RETURN;
}
void
......@@ -1263,21 +1279,17 @@ operator<<(NdbOut& out, const LogLevel & ll)
}
void
MgmStatService::log(int eventType, const Uint32* theData, NodeId nodeId){
Ndb_mgmd_event_service::log(int eventType, const Uint32* theData, NodeId nodeId){
Uint32 threshold = 0;
LogLevel::EventCategory cat= LogLevel::llInvalid;
Uint32 threshold;
LogLevel::EventCategory cat;
Logger::LoggerLevel severity;
int i;
DBUG_ENTER("Ndb_mgmd_event_service::log");
DBUG_PRINT("enter",("eventType=%d, nodeid=%d", eventType, nodeId));
for(i = 0; (unsigned)i<EventLogger::matrixSize; i++){
if(EventLogger::matrix[i].eventType == eventType){
cat = EventLogger::matrix[i].eventCategory;
threshold = EventLogger::matrix[i].threshold;
break;
}
}
if (cat == LogLevel::llInvalid)
return;
if (EventLoggerBase::event_lookup(eventType,cat,threshold,severity))
DBUG_VOID_RETURN;
char m_text[256];
EventLogger::getText(m_text, sizeof(m_text), eventType, theData, nodeId);
......@@ -1316,10 +1328,11 @@ MgmStatService::log(int eventType, const Uint32* theData, NodeId nodeId){
m_mgmsrv->m_log_level_requests.push_back(req);
}
}
DBUG_VOID_RETURN;
}
void
MgmStatService::add_listener(const StatListener& client){
Ndb_mgmd_event_service::add_listener(const Event_listener& client){
m_clients.push_back(client);
LogLevel tmp = m_logLevel;
tmp.set_max(client.m_logLevel);
......@@ -1334,7 +1347,7 @@ MgmStatService::add_listener(const StatListener& client){
}
void
MgmStatService::stopSessions(){
Ndb_mgmd_event_service::stop_sessions(){
for(int i = m_clients.size() - 1; i >= 0; i--){
if(m_clients[i].m_socket >= 0){
NDB_CLOSE_SOCKET(m_clients[i].m_socket);
......@@ -1374,7 +1387,7 @@ MgmApiSession::listen_event(Parser<MgmApiSession>::Context & ctx,
int result = 0;
BaseString msg;
MgmStatService::StatListener le;
Ndb_mgmd_event_service::Event_listener le;
le.m_socket = m_socket;
Vector<BaseString> list;
......@@ -1419,7 +1432,7 @@ MgmApiSession::listen_event(Parser<MgmApiSession>::Context & ctx,
goto done;
}
m_mgmsrv.m_statisticsListner.add_listener(le);
m_mgmsrv.m_event_listner.add_listener(le);
m_stop = true;
m_socket = -1;
......
......@@ -626,6 +626,9 @@ TransporterFacade::ReportNodeFailureComplete(NodeId tNodeId)
* After the restart the node is up again and the Ndb object
* might not have noticed the failure.
*/
DBUG_ENTER("TransporterFacade::ReportNodeFailureComplete");
DBUG_PRINT("enter",("nodeid= %d", tNodeId));
Uint32 sz = m_threads.m_statusNext.size();
for (Uint32 i = 0; i < sz ; i ++) {
if (m_threads.getInUse(i)){
......@@ -634,6 +637,7 @@ TransporterFacade::ReportNodeFailureComplete(NodeId tNodeId)
(*RegPC) (obj, tNodeId, false, true);
}
}
DBUG_VOID_RETURN;
}
void
......
......@@ -106,7 +106,7 @@ longlong Item_func_not::val_int()
DBUG_ASSERT(fixed == 1);
double value=args[0]->val();
null_value=args[0]->null_value;
return !null_value && value == 0 ? 1 : 0;
return ((!null_value && value == 0) ? 1 : 0);
}
/*
......@@ -117,13 +117,23 @@ longlong Item_func_not_all::val_int()
{
DBUG_ASSERT(fixed == 1);
double value= args[0]->val();
if (abort_on_null)
{
null_value= 0;
return (args[0]->null_value || value == 0) ? 1 : 0;
}
/*
return TRUE if there was records in underlaying select in max/min
optimisation
*/
if (empty_underlying_subquery())
return 1;
null_value= args[0]->null_value;
return (!null_value && value == 0) ? 1 : 0;
return ((!null_value && value == 0) ? 1 : 0);
}
bool Item_func_not_all::empty_underlying_subquery()
{
return ((test_sum_item && !test_sum_item->any_value()) ||
(test_sub_item && !test_sub_item->any_value()));
}
void Item_func_not_all::print(String *str)
......@@ -134,6 +144,30 @@ void Item_func_not_all::print(String *str)
args[0]->print(str);
}
/*
Special NOP (No OPeration) for ALL subquery it is like Item_func_not_all
(return TRUE if underlaying sudquery do not return rows) but if subquery
returns some rows it return same value as argument (TRUE/FALSE).
*/
longlong Item_func_nop_all::val_int()
{
DBUG_ASSERT(fixed == 1);
double value= args[0]->val();
/*
return TRUE if there was records in underlaying select in max/min
optimisation
*/
if (empty_underlying_subquery())
return 1;
null_value= args[0]->null_value;
return (null_value || value == 0) ? 0 : 1;
}
/*
Convert a constant expression or string to an integer.
This is done when comparing DATE's of different formats and
......
......@@ -229,21 +229,43 @@ class Item_func_not :public Item_bool_func
Item *neg_transformer(THD *thd);
};
class Item_maxmin_subselect;
class Item_func_not_all :public Item_func_not
{
/* allow to check presence od values in max/min optimisation */
Item_sum_hybrid *test_sum_item;
Item_maxmin_subselect *test_sub_item;
bool abort_on_null;
public:
bool show;
Item_func_not_all(Item *a) :Item_func_not(a), abort_on_null(0), show(0) {}
Item_func_not_all(Item *a)
:Item_func_not(a), test_sum_item(0), test_sub_item(0), abort_on_null(0),
show(0)
{}
virtual void top_level_item() { abort_on_null= 1; }
bool top_level() { return abort_on_null; }
longlong val_int();
enum Functype functype() const { return NOT_ALL_FUNC; }
const char *func_name() const { return "<not>"; }
void print(String *str);
void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
bool empty_underlying_subquery();
};
class Item_func_nop_all :public Item_func_not_all
{
public:
Item_func_nop_all(Item *a) :Item_func_not_all(a) {}
longlong val_int();
const char *func_name() const { return "<nop>"; }
};
class Item_func_eq :public Item_bool_rowready_func2
{
public:
......
......@@ -155,6 +155,8 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
// did we changed top item of WHERE condition
if (unit->outer_select()->where == (*ref))
unit->outer_select()->where= substitution; // correct WHERE for PS
else if (unit->outer_select()->having == (*ref))
unit->outer_select()->having= substitution; // correct HAVING for PS
(*ref)= substitution;
substitution->name= name;
......@@ -271,7 +273,7 @@ Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex)
Item_maxmin_subselect::Item_maxmin_subselect(Item_subselect *parent,
st_select_lex *select_lex,
bool max_arg)
:Item_singlerow_subselect()
:Item_singlerow_subselect(), was_values(TRUE)
{
DBUG_ENTER("Item_maxmin_subselect::Item_maxmin_subselect");
max= max_arg;
......@@ -290,12 +292,31 @@ Item_maxmin_subselect::Item_maxmin_subselect(Item_subselect *parent,
DBUG_VOID_RETURN;
}
void Item_maxmin_subselect::cleanup()
{
DBUG_ENTER("Item_maxmin_subselect::cleanup");
Item_singlerow_subselect::cleanup();
/*
By default it is TRUE to avoid TRUE reporting by
Item_func_not_all/Item_func_nop_all if this item was never called.
Engine exec() set it to FALSE by reset_value_registration() call.
select_max_min_finder_subselect::send_data() set it back to TRUE if some
value will be found.
*/
was_values= TRUE;
DBUG_VOID_RETURN;
}
void Item_maxmin_subselect::print(String *str)
{
str->append(max?"<max>":"<min>", 5);
Item_singlerow_subselect::print(str);
}
void Item_singlerow_subselect::reset()
{
null_value= 1;
......@@ -303,6 +324,7 @@ void Item_singlerow_subselect::reset()
value->null_value= 1;
}
Item_subselect::trans_res
Item_singlerow_subselect::select_transformer(JOIN *join)
{
......@@ -519,7 +541,7 @@ bool Item_in_subselect::test_limit(SELECT_LEX_UNIT *unit)
Item_in_subselect::Item_in_subselect(Item * left_exp,
st_select_lex *select_lex):
Item_exists_subselect(), transformed(0), upper_not(0)
Item_exists_subselect(), transformed(0), upper_item(0)
{
DBUG_ENTER("Item_in_subselect::Item_in_subselect");
left_expr= left_exp;
......@@ -680,7 +702,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
NULL/IS NOT NULL functions). If so, we rewrite ALL/ANY with NOT EXISTS
later in this method.
*/
if ((abort_on_null || (upper_not && upper_not->top_level())) &&
if ((abort_on_null || (upper_item && upper_item->top_level())) &&
!select_lex->master_unit()->uncacheable && !func->eqne_op())
{
if (substitution)
......@@ -694,7 +716,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
!select_lex->with_sum_func &&
!(select_lex->next_select()))
{
Item *item;
Item_sum_hybrid *item;
if (func->l_op())
{
/*
......@@ -711,6 +733,8 @@ Item_in_subselect::single_value_transformer(JOIN *join,
*/
item= new Item_sum_min(*select_lex->ref_pointer_array);
}
if (upper_item)
upper_item->set_sum_test(item);
*select_lex->ref_pointer_array= item;
{
List_iterator<Item> it(select_lex->item_list);
......@@ -731,10 +755,13 @@ Item_in_subselect::single_value_transformer(JOIN *join,
}
else
{
Item_maxmin_subselect *item;
// remove LIMIT placed by ALL/ANY subquery
select_lex->master_unit()->global_parameters->select_limit=
HA_POS_ERROR;
subs= new Item_maxmin_subselect(this, select_lex, func->l_op());
subs= item= new Item_maxmin_subselect(this, select_lex, func->l_op());
if (upper_item)
upper_item->set_sub_test(item);
}
// left expression belong to outer select
SELECT_LEX *current= thd->lex->current_select, *up;
......@@ -1041,8 +1068,8 @@ Item_subselect::trans_res
Item_allany_subselect::select_transformer(JOIN *join)
{
transformed= 1;
if (upper_not)
upper_not->show= 1;
if (upper_item)
upper_item->show= 1;
return single_value_transformer(join, func);
}
......@@ -1247,6 +1274,7 @@ int subselect_single_select_engine::exec()
}
if (!executed)
{
item->reset_value_registration();
join->exec();
executed= 1;
join->thd->where= save_where;
......
......@@ -93,7 +93,7 @@ class Item_subselect :public Item_result_field
return null_value;
}
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
bool exec();
virtual bool exec();
virtual void fix_length_and_dec();
table_map used_tables() const;
bool const_item() const;
......@@ -109,6 +109,11 @@ class Item_subselect :public Item_result_field
engine_changed= 1;
return eng == 0;
}
/*
Used by max/min subquery to initialize value presence registration
mechanism. Engine call this method before rexecution query.
*/
virtual void reset_value_registration() {}
friend class select_subselect;
friend class Item_in_optimizer;
......@@ -150,13 +155,20 @@ class Item_singlerow_subselect :public Item_subselect
};
/* used in static ALL/ANY optimisation */
class select_max_min_finder_subselect;
class Item_maxmin_subselect :public Item_singlerow_subselect
{
protected:
bool max;
bool was_values; // Set if we have found at least one row
public:
Item_maxmin_subselect(Item_subselect *parent,
st_select_lex *select_lex, bool max);
void print(String *str);
void cleanup();
bool any_value() { return was_values; }
void register_value() { was_values= TRUE; }
void reset_value_registration() { was_values= FALSE; }
};
/* exists subselect */
......@@ -204,11 +216,11 @@ class Item_in_subselect :public Item_exists_subselect
bool abort_on_null;
bool transformed;
public:
Item_func_not_all *upper_not; // point on NOT before ALL subquery
Item_func_not_all *upper_item; // point on NOT/NOP before ALL/SOME subquery
Item_in_subselect(Item * left_expr, st_select_lex *select_lex);
Item_in_subselect()
:Item_exists_subselect(), abort_on_null(0), transformed(0), upper_not(0)
:Item_exists_subselect(), abort_on_null(0), transformed(0), upper_item(0)
{}
......@@ -249,7 +261,7 @@ class Item_allany_subselect :public Item_in_subselect
st_select_lex *select_lex, bool all);
// only ALL subquery has upper not
subs_type substype() { return upper_not?ALL_SUBS:ANY_SUBS; }
subs_type substype() { return all?ALL_SUBS:ANY_SUBS; }
trans_res select_transformer(JOIN *join);
void print(String *str);
};
......
......@@ -537,9 +537,24 @@ void Item_sum_hybrid::cleanup()
DBUG_ENTER("Item_sum_hybrid::cleanup");
Item_sum::cleanup();
used_table_cache= ~(table_map) 0;
/*
by default it is TRUE to avoid TRUE reporting by
Item_func_not_all/Item_func_nop_all if this item was never called.
no_rows_in_result() set it to FALSE if was not results found.
If some results found it will be left unchanged.
*/
was_values= TRUE;
DBUG_VOID_RETURN;
}
void Item_sum_hybrid::no_rows_in_result()
{
Item_sum::no_rows_in_result();
was_values= FALSE;
}
Item *Item_sum_min::copy_or_same(THD* thd)
{
......
......@@ -402,18 +402,20 @@ class Item_sum_hybrid :public Item_sum
enum_field_types hybrid_field_type;
int cmp_sign;
table_map used_table_cache;
bool was_values; // Set if we have found at least one row (for max/min only)
public:
Item_sum_hybrid(Item *item_par,int sign)
:Item_sum(item_par), sum(0.0), sum_int(0),
hybrid_type(INT_RESULT), hybrid_field_type(FIELD_TYPE_LONGLONG),
cmp_sign(sign), used_table_cache(~(table_map) 0)
cmp_sign(sign), used_table_cache(~(table_map) 0), was_values(TRUE)
{ collation.set(&my_charset_bin); }
Item_sum_hybrid(THD *thd, Item_sum_hybrid *item):
Item_sum(thd, item), value(item->value),
sum(item->sum), sum_int(item->sum_int), hybrid_type(item->hybrid_type),
hybrid_field_type(item->hybrid_field_type),cmp_sign(item->cmp_sign),
used_table_cache(item->used_table_cache)
used_table_cache(item->used_table_cache),
was_values(TRUE)
{ collation.set(item->collation); }
bool fix_fields(THD *, TABLE_LIST *, Item **);
table_map used_tables() const { return used_table_cache; }
......@@ -433,6 +435,8 @@ class Item_sum_hybrid :public Item_sum
void min_max_update_real_field();
void min_max_update_int_field();
void cleanup();
bool any_value() { return was_values; }
void no_rows_in_result();
};
......
......@@ -1244,9 +1244,10 @@ bool select_singlerow_subselect::send_data(List<Item> &items)
bool select_max_min_finder_subselect::send_data(List<Item> &items)
{
DBUG_ENTER("select_max_min_finder_subselect::send_data");
Item_singlerow_subselect *it= (Item_singlerow_subselect *)item;
Item_maxmin_subselect *it= (Item_maxmin_subselect *)item;
List_iterator_fast<Item> li(items);
Item *val_item= li++;
it->register_value();
if (it->assigned())
{
cache->store(val_item);
......
......@@ -2600,7 +2600,9 @@ mysql_execute_command(THD *thd)
check_access(thd, SELECT_ACL | EXTRA_ACL, tables->db,
&tables->grant.privilege,0,0))
goto error;
res = mysqld_show_create(thd, tables);
if (grant_option && check_grant(thd, SELECT_ACL, tables, 2, UINT_MAX, 0))
goto error;
res= mysqld_show_create(thd, tables);
break;
}
#endif
......@@ -5085,9 +5087,9 @@ Item * all_any_subquery_creator(Item *left_expr,
Item_allany_subselect *it=
new Item_allany_subselect(left_expr, (*cmp)(all), select_lex, all);
if (all)
return it->upper_not= new Item_func_not_all(it); /* ALL */
return it->upper_item= new Item_func_not_all(it); /* ALL */
return it; /* ANY/SOME */
return it->upper_item= new Item_func_nop_all(it); /* ANY/SOME */
}
......
......@@ -394,6 +394,8 @@ int st_select_lex_unit::exec()
if (uncacheable || !item || !item->assigned() || describe)
{
if (item)
item->reset_value_registration();
if (optimized && item)
{
if (item->assigned())
......
......@@ -11389,6 +11389,67 @@ static void test_conversion()
myquery(rc);
}
static void test_rewind(void)
{
MYSQL_STMT *stmt;
MYSQL_BIND bind;
int rc = 0;
const char *stmt_text;
long unsigned int length=4, Data=0;
my_bool isnull=0;
myheader("test_rewind");
stmt_text= "CREATE TABLE t1 (a int)";
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
myquery(rc);
stmt_text= "INSERT INTO t1 VALUES(2),(3),(4)";
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
myquery(rc);
stmt= mysql_stmt_init(mysql);
stmt_text= "SELECT * FROM t1";
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
check_execute(stmt, rc);
bzero(&bind,sizeof(MYSQL_BIND));
bind.buffer_type= MYSQL_TYPE_LONG;
bind.buffer= (void *)&Data; /* this buffer won't be altered */
bind.length= &length;
bind.is_null= &isnull;
rc= mysql_stmt_execute(stmt);
check_execute(stmt, rc);
rc= mysql_stmt_store_result(stmt);
DIE_UNLESS(rc == 0);
rc= mysql_stmt_bind_result(stmt, &bind);
DIE_UNLESS(rc == 0);
/* retreive all result sets till we are at the end */
while(!mysql_stmt_fetch(stmt))
printf("fetched result:%ld\n", Data);
DIE_UNLESS(rc != MYSQL_NO_DATA);
/* seek to the first row */
mysql_stmt_data_seek(stmt, 0);
/* now we should be able to fetch the results again */
/* but mysql_stmt_fetch returns MYSQL_NO_DATA */
while(!(rc= mysql_stmt_fetch(stmt)))
printf("fetched result after seek:%ld\n", Data);
DIE_UNLESS(rc == MYSQL_NO_DATA);
stmt_text= "DROP TABLE t1";
rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
myquery(rc);
rc= mysql_stmt_free_result(stmt);
rc= mysql_stmt_close(stmt);
}
/*
Read and parse arguments and MySQL options from my.cnf
......@@ -11594,6 +11655,7 @@ static struct my_tests_st my_tests[]= {
{ "test_datetime_ranges", test_datetime_ranges },
{ "test_bug4172", test_bug4172 },
{ "test_conversion", test_conversion },
{ "test_rewind", test_rewind },
{ 0, 0 }
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment