Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-maint
This commit is contained in:
commit
ad66e7a0dd
@ -5,9 +5,13 @@
|
||||
#
|
||||
|
||||
check_cpu () {
|
||||
if test -r /proc/cpuinfo ; then
|
||||
CPUINFO=/proc/cpuinfo
|
||||
if test -n "$TEST_CPUINFO" ; then
|
||||
CPUINFO=$TEST_CPUINFO
|
||||
fi
|
||||
if test -r "$CPUINFO" -a "$CPUINFO" != " " ; then
|
||||
# on Linux (and others?) we can get detailed CPU information out of /proc
|
||||
cpuinfo="cat /proc/cpuinfo"
|
||||
cpuinfo="cat $CPUINFO"
|
||||
|
||||
# detect CPU family
|
||||
cpu_family=`$cpuinfo | grep 'family' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1`
|
||||
@ -33,6 +37,7 @@ check_cpu () {
|
||||
done
|
||||
else
|
||||
# Fallback when there is no /proc/cpuinfo
|
||||
CPUINFO=" "
|
||||
case "`uname -s`" in
|
||||
FreeBSD|OpenBSD)
|
||||
cpu_family=`uname -m`;
|
||||
@ -84,6 +89,18 @@ check_cpu () {
|
||||
*Pentium*M*pro*)
|
||||
cpu_arg="pentium-m";
|
||||
;;
|
||||
*Celeron\(R\)*\ M*)
|
||||
cpu_arg="pentium-m";
|
||||
;;
|
||||
*Celeron*Coppermine*)
|
||||
cpu_arg="pentium3"
|
||||
;;
|
||||
*Celeron\(R\)*)
|
||||
cpu_arg="pentium4"
|
||||
;;
|
||||
*Celeron*)
|
||||
cpu_arg="pentium2";
|
||||
;;
|
||||
*Athlon*64*)
|
||||
cpu_arg="athlon64";
|
||||
;;
|
||||
@ -120,7 +137,14 @@ check_cpu () {
|
||||
esac
|
||||
|
||||
|
||||
if test -z "$cpu_arg"; then
|
||||
if test -z "$cpu_arg" ; then
|
||||
if test "$CPUINFO" != " " ; then
|
||||
# fallback to uname if necessary
|
||||
TEST_CPUINFO=" "
|
||||
check_cpu_cflags=""
|
||||
check_cpu
|
||||
return
|
||||
fi
|
||||
echo "BUILD/check-cpu: Oops, could not find out what kind of cpu this machine is using." >&2
|
||||
check_cpu_cflags=""
|
||||
return
|
||||
|
@ -175,7 +175,7 @@ _rl_fix_last_undo_of_type (type, start, end)
|
||||
|
||||
for (rl = rl_undo_list; rl; rl = rl->next)
|
||||
{
|
||||
if (rl->what == (uint) type)
|
||||
if (rl->what == (unsigned int) type)
|
||||
{
|
||||
rl->start = start;
|
||||
rl->end = end;
|
||||
|
@ -2524,9 +2524,9 @@ linked_client_targets="linked_libmysql_sources"
|
||||
|
||||
if test "$THREAD_SAFE_CLIENT" = "no"
|
||||
then
|
||||
sql_client_dirs="strings regex mysys extra libmysql client"
|
||||
sql_client_dirs="strings regex mysys dbug extra libmysql client"
|
||||
else
|
||||
sql_client_dirs="strings regex mysys extra libmysql libmysql_r client"
|
||||
sql_client_dirs="strings regex mysys dbug extra libmysql libmysql_r client"
|
||||
linked_client_targets="$linked_client_targets linked_libmysql_r_sources"
|
||||
AC_CONFIG_FILES(libmysql_r/Makefile)
|
||||
AC_DEFINE([THREAD_SAFE_CLIENT], [1], [Should be client be thread safe])
|
||||
|
@ -121,6 +121,7 @@ typedef struct st_thr_lock {
|
||||
void (*get_status)(void*, int); /* When one gets a lock */
|
||||
void (*copy_status)(void*,void*);
|
||||
void (*update_status)(void*); /* Before release of write */
|
||||
void (*restore_status)(void*); /* Before release of read */
|
||||
my_bool (*check_status)(void *);
|
||||
} THR_LOCK;
|
||||
|
||||
|
@ -815,18 +815,19 @@ uint mi_get_pointer_length(ulonglong file_length, uint def)
|
||||
if (file_length) /* If not default */
|
||||
{
|
||||
#ifdef NOT_YET_READY_FOR_8_BYTE_POINTERS
|
||||
if (file_length >= (longlong) 1 << 56)
|
||||
if (file_length >= ULL(1) << 56)
|
||||
def=8;
|
||||
else
|
||||
#endif
|
||||
if (file_length >= (longlong) 1 << 48)
|
||||
if (file_length >= ULL(1) << 48)
|
||||
def=7;
|
||||
if (file_length >= (longlong) 1 << 40)
|
||||
else if (file_length >= ULL(1) << 40)
|
||||
def=6;
|
||||
else if (file_length >= (longlong) 1 << 32)
|
||||
else if (file_length >= ULL(1) << 32)
|
||||
def=5;
|
||||
else if (file_length >= (1L << 24))
|
||||
else if (file_length >= ULL(1) << 24)
|
||||
def=4;
|
||||
else if (file_length >= (1L << 16))
|
||||
else if (file_length >= ULL(1) << 16)
|
||||
def=3;
|
||||
else
|
||||
def=2;
|
||||
|
@ -80,7 +80,7 @@ int _mi_write_blob_record(MI_INFO *info, const byte *record)
|
||||
#endif
|
||||
if (!(rec_buff=(byte*) my_alloca(reclength)))
|
||||
{
|
||||
my_errno=ENOMEM;
|
||||
my_errno= HA_ERR_OUT_OF_MEM; /* purecov: inspected */
|
||||
return(-1);
|
||||
}
|
||||
reclength2= _mi_rec_pack(info,rec_buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER),
|
||||
@ -114,7 +114,7 @@ int _mi_update_blob_record(MI_INFO *info, my_off_t pos, const byte *record)
|
||||
#endif
|
||||
if (!(rec_buff=(byte*) my_alloca(reclength)))
|
||||
{
|
||||
my_errno=ENOMEM;
|
||||
my_errno= HA_ERR_OUT_OF_MEM; /* purecov: inspected */
|
||||
return(-1);
|
||||
}
|
||||
reclength=_mi_rec_pack(info,rec_buff+ALIGN_SIZE(MI_MAX_DYN_BLOCK_HEADER),
|
||||
|
@ -325,6 +325,15 @@ void mi_update_status(void* param)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mi_restore_status(void *param)
|
||||
{
|
||||
MI_INFO *info= (MI_INFO*) param;
|
||||
info->state= &info->s->state.state;
|
||||
info->append_insert_at_end= 0;
|
||||
}
|
||||
|
||||
|
||||
void mi_copy_status(void* to,void *from)
|
||||
{
|
||||
((MI_INFO*) to)->state= &((MI_INFO*) from)->save_state;
|
||||
|
@ -322,7 +322,13 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
||||
for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++)
|
||||
{
|
||||
disk_pos=mi_keyseg_read(disk_pos, pos);
|
||||
|
||||
if (pos->flag & HA_BLOB_PART &&
|
||||
! (share->options & (HA_OPTION_COMPRESS_RECORD |
|
||||
HA_OPTION_PACK_RECORD)))
|
||||
{
|
||||
my_errno= HA_ERR_CRASHED;
|
||||
goto err;
|
||||
}
|
||||
if (pos->type == HA_KEYTYPE_TEXT ||
|
||||
pos->type == HA_KEYTYPE_VARTEXT1 ||
|
||||
pos->type == HA_KEYTYPE_VARTEXT2)
|
||||
@ -440,6 +446,13 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
||||
offset+=share->rec[i].length;
|
||||
}
|
||||
share->rec[i].type=(int) FIELD_LAST; /* End marker */
|
||||
if (offset > share->base.reclength)
|
||||
{
|
||||
/* purecov: begin inspected */
|
||||
my_errno= HA_ERR_CRASHED;
|
||||
goto err;
|
||||
/* purecov: end */
|
||||
}
|
||||
|
||||
if (! lock_error)
|
||||
{
|
||||
@ -504,6 +517,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
||||
share->lock.get_status=mi_get_status;
|
||||
share->lock.copy_status=mi_copy_status;
|
||||
share->lock.update_status=mi_update_status;
|
||||
share->lock.restore_status= mi_restore_status;
|
||||
share->lock.check_status=mi_check_status;
|
||||
}
|
||||
}
|
||||
|
@ -196,7 +196,8 @@ err:
|
||||
save_errno=my_errno;
|
||||
if (changed)
|
||||
key_changed|= HA_STATE_CHANGED;
|
||||
if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL)
|
||||
if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_OUT_OF_MEM ||
|
||||
my_errno == HA_ERR_RECORD_FILE_FULL)
|
||||
{
|
||||
info->errkey= (int) i;
|
||||
flag=0;
|
||||
|
@ -168,7 +168,7 @@ int mi_write(MI_INFO *info, byte *record)
|
||||
err:
|
||||
save_errno=my_errno;
|
||||
if (my_errno == HA_ERR_FOUND_DUPP_KEY || my_errno == HA_ERR_RECORD_FILE_FULL ||
|
||||
my_errno == HA_ERR_NULL_IN_SPATIAL)
|
||||
my_errno == HA_ERR_NULL_IN_SPATIAL || my_errno == HA_ERR_OUT_OF_MEM)
|
||||
{
|
||||
if (info->bulk_insert)
|
||||
{
|
||||
|
@ -731,6 +731,7 @@ int mi_unique_comp(MI_UNIQUEDEF *def, const byte *a, const byte *b,
|
||||
my_bool null_are_equal);
|
||||
void mi_get_status(void* param, int concurrent_insert);
|
||||
void mi_update_status(void* param);
|
||||
void mi_restore_status(void* param);
|
||||
void mi_copy_status(void* to,void *from);
|
||||
my_bool mi_check_status(void* param);
|
||||
void mi_disable_non_unique_index(MI_INFO *info, ha_rows rows);
|
||||
|
51
mysql-test/include/wait_show_pattern.inc
Normal file
51
mysql-test/include/wait_show_pattern.inc
Normal file
@ -0,0 +1,51 @@
|
||||
# include/wait_show_pattern.inc
|
||||
#
|
||||
# SUMMARY
|
||||
#
|
||||
# Waits until output produced by SHOW statement which particular type is
|
||||
# specified as parameter matches certain pattern or maximum time reached.
|
||||
#
|
||||
# NOTES
|
||||
#
|
||||
# Only the first row produced by the parameter statement is checked.
|
||||
#
|
||||
# USAGE
|
||||
#
|
||||
# let $show_type= <Tail of SHOW statement>;
|
||||
# let $show_pattern= 'Pattern to be used for LIKE matching';
|
||||
# --source wait_show_pattern.inc
|
||||
#
|
||||
# EXAMPLES
|
||||
#
|
||||
# alter_table-big.test, wait_slave_status.inc
|
||||
#
|
||||
# SEE ALSO
|
||||
#
|
||||
# wait_slave_status.inc, wait_condition.inc (>=5.1)
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
--disable_query_log
|
||||
|
||||
# We accept to wait maximum 30 seconds (0.2 sec/loop).
|
||||
let $wait_counter= 150;
|
||||
while ($wait_counter)
|
||||
{
|
||||
let $result= `SHOW $show_type`;
|
||||
let $success= `SELECT '$result' LIKE $show_pattern`;
|
||||
if ($success)
|
||||
{
|
||||
let $wait_counter= 0;
|
||||
}
|
||||
if (!$success)
|
||||
{
|
||||
real_sleep 0.2;
|
||||
dec $wait_counter;
|
||||
}
|
||||
}
|
||||
if (!$success)
|
||||
{
|
||||
echo Timeout in wait_show_pattern.inc \$show_type= $show_type \$show_pattern= $show_pattern (\$result= '$result');
|
||||
}
|
||||
|
||||
--enable_query_log
|
@ -104,50 +104,21 @@
|
||||
eval SELECT "let \$result_pattern= $result_pattern ;" AS "";
|
||||
SELECT '--source include/wait_slave_status.inc' AS "";
|
||||
|
||||
# We accept to wait maximum 30 seconds (0.2 sec/loop).
|
||||
let $max_wait= 150;
|
||||
while ($max_wait)
|
||||
{
|
||||
let $my_val= `SHOW SLAVE STATUS`;
|
||||
# Now we have the first record of the SHOW result set as one fat string
|
||||
# within the variable $my_val.
|
||||
|
||||
eval SET @my_val = '$my_val';
|
||||
# DEBUG eval SELECT @my_val AS "response to SHOW SLAVE STATUS";
|
||||
|
||||
eval SELECT @my_val LIKE $result_pattern INTO @success;
|
||||
# @success is '1' if we have a match
|
||||
# '0' if we have no match
|
||||
# DEBUG SELECT @success;
|
||||
|
||||
let $success= `SELECT @success`;
|
||||
let $no_success= `SELECT @success = 0`;
|
||||
if ($success)
|
||||
{
|
||||
# We reached the expected result and want to jump out of the loop
|
||||
# without unneeded sleeps.
|
||||
# Attention: Do not set $max_wait to 0, because "while" with negative value
|
||||
# does not work.
|
||||
let $max_wait= 1;
|
||||
}
|
||||
if ($no_success)
|
||||
{
|
||||
# We did not reach the expected result and will have to sleep again
|
||||
# or jump out of the loop, when max_wait is exhausted.
|
||||
real_sleep 0.2;
|
||||
}
|
||||
dec $max_wait;
|
||||
}
|
||||
let $show_type= SLAVE STATUS;
|
||||
let $show_pattern= $result_pattern;
|
||||
--enable_query_log
|
||||
if ($no_success)
|
||||
|
||||
--source include/wait_show_pattern.inc
|
||||
|
||||
if (!$success)
|
||||
{
|
||||
let $message= ! Attention: Timeout in wait_slave_status.inc.
|
||||
| Possible reasons with decreasing probability:
|
||||
| - The LIKE pattern ($result_pattern) is wrong, because the
|
||||
| - The LIKE pattern is wrong, because the
|
||||
| testcase was altered or the layout of the
|
||||
| SHOW SLAVE STATUS result set changed.
|
||||
| - There is a new bug within the replication.
|
||||
| - We met an extreme testing environment and $max_wait is
|
||||
| - We met an extreme testing environment and timeout is
|
||||
| too small.;
|
||||
--source include/show_msg80.inc
|
||||
--echo DEBUG INFO START (wait_slave_status.inc):
|
||||
|
@ -1039,7 +1039,7 @@ sub command_line_setup () {
|
||||
# On some operating systems, there is a limit to the length of a
|
||||
# UNIX domain socket's path far below PATH_MAX, so try to avoid long
|
||||
# socket path names.
|
||||
$sockdir = tempdir(CLEANUP => 1) if ( length($sockdir) > 80 );
|
||||
$sockdir = tempdir(CLEANUP => 0) if ( length($sockdir) > 80 );
|
||||
|
||||
# Put this into a hash, will be a C struct
|
||||
|
||||
|
18
mysql-test/r/alter_table-big.result
Normal file
18
mysql-test/r/alter_table-big.result
Normal file
@ -0,0 +1,18 @@
|
||||
drop table if exists t1, t2;
|
||||
create table t1 (n1 int, n2 int, n3 int,
|
||||
key (n1, n2, n3),
|
||||
key (n2, n3, n1),
|
||||
key (n3, n1, n2));
|
||||
create table t2 (i int);
|
||||
alter table t1 disable keys;
|
||||
reset master;
|
||||
alter table t1 enable keys;;
|
||||
insert into t2 values (1);
|
||||
insert into t1 values (1, 1, 1);
|
||||
show binlog events in 'master-bin.000001' from 98;
|
||||
Log_name Pos Event_type Server_id End_log_pos Info
|
||||
master-bin.000001 # Query 1 # use `test`; insert into t2 values (1)
|
||||
master-bin.000001 # Query 1 # use `test`; alter table t1 enable keys
|
||||
master-bin.000001 # Query 1 # use `test`; insert into t1 values (1, 1, 1)
|
||||
drop tables t1, t2;
|
||||
End of 5.0 tests
|
@ -703,6 +703,119 @@ SHOW INDEX FROM bug24219_2;
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
bug24219_2 1 a 1 a A NULL NULL NULL YES BTREE disabled
|
||||
DROP TABLE bug24219_2;
|
||||
drop table if exists table_24562;
|
||||
create table table_24562(
|
||||
section int,
|
||||
subsection int,
|
||||
title varchar(50));
|
||||
insert into table_24562 values
|
||||
(1, 0, "Introduction"),
|
||||
(1, 1, "Authors"),
|
||||
(1, 2, "Acknowledgements"),
|
||||
(2, 0, "Basics"),
|
||||
(2, 1, "Syntax"),
|
||||
(2, 2, "Client"),
|
||||
(2, 3, "Server"),
|
||||
(3, 0, "Intermediate"),
|
||||
(3, 1, "Complex queries"),
|
||||
(3, 2, "Stored Procedures"),
|
||||
(3, 3, "Stored Functions"),
|
||||
(4, 0, "Advanced"),
|
||||
(4, 1, "Replication"),
|
||||
(4, 2, "Load balancing"),
|
||||
(4, 3, "High availability"),
|
||||
(5, 0, "Conclusion");
|
||||
select * from table_24562;
|
||||
section subsection title
|
||||
1 0 Introduction
|
||||
1 1 Authors
|
||||
1 2 Acknowledgements
|
||||
2 0 Basics
|
||||
2 1 Syntax
|
||||
2 2 Client
|
||||
2 3 Server
|
||||
3 0 Intermediate
|
||||
3 1 Complex queries
|
||||
3 2 Stored Procedures
|
||||
3 3 Stored Functions
|
||||
4 0 Advanced
|
||||
4 1 Replication
|
||||
4 2 Load balancing
|
||||
4 3 High availability
|
||||
5 0 Conclusion
|
||||
alter table table_24562 add column reviewer varchar(20),
|
||||
order by title;
|
||||
select * from table_24562;
|
||||
section subsection title reviewer
|
||||
1 2 Acknowledgements NULL
|
||||
4 0 Advanced NULL
|
||||
1 1 Authors NULL
|
||||
2 0 Basics NULL
|
||||
2 2 Client NULL
|
||||
3 1 Complex queries NULL
|
||||
5 0 Conclusion NULL
|
||||
4 3 High availability NULL
|
||||
3 0 Intermediate NULL
|
||||
1 0 Introduction NULL
|
||||
4 2 Load balancing NULL
|
||||
4 1 Replication NULL
|
||||
2 3 Server NULL
|
||||
3 3 Stored Functions NULL
|
||||
3 2 Stored Procedures NULL
|
||||
2 1 Syntax NULL
|
||||
update table_24562 set reviewer="Me" where section=2;
|
||||
update table_24562 set reviewer="You" where section=3;
|
||||
alter table table_24562
|
||||
order by section ASC, subsection DESC;
|
||||
select * from table_24562;
|
||||
section subsection title reviewer
|
||||
1 2 Acknowledgements NULL
|
||||
1 1 Authors NULL
|
||||
1 0 Introduction NULL
|
||||
2 3 Server Me
|
||||
2 2 Client Me
|
||||
2 1 Syntax Me
|
||||
2 0 Basics Me
|
||||
3 3 Stored Functions You
|
||||
3 2 Stored Procedures You
|
||||
3 1 Complex queries You
|
||||
3 0 Intermediate You
|
||||
4 3 High availability NULL
|
||||
4 2 Load balancing NULL
|
||||
4 1 Replication NULL
|
||||
4 0 Advanced NULL
|
||||
5 0 Conclusion NULL
|
||||
alter table table_24562
|
||||
order by table_24562.subsection ASC, table_24562.section DESC;
|
||||
select * from table_24562;
|
||||
section subsection title reviewer
|
||||
5 0 Conclusion NULL
|
||||
4 0 Advanced NULL
|
||||
3 0 Intermediate You
|
||||
2 0 Basics Me
|
||||
1 0 Introduction NULL
|
||||
4 1 Replication NULL
|
||||
3 1 Complex queries You
|
||||
2 1 Syntax Me
|
||||
1 1 Authors NULL
|
||||
4 2 Load balancing NULL
|
||||
3 2 Stored Procedures You
|
||||
2 2 Client Me
|
||||
1 2 Acknowledgements NULL
|
||||
4 3 High availability NULL
|
||||
3 3 Stored Functions You
|
||||
2 3 Server Me
|
||||
alter table table_24562 order by 12;
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '12' at line 1
|
||||
alter table table_24562 order by (section + 12);
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(section + 12)' at line 1
|
||||
alter table table_24562 order by length(title);
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'length(title)' at line 1
|
||||
alter table table_24562 order by (select 12 from dual);
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(select 12 from dual)' at line 1
|
||||
alter table table_24562 order by no_such_col;
|
||||
ERROR 42S22: Unknown column 'no_such_col' in 'order clause'
|
||||
drop table table_24562;
|
||||
create table t1 (mycol int(10) not null);
|
||||
alter table t1 alter column mycol set default 0;
|
||||
desc t1;
|
||||
|
@ -176,6 +176,14 @@ create table t1 (a int);
|
||||
delete `4.t1` from t1 as `4.t1` where `4.t1`.a = 5;
|
||||
delete FROM `4.t1` USING t1 as `4.t1` where `4.t1`.a = 5;
|
||||
drop table t1;
|
||||
create table t1(f1 int primary key);
|
||||
insert into t1 values (4),(3),(1),(2);
|
||||
delete from t1 where (@a:= f1) order by f1 limit 1;
|
||||
select @a;
|
||||
@a
|
||||
1
|
||||
drop table t1;
|
||||
End of 4.1 tests
|
||||
CREATE TABLE t1 (a int not null,b int not null);
|
||||
CREATE TABLE t2 (a int not null, b int not null, primary key (a,b));
|
||||
CREATE TABLE t3 (a int not null, b int not null, primary key (a,b));
|
||||
|
@ -67,3 +67,26 @@ id d e m_id f
|
||||
4 bword aword NULL NULL
|
||||
5 aword and bword NULL 5
|
||||
drop table t1,t2;
|
||||
CREATE TABLE t1 (
|
||||
id int(10) NOT NULL auto_increment,
|
||||
link int(10) default NULL,
|
||||
name mediumtext default NULL,
|
||||
PRIMARY KEY (id),
|
||||
FULLTEXT (name)
|
||||
);
|
||||
INSERT INTO t1 VALUES (1, 1, 'string');
|
||||
INSERT INTO t1 VALUES (2, 0, 'string');
|
||||
CREATE TABLE t2 (
|
||||
id int(10) NOT NULL auto_increment,
|
||||
name mediumtext default NULL,
|
||||
PRIMARY KEY (id),
|
||||
FULLTEXT (name)
|
||||
);
|
||||
INSERT INTO t2 VALUES (1, 'string');
|
||||
SELECT t1.*, MATCH(t1.name) AGAINST('string') AS relevance
|
||||
FROM t1 LEFT JOIN t2 ON t1.link = t2.id
|
||||
WHERE MATCH(t1.name, t2.name) AGAINST('string' IN BOOLEAN MODE);
|
||||
id link name relevance
|
||||
1 1 string 0
|
||||
2 0 string 0
|
||||
DROP TABLE t1,t2;
|
||||
|
@ -355,4 +355,47 @@ some_id
|
||||
1
|
||||
2
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (a int, b int, PRIMARY KEY (a));
|
||||
INSERT INTO t1 VALUES (1,1),(2,1),(3,1),(4,1),(5,1),(6,1);
|
||||
CREATE TABLE t2 (a int, b int, PRIMARY KEY (a));
|
||||
INSERT INTO t2 VALUES (3,2),(4,2);
|
||||
CREATE TABLE t3 (a int PRIMARY KEY);
|
||||
INSERT INTO t3 VALUES (1),(2),(3),(4);
|
||||
CREATE TABLE t4 (a int PRIMARY KEY);
|
||||
INSERT INTO t4 VALUES (1),(2);
|
||||
EXPLAIN SELECT STRAIGHT_JOIN * FROM t3
|
||||
JOIN t1 ON t3.a=t1.a
|
||||
JOIN t2 ON t3.a=t2.a
|
||||
JOIN t4 WHERE t4.a IN (t1.b, t2.b);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t3 index PRIMARY PRIMARY 4 NULL 4 Using index
|
||||
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1
|
||||
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t3.a 1
|
||||
1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 2 Range checked for each record (index map: 0x1)
|
||||
SELECT STRAIGHT_JOIN * FROM t3
|
||||
JOIN t1 ON t3.a=t1.a
|
||||
JOIN t2 ON t3.a=t2.a
|
||||
JOIN t4 WHERE t4.a IN (t1.b, t2.b);
|
||||
a a b a b a
|
||||
3 3 1 3 2 1
|
||||
3 3 1 3 2 2
|
||||
4 4 1 4 2 1
|
||||
4 4 1 4 2 2
|
||||
EXPLAIN SELECT STRAIGHT_JOIN
|
||||
(SELECT SUM(t4.a) FROM t4 WHERE t4.a IN (t1.b, t2.b))
|
||||
FROM t3, t1, t2
|
||||
WHERE t3.a=t1.a AND t3.a=t2.a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t3 index PRIMARY PRIMARY 4 NULL 4 Using index
|
||||
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1
|
||||
1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t3.a 1
|
||||
2 DEPENDENT SUBQUERY t4 index NULL PRIMARY 4 NULL 2 Using where; Using index
|
||||
SELECT STRAIGHT_JOIN
|
||||
(SELECT SUM(t4.a) FROM t4 WHERE t4.a IN (t1.b, t2.b))
|
||||
FROM t3, t1, t2
|
||||
WHERE t3.a=t1.a AND t3.a=t2.a;
|
||||
(SELECT SUM(t4.a) FROM t4 WHERE t4.a IN (t1.b, t2.b))
|
||||
3
|
||||
3
|
||||
DROP TABLE t1,t2,t3,t4;
|
||||
End of 5.0 tests
|
||||
|
@ -817,7 +817,7 @@ explain extended select md5('hello'), sha('abc'), sha1('abc'), soundex(''), 'moo
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
Warnings:
|
||||
Note 1003 select md5(_latin1'hello') AS `md5('hello')`,sha(_latin1'abc') AS `sha('abc')`,sha(_latin1'abc') AS `sha1('abc')`,soundex(_latin1'') AS `soundex('')`,(soundex(_latin1'mood') = soundex(_latin1'mud')) AS `'mood' sounds like 'mud'`,aes_decrypt(aes_encrypt(_latin1'abc',_latin1'1'),_latin1'1') AS `aes_decrypt(aes_encrypt('abc','1'),'1')`,concat(_latin1'*',repeat(_latin1' ',5),_latin1'*') AS `concat('*',space(5),'*')`,reverse(_latin1'abc') AS `reverse('abc')`,rpad(_latin1'a',4,_latin1'1') AS `rpad('a',4,'1')`,lpad(_latin1'a',4,_latin1'1') AS `lpad('a',4,'1')`,concat_ws(_latin1',',_latin1'',NULL,_latin1'a') AS `concat_ws(',','',NULL,'a')`,make_set(255,_latin2'a',_latin2'b',_latin2'c') AS `make_set(255,_latin2'a',_latin2'b',_latin2'c')`,elt(2,1) AS `elt(2,1)`,locate(_latin1'a',_latin1'b',2) AS `locate("a","b",2)`,format(130,10) AS `format(130,10)`,char(0) AS `char(0)`,conv(130,16,10) AS `conv(130,16,10)`,hex(130) AS `hex(130)`,cast(_latin1'HE' as char charset binary) AS `binary 'HE'`,export_set(255,_latin2'y',_latin2'n',_latin2' ') AS `export_set(255,_latin2'y',_latin2'n',_latin2' ')`,field((_latin1'b' collate latin1_bin),_latin1'A',_latin1'B') AS `FIELD('b' COLLATE latin1_bin,'A','B')`,find_in_set(_latin1'B',_latin1'a,b,c,d') AS `FIND_IN_SET(_latin1'B',_latin1'a,b,c,d')`,collation(conv(130,16,10)) AS `collation(conv(130,16,10))`,coercibility(conv(130,16,10)) AS `coercibility(conv(130,16,10))`,length(_latin1'\n \r\0\\_\\%\\') AS `length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,concat(_latin1'monty',_latin1' was here ',_latin1'again') AS `concat('monty',' was here ','again')`,length(_latin1'hello') AS `length('hello')`,char(ascii(_latin1'h')) AS `char(ascii('h'))`,ord(_latin1'h') AS `ord('h')`,quote((1 / 0)) AS `quote(1/0)`,crc32(_latin1'123') AS `crc32("123")`,replace(_latin1'aaaa',_latin1'a',_latin1'b') AS `replace('aaaa','a','b')`,insert(_latin1'txs',2,1,_latin1'hi') AS `insert('txs',2,1,'hi')`,left(_latin2'a',1) AS `left(_latin2'a',1)`,right(_latin2'a',1) AS `right(_latin2'a',1)`,lcase(_latin2'a') AS `lcase(_latin2'a')`,ucase(_latin2'a') AS `ucase(_latin2'a')`,substr(_latin1'abcdefg',3,2) AS `SUBSTR('abcdefg',3,2)`,substring_index(_latin1'1abcd;2abcd;3abcd;4abcd',_latin1';',2) AS `substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2)`,trim(_latin2' a ') AS `trim(_latin2' a ')`,ltrim(_latin2' a ') AS `ltrim(_latin2' a ')`,rtrim(_latin2' a ') AS `rtrim(_latin2' a ')`,decode(encode(repeat(_latin1'a',100000))) AS `decode(encode(repeat("a",100000),"monty"),"monty")`
|
||||
Note 1003 select md5(_latin1'hello') AS `md5('hello')`,sha(_latin1'abc') AS `sha('abc')`,sha(_latin1'abc') AS `sha1('abc')`,soundex(_latin1'') AS `soundex('')`,(soundex(_latin1'mood') = soundex(_latin1'mud')) AS `'mood' sounds like 'mud'`,aes_decrypt(aes_encrypt(_latin1'abc',_latin1'1'),_latin1'1') AS `aes_decrypt(aes_encrypt('abc','1'),'1')`,concat(_latin1'*',repeat(_latin1' ',5),_latin1'*') AS `concat('*',space(5),'*')`,reverse(_latin1'abc') AS `reverse('abc')`,rpad(_latin1'a',4,_latin1'1') AS `rpad('a',4,'1')`,lpad(_latin1'a',4,_latin1'1') AS `lpad('a',4,'1')`,concat_ws(_latin1',',_latin1'',NULL,_latin1'a') AS `concat_ws(',','',NULL,'a')`,make_set(255,_latin2'a',_latin2'b',_latin2'c') AS `make_set(255,_latin2'a',_latin2'b',_latin2'c')`,elt(2,1) AS `elt(2,1)`,locate(_latin1'a',_latin1'b',2) AS `locate("a","b",2)`,format(130,10) AS `format(130,10)`,char(0) AS `char(0)`,conv(130,16,10) AS `conv(130,16,10)`,hex(130) AS `hex(130)`,cast(_latin1'HE' as char charset binary) AS `binary 'HE'`,export_set(255,_latin2'y',_latin2'n',_latin2' ') AS `export_set(255,_latin2'y',_latin2'n',_latin2' ')`,field((_latin1'b' collate latin1_bin),_latin1'A',_latin1'B') AS `FIELD('b' COLLATE latin1_bin,'A','B')`,find_in_set(_latin1'B',_latin1'a,b,c,d') AS `FIND_IN_SET(_latin1'B',_latin1'a,b,c,d')`,collation(conv(130,16,10)) AS `collation(conv(130,16,10))`,coercibility(conv(130,16,10)) AS `coercibility(conv(130,16,10))`,length(_latin1'\n \r\0\\_\\%\\') AS `length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,bit_length(_latin1'\n \r\0\\_\\%\\') AS `bit_length('\n\t\r\b\0\_\%\\')`,concat(_latin1'monty',_latin1' was here ',_latin1'again') AS `concat('monty',' was here ','again')`,length(_latin1'hello') AS `length('hello')`,char(ascii(_latin1'h')) AS `char(ascii('h'))`,ord(_latin1'h') AS `ord('h')`,quote((1 / 0)) AS `quote(1/0)`,crc32(_latin1'123') AS `crc32("123")`,replace(_latin1'aaaa',_latin1'a',_latin1'b') AS `replace('aaaa','a','b')`,insert(_latin1'txs',2,1,_latin1'hi') AS `insert('txs',2,1,'hi')`,left(_latin2'a',1) AS `left(_latin2'a',1)`,right(_latin2'a',1) AS `right(_latin2'a',1)`,lcase(_latin2'a') AS `lcase(_latin2'a')`,ucase(_latin2'a') AS `ucase(_latin2'a')`,substr(_latin1'abcdefg',3,2) AS `SUBSTR('abcdefg',3,2)`,substring_index(_latin1'1abcd;2abcd;3abcd;4abcd',_latin1';',2) AS `substring_index("1abcd;2abcd;3abcd;4abcd", ';', 2)`,trim(_latin2' a ') AS `trim(_latin2' a ')`,ltrim(_latin2' a ') AS `ltrim(_latin2' a ')`,rtrim(_latin2' a ') AS `rtrim(_latin2' a ')`,decode(encode(repeat(_latin1'a',100000),'monty'),'monty') AS `decode(encode(repeat("a",100000),"monty"),"monty")`
|
||||
SELECT lpad(12345, 5, "#");
|
||||
lpad(12345, 5, "#")
|
||||
12345
|
||||
@ -1084,6 +1084,18 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`s` AS `s` from `test`.`t1` where (trim(both _latin1'y' from `test`.`t1`.`s`) > _latin1'ab')
|
||||
DROP TABLE t1;
|
||||
create table t1(f1 varchar(4));
|
||||
explain extended select encode(f1,'zxcv') as 'enc' from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 system NULL NULL NULL NULL 0 const row not found
|
||||
Warnings:
|
||||
Note 1003 select encode(`test`.`t1`.`f1`,'zxcv') AS `enc` from `test`.`t1`
|
||||
explain extended select decode(f1,'zxcv') as 'enc' from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 system NULL NULL NULL NULL 0 const row not found
|
||||
Warnings:
|
||||
Note 1003 select decode(`test`.`t1`.`f1`,'zxcv') AS `enc` from `test`.`t1`
|
||||
drop table t1;
|
||||
End of 4.1 tests
|
||||
create table t1 (d decimal default null);
|
||||
insert into t1 values (null);
|
||||
|
@ -933,3 +933,105 @@ b sum(1)
|
||||
18 6
|
||||
19 6
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY, b INT);
|
||||
INSERT INTO t1 VALUES (1,1),(2,1),(3,2),(4,2),(5,3),(6,3);
|
||||
SET SQL_MODE = 'ONLY_FULL_GROUP_BY';
|
||||
SELECT MAX(a)-MIN(a) FROM t1 GROUP BY b;
|
||||
MAX(a)-MIN(a)
|
||||
1
|
||||
1
|
||||
1
|
||||
SELECT CEILING(MIN(a)) FROM t1 GROUP BY b;
|
||||
CEILING(MIN(a))
|
||||
1
|
||||
3
|
||||
5
|
||||
SELECT CASE WHEN AVG(a)>=0 THEN 'Positive' ELSE 'Negative' END FROM t1
|
||||
GROUP BY b;
|
||||
CASE WHEN AVG(a)>=0 THEN 'Positive' ELSE 'Negative' END
|
||||
Positive
|
||||
Positive
|
||||
Positive
|
||||
SELECT a + 1 FROM t1 GROUP BY a;
|
||||
a + 1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
SELECT a + b FROM t1 GROUP BY b;
|
||||
ERROR 42000: 'test.t1.a' isn't in GROUP BY
|
||||
SELECT (SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1)
|
||||
FROM t1 AS t1_outer;
|
||||
(SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1)
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
SELECT 1 FROM t1 as t1_outer GROUP BY a
|
||||
HAVING (SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1);
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
SELECT (SELECT t1_outer.a FROM t1 AS t1_inner LIMIT 1)
|
||||
FROM t1 AS t1_outer GROUP BY t1_outer.b;
|
||||
ERROR 42000: 'test.t1_outer.a' isn't in GROUP BY
|
||||
SELECT 1 FROM t1 as t1_outer GROUP BY a
|
||||
HAVING (SELECT t1_outer.b FROM t1 AS t1_inner LIMIT 1);
|
||||
ERROR 42S22: Unknown column 'test.t1_outer.b' in 'field list'
|
||||
SELECT (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner LIMIT 1)
|
||||
FROM t1 AS t1_outer GROUP BY t1_outer.b;
|
||||
(SELECT SUM(t1_inner.a) FROM t1 AS t1_inner LIMIT 1)
|
||||
21
|
||||
21
|
||||
21
|
||||
SELECT (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner GROUP BY t1_inner.b LIMIT 1)
|
||||
FROM t1 AS t1_outer;
|
||||
(SELECT SUM(t1_inner.a) FROM t1 AS t1_inner GROUP BY t1_inner.b LIMIT 1)
|
||||
3
|
||||
3
|
||||
3
|
||||
3
|
||||
3
|
||||
3
|
||||
SELECT (SELECT SUM(t1_outer.a) FROM t1 AS t1_inner LIMIT 1)
|
||||
FROM t1 AS t1_outer GROUP BY t1_outer.b;
|
||||
ERROR 42000: 'test.t1_outer.a' isn't in GROUP BY
|
||||
SELECT 1 FROM t1 as t1_outer
|
||||
WHERE (SELECT t1_outer.b FROM t1 AS t1_inner GROUP BY t1_inner.b LIMIT 1);
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
SELECT b FROM t1 GROUP BY b HAVING CEILING(b) > 0;
|
||||
b
|
||||
1
|
||||
2
|
||||
3
|
||||
SELECT 1 FROM t1 GROUP BY b HAVING b = 2 OR b = 3 OR SUM(a) > 12;
|
||||
1
|
||||
1
|
||||
1
|
||||
SELECT 1 FROM t1 GROUP BY b HAVING ROW (b,b) = ROW (1,1);
|
||||
1
|
||||
1
|
||||
SELECT 1 FROM t1 GROUP BY b HAVING a = 2;
|
||||
ERROR 42S22: Unknown column 'a' in 'having clause'
|
||||
SELECT 1 FROM t1 GROUP BY SUM(b);
|
||||
ERROR HY000: Invalid use of group function
|
||||
SELECT b FROM t1 AS t1_outer GROUP BY a HAVING t1_outer.a IN
|
||||
(SELECT SUM(t1_inner.b)+t1_outer.b FROM t1 AS t1_inner GROUP BY t1_inner.a
|
||||
HAVING SUM(t1_inner.b)+t1_outer.b > 5);
|
||||
ERROR 42000: 'test.t1_outer.b' isn't in GROUP BY
|
||||
DROP TABLE t1;
|
||||
SET SQL_MODE = '';
|
||||
|
@ -325,3 +325,24 @@ select row_count();
|
||||
row_count()
|
||||
1
|
||||
drop table t1;
|
||||
create table t1 (f1 int unique, f2 int);
|
||||
create table t2 (f3 int, f4 int);
|
||||
create view v1 as select * from t1, t2 where f1= f3;
|
||||
insert into t1 values (1,11), (2,22);
|
||||
insert into t2 values (1,12), (2,24);
|
||||
insert into v1 (f1) values (3) on duplicate key update f3= f3 + 10;
|
||||
ERROR HY000: Can not modify more than one base table through a join view 'test.v1'
|
||||
insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10;
|
||||
select * from t1;
|
||||
f1 f2
|
||||
1 11
|
||||
2 22
|
||||
3 NULL
|
||||
insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10;
|
||||
select * from t1;
|
||||
f1 f2
|
||||
1 11
|
||||
2 22
|
||||
12 NULL
|
||||
drop view v1;
|
||||
drop table t1,t2;
|
||||
|
@ -922,6 +922,27 @@ SET @@myisam_repair_threads=1;
|
||||
SHOW VARIABLES LIKE 'myisam_repair%';
|
||||
Variable_name Value
|
||||
myisam_repair_threads 1
|
||||
CREATE TABLE t1(a VARCHAR(16));
|
||||
INSERT INTO t1 VALUES('aaaaaaaa'),(NULL);
|
||||
UPDATE t1 AS ta1, t1 AS ta2 SET ta1.a='aaaaaaaaaaaaaaaa';
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
aaaaaaaaaaaaaaaa
|
||||
aaaaaaaaaaaaaaaa
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(a INT);
|
||||
INSERT INTO t1 VALUES(1),(2);
|
||||
UPDATE t1,t1 AS t2 SET t1.a=t1.a+2 WHERE t1.a=t2.a-1;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a
|
||||
2
|
||||
3
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (c1 TEXT) AVG_ROW_LENGTH=70100 MAX_ROWS=4100100100;
|
||||
SHOW TABLE STATUS LIKE 't1';
|
||||
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 MyISAM 10 Dynamic X X X 72057594037927935 X X X X X X latin1_swedish_ci X max_rows=4100100100 avg_row_length=70100
|
||||
DROP TABLE t1;
|
||||
End of 4.1 tests
|
||||
set storage_engine=MyISAM;
|
||||
drop table if exists t1,t2,t3;
|
||||
|
@ -749,3 +749,19 @@ f1 f2 f3
|
||||
222222 bbbbbb 2
|
||||
drop table t1;
|
||||
Illegal ndb error code: 1186
|
||||
CREATE TABLE t1 (
|
||||
a VARBINARY(40) NOT NULL,
|
||||
b VARCHAR (256) CHARACTER SET UTF8 NOT NULL,
|
||||
c VARCHAR(256) CHARACTER SET UTF8 NOT NULL,
|
||||
PRIMARY KEY (b,c)) ENGINE=ndbcluster;
|
||||
INSERT INTO t1 VALUES
|
||||
("a","ab","abc"),("b","abc","abcd"),("c","abc","ab"),("d","ab","ab"),("e","abc","abc");
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
a b c
|
||||
a ab abc
|
||||
b abc abcd
|
||||
c abc ab
|
||||
d ab ab
|
||||
e abc abc
|
||||
DROP TABLE t1;
|
||||
End of 5.0 tests
|
||||
|
@ -658,3 +658,11 @@ insert into t1 (a, c) values (1,'aaa'),(3,'bbb');
|
||||
select count(*) from t1 where c<'bbb';
|
||||
count(*)
|
||||
1
|
||||
create table nationaldish (DishID int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
CountryCode char(3) NOT NULL,
|
||||
DishTitle varchar(64) NOT NULL,
|
||||
calories smallint(5) unsigned DEFAULT NULL,
|
||||
PRIMARY KEY (DishID),
|
||||
INDEX i USING HASH (countrycode,calories)
|
||||
) ENGINE=ndbcluster;
|
||||
ERROR HY000: Can't create table './test/nationaldish.frm' (errno: 138)
|
||||
|
@ -367,3 +367,17 @@ a b c
|
||||
406994 67 2006-02-27 11:26:46
|
||||
406995 67 2006-02-28 11:55:00
|
||||
DROP TABLE t1, t11, t12, t21, t22;
|
||||
CREATE TABLE t1 (id varchar(255) NOT NULL,
|
||||
tag int(11) NOT NULL,
|
||||
doc text NOT NULL,
|
||||
type varchar(150) NOT NULL,
|
||||
modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=ndbcluster;
|
||||
INSERT INTO t1 VALUES ('sakila',1,'Some text goes here','text',CURRENT_TIMESTAMP);
|
||||
SELECT id, tag, doc, type FROM t1 WHERE id IN ('flipper','orka');
|
||||
id tag doc type
|
||||
SELECT id, tag, doc, type FROM t1 WHERE id IN ('flipper','sakila');
|
||||
id tag doc type
|
||||
sakila 1 Some text goes here text
|
||||
DROP TABLE t1;
|
||||
|
@ -9,7 +9,7 @@ insert into t2 values (1,1,1),(2,2,2),(3,3,3), (4,4,4), (5,5,5);
|
||||
explain select * from t2 where p NOT IN (select p from t1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where
|
||||
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 Using index
|
||||
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1
|
||||
select * from t2 where p NOT IN (select p from t1) order by p;
|
||||
p u o
|
||||
4 4 4
|
||||
@ -17,7 +17,7 @@ p u o
|
||||
explain select * from t2 where p NOT IN (select u from t1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where
|
||||
2 DEPENDENT SUBQUERY t1 unique_subquery u u 4 func 1 Using index
|
||||
2 DEPENDENT SUBQUERY t1 unique_subquery u u 4 func 1
|
||||
select * from t2 where p NOT IN (select u from t1) order by p;
|
||||
p u o
|
||||
4 4 4
|
||||
@ -25,7 +25,7 @@ p u o
|
||||
explain select * from t2 where p NOT IN (select o from t1);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where
|
||||
2 DEPENDENT SUBQUERY t1 index_subquery o o 4 func 1 Using index
|
||||
2 DEPENDENT SUBQUERY t1 index_subquery o o 4 func 1
|
||||
select * from t2 where p NOT IN (select o from t1) order by p;
|
||||
p u o
|
||||
4 4 4
|
||||
|
@ -1645,4 +1645,20 @@ t1 CREATE TABLE `t1` (
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=100 DEFAULT CHARSET=latin1 COMMENT='comment for table t1'
|
||||
deallocate prepare stmt;
|
||||
drop table t1, t2;
|
||||
drop tables if exists t1;
|
||||
create table t1 (id int primary key auto_increment, value varchar(10));
|
||||
insert into t1 (id, value) values (1, 'FIRST'), (2, 'SECOND'), (3, 'THIRD');
|
||||
prepare stmt from "insert into t1 (id, value) select * from (select 4 as i, 'FOURTH' as v) as y on duplicate key update v = 'DUP'";
|
||||
execute stmt;
|
||||
ERROR 42S22: Unknown column 'v' in 'field list'
|
||||
execute stmt;
|
||||
ERROR 42S22: Unknown column 'v' in 'field list'
|
||||
deallocate prepare stmt;
|
||||
prepare stmt from "insert into t1 (id, value) select * from (select 4 as id, 'FOURTH' as value) as y on duplicate key update y.value = 'DUP'";
|
||||
execute stmt;
|
||||
ERROR 42S22: Unknown column 'y.value' in 'field list'
|
||||
execute stmt;
|
||||
ERROR 42S22: Unknown column 'y.value' in 'field list'
|
||||
deallocate prepare stmt;
|
||||
drop tables t1;
|
||||
End of 5.0 tests.
|
||||
|
@ -674,6 +674,49 @@ select a from t1 where a > 'x';
|
||||
a
|
||||
xx
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (
|
||||
OXID varchar(32) COLLATE latin1_german2_ci NOT NULL DEFAULT '',
|
||||
OXPARENTID varchar(32) COLLATE latin1_german2_ci NOT NULL DEFAULT 'oxrootid',
|
||||
OXLEFT int NOT NULL DEFAULT '0',
|
||||
OXRIGHT int NOT NULL DEFAULT '0',
|
||||
OXROOTID varchar(32) COLLATE latin1_german2_ci NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (OXID),
|
||||
KEY OXNID (OXID),
|
||||
KEY OXLEFT (OXLEFT),
|
||||
KEY OXRIGHT (OXRIGHT),
|
||||
KEY OXROOTID (OXROOTID)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_german2_ci;
|
||||
INSERT INTO t1 VALUES
|
||||
('d8c4177d09f8b11f5.52725521','oxrootid',1,40,'d8c4177d09f8b11f5.52725521'),
|
||||
('d8c4177d151affab2.81582770','d8c4177d09f8b11f5.52725521',2,3,
|
||||
'd8c4177d09f8b11f5.52725521'),
|
||||
('d8c4177d206a333d2.74422679','d8c4177d09f8b11f5.52725521',4,5,
|
||||
'd8c4177d09f8b11f5.52725521'),
|
||||
('d8c4177d225791924.30714720','d8c4177d09f8b11f5.52725521',6,7,
|
||||
'd8c4177d09f8b11f5.52725521'),
|
||||
('d8c4177d2380fc201.39666693','d8c4177d09f8b11f5.52725521',8,9,
|
||||
'd8c4177d09f8b11f5.52725521'),
|
||||
('d8c4177d24ccef970.14957924','d8c4177d09f8b11f5.52725521',10,11,
|
||||
'd8c4177d09f8b11f5.52725521');
|
||||
EXPLAIN
|
||||
SELECT s.oxid FROM t1 v, t1 s
|
||||
WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
|
||||
v.oxrootid ='d8c4177d09f8b11f5.52725521' AND
|
||||
s.oxleft > v.oxleft AND s.oxleft < v.oxright;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE v ref OXLEFT,OXRIGHT,OXROOTID OXROOTID 34 const 5 Using where
|
||||
1 SIMPLE s ALL OXLEFT NULL NULL NULL 5 Range checked for each record (index map: 0x4)
|
||||
SELECT s.oxid FROM t1 v, t1 s
|
||||
WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
|
||||
v.oxrootid ='d8c4177d09f8b11f5.52725521' AND
|
||||
s.oxleft > v.oxleft AND s.oxleft < v.oxright;
|
||||
oxid
|
||||
d8c4177d151affab2.81582770
|
||||
d8c4177d206a333d2.74422679
|
||||
d8c4177d225791924.30714720
|
||||
d8c4177d2380fc201.39666693
|
||||
d8c4177d24ccef970.14957924
|
||||
DROP TABLE t1;
|
||||
End of 4.1 tests
|
||||
CREATE TABLE t1 (
|
||||
id int(11) NOT NULL auto_increment,
|
||||
|
@ -3628,6 +3628,14 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 range si,ai si 5 NULL 2 Using where
|
||||
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
|
||||
DROP TABLE t1,t2,t3;
|
||||
CREATE TABLE t1 ( f1 int primary key, f2 int, f3 int, f4 int, f5 int, f6 int, checked_out int);
|
||||
CREATE TABLE t2 ( f11 int PRIMARY KEY );
|
||||
INSERT INTO t1 VALUES (1,1,1,0,0,0,0),(2,1,1,3,8,1,0),(3,1,1,4,12,1,0);
|
||||
INSERT INTO t2 VALUES (62);
|
||||
SELECT * FROM t1 LEFT JOIN t2 ON f11 = t1.checked_out GROUP BY f1 ORDER BY f2, f3, f4, f5 LIMIT 0, 1;
|
||||
f1 f2 f3 f4 f5 f6 checked_out f11
|
||||
1 1 1 0 0 0 0 NULL
|
||||
DROP TABLE t1, t2;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1(a int);
|
||||
INSERT into t1 values (1), (2), (3);
|
||||
|
@ -187,7 +187,7 @@ Pos Instruction
|
||||
32 set v_dig@4 (v_dig@4 + 1)
|
||||
33 stmt 4 "update sudoku_work set dig = v_dig wh..."
|
||||
34 set v_tcounter@6 (v_tcounter@6 + 1)
|
||||
35 jump_if_not 37(37) not(`test`.`sudoku_digit_ok`(v_row@7,v_col@8,v_dig@4))
|
||||
35 jump_if_not 37(37) (not(`test`.`sudoku_digit_ok`(v_row@7,v_col@8,v_dig@4)))
|
||||
36 jump 15
|
||||
37 set v_i@3 (v_i@3 + 1)
|
||||
38 jump 15
|
||||
|
@ -1250,3 +1250,22 @@ ERROR HY000: View's SELECT contains a variable or parameter
|
||||
PREPARE stmt FROM "CREATE VIEW v AS SELECT ?";
|
||||
ERROR HY000: View's SELECT contains a variable or parameter
|
||||
DROP TABLE t1;
|
||||
drop tables if exists t1;
|
||||
drop procedure if exists bug24491;
|
||||
create table t1 (id int primary key auto_increment, value varchar(10));
|
||||
insert into t1 (id, value) values (1, 'FIRST'), (2, 'SECOND'), (3, 'THIRD');
|
||||
create procedure bug24491()
|
||||
insert into t1 (id, value) select * from (select 4 as i, 'FOURTH' as v) as y on duplicate key update v = 'DUP';
|
||||
call bug24491();
|
||||
ERROR 42S22: Unknown column 'v' in 'field list'
|
||||
call bug24491();
|
||||
ERROR 42S22: Unknown column 'v' in 'field list'
|
||||
drop procedure bug24491;
|
||||
create procedure bug24491()
|
||||
insert into t1 (id, value) select * from (select 4 as id, 'FOURTH' as value) as y on duplicate key update y.value = 'DUP';
|
||||
call bug24491();
|
||||
ERROR 42S22: Unknown column 'y.value' in 'field list'
|
||||
call bug24491();
|
||||
ERROR 42S22: Unknown column 'y.value' in 'field list'
|
||||
drop procedure bug24491;
|
||||
drop tables t1;
|
||||
|
@ -744,7 +744,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`id`,<exists>(select 1 AS `1` having trigcond((<cache>(`test`.`t2`.`id`) = <ref_null_helper>(1))) union select 3 AS `3` having trigcond((<cache>(`test`.`t2`.`id`) = <ref_null_helper>(3)))))
|
||||
Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`id`,<exists>(select 1 AS `1` having (<cache>(`test`.`t2`.`id`) = <ref_null_helper>(1)) union select 3 AS `3` having (<cache>(`test`.`t2`.`id`) = <ref_null_helper>(3))))
|
||||
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3);
|
||||
id
|
||||
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
|
||||
@ -892,7 +892,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 Using index
|
||||
2 DEPENDENT SUBQUERY t2 index_subquery a a 5 func 2 Using index
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,<in_optimizer>(`test`.`t1`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`a`) in t2 on a checking NULL))) AS `t1.a in (select t2.a from t2)` from `test`.`t1`
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,<in_optimizer>(`test`.`t1`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`a`) in t2 on a checking NULL having <is_not_null_test>(`test`.`t2`.`a`)))) AS `t1.a in (select t2.a from t2)` from `test`.`t1`
|
||||
CREATE TABLE t3 (a int(11) default '0');
|
||||
INSERT INTO t3 VALUES (1),(2),(3);
|
||||
SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1;
|
||||
@ -907,7 +907,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
2 DEPENDENT SUBQUERY t2 ref_or_null a a 5 func 2 Using where; Using index
|
||||
2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,<in_optimizer>(`test`.`t1`.`a`,<exists>(select 1 AS `Not_used` from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and trigcond(((<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`) or isnull(`test`.`t2`.`a`)))) having trigcond(<is_not_null_test>(`test`.`t2`.`a`)))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1`
|
||||
Note 1003 select `test`.`t1`.`a` AS `a`,<in_optimizer>(`test`.`t1`.`a`,<exists>(select 1 AS `Not_used` from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and ((<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`) or isnull(`test`.`t2`.`a`))) having <is_not_null_test>(`test`.`t2`.`a`))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1`
|
||||
drop table t1,t2,t3;
|
||||
create table t1 (a float);
|
||||
select 10.5 IN (SELECT * from t1 LIMIT 1);
|
||||
@ -1305,7 +1305,7 @@ a
|
||||
explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 Using where; Using index
|
||||
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 Using index; Using where
|
||||
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY where (`test`.`t1`.`b` <> 30))))
|
||||
select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
|
||||
@ -1462,27 +1462,27 @@ 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 6 NULL 3 Using index
|
||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index; Full scan on NULL key
|
||||
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`
|
||||
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 having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))))) 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 6 NULL 3 Using index
|
||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index; Full scan on NULL key
|
||||
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`
|
||||
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 having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))) 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 6 NULL 3 Using index
|
||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index; Full scan on NULL key
|
||||
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`
|
||||
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 having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))))) 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 6 NULL 3 Using index
|
||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index; Using where
|
||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index; Using where; Full scan on NULL key
|
||||
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`
|
||||
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') having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1`
|
||||
drop table t1,t2;
|
||||
create table t2 (a int, b int);
|
||||
create table t3 (a int);
|
||||
@ -1737,14 +1737,14 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 12 Using where
|
||||
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 Using index; Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `test`.`t1` where not(<in_optimizer>(`test`.`t1`.`id`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`id`) in t1 on PRIMARY where (`test`.`t1`.`id` < 8)))))
|
||||
Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `test`.`t1` where (not(<in_optimizer>(`test`.`t1`.`id`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`id`) in t1 on PRIMARY where (`test`.`t1`.`id` < 8))))))
|
||||
explain extended select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY tt ALL NULL NULL NULL NULL 12 Using where
|
||||
2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 test.tt.id 1 Using where; Using index
|
||||
Warnings:
|
||||
Note 1276 Field or reference 'tt.id' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where not(exists(select `test`.`t1`.`id` AS `id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null)))
|
||||
Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(exists(select `test`.`t1`.`id` AS `id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null))))
|
||||
insert into t1 (id, text) values (1000, 'text1000'), (1001, 'text1001');
|
||||
create table t2 (id int not null, text varchar(20) not null default '', primary key (id));
|
||||
insert into t2 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text1'), (12, 'text2'), (13, 'text3'), (14, 'text4'), (15, 'text5'), (16, 'text6'), (17, 'text7'), (18, 'text8'), (19, 'text9'), (20, 'text10'),(21, 'text1'), (22, 'text2'), (23, 'text3'), (24, 'text4'), (25, 'text5'), (26, 'text6'), (27, 'text7'), (28, 'text8'), (29, 'text9'), (30, 'text10'), (31, 'text1'), (32, 'text2'), (33, 'text3'), (34, 'text4'), (35, 'text5'), (36, 'text6'), (37, 'text7'), (38, 'text8'), (39, 'text9'), (40, 'text10'), (41, 'text1'), (42, 'text2'), (43, 'text3'), (44, 'text4'), (45, 'text5'), (46, 'text6'), (47, 'text7'), (48, 'text8'), (49, 'text9'), (50, 'text10');
|
||||
@ -2816,19 +2816,19 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 8
|
||||
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one` AS `one`,`test`.`t2`.`two` AS `two` from `test`.`t2` where ((`test`.`t2`.`flag` = _latin1'0') and trigcond((((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`)) and ((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))))) having trigcond((<is_not_null_test>(`test`.`t2`.`one`) and <is_not_null_test>(`test`.`t2`.`two`))))) AS `test` from `test`.`t1`
|
||||
Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one` AS `one`,`test`.`t2`.`two` AS `two` from `test`.`t2` where ((`test`.`t2`.`flag` = _latin1'0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`))))) AS `test` from `test`.`t1`
|
||||
explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
|
||||
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 Using where
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` where <in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one` AS `one`,`test`.`t2`.`two` AS `two` from `test`.`t2` where ((`test`.`t2`.`flag` = _latin1'N') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) and (<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`))))))
|
||||
Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` where <in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one` AS `one`,`test`.`t2`.`two` AS `two` from `test`.`t2` where ((`test`.`t2`.`flag` = _latin1'N') and (<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) and (<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`))))
|
||||
explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 8
|
||||
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 Using where; Using temporary; Using filesort
|
||||
Warnings:
|
||||
Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one` AS `one`,`test`.`t2`.`two` AS `two` from `test`.`t2` where (`test`.`t2`.`flag` = _latin1'0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having trigcond((((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`)) and ((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)) and <is_not_null_test>(`test`.`t2`.`one`) and <is_not_null_test>(`test`.`t2`.`two`))))) AS `test` from `test`.`t1`
|
||||
Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one` AS `one`,`test`.`t2`.`two` AS `two` from `test`.`t2` where (`test`.`t2`.`flag` = _latin1'0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`))))) AS `test` from `test`.`t1`
|
||||
DROP TABLE t1,t2;
|
||||
CREATE TABLE t1 (a char(5), b char(5));
|
||||
INSERT INTO t1 VALUES (NULL,'aaa'), ('aaa','aaa');
|
||||
@ -3009,7 +3009,7 @@ INSERT INTO t2 VALUES (1),(2),(3);
|
||||
EXPLAIN SELECT a, a IN (SELECT a FROM t1) FROM t2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 3
|
||||
2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 2 Using index
|
||||
2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 2 Using index; Full scan on NULL key
|
||||
SELECT a, a IN (SELECT a FROM t1) FROM t2;
|
||||
a a IN (SELECT a FROM t1)
|
||||
1 1
|
||||
@ -3605,3 +3605,36 @@ FROM t1) t;
|
||||
COUNT(*)
|
||||
3000
|
||||
DROP TABLE t1,t2;
|
||||
CREATE TABLE t1 (id char(4) PRIMARY KEY, c int);
|
||||
CREATE TABLE t2 (c int);
|
||||
INSERT INTO t1 VALUES ('aa', 1);
|
||||
INSERT INTO t2 VALUES (1);
|
||||
SELECT * FROM t1
|
||||
WHERE EXISTS (SELECT c FROM t2 WHERE c=1
|
||||
UNION
|
||||
SELECT c from t2 WHERE c=t1.c);
|
||||
id c
|
||||
aa 1
|
||||
INSERT INTO t1 VALUES ('bb', 2), ('cc', 3), ('dd',1);
|
||||
SELECT * FROM t1
|
||||
WHERE EXISTS (SELECT c FROM t2 WHERE c=1
|
||||
UNION
|
||||
SELECT c from t2 WHERE c=t1.c);
|
||||
id c
|
||||
aa 1
|
||||
bb 2
|
||||
cc 3
|
||||
dd 1
|
||||
INSERT INTO t2 VALUES (2);
|
||||
CREATE TABLE t3 (c int);
|
||||
INSERT INTO t3 VALUES (1);
|
||||
SELECT * FROM t1
|
||||
WHERE EXISTS (SELECT t2.c FROM t2 JOIN t3 ON t2.c=t3.c WHERE t2.c=1
|
||||
UNION
|
||||
SELECT c from t2 WHERE c=t1.c);
|
||||
id c
|
||||
aa 1
|
||||
bb 2
|
||||
cc 3
|
||||
dd 1
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
@ -126,11 +126,11 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL DDOCTYPEID_IDX NULL NULL NULL 9 Using where
|
||||
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 34 test.t2.DOCID 1
|
||||
1 PRIMARY t4 eq_ref PRIMARY PRIMARY 34 test.t2.DOCTYPEID 1
|
||||
2 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX PRIMARY 34 func 1 Using index; Using where
|
||||
3 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX PRIMARY 34 func 1 Using index; Using where
|
||||
4 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX PRIMARY 34 func 1 Using index; Using where
|
||||
5 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX PRIMARY 34 func 1 Using index; Using where
|
||||
6 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 func 1 Using index; Using where
|
||||
2 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX PRIMARY 34 func 1 Using where
|
||||
3 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX PRIMARY 34 func 1 Using where
|
||||
4 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX PRIMARY 34 func 1 Using where
|
||||
5 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX PRIMARY 34 func 1 Using where
|
||||
6 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 func 1 Using where
|
||||
drop table t1, t2, t3, t4;
|
||||
CREATE TABLE t1 (a int(10) , PRIMARY KEY (a)) Engine=InnoDB;
|
||||
INSERT INTO t1 VALUES (1),(2);
|
||||
|
@ -15,9 +15,8 @@ insert into t2 values
|
||||
(4, NULL),
|
||||
(2, NULL);
|
||||
select a, oref, a in (select max(ie)
|
||||
from t1 where oref=t2.oref group by grp) from t2;
|
||||
a oref a in (select max(ie)
|
||||
from t1 where oref=t2.oref group by grp)
|
||||
from t1 where oref=t2.oref group by grp) Z from t2;
|
||||
a oref Z
|
||||
1 1 1
|
||||
2 2 0
|
||||
3 3 NULL
|
||||
@ -25,14 +24,13 @@ NULL 4 0
|
||||
NULL 2 NULL
|
||||
explain extended
|
||||
select a, oref, a in (select max(ie)
|
||||
from t1 where oref=t2.oref group by grp) from t2;
|
||||
from t1 where oref=t2.oref group by grp) Z from t2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 5
|
||||
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 6 Using where; Using temporary; Using filesort
|
||||
Warnings:
|
||||
Note 1276 Field or reference 't2.oref' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`oref` AS `oref`,<in_optimizer>(`test`.`t2`.`a`,<exists>(select max(`test`.`t1`.`ie`) AS `max(ie)` from `test`.`t1` where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) group by `test`.`t1`.`grp` having trigcond((<cache>(`test`.`t2`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`)))))) AS `a in (select max(ie)
|
||||
from t1 where oref=t2.oref group by grp)` from `test`.`t2`
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`oref` AS `oref`,<in_optimizer>(`test`.`t2`.`a`,<exists>(select max(`test`.`t1`.`ie`) AS `max(ie)` from `test`.`t1` where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) group by `test`.`t1`.`grp` having trigcond((<cache>(`test`.`t2`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`)))))) AS `Z` from `test`.`t2`
|
||||
explain extended
|
||||
select a, oref from t2
|
||||
where a in (select max(ie) from t1 where oref=t2.oref group by grp);
|
||||
@ -42,6 +40,16 @@ id select_type table type possible_keys key key_len ref rows Extra
|
||||
Warnings:
|
||||
Note 1276 Field or reference 't2.oref' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`oref` AS `oref` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(select max(`test`.`t1`.`ie`) AS `max(ie)` from `test`.`t1` where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) group by `test`.`t1`.`grp` having (<cache>(`test`.`t2`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`)))))
|
||||
select a, oref, a in (
|
||||
select max(ie) from t1 where oref=t2.oref group by grp union
|
||||
select max(ie) from t1 where oref=t2.oref group by grp
|
||||
) Z from t2;
|
||||
a oref Z
|
||||
1 1 1
|
||||
2 2 0
|
||||
3 3 NULL
|
||||
NULL 4 0
|
||||
NULL 2 NULL
|
||||
create table t3 (a int);
|
||||
insert into t3 values (NULL), (NULL);
|
||||
flush status;
|
||||
@ -81,10 +89,10 @@ explain extended
|
||||
select oref, a, a in (select a from t1 where oref=t2.oref) Z from t2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 4
|
||||
2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 2 Using index; Using where
|
||||
2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 2 Using where; Full scan on NULL key
|
||||
Warnings:
|
||||
Note 1276 Field or reference 't2.oref' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1003 select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,<in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a checking NULL where (`test`.`t1`.`oref` = `test`.`t2`.`oref`)))) AS `Z` from `test`.`t2`
|
||||
Note 1003 select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,<in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a checking NULL where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) having trigcond(<is_not_null_test>(`test`.`t1`.`a`))))) AS `Z` from `test`.`t2`
|
||||
flush status;
|
||||
select oref, a from t2 where a in (select a from t1 where oref=t2.oref);
|
||||
oref a
|
||||
@ -145,9 +153,479 @@ t3.a in (select t1.a from t1, t2 where t1.b=t2.a and t2.b=t3.oref) Z
|
||||
from t3;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
|
||||
2 DEPENDENT SUBQUERY t1 ref_or_null a a 5 func 4 Using where
|
||||
2 DEPENDENT SUBQUERY t1 ref_or_null a a 5 func 4 Using where; Full scan on NULL key
|
||||
2 DEPENDENT SUBQUERY t2 ref a a 5 test.t1.b 1 Using where
|
||||
Warnings:
|
||||
Note 1276 Field or reference 't3.oref' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`oref` AS `oref`,<in_optimizer>(`test`.`t3`.`a`,<exists>(select 1 AS `Not_used` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond(((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`)))) having trigcond(<is_not_null_test>(`test`.`t1`.`a`)))) AS `Z` from `test`.`t3`
|
||||
drop table t1, t2, t3;
|
||||
create table t1 (a int NOT NULL, b int NOT NULL, key(a));
|
||||
insert into t1 values
|
||||
(0,0),(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
|
||||
create table t2 like t1;
|
||||
insert into t2 select * from t1;
|
||||
update t2 set b=1;
|
||||
create table t3 (a int, oref int);
|
||||
insert into t3 values (1, 1), (NULL,1), (NULL,0);
|
||||
select a, oref,
|
||||
t3.a in (select t1.a from t1, t2 where t1.b=t2.a and t2.b=t3.oref) Z
|
||||
from t3;
|
||||
a oref Z
|
||||
1 1 1
|
||||
NULL 1 NULL
|
||||
NULL 0 0
|
||||
This must show a trig_cond:
|
||||
explain extended
|
||||
select a, oref,
|
||||
t3.a in (select t1.a from t1, t2 where t1.b=t2.a and t2.b=t3.oref) Z
|
||||
from t3;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t3 ALL NULL NULL NULL NULL 3
|
||||
2 DEPENDENT SUBQUERY t1 ref a a 4 func 2 Using where; Full scan on NULL key
|
||||
2 DEPENDENT SUBQUERY t2 ref a a 4 test.t1.b 1 Using where
|
||||
Warnings:
|
||||
Note 1276 Field or reference 't3.oref' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`oref` AS `oref`,<in_optimizer>(`test`.`t3`.`a`,<exists>(select 1 AS `Not_used` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`))))) AS `Z` from `test`.`t3`
|
||||
drop table t1,t2,t3;
|
||||
create table t1 (oref int, grp int);
|
||||
insert into t1 (oref, grp) values
|
||||
(1, 1),
|
||||
(1, 1);
|
||||
create table t2 (oref int, a int);
|
||||
insert into t2 values
|
||||
(1, NULL),
|
||||
(2, NULL);
|
||||
select a, oref,
|
||||
a in (select count(*) from t1 group by grp having grp=t2.oref) Z from t2;
|
||||
a oref Z
|
||||
NULL 1 NULL
|
||||
NULL 2 0
|
||||
This must show a trig_cond:
|
||||
explain extended
|
||||
select a, oref,
|
||||
a in (select count(*) from t1 group by grp having grp=t2.oref) Z from t2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
|
||||
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
|
||||
Warnings:
|
||||
Note 1276 Field or reference 't2.oref' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`oref` AS `oref`,<in_optimizer>(`test`.`t2`.`a`,<exists>(select count(0) AS `count(*)` from `test`.`t1` group by `test`.`t1`.`grp` having ((`test`.`t1`.`grp` = `test`.`t2`.`oref`) and trigcond((<cache>(`test`.`t2`.`a`) = <ref_null_helper>(count(0))))))) AS `Z` from `test`.`t2`
|
||||
drop table t1, t2;
|
||||
create table t1 (a int, b int, primary key (a));
|
||||
insert into t1 values (1,1), (3,1),(100,1);
|
||||
create table t2 (a int, b int);
|
||||
insert into t2 values (1,1),(2,1),(NULL,1),(NULL,0);
|
||||
select a,b, a in (select a from t1 where t1.b = t2.b union select a from
|
||||
t1 where t1.b = t2.b) Z from t2 ;
|
||||
a b Z
|
||||
1 1 1
|
||||
2 1 0
|
||||
NULL 1 NULL
|
||||
NULL 0 0
|
||||
select a,b, a in (select a from t1 where t1.b = t2.b) Z from t2 ;
|
||||
a b Z
|
||||
1 1 1
|
||||
2 1 0
|
||||
NULL 1 NULL
|
||||
NULL 0 0
|
||||
drop table t1, t2;
|
||||
create table t3 (a int);
|
||||
insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||
create table t2 (a int, b int, oref int);
|
||||
insert into t2 values (NULL,1, 100), (NULL,2, 100);
|
||||
create table t1 (a int, b int, c int, key(a,b));
|
||||
insert into t1 select 2*A, 2*A, 100 from t3;
|
||||
explain extended select a,b, oref, (a,b) in (select a,b from t1 where c=t2.oref) Z from t2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
|
||||
2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 2 Using where; Full scan on NULL key
|
||||
Warnings:
|
||||
Note 1276 Field or reference 't2.oref' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`oref` AS `oref`,<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a checking NULL where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`)))))) AS `Z` from `test`.`t2`
|
||||
select a,b, oref, (a,b) in (select a,b from t1 where c=t2.oref) Z from t2;
|
||||
a b oref Z
|
||||
NULL 1 100 0
|
||||
NULL 2 100 NULL
|
||||
create table t4 (x int);
|
||||
insert into t4 select A.a + 10*B.a from t1 A, t1 B;
|
||||
explain extended
|
||||
select a,b, oref,
|
||||
(a,b) in (select a,b from t1,t4 where c=t2.oref) Z
|
||||
from t2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
|
||||
2 DEPENDENT SUBQUERY t1 ref_or_null a a 5 func 2 Using where; Full scan on NULL key
|
||||
2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 100 Using where
|
||||
Warnings:
|
||||
Note 1276 Field or reference 't2.oref' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`oref` AS `oref`,<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` join `test`.`t4` where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`))))) AS `Z` from `test`.`t2`
|
||||
select a,b, oref,
|
||||
(a,b) in (select a,b from t1,t4 where c=t2.oref) Z
|
||||
from t2;
|
||||
a b oref Z
|
||||
NULL 1 100 0
|
||||
NULL 2 100 NULL
|
||||
drop table t1,t2,t3,t4;
|
||||
create table t1 (oref char(4), grp int, ie1 int, ie2 int);
|
||||
insert into t1 (oref, grp, ie1, ie2) values
|
||||
('aa', 10, 2, 1),
|
||||
('aa', 10, 1, 1),
|
||||
('aa', 20, 2, 1),
|
||||
('bb', 10, 3, 1),
|
||||
('cc', 10, 4, 2),
|
||||
('cc', 20, 3, 2),
|
||||
('ee', 10, 2, 1),
|
||||
('ee', 10, 1, 2),
|
||||
('ff', 20, 2, 2),
|
||||
('ff', 20, 1, 2);
|
||||
create table t2 (oref char(4), a int, b int);
|
||||
insert into t2 values
|
||||
('ee', NULL, 1),
|
||||
('bb', 2, 1),
|
||||
('ff', 2, 2),
|
||||
('cc', 3, NULL),
|
||||
('bb', NULL, NULL),
|
||||
('aa', 1, 1),
|
||||
('dd', 1, NULL);
|
||||
alter table t1 add index idx(ie1,ie2);
|
||||
select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2 where a=3 and b is null ;
|
||||
oref a b Z
|
||||
cc 3 NULL NULL
|
||||
insert into t2 values ('new1', 10,10);
|
||||
insert into t1 values ('new1', 1234, 10, NULL);
|
||||
select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2 where a=10 and b=10;
|
||||
oref a b Z
|
||||
new1 10 10 NULL
|
||||
explain extended
|
||||
select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2 where a=10 and b=10;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 8 Using where
|
||||
2 DEPENDENT SUBQUERY t1 index_subquery idx idx 5 func 4 Using where; Full scan on NULL key
|
||||
Warnings:
|
||||
Note 1276 Field or reference 't2.oref' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1003 select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on idx checking NULL where ((`test`.`t1`.`oref` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`ie1`) or isnull(`test`.`t1`.`ie1`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`ie2`) or isnull(`test`.`t1`.`ie2`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`ie1`)) and trigcond(<is_not_null_test>(`test`.`t1`.`ie2`)))))) AS `Z` from `test`.`t2` where ((`test`.`t2`.`b` = 10) and (`test`.`t2`.`a` = 10))
|
||||
drop table t1, t2;
|
||||
create table t1 (oref char(4), grp int, ie int);
|
||||
insert into t1 (oref, grp, ie) values
|
||||
('aa', 10, 2),
|
||||
('aa', 10, 1),
|
||||
('aa', 20, NULL),
|
||||
('bb', 10, 3),
|
||||
('cc', 10, 4),
|
||||
('cc', 20, NULL),
|
||||
('ee', 10, NULL),
|
||||
('ee', 10, NULL),
|
||||
('ff', 20, 2),
|
||||
('ff', 20, 1);
|
||||
create table t2 (oref char(4), a int);
|
||||
insert into t2 values
|
||||
('ee', NULL),
|
||||
('bb', 2),
|
||||
('ff', 2),
|
||||
('cc', 3),
|
||||
('aa', 1),
|
||||
('dd', NULL),
|
||||
('bb', NULL);
|
||||
select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
|
||||
oref a Z
|
||||
ee NULL NULL
|
||||
bb 2 0
|
||||
ff 2 1
|
||||
cc 3 NULL
|
||||
aa 1 1
|
||||
dd NULL 0
|
||||
bb NULL NULL
|
||||
select oref, a from t2 where a in (select ie from t1 where oref=t2.oref);
|
||||
oref a
|
||||
ff 2
|
||||
aa 1
|
||||
select oref, a from t2 where a not in (select ie from t1 where oref=t2.oref);
|
||||
oref a
|
||||
bb 2
|
||||
dd NULL
|
||||
select oref, a, a in (select min(ie) from t1 where oref=t2.oref group by grp) Z from t2;
|
||||
oref a Z
|
||||
ee NULL NULL
|
||||
bb 2 0
|
||||
ff 2 0
|
||||
cc 3 NULL
|
||||
aa 1 1
|
||||
dd NULL 0
|
||||
bb NULL NULL
|
||||
select oref, a from t2 where
|
||||
a in (select min(ie) from t1 where oref=t2.oref group by grp);
|
||||
oref a
|
||||
aa 1
|
||||
select oref, a from t2 where
|
||||
a not in (select min(ie) from t1 where oref=t2.oref group by grp);
|
||||
oref a
|
||||
bb 2
|
||||
ff 2
|
||||
dd NULL
|
||||
update t1 set ie=3 where oref='ff' and ie=1;
|
||||
select oref, a, a in (select min(ie) from t1 where oref=t2.oref group by
|
||||
grp) Z from t2;
|
||||
oref a Z
|
||||
ee NULL NULL
|
||||
bb 2 0
|
||||
ff 2 1
|
||||
cc 3 NULL
|
||||
aa 1 1
|
||||
dd NULL 0
|
||||
bb NULL NULL
|
||||
select oref, a from t2 where a in (select min(ie) from t1 where
|
||||
oref=t2.oref group by grp);
|
||||
oref a
|
||||
ff 2
|
||||
aa 1
|
||||
select oref, a from t2 where a not in (select min(ie) from t1 where
|
||||
oref=t2.oref group by grp);
|
||||
oref a
|
||||
bb 2
|
||||
dd NULL
|
||||
select oref, a, a in (select min(ie) from t1 where oref=t2.oref group by
|
||||
grp having min(ie) > 1) Z from t2;
|
||||
oref a Z
|
||||
ee NULL 0
|
||||
bb 2 0
|
||||
ff 2 1
|
||||
cc 3 0
|
||||
aa 1 0
|
||||
dd NULL 0
|
||||
bb NULL NULL
|
||||
select oref, a from t2 where a in (select min(ie) from t1 where
|
||||
oref=t2.oref group by grp having min(ie) > 1);
|
||||
oref a
|
||||
ff 2
|
||||
select oref, a from t2 where a not in (select min(ie) from t1 where
|
||||
oref=t2.oref group by grp having min(ie) > 1);
|
||||
oref a
|
||||
ee NULL
|
||||
bb 2
|
||||
cc 3
|
||||
aa 1
|
||||
dd NULL
|
||||
alter table t1 add index idx(ie);
|
||||
explain select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 7
|
||||
2 DEPENDENT SUBQUERY t1 index_subquery idx idx 5 func 4 Using where; Full scan on NULL key
|
||||
select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
|
||||
oref a Z
|
||||
ee NULL NULL
|
||||
bb 2 0
|
||||
ff 2 1
|
||||
cc 3 NULL
|
||||
aa 1 1
|
||||
dd NULL 0
|
||||
bb NULL NULL
|
||||
select oref, a from t2 where a in (select ie from t1 where oref=t2.oref);
|
||||
oref a
|
||||
ff 2
|
||||
aa 1
|
||||
select oref, a from t2 where a not in (select ie from t1 where oref=t2.oref);
|
||||
oref a
|
||||
bb 2
|
||||
dd NULL
|
||||
alter table t1 drop index idx;
|
||||
alter table t1 add index idx(oref,ie);
|
||||
explain select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 7
|
||||
2 DEPENDENT SUBQUERY t1 ref_or_null idx idx 10 test.t2.oref,func 4 Using where; Using index; Full scan on NULL key
|
||||
select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
|
||||
oref a Z
|
||||
ee NULL NULL
|
||||
bb 2 0
|
||||
ff 2 1
|
||||
cc 3 NULL
|
||||
aa 1 1
|
||||
dd NULL 0
|
||||
bb NULL NULL
|
||||
select oref, a from t2 where a in (select ie from t1 where oref=t2.oref);
|
||||
oref a
|
||||
ff 2
|
||||
aa 1
|
||||
select oref, a from t2 where a not in (select ie from t1 where oref=t2.oref);
|
||||
oref a
|
||||
bb 2
|
||||
dd NULL
|
||||
explain
|
||||
select oref, a,
|
||||
a in (select min(ie) from t1 where oref=t2.oref
|
||||
group by grp having min(ie) > 1) Z
|
||||
from t2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 7
|
||||
2 DEPENDENT SUBQUERY t1 ref idx idx 5 test.t2.oref 2 Using where; Using temporary; Using filesort
|
||||
select oref, a,
|
||||
a in (select min(ie) from t1 where oref=t2.oref
|
||||
group by grp having min(ie) > 1) Z
|
||||
from t2;
|
||||
oref a Z
|
||||
ee NULL 0
|
||||
bb 2 0
|
||||
ff 2 1
|
||||
cc 3 0
|
||||
aa 1 0
|
||||
dd NULL 0
|
||||
bb NULL NULL
|
||||
select oref, a from t2 where a in (select min(ie) from t1 where oref=t2.oref
|
||||
group by grp having min(ie) > 1);
|
||||
oref a
|
||||
ff 2
|
||||
select oref, a from t2 where a not in (select min(ie) from t1 where oref=t2.oref
|
||||
group by grp having min(ie) > 1);
|
||||
oref a
|
||||
ee NULL
|
||||
bb 2
|
||||
cc 3
|
||||
aa 1
|
||||
dd NULL
|
||||
drop table t1,t2;
|
||||
create table t1 (oref char(4), grp int, ie1 int, ie2 int);
|
||||
insert into t1 (oref, grp, ie1, ie2) values
|
||||
('aa', 10, 2, 1),
|
||||
('aa', 10, 1, 1),
|
||||
('aa', 20, 2, 1),
|
||||
('bb', 10, 3, 1),
|
||||
('cc', 10, 4, 2),
|
||||
('cc', 20, 3, 2),
|
||||
('ee', 10, 2, 1),
|
||||
('ee', 10, 1, 2),
|
||||
('ff', 20, 2, 2),
|
||||
('ff', 20, 1, 2);
|
||||
create table t2 (oref char(4), a int, b int);
|
||||
insert into t2 values
|
||||
('ee', NULL, 1),
|
||||
('bb', 2, 1),
|
||||
('ff', 2, 2),
|
||||
('cc', 3, NULL),
|
||||
('bb', NULL, NULL),
|
||||
('aa', 1, 1),
|
||||
('dd', 1, NULL);
|
||||
select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2;
|
||||
oref a b Z
|
||||
ee NULL 1 NULL
|
||||
bb 2 1 0
|
||||
ff 2 2 1
|
||||
cc 3 NULL NULL
|
||||
bb NULL NULL NULL
|
||||
aa 1 1 1
|
||||
dd 1 NULL 0
|
||||
select oref, a, b from t2 where (a,b) in (select ie1,ie2 from t1 where oref=t2.oref);
|
||||
oref a b
|
||||
ff 2 2
|
||||
aa 1 1
|
||||
select oref, a, b from t2 where (a,b) not in (select ie1,ie2 from t1 where oref=t2.oref);
|
||||
oref a b
|
||||
bb 2 1
|
||||
dd 1 NULL
|
||||
select oref, a, b,
|
||||
(a,b) in (select min(ie1),max(ie2) from t1
|
||||
where oref=t2.oref group by grp) Z
|
||||
from t2;
|
||||
oref a b Z
|
||||
ee NULL 1 0
|
||||
bb 2 1 0
|
||||
ff 2 2 0
|
||||
cc 3 NULL NULL
|
||||
bb NULL NULL NULL
|
||||
aa 1 1 1
|
||||
dd 1 NULL 0
|
||||
select oref, a, b from t2 where
|
||||
(a,b) in (select min(ie1), max(ie2) from t1 where oref=t2.oref group by grp);
|
||||
oref a b
|
||||
aa 1 1
|
||||
select oref, a, b from t2 where
|
||||
(a,b) not in (select min(ie1), max(ie2) from t1 where oref=t2.oref group by grp);
|
||||
oref a b
|
||||
ee NULL 1
|
||||
bb 2 1
|
||||
ff 2 2
|
||||
dd 1 NULL
|
||||
alter table t1 add index idx(ie1,ie2);
|
||||
explain select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 7
|
||||
2 DEPENDENT SUBQUERY t1 index_subquery idx idx 5 func 4 Using where; Full scan on NULL key
|
||||
select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2;
|
||||
oref a b Z
|
||||
ee NULL 1 NULL
|
||||
bb 2 1 0
|
||||
ff 2 2 1
|
||||
cc 3 NULL NULL
|
||||
bb NULL NULL NULL
|
||||
aa 1 1 1
|
||||
dd 1 NULL 0
|
||||
select oref, a, b from t2 where (a,b) in (select ie1,ie2 from t1 where oref=t2.oref);
|
||||
oref a b
|
||||
ff 2 2
|
||||
aa 1 1
|
||||
select oref, a, b from t2 where (a,b) not in (select ie1,ie2 from t1 where oref=t2.oref);
|
||||
oref a b
|
||||
bb 2 1
|
||||
dd 1 NULL
|
||||
explain extended
|
||||
select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 7
|
||||
2 DEPENDENT SUBQUERY t1 index_subquery idx idx 5 func 4 Using where; Full scan on NULL key
|
||||
Warnings:
|
||||
Note 1276 Field or reference 't2.oref' of SELECT #2 was resolved in SELECT #1
|
||||
Note 1003 select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on idx checking NULL where ((`test`.`t1`.`oref` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`ie1`) or isnull(`test`.`t1`.`ie1`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`ie2`) or isnull(`test`.`t1`.`ie2`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`ie1`)) and trigcond(<is_not_null_test>(`test`.`t1`.`ie2`)))))) AS `Z` from `test`.`t2`
|
||||
drop table t1,t2;
|
||||
create table t1 (oref char(4), grp int, ie int primary key);
|
||||
insert into t1 (oref, grp, ie) values
|
||||
('aa', 10, 2),
|
||||
('aa', 10, 1),
|
||||
('bb', 10, 3),
|
||||
('cc', 10, 4),
|
||||
('cc', 20, 5),
|
||||
('cc', 10, 6);
|
||||
create table t2 (oref char(4), a int);
|
||||
insert into t2 values
|
||||
('ee', NULL),
|
||||
('bb', 2),
|
||||
('cc', 5),
|
||||
('cc', 2),
|
||||
('cc', NULL),
|
||||
('aa', 1),
|
||||
('bb', NULL);
|
||||
explain select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 7
|
||||
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 Using where; Full scan on NULL key
|
||||
select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
|
||||
oref a Z
|
||||
ee NULL 0
|
||||
bb 2 0
|
||||
cc 5 1
|
||||
cc 2 0
|
||||
cc NULL NULL
|
||||
aa 1 1
|
||||
bb NULL NULL
|
||||
select oref, a from t2 where a in (select ie from t1 where oref=t2.oref);
|
||||
oref a
|
||||
cc 5
|
||||
aa 1
|
||||
select oref, a from t2 where a not in (select ie from t1 where oref=t2.oref);
|
||||
oref a
|
||||
ee NULL
|
||||
bb 2
|
||||
cc 2
|
||||
explain
|
||||
select oref, a, a in (select min(ie) from t1 where oref=t2.oref group by grp) Z from t2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 ALL NULL NULL NULL NULL 7
|
||||
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 6 Using where; Using temporary; Using filesort
|
||||
select oref, a, a in (select min(ie) from t1 where oref=t2.oref group by grp) Z from t2;
|
||||
oref a Z
|
||||
ee NULL 0
|
||||
bb 2 0
|
||||
cc 5 1
|
||||
cc 2 0
|
||||
cc NULL NULL
|
||||
aa 1 1
|
||||
bb NULL NULL
|
||||
drop table t1,t2;
|
||||
|
@ -1278,4 +1278,36 @@ a b
|
||||
2 b
|
||||
3 c
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (
|
||||
id int NOT NULL DEFAULT '0',
|
||||
a varchar(10) NOT NULL,
|
||||
b varchar(10),
|
||||
c varchar(10),
|
||||
d timestamp NOT NULL,
|
||||
PRIMARY KEY (id, a)
|
||||
);
|
||||
CREATE TABLE t2 (
|
||||
fubar_id int unsigned NOT NULL DEFAULT '0',
|
||||
last_change_time datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
PRIMARY KEY (fubar_id)
|
||||
);
|
||||
CREATE TRIGGER fubar_change
|
||||
AFTER UPDATE ON t1
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
INSERT INTO t2 (fubar_id, last_change_time)
|
||||
SELECT DISTINCT NEW.id AS fubar_id, NOW() AS last_change_time
|
||||
FROM t1 WHERE (id = NEW.id) AND (OLD.c != NEW.c)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
last_change_time =
|
||||
IF((fubar_id = NEW.id)AND(OLD.c != NEW.c),NOW(),last_change_time);
|
||||
END
|
||||
|
|
||||
INSERT INTO t1 (id,a, b,c,d) VALUES
|
||||
(1,'a','b','c',now()),(2,'a','b','c',now());
|
||||
UPDATE t1 SET c='Bang!' WHERE id=1;
|
||||
SELECT fubar_id FROM t2;
|
||||
fubar_id
|
||||
1
|
||||
DROP TABLE t1,t2;
|
||||
End of 5.0 tests
|
||||
|
@ -240,3 +240,37 @@ drop table bug18761;
|
||||
select is_const((1,2,3));
|
||||
ERROR 21000: Operand should contain 1 column(s)
|
||||
drop function if exists is_const;
|
||||
CREATE FUNCTION metaphon RETURNS STRING SONAME "UDF_EXAMPLE_LIB";
|
||||
CREATE FUNCTION myfunc_double RETURNS REAL SONAME "UDF_EXAMPLE_LIB";
|
||||
CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB";
|
||||
create function f1(p1 varchar(255))
|
||||
returns varchar(255)
|
||||
begin
|
||||
return metaphon(p1);
|
||||
end//
|
||||
create function f2(p1 varchar(255))
|
||||
returns double
|
||||
begin
|
||||
return myfunc_double(p1);
|
||||
end//
|
||||
create function f3(p1 varchar(255))
|
||||
returns double
|
||||
begin
|
||||
return myfunc_int(p1);
|
||||
end//
|
||||
select f3(NULL);
|
||||
f3(NULL)
|
||||
0
|
||||
select f2(NULL);
|
||||
f2(NULL)
|
||||
NULL
|
||||
select f1(NULL);
|
||||
f1(NULL)
|
||||
NULL
|
||||
drop function f1;
|
||||
drop function f2;
|
||||
drop function f3;
|
||||
drop function metaphon;
|
||||
drop function myfunc_double;
|
||||
drop function myfunc_int;
|
||||
End of 5.0 tests.
|
||||
|
@ -3014,6 +3014,17 @@ i j
|
||||
6 3
|
||||
DROP VIEW v1, v2;
|
||||
DROP TABLE t1;
|
||||
CREATE VIEW v AS SELECT !0 * 5 AS x FROM DUAL;
|
||||
SHOW CREATE VIEW v;
|
||||
View Create View
|
||||
v CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select ((not(0)) * 5) AS `x`
|
||||
SELECT !0 * 5 AS x FROM DUAL;
|
||||
x
|
||||
5
|
||||
SELECT * FROM v;
|
||||
x
|
||||
5
|
||||
DROP VIEW v;
|
||||
DROP VIEW IF EXISTS v1;
|
||||
CREATE VIEW v1 AS SELECT 'The\ZEnd';
|
||||
SELECT * FROM v1;
|
||||
|
@ -731,3 +731,46 @@ SELECT * FROM v1;
|
||||
ERROR HY000: There is no 'def_17254'@'localhost' registered
|
||||
DROP USER inv_17254@localhost;
|
||||
DROP DATABASE db17254;
|
||||
DROP DATABASE IF EXISTS mysqltest_db1;
|
||||
DROP DATABASE IF EXISTS mysqltest_db2;
|
||||
DROP USER mysqltest_u1;
|
||||
DROP USER mysqltest_u2;
|
||||
CREATE USER mysqltest_u1@localhost;
|
||||
CREATE USER mysqltest_u2@localhost;
|
||||
CREATE DATABASE mysqltest_db1;
|
||||
CREATE DATABASE mysqltest_db2;
|
||||
GRANT ALL ON mysqltest_db1.* TO mysqltest_u1@localhost WITH GRANT OPTION;
|
||||
GRANT ALL ON mysqltest_db2.* TO mysqltest_u2@localhost;
|
||||
CREATE TABLE t1 (i INT);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
CREATE VIEW v1 AS SELECT i FROM t1 WHERE 1 IN (SELECT * FROM t1);
|
||||
CREATE TABLE t2 (s CHAR(7));
|
||||
INSERT INTO t2 VALUES ('public');
|
||||
GRANT SELECT ON v1 TO mysqltest_u2@localhost;
|
||||
GRANT SELECT ON t2 TO mysqltest_u2@localhost;
|
||||
SELECT * FROM mysqltest_db1.v1, mysqltest_db1.t2;
|
||||
i s
|
||||
1 public
|
||||
PREPARE stmt1 FROM "SELECT * FROM mysqltest_db1.t2";
|
||||
EXECUTE stmt1;
|
||||
s
|
||||
public
|
||||
PREPARE stmt2 FROM "SELECT * FROM mysqltest_db1.v1, mysqltest_db1.t2";
|
||||
EXECUTE stmt2;
|
||||
i s
|
||||
1 public
|
||||
REVOKE SELECT ON t2 FROM mysqltest_u2@localhost;
|
||||
UPDATE t2 SET s = 'private' WHERE s = 'public';
|
||||
SELECT * FROM mysqltest_db1.v1, mysqltest_db1.t2;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_u2'@'localhost' for table 't2'
|
||||
EXECUTE stmt1;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_u2'@'localhost' for table 't2'
|
||||
EXECUTE stmt2;
|
||||
ERROR 42000: SELECT command denied to user 'mysqltest_u2'@'localhost' for table 't2'
|
||||
REVOKE ALL ON mysqltest_db1.* FROM mysqltest_u1@localhost;
|
||||
REVOKE ALL ON mysqltest_db2.* FROM mysqltest_u2@localhost;
|
||||
DROP DATABASE mysqltest_db1;
|
||||
DROP DATABASE mysqltest_db2;
|
||||
DROP USER mysqltest_u1@localhost;
|
||||
DROP USER mysqltest_u2@localhost;
|
||||
End of 5.0 tests.
|
||||
|
62
mysql-test/t/alter_table-big.test
Normal file
62
mysql-test/t/alter_table-big.test
Normal file
@ -0,0 +1,62 @@
|
||||
# In order to be more or less robust test for bug#25044 has to take
|
||||
# significant time (e.g. about 9 seconds on my (Dmitri's) computer)
|
||||
# so we probably want execute it only in --big-test mode.
|
||||
# Also in 5.1 this test will require statement-based binlog.
|
||||
--source include/big_test.inc
|
||||
|
||||
|
||||
#
|
||||
# Test for bug #25044 "ALTER TABLE ... ENABLE KEYS acquires global
|
||||
# 'opening tables' lock".
|
||||
#
|
||||
# ALTER TABLE ... ENABLE KEYS should not acquire LOCK_open mutex for
|
||||
# the whole its duration as it prevents other queries from execution.
|
||||
--disable_warnings
|
||||
drop table if exists t1, t2;
|
||||
--enable_warnings
|
||||
connect (addconroot, localhost, root,,);
|
||||
connection default;
|
||||
create table t1 (n1 int, n2 int, n3 int,
|
||||
key (n1, n2, n3),
|
||||
key (n2, n3, n1),
|
||||
key (n3, n1, n2));
|
||||
create table t2 (i int);
|
||||
|
||||
# Populating 't1' table with keys disabled, so ALTER TABLE .. ENABLE KEYS
|
||||
# will run for some time
|
||||
alter table t1 disable keys;
|
||||
--disable_query_log
|
||||
insert into t1 values (RAND()*1000,RAND()*1000,RAND()*1000);
|
||||
let $1=19;
|
||||
while ($1)
|
||||
{
|
||||
eval insert into t1 select RAND()*1000,RAND()*1000,RAND()*1000 from t1;
|
||||
dec $1;
|
||||
}
|
||||
--enable_query_log
|
||||
|
||||
# Later we use binlog to check the order in which statements are
|
||||
# executed so let us reset it first.
|
||||
reset master;
|
||||
--send alter table t1 enable keys;
|
||||
connection addconroot;
|
||||
let $show_type= PROCESSLIST;
|
||||
let $show_pattern= '%Repair by sorting%alter table t1 enable keys%';
|
||||
--source include/wait_show_pattern.inc
|
||||
# This statement should not be blocked by in-flight ALTER and therefore
|
||||
# should be executed and written to binlog before ALTER TABLE ... ENABLE KEYS
|
||||
# finishes.
|
||||
insert into t2 values (1);
|
||||
# And this should wait until the end of ALTER TABLE ... ENABLE KEYS.
|
||||
insert into t1 values (1, 1, 1);
|
||||
connection default;
|
||||
--reap
|
||||
# Check that statements were executed/binlogged in correct order.
|
||||
--replace_column 2 # 5 #
|
||||
show binlog events in 'master-bin.000001' from 98;
|
||||
|
||||
# Clean up
|
||||
drop tables t1, t2;
|
||||
|
||||
|
||||
--echo End of 5.0 tests
|
@ -528,6 +528,71 @@ SHOW INDEX FROM bug24219_2;
|
||||
|
||||
DROP TABLE bug24219_2;
|
||||
|
||||
#
|
||||
# Bug#24562 (ALTER TABLE ... ORDER BY ... with complex expression asserts)
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists table_24562;
|
||||
--enable_warnings
|
||||
|
||||
create table table_24562(
|
||||
section int,
|
||||
subsection int,
|
||||
title varchar(50));
|
||||
|
||||
insert into table_24562 values
|
||||
(1, 0, "Introduction"),
|
||||
(1, 1, "Authors"),
|
||||
(1, 2, "Acknowledgements"),
|
||||
(2, 0, "Basics"),
|
||||
(2, 1, "Syntax"),
|
||||
(2, 2, "Client"),
|
||||
(2, 3, "Server"),
|
||||
(3, 0, "Intermediate"),
|
||||
(3, 1, "Complex queries"),
|
||||
(3, 2, "Stored Procedures"),
|
||||
(3, 3, "Stored Functions"),
|
||||
(4, 0, "Advanced"),
|
||||
(4, 1, "Replication"),
|
||||
(4, 2, "Load balancing"),
|
||||
(4, 3, "High availability"),
|
||||
(5, 0, "Conclusion");
|
||||
|
||||
select * from table_24562;
|
||||
|
||||
alter table table_24562 add column reviewer varchar(20),
|
||||
order by title;
|
||||
|
||||
select * from table_24562;
|
||||
|
||||
update table_24562 set reviewer="Me" where section=2;
|
||||
update table_24562 set reviewer="You" where section=3;
|
||||
|
||||
alter table table_24562
|
||||
order by section ASC, subsection DESC;
|
||||
|
||||
select * from table_24562;
|
||||
|
||||
alter table table_24562
|
||||
order by table_24562.subsection ASC, table_24562.section DESC;
|
||||
|
||||
select * from table_24562;
|
||||
|
||||
--error ER_PARSE_ERROR
|
||||
alter table table_24562 order by 12;
|
||||
--error ER_PARSE_ERROR
|
||||
alter table table_24562 order by (section + 12);
|
||||
--error ER_PARSE_ERROR
|
||||
alter table table_24562 order by length(title);
|
||||
--error ER_PARSE_ERROR
|
||||
alter table table_24562 order by (select 12 from dual);
|
||||
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
alter table table_24562 order by no_such_col;
|
||||
|
||||
drop table table_24562;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
#
|
||||
|
@ -163,6 +163,17 @@ delete `4.t1` from t1 as `4.t1` where `4.t1`.a = 5;
|
||||
delete FROM `4.t1` USING t1 as `4.t1` where `4.t1`.a = 5;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#17711: DELETE doesn't use index when ORDER BY, LIMIT and
|
||||
# non-restricting WHERE is present.
|
||||
#
|
||||
create table t1(f1 int primary key);
|
||||
insert into t1 values (4),(3),(1),(2);
|
||||
delete from t1 where (@a:= f1) order by f1 limit 1;
|
||||
select @a;
|
||||
drop table t1;
|
||||
|
||||
--echo End of 4.1 tests
|
||||
# End of 4.1 tests
|
||||
|
||||
#
|
||||
|
@ -58,4 +58,32 @@ insert into t2 values (1, 'bword'), (3, 'aword'), (5, '');
|
||||
select * from t1 left join t2 on m_id = id where match(d, e, f) against ('+aword +bword' in boolean mode);
|
||||
drop table t1,t2;
|
||||
|
||||
#
|
||||
# BUG#25637: LEFT JOIN with BOOLEAN FULLTEXT loses left table matches
|
||||
# (this is actually the same bug as bug #14708)
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id int(10) NOT NULL auto_increment,
|
||||
link int(10) default NULL,
|
||||
name mediumtext default NULL,
|
||||
PRIMARY KEY (id),
|
||||
FULLTEXT (name)
|
||||
);
|
||||
INSERT INTO t1 VALUES (1, 1, 'string');
|
||||
INSERT INTO t1 VALUES (2, 0, 'string');
|
||||
CREATE TABLE t2 (
|
||||
id int(10) NOT NULL auto_increment,
|
||||
name mediumtext default NULL,
|
||||
PRIMARY KEY (id),
|
||||
FULLTEXT (name)
|
||||
);
|
||||
INSERT INTO t2 VALUES (1, 'string');
|
||||
|
||||
SELECT t1.*, MATCH(t1.name) AGAINST('string') AS relevance
|
||||
FROM t1 LEFT JOIN t2 ON t1.link = t2.id
|
||||
WHERE MATCH(t1.name, t2.name) AGAINST('string' IN BOOLEAN MODE);
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
@ -261,5 +261,41 @@ select some_id from t1 where some_id not in('-1', '0');
|
||||
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# BUG#20420: optimizer reports wrong keys on left join with IN
|
||||
#
|
||||
CREATE TABLE t1 (a int, b int, PRIMARY KEY (a));
|
||||
INSERT INTO t1 VALUES (1,1),(2,1),(3,1),(4,1),(5,1),(6,1);
|
||||
|
||||
CREATE TABLE t2 (a int, b int, PRIMARY KEY (a));
|
||||
INSERT INTO t2 VALUES (3,2),(4,2);
|
||||
|
||||
CREATE TABLE t3 (a int PRIMARY KEY);
|
||||
INSERT INTO t3 VALUES (1),(2),(3),(4);
|
||||
|
||||
CREATE TABLE t4 (a int PRIMARY KEY);
|
||||
INSERT INTO t4 VALUES (1),(2);
|
||||
|
||||
EXPLAIN SELECT STRAIGHT_JOIN * FROM t3
|
||||
JOIN t1 ON t3.a=t1.a
|
||||
JOIN t2 ON t3.a=t2.a
|
||||
JOIN t4 WHERE t4.a IN (t1.b, t2.b);
|
||||
|
||||
SELECT STRAIGHT_JOIN * FROM t3
|
||||
JOIN t1 ON t3.a=t1.a
|
||||
JOIN t2 ON t3.a=t2.a
|
||||
JOIN t4 WHERE t4.a IN (t1.b, t2.b);
|
||||
|
||||
EXPLAIN SELECT STRAIGHT_JOIN
|
||||
(SELECT SUM(t4.a) FROM t4 WHERE t4.a IN (t1.b, t2.b))
|
||||
FROM t3, t1, t2
|
||||
WHERE t3.a=t1.a AND t3.a=t2.a;
|
||||
|
||||
SELECT STRAIGHT_JOIN
|
||||
(SELECT SUM(t4.a) FROM t4 WHERE t4.a IN (t1.b, t2.b))
|
||||
FROM t3, t1, t2
|
||||
WHERE t3.a=t1.a AND t3.a=t2.a;
|
||||
|
||||
DROP TABLE t1,t2,t3,t4;
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
@ -730,6 +730,14 @@ EXPLAIN EXTENDED SELECT s FROM t1 WHERE TRIM(BOTH 'y' FROM s) > 'ab';
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug#23409: ENCODE() and DECODE() functions aren't printed correctly
|
||||
#
|
||||
create table t1(f1 varchar(4));
|
||||
explain extended select encode(f1,'zxcv') as 'enc' from t1;
|
||||
explain extended select decode(f1,'zxcv') as 'enc' from t1;
|
||||
drop table t1;
|
||||
|
||||
--echo End of 4.1 tests
|
||||
|
||||
#
|
||||
|
@ -701,3 +701,54 @@ EXPLAIN SELECT SQL_BIG_RESULT b, sum(1) FROM t1 GROUP BY b;
|
||||
SELECT b, sum(1) FROM t1 GROUP BY b;
|
||||
SELECT SQL_BIG_RESULT b, sum(1) FROM t1 GROUP BY b;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug #23417: Too strict checks against GROUP BY in the ONLY_FULL_GROUP_BY mode
|
||||
#
|
||||
CREATE TABLE t1 (a INT PRIMARY KEY, b INT);
|
||||
INSERT INTO t1 VALUES (1,1),(2,1),(3,2),(4,2),(5,3),(6,3);
|
||||
|
||||
SET SQL_MODE = 'ONLY_FULL_GROUP_BY';
|
||||
SELECT MAX(a)-MIN(a) FROM t1 GROUP BY b;
|
||||
SELECT CEILING(MIN(a)) FROM t1 GROUP BY b;
|
||||
SELECT CASE WHEN AVG(a)>=0 THEN 'Positive' ELSE 'Negative' END FROM t1
|
||||
GROUP BY b;
|
||||
SELECT a + 1 FROM t1 GROUP BY a;
|
||||
--error ER_WRONG_FIELD_WITH_GROUP
|
||||
SELECT a + b FROM t1 GROUP BY b;
|
||||
SELECT (SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1)
|
||||
FROM t1 AS t1_outer;
|
||||
SELECT 1 FROM t1 as t1_outer GROUP BY a
|
||||
HAVING (SELECT t1_outer.a FROM t1 AS t1_inner GROUP BY b LIMIT 1);
|
||||
--error ER_WRONG_FIELD_WITH_GROUP
|
||||
SELECT (SELECT t1_outer.a FROM t1 AS t1_inner LIMIT 1)
|
||||
FROM t1 AS t1_outer GROUP BY t1_outer.b;
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
SELECT 1 FROM t1 as t1_outer GROUP BY a
|
||||
HAVING (SELECT t1_outer.b FROM t1 AS t1_inner LIMIT 1);
|
||||
SELECT (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner LIMIT 1)
|
||||
FROM t1 AS t1_outer GROUP BY t1_outer.b;
|
||||
SELECT (SELECT SUM(t1_inner.a) FROM t1 AS t1_inner GROUP BY t1_inner.b LIMIT 1)
|
||||
FROM t1 AS t1_outer;
|
||||
--error ER_WRONG_FIELD_WITH_GROUP
|
||||
SELECT (SELECT SUM(t1_outer.a) FROM t1 AS t1_inner LIMIT 1)
|
||||
FROM t1 AS t1_outer GROUP BY t1_outer.b;
|
||||
|
||||
SELECT 1 FROM t1 as t1_outer
|
||||
WHERE (SELECT t1_outer.b FROM t1 AS t1_inner GROUP BY t1_inner.b LIMIT 1);
|
||||
|
||||
SELECT b FROM t1 GROUP BY b HAVING CEILING(b) > 0;
|
||||
|
||||
SELECT 1 FROM t1 GROUP BY b HAVING b = 2 OR b = 3 OR SUM(a) > 12;
|
||||
SELECT 1 FROM t1 GROUP BY b HAVING ROW (b,b) = ROW (1,1);
|
||||
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
SELECT 1 FROM t1 GROUP BY b HAVING a = 2;
|
||||
--error ER_INVALID_GROUP_FUNC_USE
|
||||
SELECT 1 FROM t1 GROUP BY SUM(b);
|
||||
--error ER_WRONG_FIELD_WITH_GROUP
|
||||
SELECT b FROM t1 AS t1_outer GROUP BY a HAVING t1_outer.a IN
|
||||
(SELECT SUM(t1_inner.b)+t1_outer.b FROM t1 AS t1_inner GROUP BY t1_inner.a
|
||||
HAVING SUM(t1_inner.b)+t1_outer.b > 5);
|
||||
DROP TABLE t1;
|
||||
SET SQL_MODE = '';
|
||||
|
@ -198,3 +198,21 @@ select row_count();
|
||||
insert into t1 values (5, 5) on duplicate key update data= data + 10;
|
||||
select row_count();
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#25123: ON DUPLICATE KEY clause allows fields not from the insert table
|
||||
#
|
||||
create table t1 (f1 int unique, f2 int);
|
||||
create table t2 (f3 int, f4 int);
|
||||
create view v1 as select * from t1, t2 where f1= f3;
|
||||
insert into t1 values (1,11), (2,22);
|
||||
insert into t2 values (1,12), (2,24);
|
||||
--error 1393
|
||||
insert into v1 (f1) values (3) on duplicate key update f3= f3 + 10;
|
||||
insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10;
|
||||
select * from t1;
|
||||
insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10;
|
||||
select * from t1;
|
||||
drop view v1;
|
||||
drop table t1,t2;
|
||||
|
||||
|
@ -847,6 +847,33 @@ DROP TABLE t1;
|
||||
SET @@myisam_repair_threads=1;
|
||||
SHOW VARIABLES LIKE 'myisam_repair%';
|
||||
|
||||
#
|
||||
# BUG#21310 - Trees in SQL causing a "crashed" table with MyISAM storage
|
||||
# engine
|
||||
#
|
||||
|
||||
# A simplified test case that reflect crashed table issue.
|
||||
CREATE TABLE t1(a VARCHAR(16));
|
||||
INSERT INTO t1 VALUES('aaaaaaaa'),(NULL);
|
||||
UPDATE t1 AS ta1, t1 AS ta2 SET ta1.a='aaaaaaaaaaaaaaaa';
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
# A test case that reflect wrong result set.
|
||||
CREATE TABLE t1(a INT);
|
||||
INSERT INTO t1 VALUES(1),(2);
|
||||
UPDATE t1,t1 AS t2 SET t1.a=t1.a+2 WHERE t1.a=t2.a-1;
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug#24607 - MyISAM pointer size determined incorrectly
|
||||
#
|
||||
CREATE TABLE t1 (c1 TEXT) AVG_ROW_LENGTH=70100 MAX_ROWS=4100100100;
|
||||
--replace_column 5 X 6 X 7 X 9 X 10 X 11 X 12 X 13 X 14 X 16 X
|
||||
SHOW TABLE STATUS LIKE 't1';
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 4.1 tests
|
||||
|
||||
|
||||
|
@ -710,3 +710,22 @@ drop table t1;
|
||||
--error 1
|
||||
--exec $MY_PERROR --ndb 1186 2>&1
|
||||
|
||||
#
|
||||
# Bug #25746 - VARCHAR UTF8 PK issue
|
||||
# - prior to bugfix 4209, illegal length parameter would be
|
||||
# returned in SELECT *
|
||||
|
||||
CREATE TABLE t1 (
|
||||
a VARBINARY(40) NOT NULL,
|
||||
b VARCHAR (256) CHARACTER SET UTF8 NOT NULL,
|
||||
c VARCHAR(256) CHARACTER SET UTF8 NOT NULL,
|
||||
PRIMARY KEY (b,c)) ENGINE=ndbcluster;
|
||||
INSERT INTO t1 VALUES
|
||||
("a","ab","abc"),("b","abc","abcd"),("c","abc","ab"),("d","ab","ab"),("e","abc","abc");
|
||||
SELECT * FROM t1 ORDER BY a;
|
||||
DROP TABLE t1;
|
||||
|
||||
# End of 5.0 tests
|
||||
--echo End of 5.0 tests
|
||||
|
||||
|
||||
|
@ -356,3 +356,15 @@ insert into t1 (a, c) values (1,'aaa'),(3,'bbb');
|
||||
select count(*) from t1 where c<'bbb';
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
# bug#24820 CREATE INDEX ....USING HASH on NDB table creates ordered index, not HASH index
|
||||
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
create table nationaldish (DishID int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
CountryCode char(3) NOT NULL,
|
||||
DishTitle varchar(64) NOT NULL,
|
||||
calories smallint(5) unsigned DEFAULT NULL,
|
||||
PRIMARY KEY (DishID),
|
||||
INDEX i USING HASH (countrycode,calories)
|
||||
) ENGINE=ndbcluster;
|
||||
|
||||
|
@ -238,3 +238,18 @@ select * from t12 order by 1,2,3;
|
||||
select * from t21 order by 1,2,3;
|
||||
select * from t22 order by 1,2,3;
|
||||
DROP TABLE t1, t11, t12, t21, t22;
|
||||
|
||||
# bug#19956
|
||||
CREATE TABLE t1 (id varchar(255) NOT NULL,
|
||||
tag int(11) NOT NULL,
|
||||
doc text NOT NULL,
|
||||
type varchar(150) NOT NULL,
|
||||
modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=ndbcluster;
|
||||
|
||||
INSERT INTO t1 VALUES ('sakila',1,'Some text goes here','text',CURRENT_TIMESTAMP);
|
||||
SELECT id, tag, doc, type FROM t1 WHERE id IN ('flipper','orka');
|
||||
SELECT id, tag, doc, type FROM t1 WHERE id IN ('flipper','sakila');
|
||||
|
||||
DROP TABLE t1;
|
||||
|
@ -1649,6 +1649,7 @@ execute sq;
|
||||
deallocate prepare no_index;
|
||||
deallocate prepare sq;
|
||||
|
||||
|
||||
#
|
||||
# Bug 25027: query with a single-row non-correlated subquery
|
||||
# and IS NULL predicate
|
||||
@ -1743,4 +1744,34 @@ drop table t1, t2;
|
||||
#deallocate prepare stmt;
|
||||
#set @@character_set_server= @old_character_set_server;
|
||||
|
||||
|
||||
#
|
||||
# BUG#24491 "using alias from source table in insert ... on duplicate key"
|
||||
#
|
||||
--disable_warnings
|
||||
drop tables if exists t1;
|
||||
--enable_warnings
|
||||
create table t1 (id int primary key auto_increment, value varchar(10));
|
||||
insert into t1 (id, value) values (1, 'FIRST'), (2, 'SECOND'), (3, 'THIRD');
|
||||
# Let us prepare INSERT ... SELECT ... ON DUPLICATE KEY UPDATE statement
|
||||
# which in its ON DUPLICATE KEY clause erroneously tries to assign value
|
||||
# to a column which is mentioned only in SELECT part.
|
||||
prepare stmt from "insert into t1 (id, value) select * from (select 4 as i, 'FOURTH' as v) as y on duplicate key update v = 'DUP'";
|
||||
# Both first and second attempts to execute it should fail
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
execute stmt;
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
execute stmt;
|
||||
deallocate prepare stmt;
|
||||
# And now the same test for more complex case which is more close
|
||||
# to the one that was reported originally.
|
||||
prepare stmt from "insert into t1 (id, value) select * from (select 4 as id, 'FOURTH' as value) as y on duplicate key update y.value = 'DUP'";
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
execute stmt;
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
execute stmt;
|
||||
deallocate prepare stmt;
|
||||
drop tables t1;
|
||||
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
@ -525,6 +525,49 @@ explain select a from t1 where a > 'x';
|
||||
select a from t1 where a > 'x';
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug #24776: assertion abort for 'range checked for each record'
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
OXID varchar(32) COLLATE latin1_german2_ci NOT NULL DEFAULT '',
|
||||
OXPARENTID varchar(32) COLLATE latin1_german2_ci NOT NULL DEFAULT 'oxrootid',
|
||||
OXLEFT int NOT NULL DEFAULT '0',
|
||||
OXRIGHT int NOT NULL DEFAULT '0',
|
||||
OXROOTID varchar(32) COLLATE latin1_german2_ci NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (OXID),
|
||||
KEY OXNID (OXID),
|
||||
KEY OXLEFT (OXLEFT),
|
||||
KEY OXRIGHT (OXRIGHT),
|
||||
KEY OXROOTID (OXROOTID)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_german2_ci;
|
||||
|
||||
INSERT INTO t1 VALUES
|
||||
('d8c4177d09f8b11f5.52725521','oxrootid',1,40,'d8c4177d09f8b11f5.52725521'),
|
||||
('d8c4177d151affab2.81582770','d8c4177d09f8b11f5.52725521',2,3,
|
||||
'd8c4177d09f8b11f5.52725521'),
|
||||
('d8c4177d206a333d2.74422679','d8c4177d09f8b11f5.52725521',4,5,
|
||||
'd8c4177d09f8b11f5.52725521'),
|
||||
('d8c4177d225791924.30714720','d8c4177d09f8b11f5.52725521',6,7,
|
||||
'd8c4177d09f8b11f5.52725521'),
|
||||
('d8c4177d2380fc201.39666693','d8c4177d09f8b11f5.52725521',8,9,
|
||||
'd8c4177d09f8b11f5.52725521'),
|
||||
('d8c4177d24ccef970.14957924','d8c4177d09f8b11f5.52725521',10,11,
|
||||
'd8c4177d09f8b11f5.52725521');
|
||||
|
||||
EXPLAIN
|
||||
SELECT s.oxid FROM t1 v, t1 s
|
||||
WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
|
||||
v.oxrootid ='d8c4177d09f8b11f5.52725521' AND
|
||||
s.oxleft > v.oxleft AND s.oxleft < v.oxright;
|
||||
|
||||
SELECT s.oxid FROM t1 v, t1 s
|
||||
WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
|
||||
v.oxrootid ='d8c4177d09f8b11f5.52725521' AND
|
||||
s.oxleft > v.oxleft AND s.oxleft < v.oxright;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 4.1 tests
|
||||
|
||||
#
|
||||
|
@ -3103,6 +3103,16 @@ SELECT t3.a FROM t1,t2,t3
|
||||
t3.c IN ('bb','ee');
|
||||
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
||||
#
|
||||
# Bug#25172: Not checked buffer size leads to a server crash
|
||||
#
|
||||
CREATE TABLE t1 ( f1 int primary key, f2 int, f3 int, f4 int, f5 int, f6 int, checked_out int);
|
||||
CREATE TABLE t2 ( f11 int PRIMARY KEY );
|
||||
INSERT INTO t1 VALUES (1,1,1,0,0,0,0),(2,1,1,3,8,1,0),(3,1,1,4,12,1,0);
|
||||
INSERT INTO t2 VALUES (62);
|
||||
SELECT * FROM t1 LEFT JOIN t2 ON f11 = t1.checked_out GROUP BY f1 ORDER BY f2, f3, f4, f5 LIMIT 0, 1;
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
#
|
||||
# Bug#6298: LIMIT #, -1 no longer works to set start with no end limit
|
||||
|
@ -1808,6 +1808,38 @@ PREPARE stmt FROM "CREATE VIEW v AS SELECT ?";
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
#
|
||||
# BUG#24491 "using alias from source table in insert ... on duplicate key"
|
||||
#
|
||||
--disable_warnings
|
||||
drop tables if exists t1;
|
||||
drop procedure if exists bug24491;
|
||||
--enable_warnings
|
||||
create table t1 (id int primary key auto_increment, value varchar(10));
|
||||
insert into t1 (id, value) values (1, 'FIRST'), (2, 'SECOND'), (3, 'THIRD');
|
||||
# Let us create routine with INSERT ... SELECT ... ON DUPLICATE KEY UPDATE
|
||||
# statement which in its ON DUPLICATE KEY clause erroneously tries to assign
|
||||
# value to a column which is mentioned only in SELECT part.
|
||||
create procedure bug24491()
|
||||
insert into t1 (id, value) select * from (select 4 as i, 'FOURTH' as v) as y on duplicate key update v = 'DUP';
|
||||
# Both first and second calls to it should fail
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
call bug24491();
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
call bug24491();
|
||||
drop procedure bug24491;
|
||||
# And now the same test for more complex case which is more close
|
||||
# to the one that was reported originally.
|
||||
create procedure bug24491()
|
||||
insert into t1 (id, value) select * from (select 4 as id, 'FOURTH' as value) as y on duplicate key update y.value = 'DUP';
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
call bug24491();
|
||||
--error ER_BAD_FIELD_ERROR
|
||||
call bug24491();
|
||||
drop procedure bug24491;
|
||||
drop tables t1;
|
||||
|
||||
|
||||
#
|
||||
# BUG#NNNN: New bug synopsis
|
||||
#
|
||||
|
@ -2508,3 +2508,37 @@ SELECT SQL_NO_CACHE COUNT(*)
|
||||
FROM t1) t;
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
#
|
||||
# Bug #25219: EXIST subquery with UNION over a mix of
|
||||
# correlated and uncorrelated selects
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (id char(4) PRIMARY KEY, c int);
|
||||
CREATE TABLE t2 (c int);
|
||||
|
||||
INSERT INTO t1 VALUES ('aa', 1);
|
||||
INSERT INTO t2 VALUES (1);
|
||||
|
||||
SELECT * FROM t1
|
||||
WHERE EXISTS (SELECT c FROM t2 WHERE c=1
|
||||
UNION
|
||||
SELECT c from t2 WHERE c=t1.c);
|
||||
|
||||
INSERT INTO t1 VALUES ('bb', 2), ('cc', 3), ('dd',1);
|
||||
|
||||
SELECT * FROM t1
|
||||
WHERE EXISTS (SELECT c FROM t2 WHERE c=1
|
||||
UNION
|
||||
SELECT c from t2 WHERE c=t1.c);
|
||||
|
||||
INSERT INTO t2 VALUES (2);
|
||||
CREATE TABLE t3 (c int);
|
||||
INSERT INTO t3 VALUES (1);
|
||||
|
||||
SELECT * FROM t1
|
||||
WHERE EXISTS (SELECT t2.c FROM t2 JOIN t3 ON t2.c=t3.c WHERE t2.c=1
|
||||
UNION
|
||||
SELECT c from t2 WHERE c=t1.c);
|
||||
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
@ -16,13 +16,14 @@ insert into t1 (oref, grp, ie) values
|
||||
(3, 1, 4),
|
||||
(3, 2, NULL);
|
||||
|
||||
# Ok, for
|
||||
# Ok, for
|
||||
# select max(ie) from t1 where oref=PARAM group by grp
|
||||
# we'll have:
|
||||
# 1 -> (1, NULL) matching + NULL
|
||||
# 2 -> (3) non-matching
|
||||
# 3 -> (3, NULL) non-matching + NULL
|
||||
# 4 -> () nothing.
|
||||
# PARAM subquery result
|
||||
# 1 -> {(1), (NULL)} matching + NULL
|
||||
# 2 -> {(3)} non-matching
|
||||
# 3 -> {(3), (NULL)} non-matching + NULL
|
||||
# 4 -> {} empty set
|
||||
|
||||
create table t2 (oref int, a int);
|
||||
insert into t2 values
|
||||
@ -34,18 +35,21 @@ insert into t2 values
|
||||
|
||||
# true, false, null, false, null
|
||||
select a, oref, a in (select max(ie)
|
||||
from t1 where oref=t2.oref group by grp) from t2;
|
||||
from t1 where oref=t2.oref group by grp) Z from t2;
|
||||
|
||||
# This must have a trigcond
|
||||
explain extended
|
||||
select a, oref, a in (select max(ie)
|
||||
from t1 where oref=t2.oref group by grp) from t2;
|
||||
from t1 where oref=t2.oref group by grp) Z from t2;
|
||||
|
||||
# This must not have a trigcond:
|
||||
explain extended
|
||||
select a, oref from t2
|
||||
where a in (select max(ie) from t1 where oref=t2.oref group by grp);
|
||||
|
||||
select a, oref, a in (
|
||||
select max(ie) from t1 where oref=t2.oref group by grp union
|
||||
select max(ie) from t1 where oref=t2.oref group by grp
|
||||
) Z from t2;
|
||||
|
||||
# Non-correlated subquery, 2 NULL evaluations
|
||||
create table t3 (a int);
|
||||
@ -135,3 +139,336 @@ from t3;
|
||||
|
||||
drop table t1, t2, t3;
|
||||
|
||||
|
||||
#
|
||||
# BUG#24085: Wrong query result for "NULL IN (SELECT ... UNION SELECT ...)"
|
||||
#
|
||||
|
||||
# case 1: NULL IN (SELECT not_null_val FROM ...) w/o HAVING/GROUP-BY/etc
|
||||
create table t1 (a int NOT NULL, b int NOT NULL, key(a));
|
||||
insert into t1 values
|
||||
(0,0),(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
|
||||
|
||||
create table t2 like t1;
|
||||
insert into t2 select * from t1;
|
||||
update t2 set b=1;
|
||||
|
||||
create table t3 (a int, oref int);
|
||||
insert into t3 values (1, 1), (NULL,1), (NULL,0);
|
||||
select a, oref,
|
||||
t3.a in (select t1.a from t1, t2 where t1.b=t2.a and t2.b=t3.oref) Z
|
||||
from t3;
|
||||
|
||||
--echo This must show a trig_cond:
|
||||
explain extended
|
||||
select a, oref,
|
||||
t3.a in (select t1.a from t1, t2 where t1.b=t2.a and t2.b=t3.oref) Z
|
||||
from t3;
|
||||
drop table t1,t2,t3;
|
||||
|
||||
|
||||
# case 2: NULL IN (SELECT not_null_val FROM) where SELECT has GROUP BY
|
||||
create table t1 (oref int, grp int);
|
||||
insert into t1 (oref, grp) values
|
||||
(1, 1),
|
||||
(1, 1);
|
||||
|
||||
# Ok, for
|
||||
# select count(*) from t1 group by grp having grp=PARAM
|
||||
# we'll have:
|
||||
# PARAM subuqery result
|
||||
# 1 -> {(2)}
|
||||
# 2 -> {} - empty set
|
||||
create table t2 (oref int, a int);
|
||||
insert into t2 values
|
||||
(1, NULL),
|
||||
(2, NULL);
|
||||
|
||||
select a, oref,
|
||||
a in (select count(*) from t1 group by grp having grp=t2.oref) Z from t2;
|
||||
|
||||
--echo This must show a trig_cond:
|
||||
explain extended
|
||||
select a, oref,
|
||||
a in (select count(*) from t1 group by grp having grp=t2.oref) Z from t2;
|
||||
|
||||
drop table t1, t2;
|
||||
|
||||
create table t1 (a int, b int, primary key (a));
|
||||
insert into t1 values (1,1), (3,1),(100,1);
|
||||
create table t2 (a int, b int);
|
||||
insert into t2 values (1,1),(2,1),(NULL,1),(NULL,0);
|
||||
|
||||
select a,b, a in (select a from t1 where t1.b = t2.b union select a from
|
||||
t1 where t1.b = t2.b) Z from t2 ;
|
||||
select a,b, a in (select a from t1 where t1.b = t2.b) Z from t2 ;
|
||||
drop table t1, t2;
|
||||
|
||||
|
||||
#
|
||||
# BUG#24127: Incorrect results of row-based subqueries with NULLs on the left side.
|
||||
#
|
||||
create table t3 (a int);
|
||||
insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||
create table t2 (a int, b int, oref int);
|
||||
insert into t2 values (NULL,1, 100), (NULL,2, 100);
|
||||
|
||||
create table t1 (a int, b int, c int, key(a,b));
|
||||
insert into t1 select 2*A, 2*A, 100 from t3;
|
||||
|
||||
# First test index subquery engine
|
||||
explain extended select a,b, oref, (a,b) in (select a,b from t1 where c=t2.oref) Z from t2;
|
||||
select a,b, oref, (a,b) in (select a,b from t1 where c=t2.oref) Z from t2;
|
||||
|
||||
# Then check that we do turn off 'ref' scans in the subquery
|
||||
create table t4 (x int);
|
||||
insert into t4 select A.a + 10*B.a from t1 A, t1 B;
|
||||
explain extended
|
||||
select a,b, oref,
|
||||
(a,b) in (select a,b from t1,t4 where c=t2.oref) Z
|
||||
from t2;
|
||||
select a,b, oref,
|
||||
(a,b) in (select a,b from t1,t4 where c=t2.oref) Z
|
||||
from t2;
|
||||
|
||||
drop table t1,t2,t3,t4;
|
||||
|
||||
# More tests for tricky multi-column cases, where some of pushed-down
|
||||
# equalities are used for index lookups and some arent.
|
||||
create table t1 (oref char(4), grp int, ie1 int, ie2 int);
|
||||
insert into t1 (oref, grp, ie1, ie2) values
|
||||
('aa', 10, 2, 1),
|
||||
('aa', 10, 1, 1),
|
||||
('aa', 20, 2, 1),
|
||||
('bb', 10, 3, 1),
|
||||
('cc', 10, 4, 2),
|
||||
('cc', 20, 3, 2),
|
||||
|
||||
('ee', 10, 2, 1),
|
||||
('ee', 10, 1, 2),
|
||||
|
||||
('ff', 20, 2, 2),
|
||||
('ff', 20, 1, 2);
|
||||
create table t2 (oref char(4), a int, b int);
|
||||
insert into t2 values
|
||||
('ee', NULL, 1),
|
||||
('bb', 2, 1),
|
||||
('ff', 2, 2),
|
||||
('cc', 3, NULL),
|
||||
('bb', NULL, NULL),
|
||||
('aa', 1, 1),
|
||||
('dd', 1, NULL);
|
||||
alter table t1 add index idx(ie1,ie2);
|
||||
|
||||
--cc 3 NULL NULL
|
||||
select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2 where a=3 and b is null ;
|
||||
insert into t2 values ('new1', 10,10);
|
||||
insert into t1 values ('new1', 1234, 10, NULL);
|
||||
-- new1, 10, 10, NULL,
|
||||
select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2 where a=10 and b=10;
|
||||
explain extended
|
||||
select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2 where a=10 and b=10;
|
||||
drop table t1, t2;
|
||||
|
||||
# Now test different column types:
|
||||
create table t1 (oref char(4), grp int, ie int);
|
||||
insert into t1 (oref, grp, ie) values
|
||||
('aa', 10, 2),
|
||||
('aa', 10, 1),
|
||||
('aa', 20, NULL),
|
||||
|
||||
('bb', 10, 3),
|
||||
|
||||
('cc', 10, 4),
|
||||
('cc', 20, NULL),
|
||||
|
||||
('ee', 10, NULL),
|
||||
('ee', 10, NULL),
|
||||
|
||||
('ff', 20, 2),
|
||||
('ff', 20, 1);
|
||||
|
||||
create table t2 (oref char(4), a int);
|
||||
insert into t2 values
|
||||
('ee', NULL),
|
||||
('bb', 2),
|
||||
('ff', 2),
|
||||
('cc', 3),
|
||||
('aa', 1),
|
||||
('dd', NULL),
|
||||
('bb', NULL);
|
||||
|
||||
select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
|
||||
|
||||
select oref, a from t2 where a in (select ie from t1 where oref=t2.oref);
|
||||
|
||||
select oref, a from t2 where a not in (select ie from t1 where oref=t2.oref);
|
||||
|
||||
|
||||
select oref, a, a in (select min(ie) from t1 where oref=t2.oref group by grp) Z from t2;
|
||||
|
||||
select oref, a from t2 where
|
||||
a in (select min(ie) from t1 where oref=t2.oref group by grp);
|
||||
|
||||
select oref, a from t2 where
|
||||
a not in (select min(ie) from t1 where oref=t2.oref group by grp);
|
||||
|
||||
#
|
||||
update t1 set ie=3 where oref='ff' and ie=1;
|
||||
|
||||
select oref, a, a in (select min(ie) from t1 where oref=t2.oref group by
|
||||
grp) Z from t2;
|
||||
|
||||
|
||||
select oref, a from t2 where a in (select min(ie) from t1 where
|
||||
oref=t2.oref group by grp);
|
||||
|
||||
select oref, a from t2 where a not in (select min(ie) from t1 where
|
||||
oref=t2.oref group by grp);
|
||||
|
||||
select oref, a, a in (select min(ie) from t1 where oref=t2.oref group by
|
||||
grp having min(ie) > 1) Z from t2;
|
||||
|
||||
select oref, a from t2 where a in (select min(ie) from t1 where
|
||||
oref=t2.oref group by grp having min(ie) > 1);
|
||||
|
||||
select oref, a from t2 where a not in (select min(ie) from t1 where
|
||||
oref=t2.oref group by grp having min(ie) > 1);
|
||||
|
||||
#
|
||||
alter table t1 add index idx(ie);
|
||||
|
||||
explain select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
|
||||
|
||||
select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
|
||||
|
||||
select oref, a from t2 where a in (select ie from t1 where oref=t2.oref);
|
||||
|
||||
select oref, a from t2 where a not in (select ie from t1 where oref=t2.oref);
|
||||
|
||||
|
||||
alter table t1 drop index idx;
|
||||
alter table t1 add index idx(oref,ie);
|
||||
|
||||
explain select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
|
||||
|
||||
select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
|
||||
|
||||
select oref, a from t2 where a in (select ie from t1 where oref=t2.oref);
|
||||
|
||||
select oref, a from t2 where a not in (select ie from t1 where oref=t2.oref);
|
||||
|
||||
explain
|
||||
select oref, a,
|
||||
a in (select min(ie) from t1 where oref=t2.oref
|
||||
group by grp having min(ie) > 1) Z
|
||||
from t2;
|
||||
|
||||
select oref, a,
|
||||
a in (select min(ie) from t1 where oref=t2.oref
|
||||
group by grp having min(ie) > 1) Z
|
||||
from t2;
|
||||
|
||||
select oref, a from t2 where a in (select min(ie) from t1 where oref=t2.oref
|
||||
group by grp having min(ie) > 1);
|
||||
|
||||
select oref, a from t2 where a not in (select min(ie) from t1 where oref=t2.oref
|
||||
group by grp having min(ie) > 1);
|
||||
|
||||
drop table t1,t2;
|
||||
|
||||
create table t1 (oref char(4), grp int, ie1 int, ie2 int);
|
||||
insert into t1 (oref, grp, ie1, ie2) values
|
||||
('aa', 10, 2, 1),
|
||||
('aa', 10, 1, 1),
|
||||
('aa', 20, 2, 1),
|
||||
|
||||
('bb', 10, 3, 1),
|
||||
|
||||
('cc', 10, 4, 2),
|
||||
('cc', 20, 3, 2),
|
||||
|
||||
('ee', 10, 2, 1),
|
||||
('ee', 10, 1, 2),
|
||||
|
||||
('ff', 20, 2, 2),
|
||||
('ff', 20, 1, 2);
|
||||
|
||||
create table t2 (oref char(4), a int, b int);
|
||||
insert into t2 values
|
||||
('ee', NULL, 1),
|
||||
('bb', 2, 1),
|
||||
('ff', 2, 2),
|
||||
('cc', 3, NULL),
|
||||
('bb', NULL, NULL),
|
||||
('aa', 1, 1),
|
||||
('dd', 1, NULL);
|
||||
|
||||
select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2;
|
||||
|
||||
select oref, a, b from t2 where (a,b) in (select ie1,ie2 from t1 where oref=t2.oref);
|
||||
|
||||
select oref, a, b from t2 where (a,b) not in (select ie1,ie2 from t1 where oref=t2.oref);
|
||||
|
||||
select oref, a, b,
|
||||
(a,b) in (select min(ie1),max(ie2) from t1
|
||||
where oref=t2.oref group by grp) Z
|
||||
from t2;
|
||||
|
||||
select oref, a, b from t2 where
|
||||
(a,b) in (select min(ie1), max(ie2) from t1 where oref=t2.oref group by grp);
|
||||
|
||||
select oref, a, b from t2 where
|
||||
(a,b) not in (select min(ie1), max(ie2) from t1 where oref=t2.oref group by grp);
|
||||
|
||||
alter table t1 add index idx(ie1,ie2);
|
||||
|
||||
explain select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2;
|
||||
|
||||
select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2;
|
||||
|
||||
select oref, a, b from t2 where (a,b) in (select ie1,ie2 from t1 where oref=t2.oref);
|
||||
|
||||
select oref, a, b from t2 where (a,b) not in (select ie1,ie2 from t1 where oref=t2.oref);
|
||||
|
||||
explain extended
|
||||
select oref, a, b, (a,b) in (select ie1,ie2 from t1 where oref=t2.oref) Z from t2;
|
||||
|
||||
drop table t1,t2;
|
||||
|
||||
create table t1 (oref char(4), grp int, ie int primary key);
|
||||
insert into t1 (oref, grp, ie) values
|
||||
('aa', 10, 2),
|
||||
('aa', 10, 1),
|
||||
|
||||
('bb', 10, 3),
|
||||
|
||||
('cc', 10, 4),
|
||||
('cc', 20, 5),
|
||||
('cc', 10, 6);
|
||||
|
||||
create table t2 (oref char(4), a int);
|
||||
insert into t2 values
|
||||
('ee', NULL),
|
||||
('bb', 2),
|
||||
('cc', 5),
|
||||
('cc', 2),
|
||||
('cc', NULL),
|
||||
('aa', 1),
|
||||
('bb', NULL);
|
||||
|
||||
explain select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
|
||||
|
||||
select oref, a, a in (select ie from t1 where oref=t2.oref) Z from t2;
|
||||
|
||||
select oref, a from t2 where a in (select ie from t1 where oref=t2.oref);
|
||||
|
||||
select oref, a from t2 where a not in (select ie from t1 where oref=t2.oref);
|
||||
|
||||
explain
|
||||
select oref, a, a in (select min(ie) from t1 where oref=t2.oref group by grp) Z from t2;
|
||||
|
||||
select oref, a, a in (select min(ie) from t1 where oref=t2.oref group by grp) Z from t2;
|
||||
|
||||
drop table t1,t2;
|
||||
|
||||
|
@ -1554,4 +1554,50 @@ select * from t1;
|
||||
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#25398: crash when a trigger contains a SELECT with
|
||||
# trigger fields in the select list under DISTINCT
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id int NOT NULL DEFAULT '0',
|
||||
a varchar(10) NOT NULL,
|
||||
b varchar(10),
|
||||
c varchar(10),
|
||||
d timestamp NOT NULL,
|
||||
PRIMARY KEY (id, a)
|
||||
);
|
||||
|
||||
CREATE TABLE t2 (
|
||||
fubar_id int unsigned NOT NULL DEFAULT '0',
|
||||
last_change_time datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
PRIMARY KEY (fubar_id)
|
||||
);
|
||||
|
||||
DELIMITER |;
|
||||
|
||||
CREATE TRIGGER fubar_change
|
||||
AFTER UPDATE ON t1
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
INSERT INTO t2 (fubar_id, last_change_time)
|
||||
SELECT DISTINCT NEW.id AS fubar_id, NOW() AS last_change_time
|
||||
FROM t1 WHERE (id = NEW.id) AND (OLD.c != NEW.c)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
last_change_time =
|
||||
IF((fubar_id = NEW.id)AND(OLD.c != NEW.c),NOW(),last_change_time);
|
||||
END
|
||||
|
|
||||
|
||||
DELIMITER ;|
|
||||
|
||||
INSERT INTO t1 (id,a, b,c,d) VALUES
|
||||
(1,'a','b','c',now()),(2,'a','b','c',now());
|
||||
|
||||
UPDATE t1 SET c='Bang!' WHERE id=1;
|
||||
|
||||
SELECT fubar_id FROM t2;
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
@ -242,3 +242,50 @@ drop table bug18761;
|
||||
select is_const((1,2,3));
|
||||
|
||||
drop function if exists is_const;
|
||||
|
||||
#
|
||||
# Bug #25382: Passing NULL to an UDF called from stored procedures
|
||||
# crashes server
|
||||
#
|
||||
--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
|
||||
eval CREATE FUNCTION metaphon RETURNS STRING SONAME "$UDF_EXAMPLE_LIB";
|
||||
|
||||
--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
|
||||
eval CREATE FUNCTION myfunc_double RETURNS REAL SONAME "$UDF_EXAMPLE_LIB";
|
||||
|
||||
--replace_result $UDF_EXAMPLE_LIB UDF_EXAMPLE_LIB
|
||||
eval CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "$UDF_EXAMPLE_LIB";
|
||||
|
||||
delimiter //;
|
||||
create function f1(p1 varchar(255))
|
||||
returns varchar(255)
|
||||
begin
|
||||
return metaphon(p1);
|
||||
end//
|
||||
|
||||
create function f2(p1 varchar(255))
|
||||
returns double
|
||||
begin
|
||||
return myfunc_double(p1);
|
||||
end//
|
||||
|
||||
create function f3(p1 varchar(255))
|
||||
returns double
|
||||
begin
|
||||
return myfunc_int(p1);
|
||||
end//
|
||||
|
||||
delimiter ;//
|
||||
|
||||
select f3(NULL);
|
||||
select f2(NULL);
|
||||
select f1(NULL);
|
||||
|
||||
drop function f1;
|
||||
drop function f2;
|
||||
drop function f3;
|
||||
drop function metaphon;
|
||||
drop function myfunc_double;
|
||||
drop function myfunc_int;
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
@ -2959,6 +2959,17 @@ SELECT * FROM t1;
|
||||
DROP VIEW v1, v2;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug #25580: !0 as an operand in a select expression of a view
|
||||
#
|
||||
|
||||
CREATE VIEW v AS SELECT !0 * 5 AS x FROM DUAL;
|
||||
SHOW CREATE VIEW v;
|
||||
|
||||
SELECT !0 * 5 AS x FROM DUAL;
|
||||
SELECT * FROM v;
|
||||
|
||||
DROP VIEW v;
|
||||
|
||||
#
|
||||
# BUG#24293: '\Z' token is not handled correctly in views
|
||||
|
@ -927,6 +927,7 @@ DROP VIEW v2;
|
||||
DROP VIEW v1;
|
||||
DROP USER mysqltest_u1@localhost;
|
||||
|
||||
|
||||
#
|
||||
# Bug#17254: Error for DEFINER security on VIEW provides too much info
|
||||
#
|
||||
@ -964,4 +965,74 @@ DROP DATABASE db17254;
|
||||
disconnect def;
|
||||
disconnect inv;
|
||||
|
||||
# End of 5.0 tests.
|
||||
|
||||
#
|
||||
# BUG#24404: strange bug with view+permission+prepared statement
|
||||
#
|
||||
--disable_warnings
|
||||
DROP DATABASE IF EXISTS mysqltest_db1;
|
||||
DROP DATABASE IF EXISTS mysqltest_db2;
|
||||
--enable_warnings
|
||||
--error 0,ER_CANNOT_USER
|
||||
DROP USER mysqltest_u1;
|
||||
--error 0,ER_CANNOT_USER
|
||||
DROP USER mysqltest_u2;
|
||||
|
||||
CREATE USER mysqltest_u1@localhost;
|
||||
CREATE USER mysqltest_u2@localhost;
|
||||
|
||||
CREATE DATABASE mysqltest_db1;
|
||||
CREATE DATABASE mysqltest_db2;
|
||||
|
||||
GRANT ALL ON mysqltest_db1.* TO mysqltest_u1@localhost WITH GRANT OPTION;
|
||||
GRANT ALL ON mysqltest_db2.* TO mysqltest_u2@localhost;
|
||||
|
||||
connect (conn1, localhost, mysqltest_u1, , mysqltest_db1);
|
||||
|
||||
CREATE TABLE t1 (i INT);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
|
||||
# Use view with subquery for better coverage.
|
||||
CREATE VIEW v1 AS SELECT i FROM t1 WHERE 1 IN (SELECT * FROM t1);
|
||||
|
||||
CREATE TABLE t2 (s CHAR(7));
|
||||
INSERT INTO t2 VALUES ('public');
|
||||
|
||||
GRANT SELECT ON v1 TO mysqltest_u2@localhost;
|
||||
GRANT SELECT ON t2 TO mysqltest_u2@localhost;
|
||||
|
||||
connect (conn2, localhost, mysqltest_u2, , mysqltest_db2);
|
||||
|
||||
SELECT * FROM mysqltest_db1.v1, mysqltest_db1.t2;
|
||||
PREPARE stmt1 FROM "SELECT * FROM mysqltest_db1.t2";
|
||||
EXECUTE stmt1;
|
||||
PREPARE stmt2 FROM "SELECT * FROM mysqltest_db1.v1, mysqltest_db1.t2";
|
||||
EXECUTE stmt2;
|
||||
|
||||
connection conn1;
|
||||
# Make table 't2' private.
|
||||
REVOKE SELECT ON t2 FROM mysqltest_u2@localhost;
|
||||
UPDATE t2 SET s = 'private' WHERE s = 'public';
|
||||
|
||||
connection conn2;
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
SELECT * FROM mysqltest_db1.v1, mysqltest_db1.t2;
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
EXECUTE stmt1;
|
||||
# Original bug was here: the statement didn't fail.
|
||||
--error ER_TABLEACCESS_DENIED_ERROR
|
||||
EXECUTE stmt2;
|
||||
|
||||
# Cleanup.
|
||||
disconnect conn2;
|
||||
disconnect conn1;
|
||||
connection default;
|
||||
REVOKE ALL ON mysqltest_db1.* FROM mysqltest_u1@localhost;
|
||||
REVOKE ALL ON mysqltest_db2.* FROM mysqltest_u2@localhost;
|
||||
DROP DATABASE mysqltest_db1;
|
||||
DROP DATABASE mysqltest_db2;
|
||||
DROP USER mysqltest_u1@localhost;
|
||||
DROP USER mysqltest_u2@localhost;
|
||||
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
@ -757,8 +757,16 @@ void thr_unlock(THR_LOCK_DATA *data)
|
||||
}
|
||||
else
|
||||
lock->write.last=data->prev;
|
||||
if (lock_type >= TL_WRITE_CONCURRENT_INSERT && lock->update_status)
|
||||
(*lock->update_status)(data->status_param);
|
||||
if (lock_type >= TL_WRITE_CONCURRENT_INSERT)
|
||||
{
|
||||
if (lock->update_status)
|
||||
(*lock->update_status)(data->status_param);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lock->restore_status)
|
||||
(*lock->restore_status)(data->status_param);
|
||||
}
|
||||
if (lock_type == TL_READ_NO_INSERT)
|
||||
lock->read_no_write_count--;
|
||||
data->type=TL_UNLOCK; /* Mark unlocked */
|
||||
|
@ -67,6 +67,7 @@ public:
|
||||
// 100-105 TUP and ACC
|
||||
// 200-240 UTIL
|
||||
// 300-305 TRIX
|
||||
QmgrErr935 = 935,
|
||||
NdbfsDumpFileStat = 400,
|
||||
NdbfsDumpAllFiles = 401,
|
||||
NdbfsDumpOpenFiles = 402,
|
||||
|
@ -540,6 +540,16 @@ extern "C" {
|
||||
*/
|
||||
const char *ndb_mgm_get_connectstring(NdbMgmHandle handle, char *buf, int buf_sz);
|
||||
|
||||
/**
|
||||
* Sets the number of seconds to wait for connect(2) during ndb_mgm_connect
|
||||
* Default is no timeout
|
||||
*
|
||||
* @param handle NdbMgmHandle
|
||||
* @param seconds number of seconds
|
||||
* @return non-zero on success
|
||||
*/
|
||||
int ndb_mgm_set_connect_timeout(NdbMgmHandle handle, unsigned int seconds);
|
||||
|
||||
/**
|
||||
* Connects to a management server. Connectstring is set by
|
||||
* ndb_mgm_set_connectstring().
|
||||
|
@ -65,7 +65,7 @@ void NdbMem_Free(void* ptr);
|
||||
* NdbMem_MemLockAll
|
||||
* Locks virtual memory in main memory
|
||||
*/
|
||||
int NdbMem_MemLockAll(void);
|
||||
int NdbMem_MemLockAll(int);
|
||||
|
||||
/**
|
||||
* NdbMem_MemUnlockAll
|
||||
|
@ -23,6 +23,7 @@ class SocketClient
|
||||
{
|
||||
NDB_SOCKET_TYPE m_sockfd;
|
||||
struct sockaddr_in m_servaddr;
|
||||
unsigned int m_connect_timeout_sec;
|
||||
unsigned short m_port;
|
||||
char *m_server_name;
|
||||
SocketAuthenticator *m_auth;
|
||||
@ -34,6 +35,9 @@ public:
|
||||
m_port = port;
|
||||
m_servaddr.sin_port = htons(m_port);
|
||||
};
|
||||
void set_connect_timeout(unsigned int s) {
|
||||
m_connect_timeout_sec= s;
|
||||
}
|
||||
unsigned short get_port() { return m_port; };
|
||||
char *get_server_name() { return m_server_name; };
|
||||
int bind(const char* toaddress, unsigned short toport);
|
||||
|
@ -115,7 +115,8 @@ void getTextNDBStopForced(QQQQ) {
|
||||
int sphase = theData[4];
|
||||
int extra = theData[5];
|
||||
getRestartAction(theData[1],action_str);
|
||||
reason_str.appfmt(" Initiated by signal %d.", signum);
|
||||
if (signum)
|
||||
reason_str.appfmt(" Initiated by signal %d.", signum);
|
||||
if (error)
|
||||
{
|
||||
ndbd_exit_classification cl;
|
||||
|
@ -56,7 +56,15 @@ void NdbMem_Free(void* ptr)
|
||||
}
|
||||
|
||||
|
||||
int NdbMem_MemLockAll(){
|
||||
int NdbMem_MemLockAll(int i){
|
||||
if (i == 1)
|
||||
{
|
||||
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && defined (MCL_FUTURE)
|
||||
return mlockall(MCL_CURRENT | MCL_FUTURE);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
|
||||
return mlockall(MCL_CURRENT);
|
||||
#else
|
||||
|
@ -79,9 +79,13 @@ Transporter::Transporter(TransporterRegistry &t_reg,
|
||||
if (isServer)
|
||||
m_socket_client= 0;
|
||||
else
|
||||
{
|
||||
m_socket_client= new SocketClient(remoteHostName, s_port,
|
||||
new SocketAuthSimple("ndbd",
|
||||
"ndbd passwd"));
|
||||
|
||||
m_socket_client->set_connect_timeout((m_timeOutMillis+999)/1000);
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -140,9 +144,9 @@ Transporter::connect_client() {
|
||||
}
|
||||
sockfd= m_socket_client->connect();
|
||||
}
|
||||
|
||||
|
||||
return connect_client(sockfd);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Transporter::connect_client(NDB_SOCKET_TYPE sockfd) {
|
||||
|
@ -48,7 +48,7 @@ static const char Magic[] = { 'N', 'D', 'B', 'C', 'O', 'N', 'F', 'V' };
|
||||
|
||||
//#define DEBUG_CV
|
||||
#ifdef DEBUG_CV
|
||||
#define DEBUG
|
||||
#define DEBUG if(getenv("CV_DEBUG"))
|
||||
#else
|
||||
#define DEBUG if(0)
|
||||
#endif
|
||||
@ -216,62 +216,60 @@ ConfigValues::Iterator::set(Uint32 key, const char * value){
|
||||
static
|
||||
bool
|
||||
findKey(const Uint32 * values, Uint32 sz, Uint32 key, Uint32 * _pos){
|
||||
Uint32 pos = hash(key, sz);
|
||||
Uint32 count = 0;
|
||||
while((values[pos] & KP_MASK) != key && count < sz){
|
||||
pos = nextHash(key, sz, pos, ++count);
|
||||
Uint32 lo = 0;
|
||||
Uint32 hi = sz;
|
||||
Uint32 pos = (hi + lo) >> 1;
|
||||
|
||||
DEBUG printf("findKey(H'%.8x %d)", key, sz);
|
||||
|
||||
if (sz == 0)
|
||||
{
|
||||
DEBUG ndbout_c(" -> false, 0");
|
||||
* _pos = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if((values[pos] & KP_MASK)== key){
|
||||
*_pos = pos;
|
||||
return true;
|
||||
}
|
||||
Uint32 val = 0;
|
||||
Uint32 oldpos = pos + 1;
|
||||
while (pos != oldpos)
|
||||
{
|
||||
DEBUG printf(" [ %d %d %d ] ", lo, pos, hi);
|
||||
assert(pos < hi);
|
||||
assert(pos >= lo);
|
||||
val = values[2*pos] & KP_MASK;
|
||||
if (key > val)
|
||||
{
|
||||
lo = pos;
|
||||
}
|
||||
else if (key < val)
|
||||
{
|
||||
hi = pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
* _pos = 2*pos;
|
||||
DEBUG ndbout_c(" -> true, %d", pos);
|
||||
return true;
|
||||
}
|
||||
oldpos = pos;
|
||||
pos = (hi + lo) >> 1;
|
||||
}
|
||||
|
||||
DEBUG printf(" pos: %d (key %.8x val: %.8x values[pos]: %x) key>val: %d ",
|
||||
pos, key, val, values[2*pos] & KP_MASK,
|
||||
key > val);
|
||||
|
||||
pos += (key > val) ? 1 : 0;
|
||||
|
||||
* _pos = 2*pos;
|
||||
DEBUG ndbout_c(" -> false, %d", pos);
|
||||
return false;
|
||||
}
|
||||
|
||||
static
|
||||
Uint32
|
||||
hash(Uint32 key, Uint32 size){
|
||||
Uint32 tmp = (key >> 16) ^ (key & 0xFFFF);
|
||||
return (((tmp << 16) | tmp) % size) << 1;
|
||||
}
|
||||
|
||||
static
|
||||
Uint32
|
||||
nextHash(Uint32 key, Uint32 size, Uint32 pos, Uint32 count){
|
||||
Uint32 p = (pos >> 1);
|
||||
if((key % size) != 0)
|
||||
p += key;
|
||||
else
|
||||
p += 1;
|
||||
return (p % size) << 1;
|
||||
}
|
||||
|
||||
static
|
||||
Uint32
|
||||
directory(Uint32 sz){
|
||||
const Uint32 _input = sz;
|
||||
if((sz & 1) == 0)
|
||||
sz ++;
|
||||
|
||||
bool prime = false;
|
||||
while(!prime){
|
||||
prime = true;
|
||||
for(Uint32 n = 3; n*n <= sz; n += 2){
|
||||
if((sz % n) == 0){
|
||||
prime = false;
|
||||
sz += 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
DEBUG printf("directory %d -> %d\n", _input, sz);
|
||||
return sz;
|
||||
}
|
||||
|
||||
ConfigValuesFactory::ConfigValuesFactory(Uint32 keys, Uint32 data){
|
||||
m_sectionCounter = (1 << KP_SECTION_SHIFT);
|
||||
m_freeKeys = directory(keys);
|
||||
m_freeKeys = keys;
|
||||
m_freeData = (data + 7) & ~7;
|
||||
m_currentSection = 0;
|
||||
m_cfg = create(m_freeKeys, m_freeData);
|
||||
@ -330,11 +328,14 @@ ConfigValuesFactory::expand(Uint32 fk, Uint32 fs){
|
||||
return ;
|
||||
}
|
||||
|
||||
DEBUG printf("[ fk fd ] : [ %d %d ]", m_freeKeys, m_freeData);
|
||||
|
||||
m_freeKeys = (m_freeKeys >= fk ? m_cfg->m_size : fk + m_cfg->m_size);
|
||||
m_freeData = (m_freeData >= fs ? m_cfg->m_dataSize : fs + m_cfg->m_dataSize);
|
||||
m_freeKeys = directory(m_freeKeys);
|
||||
m_freeData = (m_freeData + 7) & ~7;
|
||||
|
||||
|
||||
DEBUG ndbout_c(" [ %d %d ]", m_freeKeys, m_freeData);
|
||||
|
||||
ConfigValues * m_tmp = m_cfg;
|
||||
m_cfg = create(m_freeKeys, m_freeData);
|
||||
put(* m_tmp);
|
||||
@ -350,7 +351,6 @@ ConfigValuesFactory::shrink(){
|
||||
|
||||
m_freeKeys = m_cfg->m_size - m_freeKeys;
|
||||
m_freeData = m_cfg->m_dataSize - m_freeData;
|
||||
m_freeKeys = directory(m_freeKeys);
|
||||
m_freeData = (m_freeData + 7) & ~7;
|
||||
|
||||
ConfigValues * m_tmp = m_cfg;
|
||||
@ -429,52 +429,58 @@ ConfigValuesFactory::put(const ConfigValues::Entry & entry){
|
||||
}
|
||||
|
||||
const Uint32 tmp = entry.m_key | m_currentSection;
|
||||
const Uint32 sz = m_cfg->m_size;
|
||||
Uint32 pos = hash(tmp, sz);
|
||||
Uint32 count = 0;
|
||||
Uint32 val = m_cfg->m_values[pos];
|
||||
const Uint32 sz = m_cfg->m_size - m_freeKeys;
|
||||
|
||||
while((val & KP_MASK) != tmp && val != CFV_KEY_FREE && count < sz){
|
||||
pos = nextHash(tmp, sz, pos, ++count);
|
||||
val = m_cfg->m_values[pos];
|
||||
}
|
||||
|
||||
if((val & KP_MASK) == tmp){
|
||||
Uint32 pos;
|
||||
if (findKey(m_cfg->m_values, sz, tmp, &pos))
|
||||
{
|
||||
DEBUG ndbout_c("key %x already found at pos: %d", tmp, pos);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(count >= sz){
|
||||
pos = hash(tmp, sz);
|
||||
count = 0;
|
||||
Uint32 val = m_cfg->m_values[pos];
|
||||
|
||||
printf("key: %d, (key %% size): %d\n", entry.m_key, (entry.m_key % sz));
|
||||
printf("pos: %d", pos);
|
||||
while((val & KP_MASK) != tmp && val != CFV_KEY_FREE && count < sz){
|
||||
pos = nextHash(tmp, sz, pos, ++count);
|
||||
val = m_cfg->m_values[pos];
|
||||
printf(" %d", pos);
|
||||
DEBUG {
|
||||
printf("H'before ");
|
||||
Uint32 prev = 0;
|
||||
for (Uint32 i = 0; i<sz; i++)
|
||||
{
|
||||
Uint32 val = m_cfg->m_values[2*i] & KP_MASK;
|
||||
ndbout_c("%.8x", val);
|
||||
assert(val >= prev);
|
||||
prev = val;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
abort();
|
||||
printf("Full\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pos != 2*sz)
|
||||
{
|
||||
DEBUG ndbout_c("pos: %d sz: %d", pos, sz);
|
||||
memmove(m_cfg->m_values + pos + 2, m_cfg->m_values + pos,
|
||||
4 * (2*sz - pos));
|
||||
}
|
||||
|
||||
assert(pos < (sz << 1));
|
||||
|
||||
Uint32 key = tmp;
|
||||
key |= (entry.m_type << KP_TYPE_SHIFT);
|
||||
m_cfg->m_values[pos] = key;
|
||||
|
||||
DEBUG {
|
||||
printf("H'after ");
|
||||
Uint32 prev = 0;
|
||||
for (Uint32 i = 0; i<=sz; i++)
|
||||
{
|
||||
Uint32 val = m_cfg->m_values[2*i] & KP_MASK;
|
||||
ndbout_c("%.8x", val);
|
||||
assert(val >= prev);
|
||||
prev = val;
|
||||
}
|
||||
}
|
||||
|
||||
switch(entry.m_type){
|
||||
case ConfigValues::IntType:
|
||||
case ConfigValues::SectionType:
|
||||
m_cfg->m_values[pos+1] = entry.m_int;
|
||||
m_freeKeys--;
|
||||
DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value: %d\n",
|
||||
pos, sz, count,
|
||||
pos, sz, 0,
|
||||
(key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK,
|
||||
entry.m_int);
|
||||
return true;
|
||||
@ -486,7 +492,7 @@ ConfigValuesFactory::put(const ConfigValues::Entry & entry){
|
||||
m_freeKeys--;
|
||||
m_freeData -= sizeof(char *);
|
||||
DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value(%d): %s\n",
|
||||
pos, sz, count,
|
||||
pos, sz, 0,
|
||||
(key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK,
|
||||
index,
|
||||
entry.m_string);
|
||||
@ -499,7 +505,7 @@ ConfigValuesFactory::put(const ConfigValues::Entry & entry){
|
||||
m_freeKeys--;
|
||||
m_freeData -= 8;
|
||||
DEBUG printf("Putting at: %d(%d) (loop = %d) key: %d value64(%d): %lld\n",
|
||||
pos, sz, count,
|
||||
pos, sz, 0,
|
||||
(key >> KP_KEYVAL_SHIFT) & KP_KEYVAL_MASK,
|
||||
index,
|
||||
entry.m_int64);
|
||||
@ -662,7 +668,9 @@ ConfigValuesFactory::unpack(const void * _src, Uint32 len){
|
||||
}
|
||||
|
||||
const char * src = (const char *)_src;
|
||||
|
||||
const char * end = src + len - 4;
|
||||
src += sizeof(Magic);
|
||||
|
||||
{
|
||||
Uint32 len32 = (len >> 2);
|
||||
const Uint32 * tmp = (const Uint32*)_src;
|
||||
@ -677,9 +685,37 @@ ConfigValuesFactory::unpack(const void * _src, Uint32 len){
|
||||
}
|
||||
}
|
||||
|
||||
const char * end = src + len - 4;
|
||||
src += sizeof(Magic);
|
||||
|
||||
const char * save = src;
|
||||
|
||||
{
|
||||
Uint32 keys = 0;
|
||||
Uint32 data = 0;
|
||||
while(end - src > 4){
|
||||
Uint32 tmp = ntohl(* (const Uint32 *)src); src += 4;
|
||||
keys++;
|
||||
switch(::getTypeOf(tmp)){
|
||||
case ConfigValues::IntType:
|
||||
case ConfigValues::SectionType:
|
||||
src += 4;
|
||||
break;
|
||||
case ConfigValues::Int64Type:
|
||||
src += 8;
|
||||
data += 8;
|
||||
break;
|
||||
case ConfigValues::StringType:{
|
||||
Uint32 s_len = ntohl(* (const Uint32 *)src);
|
||||
src += 4 + mod4(s_len);
|
||||
data += sizeof(char*);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
expand(keys, data);
|
||||
}
|
||||
|
||||
src = save;
|
||||
ConfigValues::Entry entry;
|
||||
while(end - src > 4){
|
||||
Uint32 tmp = ntohl(* (const Uint32 *)src); src += 4;
|
||||
|
@ -26,6 +26,7 @@ SocketClient::SocketClient(const char *server_name, unsigned short port, SocketA
|
||||
m_port= port;
|
||||
m_server_name= server_name ? strdup(server_name) : 0;
|
||||
m_sockfd= NDB_INVALID_SOCKET;
|
||||
m_connect_timeout_sec= 0;
|
||||
}
|
||||
|
||||
SocketClient::~SocketClient()
|
||||
@ -58,7 +59,7 @@ SocketClient::init()
|
||||
if (m_sockfd == NDB_INVALID_SOCKET) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
DBUG_PRINT("info",("NDB_SOCKET: %d", m_sockfd));
|
||||
|
||||
return true;
|
||||
@ -104,6 +105,13 @@ SocketClient::bind(const char* bindaddress, unsigned short localport)
|
||||
NDB_SOCKET_TYPE
|
||||
SocketClient::connect(const char *toaddress, unsigned short toport)
|
||||
{
|
||||
fd_set rset, wset;
|
||||
struct timeval tval;
|
||||
int r;
|
||||
bool use_timeout;
|
||||
SOCKOPT_OPTLEN_TYPE len;
|
||||
int flags;
|
||||
|
||||
if (m_sockfd == NDB_INVALID_SOCKET)
|
||||
{
|
||||
if (!init()) {
|
||||
@ -127,14 +135,58 @@ SocketClient::connect(const char *toaddress, unsigned short toport)
|
||||
if (Ndb_getInAddr(&m_servaddr.sin_addr, m_server_name))
|
||||
return NDB_INVALID_SOCKET;
|
||||
}
|
||||
|
||||
const int r = ::connect(m_sockfd, (struct sockaddr*) &m_servaddr, sizeof(m_servaddr));
|
||||
if (r == -1) {
|
||||
|
||||
flags= fcntl(m_sockfd, F_GETFL, 0);
|
||||
fcntl(m_sockfd, F_SETFL, flags | O_NONBLOCK);
|
||||
|
||||
r= ::connect(m_sockfd, (struct sockaddr*) &m_servaddr, sizeof(m_servaddr));
|
||||
|
||||
if (r == 0)
|
||||
goto done; // connected immediately.
|
||||
|
||||
if (r < 0 && (errno != EINPROGRESS)) {
|
||||
NDB_CLOSE_SOCKET(m_sockfd);
|
||||
m_sockfd= NDB_INVALID_SOCKET;
|
||||
return NDB_INVALID_SOCKET;
|
||||
}
|
||||
|
||||
FD_ZERO(&rset);
|
||||
FD_SET(m_sockfd, &rset);
|
||||
wset= rset;
|
||||
tval.tv_sec= m_connect_timeout_sec;
|
||||
tval.tv_usec= 0;
|
||||
use_timeout= m_connect_timeout_sec;
|
||||
|
||||
if ((r= select(m_sockfd+1, &rset, &wset, NULL,
|
||||
use_timeout? &tval : NULL)) == 0)
|
||||
{
|
||||
NDB_CLOSE_SOCKET(m_sockfd);
|
||||
m_sockfd= NDB_INVALID_SOCKET;
|
||||
return NDB_INVALID_SOCKET;
|
||||
}
|
||||
|
||||
if (FD_ISSET(m_sockfd, &rset) || FD_ISSET(m_sockfd, &wset))
|
||||
{
|
||||
len= sizeof(r);
|
||||
if (getsockopt(m_sockfd, SOL_SOCKET, SO_ERROR, &r, &len) < 0 || r)
|
||||
{
|
||||
// Solaris got an error... different than others
|
||||
NDB_CLOSE_SOCKET(m_sockfd);
|
||||
m_sockfd= NDB_INVALID_SOCKET;
|
||||
return NDB_INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// select error, probably m_sockfd not set.
|
||||
NDB_CLOSE_SOCKET(m_sockfd);
|
||||
m_sockfd= NDB_INVALID_SOCKET;
|
||||
return NDB_INVALID_SOCKET;
|
||||
}
|
||||
|
||||
done:
|
||||
fcntl(m_sockfd, F_SETFL, flags);
|
||||
|
||||
if (m_auth) {
|
||||
if (!m_auth->client_authenticate(m_sockfd))
|
||||
{
|
||||
|
@ -21,6 +21,9 @@ Crash president when he starts to run in ArbitState 1-9.
|
||||
|
||||
910: Crash new president after node crash
|
||||
|
||||
935 : Crash master on node failure (delayed)
|
||||
and skip sending GSN_COMMIT_FAILREQ to specified node
|
||||
|
||||
ERROR CODES FOR TESTING NODE FAILURE, GLOBAL CHECKPOINT HANDLING:
|
||||
-----------------------------------------------------------------
|
||||
|
||||
|
@ -341,9 +341,9 @@ void Cmvmi::execSTTOR(Signal* signal)
|
||||
if (theStartPhase == 1){
|
||||
jam();
|
||||
|
||||
if(theConfig.lockPagesInMainMemory())
|
||||
if(theConfig.lockPagesInMainMemory() == 1)
|
||||
{
|
||||
int res = NdbMem_MemLockAll();
|
||||
int res = NdbMem_MemLockAll(0);
|
||||
if(res != 0){
|
||||
g_eventLogger.warning("Failed to memlock pages");
|
||||
warningEvent("Failed to memlock pages");
|
||||
@ -788,6 +788,21 @@ Cmvmi::execSTART_ORD(Signal* signal) {
|
||||
|
||||
if(globalData.theStartLevel == NodeState::SL_CMVMI){
|
||||
jam();
|
||||
|
||||
if(theConfig.lockPagesInMainMemory() == 2)
|
||||
{
|
||||
int res = NdbMem_MemLockAll(1);
|
||||
if(res != 0)
|
||||
{
|
||||
g_eventLogger.warning("Failed to memlock pages");
|
||||
warningEvent("Failed to memlock pages");
|
||||
}
|
||||
else
|
||||
{
|
||||
g_eventLogger.info("Locked future allocations");
|
||||
}
|
||||
}
|
||||
|
||||
globalData.theStartLevel = NodeState::SL_STARTING;
|
||||
globalData.theRestartFlag = system_started;
|
||||
/**
|
||||
|
@ -3554,7 +3554,6 @@ void Dbdih::endTakeOver(Uint32 takeOverPtrI)
|
||||
takeOverPtr.i = takeOverPtrI;
|
||||
ptrCheckGuard(takeOverPtr, MAX_NDB_NODES, takeOverRecord);
|
||||
|
||||
releaseTakeOver(takeOverPtrI);
|
||||
if ((takeOverPtr.p->toMasterStatus != TakeOverRecord::IDLE) &&
|
||||
(takeOverPtr.p->toMasterStatus != TakeOverRecord::TO_WAIT_START_TAKE_OVER)) {
|
||||
jam();
|
||||
@ -3568,6 +3567,7 @@ void Dbdih::endTakeOver(Uint32 takeOverPtrI)
|
||||
}//if
|
||||
setAllowNodeStart(takeOverPtr.p->toStartingNode, true);
|
||||
initTakeOver(takeOverPtr);
|
||||
releaseTakeOver(takeOverPtrI);
|
||||
}//Dbdih::endTakeOver()
|
||||
|
||||
void Dbdih::releaseTakeOver(Uint32 takeOverPtrI)
|
||||
@ -4709,6 +4709,7 @@ void Dbdih::handleTakeOverNewMaster(Signal* signal, Uint32 takeOverPtrI)
|
||||
break;
|
||||
}
|
||||
ndbrequire(ok);
|
||||
endTakeOver(takeOverPtr.i);
|
||||
}//if
|
||||
}//Dbdih::handleTakeOverNewMaster()
|
||||
|
||||
|
@ -138,7 +138,6 @@
|
||||
|
||||
#define ZNOT_FOUND 626
|
||||
#define ZALREADYEXIST 630
|
||||
#define ZINCONSISTENTHASHINDEX 892
|
||||
#define ZNOTUNIQUE 893
|
||||
|
||||
#define ZINVALID_KEY 290
|
||||
|
@ -425,6 +425,10 @@ private:
|
||||
|
||||
StopReq c_stopReq;
|
||||
bool check_multi_node_shutdown(Signal* signal);
|
||||
|
||||
#ifdef ERROR_INSERT
|
||||
Uint32 c_error_insert_extra;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -2894,6 +2894,17 @@ void Qmgr::failReportLab(Signal* signal, Uint16 aFailedNode,
|
||||
systemErrorLab(signal, __LINE__);
|
||||
return;
|
||||
}//if
|
||||
|
||||
if (getNodeState().startLevel < NodeState::SL_STARTED)
|
||||
{
|
||||
jam();
|
||||
CRASH_INSERTION(932);
|
||||
char buf[100];
|
||||
BaseString::snprintf(buf, 100, "Node failure during restart");
|
||||
progError(__LINE__, NDBD_EXIT_SR_OTHERNODEFAILED, buf);
|
||||
ndbrequire(false);
|
||||
}
|
||||
|
||||
TnoFailedNodes = cnoFailedNodes;
|
||||
failReport(signal, failedNodePtr.i, (UintR)ZTRUE, aFailCause);
|
||||
if (cpresident == getOwnNodeId()) {
|
||||
@ -2980,6 +2991,16 @@ void Qmgr::execPREP_FAILREQ(Signal* signal)
|
||||
return;
|
||||
}//if
|
||||
|
||||
if (getNodeState().startLevel < NodeState::SL_STARTED)
|
||||
{
|
||||
jam();
|
||||
CRASH_INSERTION(932);
|
||||
char buf[100];
|
||||
BaseString::snprintf(buf, 100, "Node failure during restart");
|
||||
progError(__LINE__, NDBD_EXIT_SR_OTHERNODEFAILED, buf);
|
||||
ndbrequire(false);
|
||||
}
|
||||
|
||||
guard0 = cnoPrepFailedNodes - 1;
|
||||
arrGuard(guard0, MAX_NDB_NODES);
|
||||
for (Tindex = 0; Tindex <= guard0; Tindex++) {
|
||||
@ -3157,6 +3178,18 @@ Qmgr::sendCommitFailReq(Signal* signal)
|
||||
for (nodePtr.i = 1; nodePtr.i < MAX_NDB_NODES; nodePtr.i++) {
|
||||
jam();
|
||||
ptrAss(nodePtr, nodeRec);
|
||||
|
||||
#ifdef ERROR_INSERT
|
||||
if (ERROR_INSERTED(935) && nodePtr.i == c_error_insert_extra)
|
||||
{
|
||||
ndbout_c("skipping node %d", c_error_insert_extra);
|
||||
CLEAR_ERROR_INSERT_VALUE;
|
||||
signal->theData[0] = 9999;
|
||||
sendSignalWithDelay(CMVMI_REF, GSN_NDB_TAMPER, signal, 1000, 1);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (nodePtr.p->phase == ZRUNNING) {
|
||||
jam();
|
||||
nodePtr.p->sendCommitFailReqStatus = Q_ACTIVE;
|
||||
@ -3227,6 +3260,33 @@ void Qmgr::execPREP_FAILREF(Signal* signal)
|
||||
return;
|
||||
}//Qmgr::execPREP_FAILREF()
|
||||
|
||||
static
|
||||
Uint32
|
||||
clear_nodes(Uint32 dstcnt, Uint16 dst[], Uint32 srccnt, const Uint16 src[])
|
||||
{
|
||||
if (srccnt == 0)
|
||||
return dstcnt;
|
||||
|
||||
Uint32 pos = 0;
|
||||
for (Uint32 i = 0; i<dstcnt; i++)
|
||||
{
|
||||
Uint32 node = dst[i];
|
||||
for (Uint32 j = 0; j<srccnt; j++)
|
||||
{
|
||||
if (node == dst[j])
|
||||
{
|
||||
node = RNIL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (node != RNIL)
|
||||
{
|
||||
dst[pos++] = node;
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* THE PRESIDENT IS NOW COMMITTING THE PREVIOUSLY PREPARED NODE FAILURE. */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@ -3314,19 +3374,18 @@ void Qmgr::execCOMMIT_FAILREQ(Signal* signal)
|
||||
NodeFailRep::SignalLength, JBB);
|
||||
}//if
|
||||
}//for
|
||||
if (cpresident != getOwnNodeId()) {
|
||||
jam();
|
||||
cnoFailedNodes = cnoCommitFailedNodes - cnoFailedNodes;
|
||||
if (cnoFailedNodes > 0) {
|
||||
jam();
|
||||
guard0 = cnoFailedNodes - 1;
|
||||
arrGuard(guard0 + cnoCommitFailedNodes, MAX_NDB_NODES);
|
||||
for (Tj = 0; Tj <= guard0; Tj++) {
|
||||
jam();
|
||||
cfailedNodes[Tj] = cfailedNodes[Tj + cnoCommitFailedNodes];
|
||||
}//for
|
||||
}//if
|
||||
}//if
|
||||
|
||||
/**
|
||||
* Remove committed nodes from failed/prepared
|
||||
*/
|
||||
cnoFailedNodes = clear_nodes(cnoFailedNodes,
|
||||
cfailedNodes,
|
||||
cnoCommitFailedNodes,
|
||||
ccommitFailedNodes);
|
||||
cnoPrepFailedNodes = clear_nodes(cnoPrepFailedNodes,
|
||||
cprepFailedNodes,
|
||||
cnoCommitFailedNodes,
|
||||
ccommitFailedNodes);
|
||||
cnoCommitFailedNodes = 0;
|
||||
}//if
|
||||
/**-----------------------------------------------------------------------
|
||||
@ -4705,6 +4764,14 @@ Qmgr::execDUMP_STATE_ORD(Signal* signal)
|
||||
default:
|
||||
;
|
||||
}//switch
|
||||
|
||||
#ifdef ERROR_INSERT
|
||||
if (signal->theData[0] == 935 && signal->getLength() == 2)
|
||||
{
|
||||
SET_ERROR_INSERT_VALUE(935);
|
||||
c_error_insert_extra = signal->theData[1];
|
||||
}
|
||||
#endif
|
||||
}//Qmgr::execDUMP_STATE_ORD()
|
||||
|
||||
void Qmgr::execSET_VAR_REQ(Signal* signal)
|
||||
|
@ -479,7 +479,7 @@ Configuration::setupConfiguration(){
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
bool
|
||||
Uint32
|
||||
Configuration::lockPagesInMainMemory() const {
|
||||
return _lockPagesInMainMemory;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
void setupConfiguration();
|
||||
void closeConfiguration(bool end_session= true);
|
||||
|
||||
bool lockPagesInMainMemory() const;
|
||||
Uint32 lockPagesInMainMemory() const;
|
||||
|
||||
int timeBetweenWatchDogCheck() const ;
|
||||
void timeBetweenWatchDogCheck(int value);
|
||||
|
@ -93,6 +93,7 @@ struct ndb_mgm_handle {
|
||||
char last_error_desc[NDB_MGM_MAX_ERR_DESC_SIZE];
|
||||
int read_timeout;
|
||||
int write_timeout;
|
||||
unsigned int connect_timeout;
|
||||
|
||||
NDB_SOCKET_TYPE socket;
|
||||
|
||||
@ -159,6 +160,7 @@ ndb_mgm_create_handle()
|
||||
h->socket = NDB_INVALID_SOCKET;
|
||||
h->read_timeout = 50000;
|
||||
h->write_timeout = 100;
|
||||
h->connect_timeout = 0;
|
||||
h->cfg_i = -1;
|
||||
h->errstream = stdout;
|
||||
h->m_name = 0;
|
||||
@ -426,6 +428,16 @@ int ndb_mgm_is_connected(NdbMgmHandle handle)
|
||||
return handle->connected;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
int ndb_mgm_set_connect_timeout(NdbMgmHandle handle, unsigned int seconds)
|
||||
{
|
||||
if(!handle)
|
||||
return -1;
|
||||
|
||||
handle->connect_timeout= seconds;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to a management server
|
||||
*/
|
||||
@ -456,6 +468,7 @@ ndb_mgm_connect(NdbMgmHandle handle, int no_retries,
|
||||
Uint32 i;
|
||||
int binderror = 0;
|
||||
SocketClient s(0, 0);
|
||||
s.set_connect_timeout(handle->connect_timeout);
|
||||
if (!s.init())
|
||||
{
|
||||
fprintf(handle->errstream,
|
||||
|
@ -563,10 +563,10 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
|
||||
"If set to yes, then NDB Cluster data will not be swapped out to disk",
|
||||
ConfigInfo::CI_USED,
|
||||
true,
|
||||
ConfigInfo::CI_BOOL,
|
||||
"false",
|
||||
"false",
|
||||
"true" },
|
||||
ConfigInfo::CI_INT,
|
||||
"0",
|
||||
"1",
|
||||
"2" },
|
||||
|
||||
{
|
||||
CFG_DB_WATCHDOG_INTERVAL,
|
||||
|
@ -137,8 +137,11 @@ MgmtSrvr::logLevelThreadRun()
|
||||
m_started_nodes.erase(0, false);
|
||||
m_started_nodes.unlock();
|
||||
|
||||
setEventReportingLevelImpl(node, req);
|
||||
|
||||
if (setEventReportingLevelImpl(node, req))
|
||||
{
|
||||
ndbout_c("setEventReportingLevelImpl(%d): failed", node);
|
||||
}
|
||||
|
||||
SetLogLevelOrd ord;
|
||||
ord = m_nodeLogLevel[node];
|
||||
setNodeLogLevelImpl(node, ord);
|
||||
@ -155,10 +158,16 @@ MgmtSrvr::logLevelThreadRun()
|
||||
m_log_level_requests.erase(0, false);
|
||||
m_log_level_requests.unlock();
|
||||
|
||||
if(req.blockRef == 0){
|
||||
if(req.blockRef == 0)
|
||||
{
|
||||
req.blockRef = _ownReference;
|
||||
setEventReportingLevelImpl(0, req);
|
||||
} else {
|
||||
if (setEventReportingLevelImpl(0, req))
|
||||
{
|
||||
ndbout_c("setEventReportingLevelImpl: failed 2!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLogLevelOrd ord;
|
||||
ord = req;
|
||||
setNodeLogLevelImpl(req.blockRef, ord);
|
||||
@ -1376,9 +1385,6 @@ int MgmtSrvr::restartDB(bool nostart, bool initialStart,
|
||||
NodeId nodeId = 0;
|
||||
NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime;
|
||||
|
||||
ndbout_c(" %d", nodes.get(1));
|
||||
ndbout_c(" %d", nodes.get(2));
|
||||
|
||||
while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) {
|
||||
if (!nodes.get(nodeId))
|
||||
continue;
|
||||
@ -1584,6 +1590,11 @@ MgmtSrvr::setEventReportingLevelImpl(int nodeId,
|
||||
}
|
||||
}
|
||||
|
||||
if (nodes.isclear())
|
||||
{
|
||||
return SEND_OR_RECEIVE_FAILED;
|
||||
}
|
||||
|
||||
int error = 0;
|
||||
while (!nodes.isclear())
|
||||
{
|
||||
@ -1600,16 +1611,24 @@ MgmtSrvr::setEventReportingLevelImpl(int nodeId,
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
// Since sending okToSend(true),
|
||||
// there is no guarantee that NF_COMPLETEREP will come
|
||||
// i.e listen also to NODE_FAILREP
|
||||
case GSN_NODE_FAILREP: {
|
||||
const NodeFailRep * const rep =
|
||||
CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
|
||||
NdbNodeBitmask mask;
|
||||
mask.assign(NdbNodeBitmask::Size, rep->theNodes);
|
||||
nodes.bitANDC(mask);
|
||||
break;
|
||||
}
|
||||
|
||||
case GSN_NF_COMPLETEREP:{
|
||||
const NFCompleteRep * const rep =
|
||||
CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
|
||||
nodes.clear(rep->failedNodeId);
|
||||
break;
|
||||
}
|
||||
case GSN_NODE_FAILREP:{
|
||||
// ignore, NF_COMPLETEREP will arrive later
|
||||
break;
|
||||
}
|
||||
default:
|
||||
report_unknown_signal(signal);
|
||||
return SEND_OR_RECEIVE_FAILED;
|
||||
@ -1909,7 +1928,10 @@ MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete)
|
||||
|
||||
theData[1] = nodeId;
|
||||
if (alive) {
|
||||
m_started_nodes.push_back(nodeId);
|
||||
if (nodeTypes[nodeId] == NODE_TYPE_DB)
|
||||
{
|
||||
m_started_nodes.push_back(nodeId);
|
||||
}
|
||||
rep->setEventType(NDB_LE_Connected);
|
||||
} else {
|
||||
rep->setEventType(NDB_LE_Disconnected);
|
||||
|
@ -507,6 +507,7 @@ ClusterMgr::reportConnected(NodeId nodeId){
|
||||
theNode.m_info.m_version = 0;
|
||||
theNode.compatible = true;
|
||||
theNode.nfCompleteRep = true;
|
||||
theNode.m_state.startLevel = NodeState::SL_NOTHING;
|
||||
|
||||
theFacade.ReportNodeAlive(nodeId);
|
||||
}
|
||||
@ -518,14 +519,13 @@ ClusterMgr::reportDisconnected(NodeId nodeId){
|
||||
|
||||
noOfConnectedNodes--;
|
||||
theNodes[nodeId].connected = false;
|
||||
|
||||
theNodes[nodeId].m_state.m_connected_nodes.clear();
|
||||
|
||||
reportNodeFailed(nodeId);
|
||||
reportNodeFailed(nodeId, true);
|
||||
}
|
||||
|
||||
void
|
||||
ClusterMgr::reportNodeFailed(NodeId nodeId){
|
||||
ClusterMgr::reportNodeFailed(NodeId nodeId, bool disconnect){
|
||||
|
||||
Node & theNode = theNodes[nodeId];
|
||||
|
||||
@ -536,10 +536,11 @@ ClusterMgr::reportNodeFailed(NodeId nodeId){
|
||||
{
|
||||
theFacade.doDisconnect(nodeId);
|
||||
}
|
||||
|
||||
const bool report = (theNode.m_state.startLevel != NodeState::SL_NOTHING);
|
||||
theNode.m_state.startLevel = NodeState::SL_NOTHING;
|
||||
|
||||
if(report)
|
||||
if(disconnect || report)
|
||||
{
|
||||
theFacade.ReportNodeDead(nodeId);
|
||||
}
|
||||
|
@ -97,8 +97,8 @@ private:
|
||||
NdbMutex* clusterMgrThreadMutex;
|
||||
|
||||
void showState(NodeId nodeId);
|
||||
void reportNodeFailed(NodeId nodeId);
|
||||
|
||||
void reportNodeFailed(NodeId nodeId, bool disconnect = false);
|
||||
|
||||
/**
|
||||
* Signals received
|
||||
*/
|
||||
|
@ -19,6 +19,14 @@
|
||||
#include <signaldata/NFCompleteRep.hpp>
|
||||
#include <signaldata/NodeFailRep.hpp>
|
||||
|
||||
static
|
||||
void
|
||||
require(bool x)
|
||||
{
|
||||
if (!x)
|
||||
abort();
|
||||
}
|
||||
|
||||
SimpleSignal::SimpleSignal(bool dealloc){
|
||||
memset(this, 0, sizeof(* this));
|
||||
deallocSections = dealloc;
|
||||
@ -145,6 +153,7 @@ SignalSender::waitFor(Uint32 timeOutMillis, T & t)
|
||||
{
|
||||
SimpleSignal * s = t.check(m_jobBuffer);
|
||||
if(s != 0){
|
||||
m_usedBuffer.push_back(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -208,7 +208,6 @@ ErrorBundle ErrorCodes[] = {
|
||||
/**
|
||||
* Internal errors
|
||||
*/
|
||||
{ 892, IE, "Inconsistent hash index. The index needs to be dropped and recreated" },
|
||||
{ 896, IE, "Tuple corrupted - wrong checksum or column data in invalid format" },
|
||||
{ 901, IE, "Inconsistent ordered index. The index needs to be dropped and recreated" },
|
||||
{ 202, IE, "202" },
|
||||
|
@ -954,6 +954,96 @@ int runBug24717(NDBT_Context* ctx, NDBT_Step* step){
|
||||
return NDBT_OK;
|
||||
}
|
||||
|
||||
int runBug25364(NDBT_Context* ctx, NDBT_Step* step){
|
||||
int result = NDBT_OK;
|
||||
NdbRestarter restarter;
|
||||
Ndb* pNdb = GETNDB(step);
|
||||
int loops = ctx->getNumLoops();
|
||||
|
||||
if (restarter.getNumDbNodes() < 4)
|
||||
return NDBT_OK;
|
||||
|
||||
int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
|
||||
|
||||
for (; loops; loops --)
|
||||
{
|
||||
int master = restarter.getMasterNodeId();
|
||||
int victim = restarter.getRandomNodeOtherNodeGroup(master, rand());
|
||||
int second = restarter.getRandomNodeSameNodeGroup(victim, rand());
|
||||
|
||||
int dump[] = { 935, victim } ;
|
||||
if (restarter.dumpStateOneNode(master, dump, 2))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.dumpStateOneNode(master, val2, 2))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.restartOneDbNode(second, false, true, true))
|
||||
return NDBT_FAILED;
|
||||
|
||||
int nodes[2] = { master, second };
|
||||
if (restarter.waitNodesNoStart(nodes, 2))
|
||||
return NDBT_FAILED;
|
||||
|
||||
restarter.startNodes(nodes, 2);
|
||||
|
||||
if (restarter.waitNodesStarted(nodes, 2))
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
return NDBT_OK;
|
||||
}
|
||||
|
||||
int runBug25554(NDBT_Context* ctx, NDBT_Step* step){
|
||||
|
||||
int result = NDBT_OK;
|
||||
int loops = ctx->getNumLoops();
|
||||
int records = ctx->getNumRecords();
|
||||
NdbRestarter restarter;
|
||||
|
||||
if (restarter.getNumDbNodes() < 4)
|
||||
return NDBT_OK;
|
||||
|
||||
for (int i = 0; i<loops; i++)
|
||||
{
|
||||
int master = restarter.getMasterNodeId();
|
||||
int node1 = restarter.getRandomNodeOtherNodeGroup(master, rand());
|
||||
restarter.restartOneDbNode(node1, false, true, true);
|
||||
|
||||
int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
|
||||
|
||||
if (restarter.dumpStateOneNode(master, val2, 2))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.insertErrorInNode(master, 7141))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.waitNodesNoStart(&node1, 1))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.dumpStateOneNode(node1, val2, 2))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.insertErrorInNode(node1, 932))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.startNodes(&node1, 1))
|
||||
return NDBT_FAILED;
|
||||
|
||||
int nodes[] = { master, node1 };
|
||||
if (restarter.waitNodesNoStart(nodes, 2))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.startNodes(nodes, 2))
|
||||
return NDBT_FAILED;
|
||||
|
||||
if (restarter.waitClusterStarted())
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
return NDBT_OK;
|
||||
}
|
||||
|
||||
|
||||
NDBT_TESTSUITE(testNodeRestart);
|
||||
TESTCASE("NoLoad",
|
||||
@ -1270,6 +1360,12 @@ TESTCASE("Bug20185",
|
||||
TESTCASE("Bug24717", ""){
|
||||
INITIALIZER(runBug24717);
|
||||
}
|
||||
TESTCASE("Bug25364", ""){
|
||||
INITIALIZER(runBug25364);
|
||||
}
|
||||
TESTCASE("Bug25554", ""){
|
||||
INITIALIZER(runBug25554);
|
||||
}
|
||||
NDBT_TESTSUITE_END(testNodeRestart);
|
||||
|
||||
int main(int argc, const char** argv){
|
||||
|
@ -469,6 +469,14 @@ max-time: 1000
|
||||
cmd: testNodeRestart
|
||||
args: -n Bug24717 T1
|
||||
|
||||
max-time: 1000
|
||||
cmd: testNodeRestart
|
||||
args: -n Bug25364 T1
|
||||
|
||||
max-time: 1000
|
||||
cmd: testNodeRestart
|
||||
args: -n Bug25554 T1
|
||||
|
||||
# OLD FLEX
|
||||
max-time: 500
|
||||
cmd: flexBench
|
||||
|
@ -465,6 +465,9 @@ MySQLaccess::Report::Print_Header();
|
||||
elsif (-f "@sysconfdir@/$script_conf") {
|
||||
require "@sysconfdir@/$script_conf";
|
||||
}
|
||||
elsif (-f "/etc/$script_conf") {
|
||||
require "/etc/$script_conf";
|
||||
}
|
||||
|
||||
# ****************************
|
||||
# Read in all parameters
|
||||
@ -930,6 +933,7 @@ sub MergeConfigFile {
|
||||
sub MergeConfigFiles {
|
||||
my ($name,$pass,$uid,$gid,$quota,$comment,$gcos,$dir,$shell) = getpwuid $<;
|
||||
MergeConfigFile("@sysconfdir@/my.cnf");
|
||||
MergeConfigFile("/etc/my.cnf");
|
||||
MergeConfigFile("$dir/.my.cnf");
|
||||
}
|
||||
|
||||
|
@ -467,6 +467,9 @@ sub find_groups
|
||||
if (-f "@sysconfdir@/my.cnf" && -r "@sysconfdir@/my.cnf")
|
||||
{
|
||||
open(MY_CNF, "<@sysconfdir@/my.cnf") && (@tmp=<MY_CNF>) && close(MY_CNF);
|
||||
} elsif (-f "/etc/my.cnf" && -r "/etc/my.cnf")
|
||||
{
|
||||
open(MY_CNF, "</etc/my.cnf") && (@tmp=<MY_CNF>) && close(MY_CNF);
|
||||
}
|
||||
for ($i = 0; ($line = shift @tmp); $i++)
|
||||
{
|
||||
|
@ -1106,6 +1106,16 @@ int ha_ndbcluster::build_index_list(Ndb *ndb, TABLE *tab, enum ILBP phase)
|
||||
error= create_unique_index(unique_index_name, key_info);
|
||||
break;
|
||||
case ORDERED_INDEX:
|
||||
if (key_info->algorithm == HA_KEY_ALG_HASH)
|
||||
{
|
||||
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
|
||||
ER_UNSUPPORTED_EXTENSION,
|
||||
ER(ER_UNSUPPORTED_EXTENSION),
|
||||
"Ndb does not support non-unique "
|
||||
"hash based indexes");
|
||||
error= HA_ERR_UNSUPPORTED;
|
||||
break;
|
||||
}
|
||||
error= create_ordered_index(index_name, key_info);
|
||||
break;
|
||||
default:
|
||||
@ -2955,13 +2965,10 @@ KEY* key_info;
|
||||
DBUG_RETURN(error == HA_ERR_KEY_NOT_FOUND ? HA_ERR_END_OF_FILE : error);
|
||||
}
|
||||
else if (type == UNIQUE_INDEX)
|
||||
{
|
||||
error= unique_index_scan(key_info,
|
||||
start_key->key,
|
||||
start_key->length,
|
||||
buf);
|
||||
DBUG_RETURN(error == HA_ERR_KEY_NOT_FOUND ? HA_ERR_END_OF_FILE : error);
|
||||
}
|
||||
DBUG_RETURN(unique_index_scan(key_info,
|
||||
start_key->key,
|
||||
start_key->length,
|
||||
buf));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -3137,20 +3144,26 @@ void ha_ndbcluster::position(const byte *record)
|
||||
size_t len = key_part->length;
|
||||
const byte * ptr = record + key_part->offset;
|
||||
Field *field = key_part->field;
|
||||
if ((field->type() == MYSQL_TYPE_VARCHAR) &&
|
||||
((Field_varstring*)field)->length_bytes == 1)
|
||||
if (field->type() == MYSQL_TYPE_VARCHAR)
|
||||
{
|
||||
/**
|
||||
* Keys always use 2 bytes length
|
||||
*/
|
||||
buff[0] = ptr[0];
|
||||
buff[1] = 0;
|
||||
memcpy(buff+2, ptr + 1, len);
|
||||
len += 2;
|
||||
if (((Field_varstring*)field)->length_bytes == 1)
|
||||
{
|
||||
/**
|
||||
* Keys always use 2 bytes length
|
||||
*/
|
||||
buff[0] = ptr[0];
|
||||
buff[1] = 0;
|
||||
memcpy(buff+2, ptr + 1, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(buff, ptr, len + 2);
|
||||
}
|
||||
len += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(buff, ptr, len);
|
||||
memcpy(buff, ptr, len);
|
||||
}
|
||||
buff += len;
|
||||
}
|
||||
@ -4172,19 +4185,29 @@ static int create_ndb_column(NDBCOL &col,
|
||||
col.setType(NDBCOL::Text);
|
||||
col.setCharset(cs);
|
||||
}
|
||||
// Use "<=" even if "<" is the exact condition
|
||||
if (field->max_length() <= (1 << 8))
|
||||
goto mysql_type_tiny_blob;
|
||||
else if (field->max_length() <= (1 << 16))
|
||||
{
|
||||
col.setInlineSize(256);
|
||||
col.setPartSize(2000);
|
||||
col.setStripeSize(16);
|
||||
Field_blob *field_blob= (Field_blob *)field;
|
||||
/*
|
||||
* max_data_length is 2^8-1, 2^16-1, 2^24-1 for tiny, blob, medium.
|
||||
* Tinyblob gets no blob parts. The other cases are just a crude
|
||||
* way to control part size and striping.
|
||||
*
|
||||
* In mysql blob(256) is promoted to blob(65535) so it does not
|
||||
* in fact fit "inline" in NDB.
|
||||
*/
|
||||
if (field_blob->max_data_length() < (1 << 8))
|
||||
goto mysql_type_tiny_blob;
|
||||
else if (field_blob->max_data_length() < (1 << 16))
|
||||
{
|
||||
col.setInlineSize(256);
|
||||
col.setPartSize(2000);
|
||||
col.setStripeSize(16);
|
||||
}
|
||||
else if (field_blob->max_data_length() < (1 << 24))
|
||||
goto mysql_type_medium_blob;
|
||||
else
|
||||
goto mysql_type_long_blob;
|
||||
}
|
||||
else if (field->max_length() <= (1 << 24))
|
||||
goto mysql_type_medium_blob;
|
||||
else
|
||||
goto mysql_type_long_blob;
|
||||
break;
|
||||
mysql_type_medium_blob:
|
||||
case MYSQL_TYPE_MEDIUM_BLOB:
|
||||
@ -6111,7 +6134,7 @@ ndb_get_table_statistics(ha_ndbcluster* file, bool report_error, Ndb* ndb,
|
||||
retry:
|
||||
if(report_error)
|
||||
{
|
||||
if (file)
|
||||
if (file && pTrans)
|
||||
{
|
||||
reterr= file->ndb_err(pTrans);
|
||||
}
|
||||
|
23
sql/item.cc
23
sql/item.cc
@ -3469,6 +3469,16 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
|
||||
{
|
||||
if (*from_field)
|
||||
{
|
||||
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
|
||||
select->cur_pos_in_select_list != UNDEF_POS)
|
||||
{
|
||||
/*
|
||||
As this is an outer field it should be added to the list of
|
||||
non aggregated fields of the outer select.
|
||||
*/
|
||||
marker= select->cur_pos_in_select_list;
|
||||
select->non_agg_fields.push_back(this);
|
||||
}
|
||||
if (*from_field != view_ref_found)
|
||||
{
|
||||
prev_subselect_item->used_tables_cache|= (*from_field)->table->map;
|
||||
@ -3671,10 +3681,11 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
|
||||
bool Item_field::fix_fields(THD *thd, Item **reference)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 0);
|
||||
Field *from_field= (Field *)not_found_field;
|
||||
bool outer_fixed= false;
|
||||
|
||||
if (!field) // If field is not checked
|
||||
{
|
||||
Field *from_field= (Field *)not_found_field;
|
||||
bool outer_fixed= false;
|
||||
/*
|
||||
In case of view, find_field_in_tables() write pointer to view field
|
||||
expression to 'reference', i.e. it substitute that expression instead
|
||||
@ -3766,6 +3777,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
|
||||
goto error;
|
||||
else if (!ret)
|
||||
return FALSE;
|
||||
outer_fixed= 1;
|
||||
}
|
||||
|
||||
set_field(from_field);
|
||||
@ -3809,6 +3821,13 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
|
||||
}
|
||||
#endif
|
||||
fixed= 1;
|
||||
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
|
||||
!outer_fixed && !thd->lex->in_sum_func &&
|
||||
thd->lex->current_select->cur_pos_in_select_list != UNDEF_POS)
|
||||
{
|
||||
thd->lex->current_select->non_agg_fields.push_back(this);
|
||||
marker= thd->lex->current_select->cur_pos_in_select_list;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
error:
|
||||
|
15
sql/item.h
15
sql/item.h
@ -336,23 +336,18 @@ public:
|
||||
{
|
||||
save_table_list= context->table_list;
|
||||
save_first_name_resolution_table= context->first_name_resolution_table;
|
||||
save_next_name_resolution_table= (context->first_name_resolution_table) ?
|
||||
context->first_name_resolution_table->
|
||||
next_name_resolution_table :
|
||||
NULL;
|
||||
save_resolve_in_select_list= context->resolve_in_select_list;
|
||||
save_next_local= table_list->next_local;
|
||||
save_next_name_resolution_table= table_list->next_name_resolution_table;
|
||||
}
|
||||
|
||||
/* Restore a name resolution context from saved state. */
|
||||
void restore_state(Name_resolution_context *context, TABLE_LIST *table_list)
|
||||
{
|
||||
table_list->next_local= save_next_local;
|
||||
table_list->next_name_resolution_table= save_next_name_resolution_table;
|
||||
context->table_list= save_table_list;
|
||||
context->first_name_resolution_table= save_first_name_resolution_table;
|
||||
if (context->first_name_resolution_table)
|
||||
context->first_name_resolution_table->
|
||||
next_name_resolution_table= save_next_name_resolution_table;
|
||||
context->resolve_in_select_list= save_resolve_in_select_list;
|
||||
}
|
||||
};
|
||||
@ -452,7 +447,8 @@ public:
|
||||
Item *next;
|
||||
uint32 max_length;
|
||||
uint name_length; /* Length of name */
|
||||
uint8 marker, decimals;
|
||||
int8 marker;
|
||||
uint8 decimals;
|
||||
my_bool maybe_null; /* If item may be null */
|
||||
my_bool null_value; /* if item is null */
|
||||
my_bool unsigned_flag;
|
||||
@ -2268,6 +2264,9 @@ public:
|
||||
bool fix_fields(THD *, Item **);
|
||||
void print(String *str);
|
||||
table_map used_tables() const { return (table_map)0L; }
|
||||
Field *get_tmp_table_field() { return 0; }
|
||||
Item *copy_or_same(THD *thd) { return this; }
|
||||
Item *get_tmp_table_item(THD *thd) { return copy_or_same(thd); }
|
||||
void cleanup();
|
||||
|
||||
private:
|
||||
|
@ -152,6 +152,22 @@ longlong Item_func_not::val_int()
|
||||
return ((!null_value && value == 0) ? 1 : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
We put any NOT expression into parenthesis to avoid
|
||||
possible problems with internal view representations where
|
||||
any '!' is converted to NOT. It may cause a problem if
|
||||
'!' is used in an expression together with other operators
|
||||
whose precedence is lower than the precedence of '!' yet
|
||||
higher than the precedence of NOT.
|
||||
*/
|
||||
|
||||
void Item_func_not::print(String *str)
|
||||
{
|
||||
str->append('(');
|
||||
Item_func::print(str);
|
||||
str->append(')');
|
||||
}
|
||||
|
||||
/*
|
||||
special NOT for ALL subquery
|
||||
*/
|
||||
@ -868,11 +884,35 @@ longlong Item_in_optimizer::val_int()
|
||||
We disable the predicates we've pushed down into subselect, run the
|
||||
subselect and see if it has produced any rows.
|
||||
*/
|
||||
((Item_in_subselect*)args[1])->enable_pushed_conds= FALSE;
|
||||
longlong tmp= args[1]->val_bool_result();
|
||||
result_for_null_param= null_value=
|
||||
!((Item_in_subselect*)args[1])->engine->no_rows();
|
||||
((Item_in_subselect*)args[1])->enable_pushed_conds= TRUE;
|
||||
Item_in_subselect *item_subs=(Item_in_subselect*)args[1];
|
||||
if (cache->cols() == 1)
|
||||
{
|
||||
item_subs->set_cond_guard_var(0, FALSE);
|
||||
longlong tmp= args[1]->val_bool_result();
|
||||
result_for_null_param= null_value= !item_subs->engine->no_rows();
|
||||
item_subs->set_cond_guard_var(0, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint i;
|
||||
uint ncols= cache->cols();
|
||||
/*
|
||||
Turn off the predicates that are based on column compares for
|
||||
which the left part is currently NULL
|
||||
*/
|
||||
for (i= 0; i < ncols; i++)
|
||||
{
|
||||
if (cache->el(i)->null_value)
|
||||
item_subs->set_cond_guard_var(i, FALSE);
|
||||
}
|
||||
|
||||
longlong tmp= args[1]->val_bool_result();
|
||||
result_for_null_param= null_value= !item_subs->engine->no_rows();
|
||||
|
||||
/* Turn all predicates back on */
|
||||
for (i= 0; i < ncols; i++)
|
||||
item_subs->set_cond_guard_var(i, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -272,6 +272,7 @@ public:
|
||||
enum Functype functype() const { return NOT_FUNC; }
|
||||
const char *func_name() const { return "not"; }
|
||||
Item *neg_transformer(THD *thd);
|
||||
void print(String *str);
|
||||
};
|
||||
|
||||
class Item_maxmin_subselect;
|
||||
@ -314,6 +315,7 @@ public:
|
||||
enum Functype functype() const { return TRIG_COND_FUNC; };
|
||||
const char *func_name() const { return "trigcond"; };
|
||||
bool const_item() const { return FALSE; }
|
||||
bool *get_trig_var() { return trig_var; }
|
||||
};
|
||||
|
||||
class Item_func_not_all :public Item_func_not
|
||||
@ -968,6 +970,10 @@ class Item_func_in :public Item_func_opt_neg
|
||||
{
|
||||
public:
|
||||
Item_result cmp_type;
|
||||
/*
|
||||
an array of values when the right hand arguments of IN
|
||||
are all SQL constant and there are no nulls
|
||||
*/
|
||||
in_vector *array;
|
||||
cmp_item *in_item;
|
||||
bool have_null;
|
||||
@ -993,7 +999,7 @@ public:
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
optimize_type select_optimize() const
|
||||
{ return array ? OPTIMIZE_KEY : OPTIMIZE_NONE; }
|
||||
{ return OPTIMIZE_KEY; }
|
||||
void print(String *str);
|
||||
enum Functype functype() const { return IN_FUNC; }
|
||||
const char *func_name() const { return " IN "; }
|
||||
|
@ -2729,25 +2729,28 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
|
||||
|
||||
if (arguments[i]->const_item())
|
||||
{
|
||||
if (arguments[i]->null_value)
|
||||
continue;
|
||||
|
||||
switch (arguments[i]->result_type())
|
||||
{
|
||||
case STRING_RESULT:
|
||||
case DECIMAL_RESULT:
|
||||
{
|
||||
String *res= arguments[i]->val_str(&buffers[i]);
|
||||
if (arguments[i]->null_value)
|
||||
continue;
|
||||
f_args.args[i]= (char*) res->ptr();
|
||||
break;
|
||||
}
|
||||
case INT_RESULT:
|
||||
*((longlong*) to)= arguments[i]->val_int();
|
||||
if (arguments[i]->null_value)
|
||||
continue;
|
||||
f_args.args[i]= to;
|
||||
to+= ALIGN_SIZE(sizeof(longlong));
|
||||
break;
|
||||
case REAL_RESULT:
|
||||
*((double*) to)= arguments[i]->val_real();
|
||||
if (arguments[i]->null_value)
|
||||
continue;
|
||||
f_args.args[i]= to;
|
||||
to+= ALIGN_SIZE(sizeof(double));
|
||||
break;
|
||||
|
@ -1694,6 +1694,19 @@ String *Item_func_encode::val_str(String *str)
|
||||
return res;
|
||||
}
|
||||
|
||||
void Item_func_encode::print(String *str)
|
||||
{
|
||||
str->append(func_name());
|
||||
str->append('(');
|
||||
args[0]->print(str);
|
||||
str->append(',');
|
||||
str->append('\'');
|
||||
str->append(seed);
|
||||
str->append('\'');
|
||||
str->append(')');
|
||||
}
|
||||
|
||||
|
||||
String *Item_func_decode::val_str(String *str)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
|
@ -358,19 +358,24 @@ class Item_func_encode :public Item_str_func
|
||||
{
|
||||
protected:
|
||||
SQL_CRYPT sql_crypt;
|
||||
String seed;
|
||||
public:
|
||||
Item_func_encode(Item *a, char *seed):
|
||||
Item_str_func(a),sql_crypt(seed) {}
|
||||
Item_func_encode(Item *a, char *seed_arg):
|
||||
Item_str_func(a), sql_crypt(seed_arg)
|
||||
{
|
||||
seed.copy(seed_arg, strlen(seed_arg), default_charset_info);
|
||||
}
|
||||
String *val_str(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "encode"; }
|
||||
void print(String *str);
|
||||
};
|
||||
|
||||
|
||||
class Item_func_decode :public Item_func_encode
|
||||
{
|
||||
public:
|
||||
Item_func_decode(Item *a, char *seed): Item_func_encode(a,seed) {}
|
||||
Item_func_decode(Item *a, char *seed_arg): Item_func_encode(a, seed_arg) {}
|
||||
String *val_str(String *);
|
||||
const char *func_name() const { return "decode"; }
|
||||
};
|
||||
|
@ -191,16 +191,16 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
|
||||
return res;
|
||||
}
|
||||
|
||||
bool Item_subselect::exec(bool full_scan)
|
||||
bool Item_subselect::exec()
|
||||
{
|
||||
int res;
|
||||
|
||||
res= engine->exec(full_scan);
|
||||
res= engine->exec();
|
||||
|
||||
if (engine_changed)
|
||||
{
|
||||
engine_changed= 0;
|
||||
return exec(full_scan);
|
||||
return exec();
|
||||
}
|
||||
return (res);
|
||||
}
|
||||
@ -448,13 +448,13 @@ bool Item_singlerow_subselect::null_inside()
|
||||
|
||||
void Item_singlerow_subselect::bring_value()
|
||||
{
|
||||
exec(FALSE);
|
||||
exec();
|
||||
}
|
||||
|
||||
double Item_singlerow_subselect::val_real()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (!exec(FALSE) && !value->null_value)
|
||||
if (!exec() && !value->null_value)
|
||||
{
|
||||
null_value= 0;
|
||||
return value->val_real();
|
||||
@ -469,7 +469,7 @@ double Item_singlerow_subselect::val_real()
|
||||
longlong Item_singlerow_subselect::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (!exec(FALSE) && !value->null_value)
|
||||
if (!exec() && !value->null_value)
|
||||
{
|
||||
null_value= 0;
|
||||
return value->val_int();
|
||||
@ -483,7 +483,7 @@ longlong Item_singlerow_subselect::val_int()
|
||||
|
||||
String *Item_singlerow_subselect::val_str(String *str)
|
||||
{
|
||||
if (!exec(FALSE) && !value->null_value)
|
||||
if (!exec() && !value->null_value)
|
||||
{
|
||||
null_value= 0;
|
||||
return value->val_str(str);
|
||||
@ -498,7 +498,7 @@ String *Item_singlerow_subselect::val_str(String *str)
|
||||
|
||||
my_decimal *Item_singlerow_subselect::val_decimal(my_decimal *decimal_value)
|
||||
{
|
||||
if (!exec(FALSE) && !value->null_value)
|
||||
if (!exec() && !value->null_value)
|
||||
{
|
||||
null_value= 0;
|
||||
return value->val_decimal(decimal_value);
|
||||
@ -513,7 +513,7 @@ my_decimal *Item_singlerow_subselect::val_decimal(my_decimal *decimal_value)
|
||||
|
||||
bool Item_singlerow_subselect::val_bool()
|
||||
{
|
||||
if (!exec(FALSE) && !value->null_value)
|
||||
if (!exec() && !value->null_value)
|
||||
{
|
||||
null_value= 0;
|
||||
return value->val_bool();
|
||||
@ -565,7 +565,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(), optimizer(0), transformed(0),
|
||||
enable_pushed_conds(TRUE), upper_item(0)
|
||||
pushed_cond_guards(NULL), upper_item(0)
|
||||
{
|
||||
DBUG_ENTER("Item_in_subselect::Item_in_subselect");
|
||||
left_expr= left_exp;
|
||||
@ -610,7 +610,7 @@ void Item_exists_subselect::fix_length_and_dec()
|
||||
double Item_exists_subselect::val_real()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (exec(FALSE))
|
||||
if (exec())
|
||||
{
|
||||
reset();
|
||||
return 0;
|
||||
@ -621,7 +621,7 @@ double Item_exists_subselect::val_real()
|
||||
longlong Item_exists_subselect::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (exec(FALSE))
|
||||
if (exec())
|
||||
{
|
||||
reset();
|
||||
return 0;
|
||||
@ -632,7 +632,7 @@ longlong Item_exists_subselect::val_int()
|
||||
String *Item_exists_subselect::val_str(String *str)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (exec(FALSE))
|
||||
if (exec())
|
||||
{
|
||||
reset();
|
||||
return 0;
|
||||
@ -645,7 +645,7 @@ String *Item_exists_subselect::val_str(String *str)
|
||||
my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (exec(FALSE))
|
||||
if (exec())
|
||||
{
|
||||
reset();
|
||||
return 0;
|
||||
@ -658,7 +658,7 @@ my_decimal *Item_exists_subselect::val_decimal(my_decimal *decimal_value)
|
||||
bool Item_exists_subselect::val_bool()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (exec(FALSE))
|
||||
if (exec())
|
||||
{
|
||||
reset();
|
||||
return 0;
|
||||
@ -676,7 +676,7 @@ double Item_in_subselect::val_real()
|
||||
DBUG_ASSERT(0);
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
null_value= 0;
|
||||
if (exec(!enable_pushed_conds))
|
||||
if (exec())
|
||||
{
|
||||
reset();
|
||||
null_value= 1;
|
||||
@ -697,7 +697,7 @@ longlong Item_in_subselect::val_int()
|
||||
DBUG_ASSERT(0);
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
null_value= 0;
|
||||
if (exec(!enable_pushed_conds))
|
||||
if (exec())
|
||||
{
|
||||
reset();
|
||||
null_value= 1;
|
||||
@ -718,7 +718,7 @@ String *Item_in_subselect::val_str(String *str)
|
||||
DBUG_ASSERT(0);
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
null_value= 0;
|
||||
if (exec(!enable_pushed_conds))
|
||||
if (exec())
|
||||
{
|
||||
reset();
|
||||
null_value= 1;
|
||||
@ -738,7 +738,7 @@ bool Item_in_subselect::val_bool()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
null_value= 0;
|
||||
if (exec(!enable_pushed_conds))
|
||||
if (exec())
|
||||
{
|
||||
reset();
|
||||
null_value= 1;
|
||||
@ -758,7 +758,7 @@ my_decimal *Item_in_subselect::val_decimal(my_decimal *decimal_value)
|
||||
DBUG_ASSERT(0);
|
||||
null_value= 0;
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
if (exec(!enable_pushed_conds))
|
||||
if (exec())
|
||||
{
|
||||
reset();
|
||||
null_value= 1;
|
||||
@ -922,7 +922,7 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
|
||||
if (!substitution)
|
||||
{
|
||||
//first call for this unit
|
||||
/* We're invoked for the 1st (or the only) SELECT in the subquery UNION */
|
||||
SELECT_LEX_UNIT *unit= select_lex->master_unit();
|
||||
substitution= optimizer;
|
||||
|
||||
@ -948,19 +948,14 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
|
||||
unit->uncacheable|= UNCACHEABLE_DEPENDENT;
|
||||
}
|
||||
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
|
||||
{
|
||||
if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool))))
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
pushed_cond_guards[0]= TRUE;
|
||||
}
|
||||
|
||||
select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
|
||||
/*
|
||||
Add the left part of a subselect to a WHERE or HAVING clause of
|
||||
the right part, e.g.
|
||||
|
||||
SELECT 1 IN (SELECT a FROM t1) =>
|
||||
|
||||
SELECT Item_in_optimizer(1, SELECT a FROM t1 WHERE a=1)
|
||||
|
||||
HAVING is used only if the right part contains a SUM function, a GROUP
|
||||
BY or a HAVING clause.
|
||||
*/
|
||||
if (join->having || select_lex->with_sum_func ||
|
||||
select_lex->group_list.elements)
|
||||
{
|
||||
@ -972,13 +967,13 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
ref_pointer_array,
|
||||
(char *)"<ref>",
|
||||
this->full_name()));
|
||||
if (!abort_on_null && ((Item*)select_lex->item_list.head())->maybe_null)
|
||||
if (!abort_on_null && left_expr->maybe_null)
|
||||
{
|
||||
/*
|
||||
We can encounter "NULL IN (SELECT ...)". Wrap the added condition
|
||||
within a trigger.
|
||||
within a trig_cond.
|
||||
*/
|
||||
item= new Item_func_trig_cond(item, &enable_pushed_conds);
|
||||
item= new Item_func_trig_cond(item, get_cond_guard(0));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -987,6 +982,8 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
argument (reference) to fix_fields()
|
||||
*/
|
||||
select_lex->having= join->having= and_items(join->having, item);
|
||||
if (join->having == item)
|
||||
item->name= (char*)in_having_cond;
|
||||
select_lex->having_fix_field= 1;
|
||||
/*
|
||||
we do not check join->having->fixed, because Item_and (from and_items)
|
||||
@ -1013,14 +1010,19 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
item= func->create(expr, item);
|
||||
if (!abort_on_null && orig_item->maybe_null)
|
||||
{
|
||||
having=
|
||||
new Item_func_trig_cond(new Item_is_not_null_test(this, having),
|
||||
&enable_pushed_conds);
|
||||
having= new Item_is_not_null_test(this, having);
|
||||
if (left_expr->maybe_null)
|
||||
{
|
||||
if (!(having= new Item_func_trig_cond(having,
|
||||
get_cond_guard(0))))
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
/*
|
||||
Item_is_not_null_test can't be changed during fix_fields()
|
||||
we can assign select_lex->having here, and pass 0 as last
|
||||
argument (reference) to fix_fields()
|
||||
*/
|
||||
having->name= (char*)in_having_cond;
|
||||
select_lex->having= join->having= having;
|
||||
select_lex->having_fix_field= 1;
|
||||
/*
|
||||
@ -1032,17 +1034,25 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
select_lex->having_fix_field= 0;
|
||||
if (tmp)
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
/*
|
||||
NOTE: It is important that we add this "IS NULL" here, even when
|
||||
orig_item can't be NULL. This is needed so that this predicate is
|
||||
only used by ref[_or_null] analyzer (and, e.g. is not used by const
|
||||
propagation).
|
||||
*/
|
||||
item= new Item_cond_or(item,
|
||||
new Item_func_isnull(orig_item));
|
||||
item= new Item_func_trig_cond(item, &enable_pushed_conds);
|
||||
}
|
||||
/*
|
||||
If we may encounter NULL IN (SELECT ...) and care whether subquery
|
||||
result is NULL or FALSE, wrap condition in a trig_cond.
|
||||
*/
|
||||
if (!abort_on_null && left_expr->maybe_null)
|
||||
{
|
||||
if (!(item= new Item_func_trig_cond(item, get_cond_guard(0))))
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
/*
|
||||
TODO: figure out why the following is done here in
|
||||
single_value_transformer but there is no corresponding action in
|
||||
row_value_transformer?
|
||||
*/
|
||||
item->name= (char *)in_additional_cond;
|
||||
|
||||
/*
|
||||
AND can't be changed during fix_fields()
|
||||
we can assign select_lex->having here, and pass 0 as last
|
||||
@ -1073,10 +1083,16 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
||||
select_lex->ref_pointer_array,
|
||||
(char *)"<no matter>",
|
||||
(char *)"<result>"));
|
||||
new_having= new Item_func_trig_cond(new_having, &enable_pushed_conds);
|
||||
if (!abort_on_null && left_expr->maybe_null)
|
||||
{
|
||||
if (!(new_having= new Item_func_trig_cond(new_having,
|
||||
get_cond_guard(0))))
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
new_having->name= (char*)in_having_cond;
|
||||
select_lex->having= join->having= new_having;
|
||||
|
||||
select_lex->having_fix_field= 1;
|
||||
|
||||
/*
|
||||
we do not check join->having->fixed, because comparison function
|
||||
(from func->create) can't be fixed after creation
|
||||
@ -1146,6 +1162,15 @@ Item_in_subselect::row_value_transformer(JOIN *join)
|
||||
|
||||
thd->lex->current_select= current;
|
||||
unit->uncacheable|= UNCACHEABLE_DEPENDENT;
|
||||
|
||||
if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards)
|
||||
{
|
||||
if (!(pushed_cond_guards= (bool*)join->thd->alloc(sizeof(bool) *
|
||||
left_expr->cols())))
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
for (uint i= 0; i < cols_num; i++)
|
||||
pushed_cond_guards[i]= TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
select_lex->uncacheable|= UNCACHEABLE_DEPENDENT;
|
||||
@ -1162,6 +1187,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
|
||||
is_not_null_test(v3))
|
||||
where is_not_null_test used to register nulls in case if we have
|
||||
not found matching to return correct NULL value
|
||||
TODO: say here explicitly if the order of AND parts matters or not.
|
||||
*/
|
||||
Item *item_having_part2= 0;
|
||||
for (uint i= 0; i < cols_num; i++)
|
||||
@ -1190,21 +1216,28 @@ Item_in_subselect::row_value_transformer(JOIN *join)
|
||||
(char *)"<no matter>",
|
||||
(char *)"<list ref>")
|
||||
);
|
||||
having_item=
|
||||
and_items(having_item,
|
||||
new Item_cond_or(item_eq, item_isnull));
|
||||
item_having_part2=
|
||||
and_items(item_having_part2,
|
||||
new
|
||||
Item_is_not_null_test(this,
|
||||
new
|
||||
Item_ref(&select_lex->context,
|
||||
select_lex->
|
||||
ref_pointer_array + i,
|
||||
(char *)"<no matter>",
|
||||
(char *)"<list ref>")
|
||||
)
|
||||
);
|
||||
Item *col_item= new Item_cond_or(item_eq, item_isnull);
|
||||
if (!abort_on_null && left_expr->el(i)->maybe_null)
|
||||
{
|
||||
if (!(col_item= new Item_func_trig_cond(col_item, get_cond_guard(i))))
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
having_item= and_items(having_item, col_item);
|
||||
|
||||
Item *item_nnull_test=
|
||||
new Item_is_not_null_test(this,
|
||||
new Item_ref(&select_lex->context,
|
||||
select_lex->
|
||||
ref_pointer_array + i,
|
||||
(char *)"<no matter>",
|
||||
(char *)"<list ref>"));
|
||||
if (!abort_on_null && left_expr->el(i)->maybe_null)
|
||||
{
|
||||
if (!(item_nnull_test=
|
||||
new Item_func_trig_cond(item_nnull_test, get_cond_guard(i))))
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
item_having_part2= and_items(item_having_part2, item_nnull_test);
|
||||
item_having_part2->top_level_item();
|
||||
}
|
||||
having_item= and_items(having_item, item_having_part2);
|
||||
@ -1253,18 +1286,15 @@ Item_in_subselect::row_value_transformer(JOIN *join)
|
||||
);
|
||||
if (!abort_on_null)
|
||||
{
|
||||
having_item=
|
||||
and_items(having_item,
|
||||
new
|
||||
Item_is_not_null_test(this,
|
||||
new
|
||||
Item_ref(&select_lex->context,
|
||||
select_lex->
|
||||
ref_pointer_array + i,
|
||||
(char *)"<no matter>",
|
||||
(char *)"<list ref>")
|
||||
)
|
||||
);
|
||||
Item *having_col_item=
|
||||
new Item_is_not_null_test(this,
|
||||
new
|
||||
Item_ref(&select_lex->context,
|
||||
select_lex->ref_pointer_array + i,
|
||||
(char *)"<no matter>",
|
||||
(char *)"<list ref>"));
|
||||
|
||||
|
||||
item_isnull= new
|
||||
Item_func_isnull(new
|
||||
Item_direct_ref(&select_lex->context,
|
||||
@ -1273,14 +1303,23 @@ Item_in_subselect::row_value_transformer(JOIN *join)
|
||||
(char *)"<no matter>",
|
||||
(char *)"<list ref>")
|
||||
);
|
||||
|
||||
item= new Item_cond_or(item, item_isnull);
|
||||
/*
|
||||
TODO: why we create the above for cases where the right part
|
||||
cant be NULL?
|
||||
*/
|
||||
if (left_expr->el(i)->maybe_null)
|
||||
{
|
||||
if (!(item= new Item_func_trig_cond(item, get_cond_guard(i))))
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
if (!(having_col_item=
|
||||
new Item_func_trig_cond(having_col_item, get_cond_guard(i))))
|
||||
DBUG_RETURN(RES_ERROR);
|
||||
}
|
||||
having_item= and_items(having_item, having_col_item);
|
||||
}
|
||||
|
||||
where_item= and_items(where_item, item);
|
||||
}
|
||||
if (where_item)
|
||||
where_item= new Item_func_trig_cond(where_item, &enable_pushed_conds);
|
||||
/*
|
||||
AND can't be changed during fix_fields()
|
||||
we can assign select_lex->where here, and pass 0 as last
|
||||
@ -1294,9 +1333,9 @@ Item_in_subselect::row_value_transformer(JOIN *join)
|
||||
if (having_item)
|
||||
{
|
||||
bool res;
|
||||
having_item= new Item_func_trig_cond(having_item, &enable_pushed_conds);
|
||||
|
||||
select_lex->having= join->having= and_items(join->having, having_item);
|
||||
if (having_item == select_lex->having)
|
||||
having_item->name= (char*)in_having_cond;
|
||||
select_lex->having->top_level_item();
|
||||
/*
|
||||
AND can't be changed during fix_fields()
|
||||
@ -1682,7 +1721,7 @@ int init_read_record_seq(JOIN_TAB *tab);
|
||||
int join_read_always_key_or_null(JOIN_TAB *tab);
|
||||
int join_read_next_same_or_null(READ_RECORD *info);
|
||||
|
||||
int subselect_single_select_engine::exec(bool full_scan)
|
||||
int subselect_single_select_engine::exec()
|
||||
{
|
||||
DBUG_ENTER("subselect_single_select_engine::exec");
|
||||
char const *save_where= thd->where;
|
||||
@ -1720,9 +1759,13 @@ int subselect_single_select_engine::exec(bool full_scan)
|
||||
if (!executed)
|
||||
{
|
||||
item->reset_value_registration();
|
||||
if (full_scan)
|
||||
bool have_changed_access= FALSE;
|
||||
JOIN_TAB *changed_tabs[MAX_TABLES];
|
||||
JOIN_TAB **last_changed_tab= changed_tabs;
|
||||
if (item->have_guarded_conds())
|
||||
{
|
||||
/*
|
||||
For at least one of the pushed predicates the following is true:
|
||||
We should not apply optimizations based on the condition that was
|
||||
pushed down into the subquery. Those optimizations are ref[_or_null]
|
||||
acceses. Change them to be full table scans.
|
||||
@ -1730,32 +1773,36 @@ int subselect_single_select_engine::exec(bool full_scan)
|
||||
for (uint i=join->const_tables ; i < join->tables ; i++)
|
||||
{
|
||||
JOIN_TAB *tab=join->join_tab+i;
|
||||
if (tab->keyuse && tab->keyuse->outer_ref)
|
||||
if (tab && tab->keyuse)
|
||||
{
|
||||
tab->read_first_record= init_read_record_seq;
|
||||
tab->read_record.record= tab->table->record[0];
|
||||
tab->read_record.thd= join->thd;
|
||||
tab->read_record.ref_length= tab->table->file->ref_length;
|
||||
for (uint i= 0; i < tab->ref.key_parts; i++)
|
||||
{
|
||||
bool *cond_guard= tab->ref.cond_guards[i];
|
||||
if (cond_guard && !*cond_guard)
|
||||
{
|
||||
/* Change the access method to full table scan */
|
||||
tab->read_first_record= init_read_record_seq;
|
||||
tab->read_record.record= tab->table->record[0];
|
||||
tab->read_record.thd= join->thd;
|
||||
tab->read_record.ref_length= tab->table->file->ref_length;
|
||||
*(last_changed_tab++)= tab;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
join->exec();
|
||||
|
||||
if (full_scan)
|
||||
/* Enable the optimizations back */
|
||||
for (JOIN_TAB **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
|
||||
{
|
||||
/* Enable the optimizations back */
|
||||
for (uint i=join->const_tables ; i < join->tables ; i++)
|
||||
{
|
||||
JOIN_TAB *tab=join->join_tab+i;
|
||||
if (tab->keyuse && tab->keyuse->outer_ref)
|
||||
{
|
||||
tab->read_record.record= 0;
|
||||
tab->read_record.ref_length= 0;
|
||||
tab->read_first_record= join_read_always_key_or_null;
|
||||
tab->read_record.read_record= join_read_next_same_or_null;
|
||||
}
|
||||
}
|
||||
JOIN_TAB *tab= *ptab;
|
||||
tab->read_record.record= 0;
|
||||
tab->read_record.ref_length= 0;
|
||||
tab->read_first_record= join_read_always_key_or_null;
|
||||
tab->read_record.read_record= join_read_next_same_or_null;
|
||||
}
|
||||
executed= 1;
|
||||
thd->where= save_where;
|
||||
@ -1767,13 +1814,9 @@ int subselect_single_select_engine::exec(bool full_scan)
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
int subselect_union_engine::exec(bool full_scan)
|
||||
int subselect_union_engine::exec()
|
||||
{
|
||||
char const *save_where= thd->where;
|
||||
/*
|
||||
Ignore the full_scan parameter: the pushed down predicates are only used
|
||||
for filtering, and the caller has disabled them if necessary.
|
||||
*/
|
||||
int res= unit->exec();
|
||||
thd->where= save_where;
|
||||
return res;
|
||||
@ -1781,7 +1824,7 @@ int subselect_union_engine::exec(bool full_scan)
|
||||
|
||||
|
||||
/*
|
||||
Search for at least on row satisfying select condition
|
||||
Search for at least one row satisfying select condition
|
||||
|
||||
SYNOPSIS
|
||||
subselect_uniquesubquery_engine::scan_table()
|
||||
@ -1790,8 +1833,8 @@ int subselect_union_engine::exec(bool full_scan)
|
||||
Scan the table using sequential access until we find at least one row
|
||||
satisfying select condition.
|
||||
|
||||
The result of this function (info about whether a row was found) is
|
||||
stored in this->empty_result_set.
|
||||
The caller must set this->empty_result_set=FALSE before calling this
|
||||
function. This function will set it to TRUE if it finds a matching row.
|
||||
|
||||
RETURN
|
||||
FALSE - OK
|
||||
@ -1803,7 +1846,6 @@ int subselect_uniquesubquery_engine::scan_table()
|
||||
int error;
|
||||
TABLE *table= tab->table;
|
||||
DBUG_ENTER("subselect_uniquesubquery_engine::scan_table");
|
||||
empty_result_set= TRUE;
|
||||
|
||||
if (table->file->inited)
|
||||
table->file->ha_index_end();
|
||||
@ -1896,10 +1938,13 @@ bool subselect_uniquesubquery_engine::copy_ref_key()
|
||||
- FALSE otherwise.
|
||||
|
||||
In some cases (IN subselect is a top level item, i.e. abort_on_null==TRUE)
|
||||
the caller doesn't distinguish between NULL and FALSE result and we just
|
||||
the caller doesn't distinguish between NULL and FALSE result and we just
|
||||
return FALSE.
|
||||
Otherwise we make a full table scan to see if there is at least one matching row.
|
||||
|
||||
Otherwise we make a full table scan to see if there is at least one
|
||||
matching row.
|
||||
|
||||
The result of this function (info about whether a row was found) is
|
||||
stored in this->empty_result_set.
|
||||
NOTE
|
||||
|
||||
RETURN
|
||||
@ -1907,11 +1952,12 @@ bool subselect_uniquesubquery_engine::copy_ref_key()
|
||||
TRUE - an error occured while scanning
|
||||
*/
|
||||
|
||||
int subselect_uniquesubquery_engine::exec(bool full_scan)
|
||||
int subselect_uniquesubquery_engine::exec()
|
||||
{
|
||||
DBUG_ENTER("subselect_uniquesubquery_engine::exec");
|
||||
int error;
|
||||
TABLE *table= tab->table;
|
||||
empty_result_set= TRUE;
|
||||
|
||||
/* TODO: change to use of 'full_scan' here? */
|
||||
if (copy_ref_key())
|
||||
@ -1932,9 +1978,13 @@ int subselect_uniquesubquery_engine::exec(bool full_scan)
|
||||
{
|
||||
error= 0;
|
||||
table->null_row= 0;
|
||||
((Item_in_subselect *) item)->value= (!table->status &&
|
||||
(!cond || cond->val_int()) ? 1 :
|
||||
0);
|
||||
if (!table->status && (!cond || cond->val_int()))
|
||||
{
|
||||
((Item_in_subselect *) item)->value= 1;
|
||||
empty_result_set= FALSE;
|
||||
}
|
||||
else
|
||||
((Item_in_subselect *) item)->value= 0;
|
||||
}
|
||||
|
||||
DBUG_RETURN(error != 0);
|
||||
@ -2000,7 +2050,7 @@ subselect_uniquesubquery_engine::~subselect_uniquesubquery_engine()
|
||||
1
|
||||
*/
|
||||
|
||||
int subselect_indexsubquery_engine::exec(bool full_scan)
|
||||
int subselect_indexsubquery_engine::exec()
|
||||
{
|
||||
DBUG_ENTER("subselect_indexsubquery_engine::exec");
|
||||
int error;
|
||||
@ -2041,8 +2091,9 @@ int subselect_indexsubquery_engine::exec(bool full_scan)
|
||||
table->null_row= 0;
|
||||
if (!table->status)
|
||||
{
|
||||
if (!cond || cond->val_int())
|
||||
if ((!cond || cond->val_int()) && (!having || having->val_int()))
|
||||
{
|
||||
empty_result_set= FALSE;
|
||||
if (null_finding)
|
||||
((Item_in_subselect *) item)->was_null= 1;
|
||||
else
|
||||
@ -2185,11 +2236,16 @@ void subselect_indexsubquery_engine::print(String *str)
|
||||
str->append(key_info->name);
|
||||
if (check_null)
|
||||
str->append(STRING_WITH_LEN(" checking NULL"));
|
||||
if (cond)
|
||||
if (cond)
|
||||
{
|
||||
str->append(STRING_WITH_LEN(" where "));
|
||||
cond->print(str);
|
||||
}
|
||||
if (having)
|
||||
{
|
||||
str->append(STRING_WITH_LEN(" having "));
|
||||
having->print(str);
|
||||
}
|
||||
str->append(')');
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ public:
|
||||
return null_value;
|
||||
}
|
||||
bool fix_fields(THD *thd, Item **ref);
|
||||
virtual bool exec(bool full_scan);
|
||||
virtual bool exec();
|
||||
virtual void fix_length_and_dec();
|
||||
table_map used_tables() const;
|
||||
table_map not_null_tables() const { return 0; }
|
||||
@ -104,6 +104,7 @@ public:
|
||||
Item *get_tmp_table_item(THD *thd);
|
||||
void update_used_tables();
|
||||
void print(String *str);
|
||||
virtual bool have_guarded_conds() { return FALSE; }
|
||||
bool change_engine(subselect_engine *eng)
|
||||
{
|
||||
old_engine= engine;
|
||||
@ -249,13 +250,21 @@ protected:
|
||||
bool transformed;
|
||||
public:
|
||||
/* Used to trigger on/off conditions that were pushed down to subselect */
|
||||
bool enable_pushed_conds;
|
||||
bool *pushed_cond_guards;
|
||||
|
||||
bool *get_cond_guard(int i)
|
||||
{
|
||||
return pushed_cond_guards ? pushed_cond_guards + i : NULL;
|
||||
}
|
||||
void set_cond_guard_var(int i, bool v) { pushed_cond_guards[i]= v; }
|
||||
bool have_guarded_conds() { return test(pushed_cond_guards); }
|
||||
|
||||
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(), optimizer(0), abort_on_null(0), transformed(0),
|
||||
enable_pushed_conds(TRUE), upper_item(0)
|
||||
pushed_cond_guards(NULL), upper_item(0)
|
||||
{}
|
||||
|
||||
subs_type substype() { return IN_SUBS; }
|
||||
@ -340,23 +349,22 @@ public:
|
||||
|
||||
SYNOPSIS
|
||||
exec()
|
||||
full_scan TRUE - Pushed-down predicates are disabled, the engine
|
||||
must disable made based on those predicates.
|
||||
FALSE - Pushed-down predicates are in effect.
|
||||
|
||||
DESCRIPTION
|
||||
Execute the engine. The result of execution is subquery value that is
|
||||
either captured by previously set up select_result-based 'sink' or
|
||||
stored somewhere by the exec() method itself.
|
||||
|
||||
A required side effect: if full_scan==TRUE, subselect_engine->no_rows()
|
||||
should return correct result.
|
||||
A required side effect: If at least one pushed-down predicate is
|
||||
disabled, subselect_engine->no_rows() must return correct result after
|
||||
the exec() call.
|
||||
|
||||
RETURN
|
||||
0 - OK
|
||||
1 - Either an execution error, or the engine was be "changed", and
|
||||
1 - Either an execution error, or the engine was "changed", and the
|
||||
caller should call exec() again for the new engine.
|
||||
*/
|
||||
virtual int exec(bool full_scan)= 0;
|
||||
virtual int exec()= 0;
|
||||
virtual uint cols()= 0; /* return number of columns in select */
|
||||
virtual uint8 uncacheable()= 0; /* query is uncacheable */
|
||||
enum Item_result type() { return res_type; }
|
||||
@ -391,7 +399,7 @@ public:
|
||||
void cleanup();
|
||||
int prepare();
|
||||
void fix_length_and_dec(Item_cache** row);
|
||||
int exec(bool full_scan);
|
||||
int exec();
|
||||
uint cols();
|
||||
uint8 uncacheable();
|
||||
void exclude();
|
||||
@ -415,7 +423,7 @@ public:
|
||||
void cleanup();
|
||||
int prepare();
|
||||
void fix_length_and_dec(Item_cache** row);
|
||||
int exec(bool full_scan);
|
||||
int exec();
|
||||
uint cols();
|
||||
uint8 uncacheable();
|
||||
void exclude();
|
||||
@ -429,11 +437,30 @@ public:
|
||||
|
||||
|
||||
struct st_join_table;
|
||||
|
||||
|
||||
/*
|
||||
A subquery execution engine that evaluates the subquery by doing one index
|
||||
lookup in a unique index.
|
||||
|
||||
This engine is used to resolve subqueries in forms
|
||||
|
||||
outer_expr IN (SELECT tbl.unique_key FROM tbl WHERE subq_where)
|
||||
|
||||
or, tuple-based:
|
||||
|
||||
(oe1, .. oeN) IN (SELECT uniq_key_part1, ... uniq_key_partK
|
||||
FROM tbl WHERE subqwhere)
|
||||
|
||||
i.e. the subquery is a single table SELECT without GROUP BY, aggregate
|
||||
functions, etc.
|
||||
*/
|
||||
|
||||
class subselect_uniquesubquery_engine: public subselect_engine
|
||||
{
|
||||
protected:
|
||||
st_join_table *tab;
|
||||
Item *cond;
|
||||
Item *cond; /* The WHERE condition of subselect */
|
||||
/*
|
||||
TRUE<=> last execution produced empty set. Valid only when left
|
||||
expression is NULL.
|
||||
@ -453,7 +480,7 @@ public:
|
||||
void cleanup();
|
||||
int prepare();
|
||||
void fix_length_and_dec(Item_cache** row);
|
||||
int exec(bool full_scan);
|
||||
int exec();
|
||||
uint cols() { return 1; }
|
||||
uint8 uncacheable() { return UNCACHEABLE_DEPENDENT; }
|
||||
void exclude();
|
||||
@ -471,16 +498,47 @@ class subselect_indexsubquery_engine: public subselect_uniquesubquery_engine
|
||||
{
|
||||
/* FALSE for 'ref', TRUE for 'ref-or-null'. */
|
||||
bool check_null;
|
||||
/*
|
||||
The "having" clause. This clause (further reffered to as "artificial
|
||||
having") was inserted by subquery transformation code. It contains
|
||||
Item(s) that have a side-effect: they record whether the subquery has
|
||||
produced a row with NULL certain components. We need to use it for cases
|
||||
like
|
||||
(oe1, oe2) IN (SELECT t.key, t.no_key FROM t1)
|
||||
where we do index lookup on t.key=oe1 but need also to check if there
|
||||
was a row such that t.no_key IS NULL.
|
||||
|
||||
NOTE: This is currently here and not in the uniquesubquery_engine. Ideally
|
||||
it should have been in uniquesubquery_engine in order to allow execution of
|
||||
subqueries like
|
||||
|
||||
(oe1, oe2) IN (SELECT primary_key, non_key_maybe_null_field FROM tbl)
|
||||
|
||||
We could use uniquesubquery_engine for the first component and let
|
||||
Item_is_not_null_test( non_key_maybe_null_field) to handle the second.
|
||||
|
||||
However, subqueries like the above are currently not handled by index
|
||||
lookup-based subquery engines, the engine applicability check misses
|
||||
them: it doesn't switch the engine for case of artificial having and
|
||||
[eq_]ref access (only for artifical having + ref_or_null or no having).
|
||||
The above example subquery is handled as a full-blown SELECT with eq_ref
|
||||
access to one table.
|
||||
|
||||
Due to this limitation, the "artificial having" currently needs to be
|
||||
checked by only in indexsubquery_engine.
|
||||
*/
|
||||
Item *having;
|
||||
public:
|
||||
|
||||
// constructor can assign THD because it will be called after JOIN::prepare
|
||||
subselect_indexsubquery_engine(THD *thd, st_join_table *tab_arg,
|
||||
Item_subselect *subs, Item *where,
|
||||
bool chk_null)
|
||||
Item *having_arg, bool chk_null)
|
||||
:subselect_uniquesubquery_engine(thd, tab_arg, subs, where),
|
||||
check_null(chk_null)
|
||||
check_null(chk_null),
|
||||
having(having_arg)
|
||||
{}
|
||||
int exec(bool full_scan);
|
||||
int exec();
|
||||
void print (String *str);
|
||||
};
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user