Merge bk-internal.mysql.com:/home/bk/mysql-4.1
into mysql.com:/home/my/mysql-4.1 sql/sql_select.cc: Auto merged
This commit is contained in:
commit
4e7cb1ce48
2
bdb/dist/configure.ac
vendored
2
bdb/dist/configure.ac
vendored
@ -555,7 +555,7 @@ fi
|
|||||||
LIB@&t@OBJS=`echo "$LIB@&t@OBJS" |
|
LIB@&t@OBJS=`echo "$LIB@&t@OBJS" |
|
||||||
sed 's,\.[[^.]]* ,$U&,g;s,\.[[^.]]*$,$U&,'`
|
sed 's,\.[[^.]]* ,$U&,g;s,\.[[^.]]*$,$U&,'`
|
||||||
LTLIBOBJS=`echo "$LIB@&t@OBJS" |
|
LTLIBOBJS=`echo "$LIB@&t@OBJS" |
|
||||||
sed 's,\.[[^.]]* ,.lo ,g;s,\.[[^.]]*$,.lo,'`
|
sed "s,\.[[^.]]* ,$o ,g;s,\.[[^.]]*$,$o,"`
|
||||||
AC_SUBST(LTLIBOBJS)
|
AC_SUBST(LTLIBOBJS)
|
||||||
|
|
||||||
# Initial output file list.
|
# Initial output file list.
|
||||||
|
@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
|
|||||||
AC_INIT(sql/mysqld.cc)
|
AC_INIT(sql/mysqld.cc)
|
||||||
AC_CANONICAL_SYSTEM
|
AC_CANONICAL_SYSTEM
|
||||||
# The Docs Makefile.am parses this line!
|
# The Docs Makefile.am parses this line!
|
||||||
AM_INIT_AUTOMAKE(mysql, 4.1.4-beta)
|
AM_INIT_AUTOMAKE(mysql, 4.1.4-gamma)
|
||||||
AM_CONFIG_HEADER(config.h)
|
AM_CONFIG_HEADER(config.h)
|
||||||
|
|
||||||
PROTOCOL_VERSION=10
|
PROTOCOL_VERSION=10
|
||||||
@ -2823,7 +2823,7 @@ then
|
|||||||
AC_CONFIG_FILES(bdb/Makefile)
|
AC_CONFIG_FILES(bdb/Makefile)
|
||||||
|
|
||||||
echo "CONFIGURING FOR BERKELEY DB"
|
echo "CONFIGURING FOR BERKELEY DB"
|
||||||
bdb_conf_flags=
|
bdb_conf_flags="--disable-shared"
|
||||||
if test $with_debug = "yes"
|
if test $with_debug = "yes"
|
||||||
then
|
then
|
||||||
bdb_conf_flags="$bdb_conf_flags --enable-debug --enable-diagnostic"
|
bdb_conf_flags="$bdb_conf_flags --enable-debug --enable-diagnostic"
|
||||||
|
@ -16,7 +16,7 @@ DEFS = -DEMBEDDED_LIBRARY
|
|||||||
INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include -I$(srcdir) \
|
INCLUDES = @MT_INCLUDES@ -I$(top_srcdir)/include -I$(srcdir) \
|
||||||
-I$(top_srcdir) -I$(top_srcdir)/client $(openssl_includes)
|
-I$(top_srcdir) -I$(top_srcdir)/client $(openssl_includes)
|
||||||
LIBS = @LIBS@ @WRAPLIBS@ @CLIENT_LIBS@
|
LIBS = @LIBS@ @WRAPLIBS@ @CLIENT_LIBS@
|
||||||
LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @innodb_system_libs@ @bdb_libs_with_path@ @LIBDL@ $(CXXLDFLAGS)
|
LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @innodb_system_libs@ @LIBDL@ $(CXXLDFLAGS)
|
||||||
|
|
||||||
mysqltest_LINK = $(CXXLINK)
|
mysqltest_LINK = $(CXXLINK)
|
||||||
|
|
||||||
|
@ -32,20 +32,16 @@
|
|||||||
|
|
||||||
MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
|
MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
|
||||||
{
|
{
|
||||||
int save_errno,errpos;
|
int save_errno,errpos=0;
|
||||||
uint files,i,dir_length,length,key_parts;
|
uint files=0,i,dir_length,length,key_parts;
|
||||||
ulonglong file_offset;
|
ulonglong file_offset;
|
||||||
char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
|
char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end;
|
||||||
MYRG_INFO *m_info;
|
MYRG_INFO *m_info=0;
|
||||||
File fd;
|
File fd;
|
||||||
IO_CACHE file;
|
IO_CACHE file;
|
||||||
MI_INFO *isam;
|
MI_INFO *isam=0;
|
||||||
DBUG_ENTER("myrg_open");
|
DBUG_ENTER("myrg_open");
|
||||||
|
|
||||||
LINT_INIT(m_info);
|
|
||||||
m_info=0;
|
|
||||||
isam=0;
|
|
||||||
errpos=files=0;
|
|
||||||
bzero((char*) &file,sizeof(file));
|
bzero((char*) &file,sizeof(file));
|
||||||
if ((fd=my_open(fn_format(name_buff,name,"",MYRG_NAME_EXT,4),
|
if ((fd=my_open(fn_format(name_buff,name,"",MYRG_NAME_EXT,4),
|
||||||
O_RDONLY | O_SHARE,MYF(0))) < 0)
|
O_RDONLY | O_SHARE,MYF(0))) < 0)
|
||||||
|
@ -1451,9 +1451,9 @@ then
|
|||||||
then
|
then
|
||||||
echo "Starting ndbcluster"
|
echo "Starting ndbcluster"
|
||||||
./ndb/ndbcluster --port-base=$NDBCLUSTER_PORT --small --diskless --initial --data-dir=$MYSQL_TEST_DIR/var || exit 1
|
./ndb/ndbcluster --port-base=$NDBCLUSTER_PORT --small --diskless --initial --data-dir=$MYSQL_TEST_DIR/var || exit 1
|
||||||
USE_NDBCLUSTER="--ndb-connectstring=\"host=localhost:$NDBCLUSTER_PORT\""
|
USE_NDBCLUSTER="$USE_NDBCLUSTER --ndb-connectstring=\"host=localhost:$NDBCLUSTER_PORT\""
|
||||||
else
|
else
|
||||||
USE_NDBCLUSTER="--ndb-connectstring=\"$USE_RUNNING_NDBCLUSTER\""
|
USE_NDBCLUSTER="$USE_NDBCLUSTER --ndb-connectstring=\"$USE_RUNNING_NDBCLUSTER\""
|
||||||
echo "Using ndbcluster at $USE_NDBCLUSTER"
|
echo "Using ndbcluster at $USE_NDBCLUSTER"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
@ -116,3 +116,21 @@ select collation(a), collation(b), collation(binary 'ccc') from t1 limit 1;
|
|||||||
collation(a) collation(b) collation(binary 'ccc')
|
collation(a) collation(b) collation(binary 'ccc')
|
||||||
latin1_bin binary latin1_bin
|
latin1_bin binary latin1_bin
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1( firstname char(20), lastname char(20));
|
||||||
|
insert into t1 values ("john","doe"),("John","Doe");
|
||||||
|
select * from t1 where firstname='john' and firstname like binary 'john';
|
||||||
|
firstname lastname
|
||||||
|
john doe
|
||||||
|
select * from t1 where firstname='john' and binary 'john' = firstname;
|
||||||
|
firstname lastname
|
||||||
|
john doe
|
||||||
|
select * from t1 where firstname='john' and firstname = binary 'john';
|
||||||
|
firstname lastname
|
||||||
|
john doe
|
||||||
|
select * from t1 where firstname='John' and firstname like binary 'john';
|
||||||
|
firstname lastname
|
||||||
|
john doe
|
||||||
|
select * from t1 where firstname='john' and firstname like binary 'John';
|
||||||
|
firstname lastname
|
||||||
|
John Doe
|
||||||
|
drop table t1;
|
||||||
|
@ -560,3 +560,13 @@ select * from t1 where str='str';
|
|||||||
str
|
str
|
||||||
str
|
str
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (
|
||||||
|
str varchar(255) character set utf8 not null,
|
||||||
|
key str using hash (str(2))
|
||||||
|
) engine=heap;
|
||||||
|
INSERT INTO t1 VALUES ('str');
|
||||||
|
INSERT INTO t1 VALUES ('str2');
|
||||||
|
select * from t1 where str='str';
|
||||||
|
str
|
||||||
|
str
|
||||||
|
drop table t1;
|
||||||
|
@ -294,6 +294,21 @@ grp
|
|||||||
select group_concat(c order by (select mid(group_concat(c order by a),1,5) from t2 where t2.a=t1.a) desc) as grp from t1;
|
select group_concat(c order by (select mid(group_concat(c order by a),1,5) from t2 where t2.a=t1.a) desc) as grp from t1;
|
||||||
grp
|
grp
|
||||||
2,4,3,5
|
2,4,3,5
|
||||||
|
select t1.a, group_concat(c order by (select c from t2 where t2.a=t1.a limit 1)) as grp from t1 group by 1;
|
||||||
|
a grp
|
||||||
|
1 2
|
||||||
|
2 4,3
|
||||||
|
3 5
|
||||||
|
select t1.a, group_concat(c order by (select mid(group_concat(c order by a),1,5) from t2 where t2.a=t1.a)) as grp from t1 group by 1;
|
||||||
|
a grp
|
||||||
|
1 2
|
||||||
|
2 4,3
|
||||||
|
3 5
|
||||||
|
select t1.a, group_concat(c order by (select mid(group_concat(c order by a),1,5) from t2 where t2.a=t1.a) desc) as grp from t1 group by 1;
|
||||||
|
a grp
|
||||||
|
1 2
|
||||||
|
2 4,3
|
||||||
|
3 5
|
||||||
select a,c,(select group_concat(c order by a) from t2 where a=t1.a) as grp from t1 order by grp;
|
select a,c,(select group_concat(c order by a) from t2 where a=t1.a) as grp from t1 order by grp;
|
||||||
a c grp
|
a c grp
|
||||||
3 5 3,3
|
3 5 3,3
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
drop table if exists t1;
|
drop table if exists t1;
|
||||||
|
drop database if exists test2;
|
||||||
set autocommit=0;
|
set autocommit=0;
|
||||||
create table t1 (
|
create table t1 (
|
||||||
a int not null primary key,
|
a int not null primary key,
|
||||||
@ -220,6 +221,55 @@ a b c d
|
|||||||
7 7xb7 777 7xdd7
|
7 7xb7 777 7xdd7
|
||||||
8 8xb8 888 8xdd8
|
8 8xb8 888 8xdd8
|
||||||
9 9xb9 999 9xdd9
|
9 9xb9 999 9xdd9
|
||||||
|
select * from t1 order by a;
|
||||||
|
a b c d
|
||||||
|
1 1xb1 111 1xdd1
|
||||||
|
2 2xb2 222 2xdd2
|
||||||
|
3 3xb3 333 3xdd3
|
||||||
|
4 4xb4 444 4xdd4
|
||||||
|
5 5xb5 555 5xdd5
|
||||||
|
6 6xb6 666 6xdd6
|
||||||
|
7 7xb7 777 7xdd7
|
||||||
|
8 8xb8 888 8xdd8
|
||||||
|
9 9xb9 999 9xdd9
|
||||||
|
alter table t1 add x int;
|
||||||
|
select * from t1 order by a;
|
||||||
|
a b c d x
|
||||||
|
1 1xb1 111 1xdd1 NULL
|
||||||
|
2 2xb2 222 2xdd2 NULL
|
||||||
|
3 3xb3 333 3xdd3 NULL
|
||||||
|
4 4xb4 444 4xdd4 NULL
|
||||||
|
5 5xb5 555 5xdd5 NULL
|
||||||
|
6 6xb6 666 6xdd6 NULL
|
||||||
|
7 7xb7 777 7xdd7 NULL
|
||||||
|
8 8xb8 888 8xdd8 NULL
|
||||||
|
9 9xb9 999 9xdd9 NULL
|
||||||
|
alter table t1 drop x;
|
||||||
|
select * from t1 order by a;
|
||||||
|
a b c d
|
||||||
|
1 1xb1 111 1xdd1
|
||||||
|
2 2xb2 222 2xdd2
|
||||||
|
3 3xb3 333 3xdd3
|
||||||
|
4 4xb4 444 4xdd4
|
||||||
|
5 5xb5 555 5xdd5
|
||||||
|
6 6xb6 666 6xdd6
|
||||||
|
7 7xb7 777 7xdd7
|
||||||
|
8 8xb8 888 8xdd8
|
||||||
|
9 9xb9 999 9xdd9
|
||||||
|
create database test2;
|
||||||
|
use test2;
|
||||||
|
CREATE TABLE t2 (
|
||||||
|
a bigint unsigned NOT NULL PRIMARY KEY,
|
||||||
|
b int unsigned not null,
|
||||||
|
c int unsigned
|
||||||
|
) engine=ndbcluster;
|
||||||
|
insert into t2 values (1,1,1),(2,2,2);
|
||||||
|
select * from test.t1,t2 where test.t1.a = t2.a order by test.t1.a;
|
||||||
|
a b c d a b c
|
||||||
|
1 1xb1 111 1xdd1 1 1 1
|
||||||
|
2 2xb2 222 2xdd2 2 2 2
|
||||||
|
drop table t2;
|
||||||
|
use test;
|
||||||
delete from t1 where c >= 100;
|
delete from t1 where c >= 100;
|
||||||
commit;
|
commit;
|
||||||
select count(*) from t1;
|
select count(*) from t1;
|
||||||
|
@ -401,10 +401,3 @@ where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3';
|
|||||||
delete from mysql.db
|
delete from mysql.db
|
||||||
where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3';
|
where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3';
|
||||||
flush privileges;
|
flush privileges;
|
||||||
set names latin1;
|
|
||||||
create database `ä`;
|
|
||||||
create table `ä`.`ä` (a int) engine=heap;
|
|
||||||
show table status from `ä` LIKE 'ä';
|
|
||||||
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
|
|
||||||
ä HEAP 9 Fixed 0 5 # # # 0 NULL NULL NULL NULL latin1_swedish_ci NULL
|
|
||||||
drop database `ä`;
|
|
||||||
|
@ -1912,3 +1912,54 @@ a
|
|||||||
1
|
1
|
||||||
2
|
2
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
CREATE TABLE `t1` ( `aid` int(11) NOT NULL default '0', `bid` int(11) NOT NULL default '0', PRIMARY KEY (`aid`,`bid`));
|
||||||
|
CREATE TABLE `t2` ( `aid` int(11) NOT NULL default '0', `bid` int(11) NOT NULL default '0', PRIMARY KEY (`aid`,`bid`));
|
||||||
|
insert into t1 values (1,1),(1,2),(2,1),(2,2);
|
||||||
|
insert into t2 values (1,2),(2,2);
|
||||||
|
select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
|
||||||
|
aid bid
|
||||||
|
1 1
|
||||||
|
2 1
|
||||||
|
alter table t2 drop primary key;
|
||||||
|
alter table t2 add key KEY1 (aid, bid);
|
||||||
|
select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
|
||||||
|
aid bid
|
||||||
|
1 1
|
||||||
|
2 1
|
||||||
|
alter table t2 drop key KEY1;
|
||||||
|
alter table t2 add primary key (bid, aid);
|
||||||
|
select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
|
||||||
|
aid bid
|
||||||
|
1 1
|
||||||
|
2 1
|
||||||
|
drop table t1,t2;
|
||||||
|
CREATE TABLE t1 (howmanyvalues bigint, avalue int);
|
||||||
|
INSERT INTO t1 VALUES (1, 1),(2, 1),(2, 2),(3, 1),(3, 2),(3, 3),(4, 1),(4, 2),(4, 3),(4, 4);
|
||||||
|
SELECT howmanyvalues, count(*) from t1 group by howmanyvalues;
|
||||||
|
howmanyvalues count(*)
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
4 4
|
||||||
|
SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.howmanyvalues) as mycount from t1 a group by a.howmanyvalues;
|
||||||
|
howmanyvalues mycount
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
4 4
|
||||||
|
CREATE INDEX t1_howmanyvalues_idx ON t1 (howmanyvalues);
|
||||||
|
SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues+1 = a.howmanyvalues+1) as mycount from t1 a group by a.howmanyvalues;
|
||||||
|
howmanyvalues mycount
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
4 4
|
||||||
|
SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.howmanyvalues) as mycount from t1 a group by a.howmanyvalues;
|
||||||
|
howmanyvalues mycount
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
4 4
|
||||||
|
SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.avalue) as mycount from t1 a group by a.howmanyvalues;
|
||||||
|
ERROR 42S22: Unknown column 'a.avalue' in 'where clause'
|
||||||
|
drop table t1;
|
||||||
|
@ -67,3 +67,16 @@ select * from t1 where lower(b)='bbb';
|
|||||||
select charset(a), charset(b), charset(binary 'ccc') from t1 limit 1;
|
select charset(a), charset(b), charset(binary 'ccc') from t1 limit 1;
|
||||||
select collation(a), collation(b), collation(binary 'ccc') from t1 limit 1;
|
select collation(a), collation(b), collation(binary 'ccc') from t1 limit 1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug5134: WHERE x = 'bar' AND x LIKE BINARY 'bar' returns wrong results
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1( firstname char(20), lastname char(20));
|
||||||
|
insert into t1 values ("john","doe"),("John","Doe");
|
||||||
|
select * from t1 where firstname='john' and firstname like binary 'john';
|
||||||
|
select * from t1 where firstname='john' and binary 'john' = firstname;
|
||||||
|
select * from t1 where firstname='john' and firstname = binary 'john';
|
||||||
|
select * from t1 where firstname='John' and firstname like binary 'john';
|
||||||
|
select * from t1 where firstname='john' and firstname like binary 'John';
|
||||||
|
drop table t1;
|
||||||
|
@ -417,3 +417,15 @@ INSERT INTO t1 VALUES ('str');
|
|||||||
INSERT INTO t1 VALUES ('str2');
|
INSERT INTO t1 VALUES ('str2');
|
||||||
select * from t1 where str='str';
|
select * from t1 where str='str';
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
# the same for HEAP+HASH
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1 (
|
||||||
|
str varchar(255) character set utf8 not null,
|
||||||
|
key str using hash (str(2))
|
||||||
|
) engine=heap;
|
||||||
|
INSERT INTO t1 VALUES ('str');
|
||||||
|
INSERT INTO t1 VALUES ('str2');
|
||||||
|
select * from t1 where str='str';
|
||||||
|
drop table t1;
|
||||||
|
@ -1 +0,0 @@
|
|||||||
--loose-innodb_lock_wait_timeout=5
|
|
@ -169,9 +169,11 @@ create table t2 (a int, c int);
|
|||||||
insert into t2 values (1, 5), (2, 4), (3, 3), (3,3);
|
insert into t2 values (1, 5), (2, 4), (3, 3), (3,3);
|
||||||
select group_concat(c) from t1;
|
select group_concat(c) from t1;
|
||||||
select group_concat(c order by (select c from t2 where t2.a=t1.a limit 1)) as grp from t1;
|
select group_concat(c order by (select c from t2 where t2.a=t1.a limit 1)) as grp from t1;
|
||||||
|
|
||||||
select group_concat(c order by (select mid(group_concat(c order by a),1,5) from t2 where t2.a=t1.a)) as grp from t1;
|
select group_concat(c order by (select mid(group_concat(c order by a),1,5) from t2 where t2.a=t1.a)) as grp from t1;
|
||||||
select group_concat(c order by (select mid(group_concat(c order by a),1,5) from t2 where t2.a=t1.a) desc) as grp from t1;
|
select group_concat(c order by (select mid(group_concat(c order by a),1,5) from t2 where t2.a=t1.a) desc) as grp from t1;
|
||||||
|
select t1.a, group_concat(c order by (select c from t2 where t2.a=t1.a limit 1)) as grp from t1 group by 1;
|
||||||
|
select t1.a, group_concat(c order by (select mid(group_concat(c order by a),1,5) from t2 where t2.a=t1.a)) as grp from t1 group by 1;
|
||||||
|
select t1.a, group_concat(c order by (select mid(group_concat(c order by a),1,5) from t2 where t2.a=t1.a) desc) as grp from t1 group by 1;
|
||||||
|
|
||||||
# The following returns random results as we are sorting on blob addresses
|
# The following returns random results as we are sorting on blob addresses
|
||||||
# select group_concat(c order by (select group_concat(c order by a) from t2 where t2.a=t1.a)) as grp from t1;
|
# select group_concat(c order by (select group_concat(c order by a) from t2 where t2.a=t1.a)) as grp from t1;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
drop table if exists t1;
|
drop table if exists t1;
|
||||||
|
drop database if exists test2;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -203,6 +204,31 @@ where c >= 100;
|
|||||||
commit;
|
commit;
|
||||||
select * from t1 where c >= 100 order by a;
|
select * from t1 where c >= 100 order by a;
|
||||||
|
|
||||||
|
# alter table
|
||||||
|
|
||||||
|
select * from t1 order by a;
|
||||||
|
alter table t1 add x int;
|
||||||
|
select * from t1 order by a;
|
||||||
|
alter table t1 drop x;
|
||||||
|
select * from t1 order by a;
|
||||||
|
|
||||||
|
# multi db
|
||||||
|
|
||||||
|
create database test2;
|
||||||
|
use test2;
|
||||||
|
|
||||||
|
CREATE TABLE t2 (
|
||||||
|
a bigint unsigned NOT NULL PRIMARY KEY,
|
||||||
|
b int unsigned not null,
|
||||||
|
c int unsigned
|
||||||
|
) engine=ndbcluster;
|
||||||
|
|
||||||
|
insert into t2 values (1,1,1),(2,2,2);
|
||||||
|
select * from test.t1,t2 where test.t1.a = t2.a order by test.t1.a;
|
||||||
|
|
||||||
|
drop table t2;
|
||||||
|
use test;
|
||||||
|
|
||||||
# range scan delete
|
# range scan delete
|
||||||
delete from t1 where c >= 100;
|
delete from t1 where c >= 100;
|
||||||
commit;
|
commit;
|
||||||
|
@ -307,9 +307,11 @@ where user='mysqltest_1' || user='mysqltest_2' || user='mysqltest_3';
|
|||||||
flush privileges;
|
flush privileges;
|
||||||
|
|
||||||
#Bug #4374 SHOW TABLE STATUS FROM ignores collation_connection
|
#Bug #4374 SHOW TABLE STATUS FROM ignores collation_connection
|
||||||
set names latin1;
|
# This test fails on MAC OSX, so it is temporary disabled.
|
||||||
create database `ä`;
|
# This needs WL#1324 to be done.
|
||||||
create table `ä`.`ä` (a int) engine=heap;
|
#set names latin1;
|
||||||
--replace_column 7 # 8 # 9 #
|
#create database `ä`;
|
||||||
show table status from `ä` LIKE 'ä';
|
#create table `ä`.`ä` (a int) engine=heap;
|
||||||
drop database `ä`;
|
#--replace_column 7 # 8 # 9 #
|
||||||
|
#show table status from `ä` LIKE 'ä';
|
||||||
|
#drop database `ä`;
|
||||||
|
@ -1234,4 +1234,32 @@ select a,b from t1 where match(b) against ('Ball') > 0;
|
|||||||
select a from t2 where a in (select a from t1 where match(b) against ('Ball') > 0);
|
select a from t2 where a in (select a from t1 where match(b) against ('Ball') > 0);
|
||||||
drop table t1,t2;
|
drop table t1,t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Optimized IN with compound index
|
||||||
|
#
|
||||||
|
CREATE TABLE `t1` ( `aid` int(11) NOT NULL default '0', `bid` int(11) NOT NULL default '0', PRIMARY KEY (`aid`,`bid`));
|
||||||
|
CREATE TABLE `t2` ( `aid` int(11) NOT NULL default '0', `bid` int(11) NOT NULL default '0', PRIMARY KEY (`aid`,`bid`));
|
||||||
|
insert into t1 values (1,1),(1,2),(2,1),(2,2);
|
||||||
|
insert into t2 values (1,2),(2,2);
|
||||||
|
select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
|
||||||
|
alter table t2 drop primary key;
|
||||||
|
alter table t2 add key KEY1 (aid, bid);
|
||||||
|
select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
|
||||||
|
alter table t2 drop key KEY1;
|
||||||
|
alter table t2 add primary key (bid, aid);
|
||||||
|
select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
|
||||||
|
drop table t1,t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# resolving fields of grouped outer SELECT
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (howmanyvalues bigint, avalue int);
|
||||||
|
INSERT INTO t1 VALUES (1, 1),(2, 1),(2, 2),(3, 1),(3, 2),(3, 3),(4, 1),(4, 2),(4, 3),(4, 4);
|
||||||
|
SELECT howmanyvalues, count(*) from t1 group by howmanyvalues;
|
||||||
|
SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.howmanyvalues) as mycount from t1 a group by a.howmanyvalues;
|
||||||
|
CREATE INDEX t1_howmanyvalues_idx ON t1 (howmanyvalues);
|
||||||
|
SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues+1 = a.howmanyvalues+1) as mycount from t1 a group by a.howmanyvalues;
|
||||||
|
SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.howmanyvalues) as mycount from t1 a group by a.howmanyvalues;
|
||||||
|
-- error 1054
|
||||||
|
SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.avalue) as mycount from t1 a group by a.howmanyvalues;
|
||||||
|
drop table t1;
|
||||||
|
@ -234,14 +234,13 @@ private:
|
|||||||
// define blob table
|
// define blob table
|
||||||
static void getBlobTableName(char* btname, const NdbTableImpl* t, const NdbColumnImpl* c);
|
static void getBlobTableName(char* btname, const NdbTableImpl* t, const NdbColumnImpl* c);
|
||||||
static void getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnImpl* c);
|
static void getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnImpl* c);
|
||||||
// table name
|
|
||||||
char theBlobTableName[BlobTableNameSize];
|
|
||||||
// ndb api stuff
|
// ndb api stuff
|
||||||
Ndb* theNdb;
|
Ndb* theNdb;
|
||||||
NdbConnection* theNdbCon;
|
NdbConnection* theNdbCon;
|
||||||
NdbOperation* theNdbOp;
|
NdbOperation* theNdbOp;
|
||||||
NdbTableImpl* theTable;
|
NdbTableImpl* theTable;
|
||||||
NdbTableImpl* theAccessTable;
|
NdbTableImpl* theAccessTable;
|
||||||
|
NdbTableImpl* theBlobTable;
|
||||||
const NdbColumnImpl* theColumn;
|
const NdbColumnImpl* theColumn;
|
||||||
char theFillChar;
|
char theFillChar;
|
||||||
// sizes
|
// sizes
|
||||||
|
@ -144,6 +144,8 @@ public:
|
|||||||
FragAllLarge = 4 ///< Eight fragments per node group.
|
FragAllLarge = 4 ///< Eight fragments per node group.
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Table; // forward declaration
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class Column
|
* @class Column
|
||||||
@ -365,6 +367,8 @@ public:
|
|||||||
void setIndexOnlyStorage(bool);
|
void setIndexOnlyStorage(bool);
|
||||||
bool getIndexOnlyStorage() const;
|
bool getIndexOnlyStorage() const;
|
||||||
|
|
||||||
|
const Table * getBlobTable() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name ODBC Specific methods
|
* @name ODBC Specific methods
|
||||||
* @{
|
* @{
|
||||||
|
@ -140,7 +140,6 @@ void
|
|||||||
NdbBlob::init()
|
NdbBlob::init()
|
||||||
{
|
{
|
||||||
theState = Idle;
|
theState = Idle;
|
||||||
theBlobTableName[0] = 0;
|
|
||||||
theNdb = NULL;
|
theNdb = NULL;
|
||||||
theNdbCon = NULL;
|
theNdbCon = NULL;
|
||||||
theNdbOp = NULL;
|
theNdbOp = NULL;
|
||||||
@ -865,7 +864,7 @@ NdbBlob::readParts(char* buf, Uint32 part, Uint32 count)
|
|||||||
DBG("readParts part=" << part << " count=" << count);
|
DBG("readParts part=" << part << " count=" << count);
|
||||||
Uint32 n = 0;
|
Uint32 n = 0;
|
||||||
while (n < count) {
|
while (n < count) {
|
||||||
NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTableName);
|
NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTable);
|
||||||
if (tOp == NULL ||
|
if (tOp == NULL ||
|
||||||
tOp->readTuple() == -1 ||
|
tOp->readTuple() == -1 ||
|
||||||
setPartKeyValue(tOp, part + n) == -1 ||
|
setPartKeyValue(tOp, part + n) == -1 ||
|
||||||
@ -887,7 +886,7 @@ NdbBlob::insertParts(const char* buf, Uint32 part, Uint32 count)
|
|||||||
DBG("insertParts part=" << part << " count=" << count);
|
DBG("insertParts part=" << part << " count=" << count);
|
||||||
Uint32 n = 0;
|
Uint32 n = 0;
|
||||||
while (n < count) {
|
while (n < count) {
|
||||||
NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTableName);
|
NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTable);
|
||||||
if (tOp == NULL ||
|
if (tOp == NULL ||
|
||||||
tOp->insertTuple() == -1 ||
|
tOp->insertTuple() == -1 ||
|
||||||
setPartKeyValue(tOp, part + n) == -1 ||
|
setPartKeyValue(tOp, part + n) == -1 ||
|
||||||
@ -909,7 +908,7 @@ NdbBlob::updateParts(const char* buf, Uint32 part, Uint32 count)
|
|||||||
DBG("updateParts part=" << part << " count=" << count);
|
DBG("updateParts part=" << part << " count=" << count);
|
||||||
Uint32 n = 0;
|
Uint32 n = 0;
|
||||||
while (n < count) {
|
while (n < count) {
|
||||||
NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTableName);
|
NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTable);
|
||||||
if (tOp == NULL ||
|
if (tOp == NULL ||
|
||||||
tOp->updateTuple() == -1 ||
|
tOp->updateTuple() == -1 ||
|
||||||
setPartKeyValue(tOp, part + n) == -1 ||
|
setPartKeyValue(tOp, part + n) == -1 ||
|
||||||
@ -931,7 +930,7 @@ NdbBlob::deleteParts(Uint32 part, Uint32 count)
|
|||||||
DBG("deleteParts part=" << part << " count=" << count);
|
DBG("deleteParts part=" << part << " count=" << count);
|
||||||
Uint32 n = 0;
|
Uint32 n = 0;
|
||||||
while (n < count) {
|
while (n < count) {
|
||||||
NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTableName);
|
NdbOperation* tOp = theNdbCon->getNdbOperation(theBlobTable);
|
||||||
if (tOp == NULL ||
|
if (tOp == NULL ||
|
||||||
tOp->deleteTuple() == -1 ||
|
tOp->deleteTuple() == -1 ||
|
||||||
setPartKeyValue(tOp, part + n) == -1) {
|
setPartKeyValue(tOp, part + n) == -1) {
|
||||||
@ -1029,12 +1028,11 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
|
|||||||
// sanity check
|
// sanity check
|
||||||
assert((NDB_BLOB_HEAD_SIZE << 2) == sizeof(Head));
|
assert((NDB_BLOB_HEAD_SIZE << 2) == sizeof(Head));
|
||||||
assert(theColumn->m_attrSize * theColumn->m_arraySize == sizeof(Head) + theInlineSize);
|
assert(theColumn->m_attrSize * theColumn->m_arraySize == sizeof(Head) + theInlineSize);
|
||||||
getBlobTableName(theBlobTableName, theTable, theColumn);
|
|
||||||
const NdbDictionary::Table* bt;
|
const NdbDictionary::Table* bt;
|
||||||
const NdbDictionary::Column* bc;
|
const NdbDictionary::Column* bc;
|
||||||
if (thePartSize > 0) {
|
if (thePartSize > 0) {
|
||||||
if (theStripeSize == 0 ||
|
if (theStripeSize == 0 ||
|
||||||
(bt = theNdb->theDictionary->getTable(theBlobTableName)) == NULL ||
|
(bt = theColumn->getBlobTable()) == NULL ||
|
||||||
(bc = bt->getColumn("DATA")) == NULL ||
|
(bc = bt->getColumn("DATA")) == NULL ||
|
||||||
bc->getType() != partType ||
|
bc->getType() != partType ||
|
||||||
bc->getLength() != (int)thePartSize) {
|
bc->getLength() != (int)thePartSize) {
|
||||||
@ -1042,6 +1040,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
theBlobTable = & NdbTableImpl::getImpl(*bt);
|
||||||
// buffers
|
// buffers
|
||||||
theKeyBuf.alloc(theTable->m_sizeOfKeysInWords << 2);
|
theKeyBuf.alloc(theTable->m_sizeOfKeysInWords << 2);
|
||||||
theAccessKeyBuf.alloc(theAccessTable->m_sizeOfKeysInWords << 2);
|
theAccessKeyBuf.alloc(theAccessTable->m_sizeOfKeysInWords << 2);
|
||||||
|
@ -174,6 +174,14 @@ NdbDictionary::Column::getIndexOnlyStorage() const {
|
|||||||
return m_impl.m_indexOnly;
|
return m_impl.m_indexOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const NdbDictionary::Table *
|
||||||
|
NdbDictionary::Column::getBlobTable() const {
|
||||||
|
NdbTableImpl * t = m_impl.m_blobTable;
|
||||||
|
if (t)
|
||||||
|
return t->m_facade;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
NdbDictionary::Column::setAutoIncrement(bool val){
|
NdbDictionary::Column::setAutoIncrement(bool val){
|
||||||
m_impl.m_autoIncrement = val;
|
m_impl.m_autoIncrement = val;
|
||||||
|
@ -79,6 +79,7 @@ NdbColumnImpl::operator=(const NdbColumnImpl& col)
|
|||||||
m_attrSize = col.m_attrSize;
|
m_attrSize = col.m_attrSize;
|
||||||
m_arraySize = col.m_arraySize;
|
m_arraySize = col.m_arraySize;
|
||||||
m_keyInfoPos = col.m_keyInfoPos;
|
m_keyInfoPos = col.m_keyInfoPos;
|
||||||
|
m_blobTable = col.m_blobTable;
|
||||||
// Do not copy m_facade !!
|
// Do not copy m_facade !!
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@ -104,6 +105,7 @@ NdbColumnImpl::init()
|
|||||||
m_arraySize = 1,
|
m_arraySize = 1,
|
||||||
m_autoIncrement = false;
|
m_autoIncrement = false;
|
||||||
m_autoIncrementInitialValue = 1;
|
m_autoIncrementInitialValue = 1;
|
||||||
|
m_blobTable = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
NdbColumnImpl::~NdbColumnImpl()
|
NdbColumnImpl::~NdbColumnImpl()
|
||||||
@ -1211,7 +1213,6 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
|
|||||||
}
|
}
|
||||||
if (col->getBlobType())
|
if (col->getBlobType())
|
||||||
blobCount++;
|
blobCount++;
|
||||||
|
|
||||||
NdbColumnImpl * null = 0;
|
NdbColumnImpl * null = 0;
|
||||||
impl->m_columns.fill(attrDesc.AttributeId, null);
|
impl->m_columns.fill(attrDesc.AttributeId, null);
|
||||||
if(impl->m_columns[attrDesc.AttributeId] != 0){
|
if(impl->m_columns[attrDesc.AttributeId] != 0){
|
||||||
@ -1266,7 +1267,28 @@ NdbDictionaryImpl::createBlobTables(NdbTableImpl &t)
|
|||||||
NdbBlob::getBlobTable(bt, &t, &c);
|
NdbBlob::getBlobTable(bt, &t, &c);
|
||||||
if (createTable(bt) != 0)
|
if (createTable(bt) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
// Save BLOB table handle
|
||||||
|
NdbTableImpl * cachedBlobTable = getTable(bt.m_externalName.c_str());
|
||||||
|
c.m_blobTable = cachedBlobTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
NdbDictionaryImpl::addBlobTables(NdbTableImpl &t)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < t.m_columns.size(); i++) {
|
||||||
|
NdbColumnImpl & c = *t.m_columns[i];
|
||||||
|
if (! c.getBlobType() || c.getPartSize() == 0)
|
||||||
|
continue;
|
||||||
|
char btname[NdbBlob::BlobTableNameSize];
|
||||||
|
NdbBlob::getBlobTableName(btname, &t, &c);
|
||||||
|
// Save BLOB table handle
|
||||||
|
NdbTableImpl * cachedBlobTable = getTable(btname);;
|
||||||
|
c.m_blobTable = cachedBlobTable;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,6 +71,7 @@ public:
|
|||||||
bool m_autoIncrement;
|
bool m_autoIncrement;
|
||||||
Uint64 m_autoIncrementInitialValue;
|
Uint64 m_autoIncrementInitialValue;
|
||||||
BaseString m_defaultValue;
|
BaseString m_defaultValue;
|
||||||
|
NdbTableImpl * m_blobTable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal types and sizes, and aggregates
|
* Internal types and sizes, and aggregates
|
||||||
@ -362,6 +363,7 @@ public:
|
|||||||
|
|
||||||
int createTable(NdbTableImpl &t);
|
int createTable(NdbTableImpl &t);
|
||||||
int createBlobTables(NdbTableImpl &);
|
int createBlobTables(NdbTableImpl &);
|
||||||
|
int addBlobTables(NdbTableImpl &);
|
||||||
int alterTable(NdbTableImpl &t);
|
int alterTable(NdbTableImpl &t);
|
||||||
int dropTable(const char * name);
|
int dropTable(const char * name);
|
||||||
int dropTable(NdbTableImpl &);
|
int dropTable(NdbTableImpl &);
|
||||||
@ -616,7 +618,6 @@ NdbDictionaryImpl::getTableImpl(const char * internalTableName)
|
|||||||
|
|
||||||
if (ret == 0){
|
if (ret == 0){
|
||||||
ret = m_receiver.getTable(internalTableName, m_ndb.usingFullyQualifiedNames());
|
ret = m_receiver.getTable(internalTableName, m_ndb.usingFullyQualifiedNames());
|
||||||
|
|
||||||
m_globalHash->lock();
|
m_globalHash->lock();
|
||||||
m_globalHash->put(internalTableName, ret);
|
m_globalHash->put(internalTableName, ret);
|
||||||
m_globalHash->unlock();
|
m_globalHash->unlock();
|
||||||
@ -629,6 +630,8 @@ NdbDictionaryImpl::getTableImpl(const char * internalTableName)
|
|||||||
|
|
||||||
m_ndb.theFirstTupleId[ret->getTableId()] = ~0;
|
m_ndb.theFirstTupleId[ret->getTableId()] = ~0;
|
||||||
m_ndb.theLastTupleId[ret->getTableId()] = ~0;
|
m_ndb.theLastTupleId[ret->getTableId()] = ~0;
|
||||||
|
|
||||||
|
addBlobTables(*ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
70
sql/item.cc
70
sql/item.cc
@ -60,10 +60,10 @@ Item::Item():
|
|||||||
*/
|
*/
|
||||||
if (thd->lex->current_select)
|
if (thd->lex->current_select)
|
||||||
{
|
{
|
||||||
SELECT_LEX_NODE::enum_parsing_place place=
|
enum_parsing_place place=
|
||||||
thd->lex->current_select->parsing_place;
|
thd->lex->current_select->parsing_place;
|
||||||
if (place == SELECT_LEX_NODE::SELECT_LIST ||
|
if (place == SELECT_LIST ||
|
||||||
place == SELECT_LEX_NODE::IN_HAVING)
|
place == IN_HAVING)
|
||||||
thd->lex->current_select->select_n_having_items++;
|
thd->lex->current_select->select_n_having_items++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1233,21 +1233,34 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
|||||||
table_list= (last= sl)->get_table_list();
|
table_list= (last= sl)->get_table_list();
|
||||||
if (sl->resolve_mode == SELECT_LEX::INSERT_MODE && table_list)
|
if (sl->resolve_mode == SELECT_LEX::INSERT_MODE && table_list)
|
||||||
{
|
{
|
||||||
// it is primary INSERT st_select_lex => skip first table resolving
|
/*
|
||||||
|
it is primary INSERT st_select_lex => skip first table
|
||||||
|
resolving
|
||||||
|
*/
|
||||||
table_list= table_list->next;
|
table_list= table_list->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
Item_subselect *prev_subselect_item= prev_unit->item;
|
Item_subselect *prev_subselect_item= prev_unit->item;
|
||||||
if ((tmp= find_field_in_tables(thd, this,
|
enum_parsing_place place=
|
||||||
table_list, &where,
|
prev_subselect_item->parsing_place;
|
||||||
0)) != not_found_field)
|
/*
|
||||||
{
|
check table fields only if subquery used somewhere out of HAVING
|
||||||
if (!tmp)
|
or SELECT list or outer SELECT do not use groupping (i.e. tables
|
||||||
return -1;
|
are accessable)
|
||||||
prev_subselect_item->used_tables_cache|= tmp->table->map;
|
*/
|
||||||
prev_subselect_item->const_item_cache= 0;
|
if (((place != IN_HAVING &&
|
||||||
break;
|
place != SELECT_LIST) ||
|
||||||
}
|
(sl->with_sum_func == 0 && sl->group_list.elements == 0)) &&
|
||||||
|
(tmp= find_field_in_tables(thd, this,
|
||||||
|
table_list, &where,
|
||||||
|
0)) != not_found_field)
|
||||||
|
{
|
||||||
|
if (!tmp)
|
||||||
|
return -1;
|
||||||
|
prev_subselect_item->used_tables_cache|= tmp->table->map;
|
||||||
|
prev_subselect_item->const_item_cache= 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (sl->resolve_mode == SELECT_LEX::SELECT_MODE &&
|
if (sl->resolve_mode == SELECT_LEX::SELECT_MODE &&
|
||||||
(refer= find_item_in_list(this, sl->item_list, &counter,
|
(refer= find_item_in_list(this, sl->item_list, &counter,
|
||||||
REPORT_EXCEPT_NOT_FOUND)) !=
|
REPORT_EXCEPT_NOT_FOUND)) !=
|
||||||
@ -1906,16 +1919,25 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
|
|||||||
// it is primary INSERT st_select_lex => skip first table resolving
|
// it is primary INSERT st_select_lex => skip first table resolving
|
||||||
table_list= table_list->next;
|
table_list= table_list->next;
|
||||||
}
|
}
|
||||||
if ((tmp= find_field_in_tables(thd, this,
|
enum_parsing_place place=
|
||||||
table_list, &where,
|
prev_subselect_item->parsing_place;
|
||||||
0)) != not_found_field)
|
/*
|
||||||
{
|
check table fields only if subquery used somewhere out of HAVING
|
||||||
prev_subselect_item->used_tables_cache|= tmp->table->map;
|
or SELECT list or outer SELECT do not use groupping (i.e. tables
|
||||||
prev_subselect_item->const_item_cache= 0;
|
are accessable)
|
||||||
break;
|
*/
|
||||||
}
|
if (((place != IN_HAVING &&
|
||||||
|
place != SELECT_LIST) ||
|
||||||
// Reference is not found => depend from outer (or just error)
|
(sl->with_sum_func == 0 && sl->group_list.elements == 0)) &&
|
||||||
|
(tmp= find_field_in_tables(thd, this,
|
||||||
|
table_list, &where,
|
||||||
|
0)) != not_found_field)
|
||||||
|
{
|
||||||
|
prev_subselect_item->used_tables_cache|= tmp->table->map;
|
||||||
|
prev_subselect_item->const_item_cache= 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Reference is not found => depend from outer (or just error)
|
||||||
prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
|
prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
|
||||||
prev_subselect_item->const_item_cache= 0;
|
prev_subselect_item->const_item_cache= 0;
|
||||||
|
|
||||||
|
@ -63,12 +63,21 @@ void Item_subselect::init(st_select_lex *select_lex,
|
|||||||
=> we do not copy old_engine here
|
=> we do not copy old_engine here
|
||||||
*/
|
*/
|
||||||
engine= unit->item->engine;
|
engine= unit->item->engine;
|
||||||
|
parsing_place= unit->item->parsing_place;
|
||||||
unit->item->engine= 0;
|
unit->item->engine= 0;
|
||||||
unit->item= this;
|
unit->item= this;
|
||||||
engine->change_item(this, result);
|
engine->change_item(this, result);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
SELECT_LEX *outer_select= unit->outer_select();
|
||||||
|
/*
|
||||||
|
do not take into account expression inside aggregate functions because
|
||||||
|
they can access original table fields
|
||||||
|
*/
|
||||||
|
parsing_place= (outer_select->in_sum_expr ?
|
||||||
|
NO_MATTER :
|
||||||
|
outer_select->parsing_place);
|
||||||
if (select_lex->next_select())
|
if (select_lex->next_select())
|
||||||
engine= new subselect_union_engine(unit, result, this);
|
engine= new subselect_union_engine(unit, result, this);
|
||||||
else
|
else
|
||||||
@ -76,7 +85,7 @@ void Item_subselect::init(st_select_lex *select_lex,
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
SELECT_LEX *upper= unit->outer_select();
|
SELECT_LEX *upper= unit->outer_select();
|
||||||
if (upper->parsing_place == SELECT_LEX_NODE::IN_HAVING)
|
if (upper->parsing_place == IN_HAVING)
|
||||||
upper->subquery_in_having= 1;
|
upper->subquery_in_having= 1;
|
||||||
}
|
}
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
@ -1245,29 +1254,31 @@ int subselect_uniquesubquery_engine::exec()
|
|||||||
DBUG_ENTER("subselect_uniquesubquery_engine::exec");
|
DBUG_ENTER("subselect_uniquesubquery_engine::exec");
|
||||||
int error;
|
int error;
|
||||||
TABLE *table= tab->table;
|
TABLE *table= tab->table;
|
||||||
if ((tab->ref.key_err= (*tab->ref.key_copy)->copy()))
|
for (store_key **copy=tab->ref.key_copy ; *copy ; copy++)
|
||||||
{
|
{
|
||||||
table->status= STATUS_NOT_FOUND;
|
if (tab->ref.key_err= (*copy)->copy())
|
||||||
error= -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!table->file->inited)
|
|
||||||
table->file->ha_index_init(tab->ref.key);
|
|
||||||
error= table->file->index_read(table->record[0],
|
|
||||||
tab->ref.key_buff,
|
|
||||||
tab->ref.key_length,HA_READ_KEY_EXACT);
|
|
||||||
if (error && error != HA_ERR_KEY_NOT_FOUND)
|
|
||||||
error= report_error(table, error);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
error= 0;
|
table->status= STATUS_NOT_FOUND;
|
||||||
table->null_row= 0;
|
DBUG_RETURN(1);
|
||||||
((Item_in_subselect *) item)->value= (!table->status &&
|
|
||||||
(!cond || cond->val_int()) ? 1 :
|
|
||||||
0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!table->file->inited)
|
||||||
|
table->file->ha_index_init(tab->ref.key);
|
||||||
|
error= table->file->index_read(table->record[0],
|
||||||
|
tab->ref.key_buff,
|
||||||
|
tab->ref.key_length,HA_READ_KEY_EXACT);
|
||||||
|
if (error && error != HA_ERR_KEY_NOT_FOUND)
|
||||||
|
error= report_error(table, error);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error= 0;
|
||||||
|
table->null_row= 0;
|
||||||
|
((Item_in_subselect *) item)->value= (!table->status &&
|
||||||
|
(!cond || cond->val_int()) ? 1 :
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
DBUG_RETURN(error != 0);
|
DBUG_RETURN(error != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1295,55 +1306,56 @@ int subselect_indexsubquery_engine::exec()
|
|||||||
((Item_in_subselect *) item)->was_null= 0;
|
((Item_in_subselect *) item)->was_null= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*tab->ref.key_copy) && (tab->ref.key_err= (*tab->ref.key_copy)->copy()))
|
for (store_key **copy=tab->ref.key_copy ; *copy ; copy++)
|
||||||
{
|
{
|
||||||
table->status= STATUS_NOT_FOUND;
|
if (tab->ref.key_err= (*copy)->copy())
|
||||||
error= -1;
|
{
|
||||||
|
table->status= STATUS_NOT_FOUND;
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!table->file->inited)
|
||||||
|
table->file->ha_index_init(tab->ref.key);
|
||||||
|
error= table->file->index_read(table->record[0],
|
||||||
|
tab->ref.key_buff,
|
||||||
|
tab->ref.key_length,HA_READ_KEY_EXACT);
|
||||||
|
if (error && error != HA_ERR_KEY_NOT_FOUND)
|
||||||
|
error= report_error(table, error);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!table->file->inited)
|
for (;;)
|
||||||
table->file->ha_index_init(tab->ref.key);
|
|
||||||
error= table->file->index_read(table->record[0],
|
|
||||||
tab->ref.key_buff,
|
|
||||||
tab->ref.key_length,HA_READ_KEY_EXACT);
|
|
||||||
if (error && error != HA_ERR_KEY_NOT_FOUND)
|
|
||||||
error= report_error(table, error);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
for (;;)
|
error= 0;
|
||||||
|
table->null_row= 0;
|
||||||
|
if (!table->status)
|
||||||
{
|
{
|
||||||
error= 0;
|
if (!cond || cond->val_int())
|
||||||
table->null_row= 0;
|
{
|
||||||
if (!table->status)
|
if (null_finding)
|
||||||
{
|
((Item_in_subselect *) item)->was_null= 1;
|
||||||
if (!cond || cond->val_int())
|
else
|
||||||
{
|
((Item_in_subselect *) item)->value= 1;
|
||||||
if (null_finding)
|
break;
|
||||||
((Item_in_subselect *) item)->was_null= 1;
|
}
|
||||||
else
|
error= table->file->index_next_same(table->record[0],
|
||||||
((Item_in_subselect *) item)->value= 1;
|
tab->ref.key_buff,
|
||||||
break;
|
tab->ref.key_length);
|
||||||
}
|
if (error && error != HA_ERR_END_OF_FILE)
|
||||||
error= table->file->index_next_same(table->record[0],
|
{
|
||||||
tab->ref.key_buff,
|
error= report_error(table, error);
|
||||||
tab->ref.key_length);
|
break;
|
||||||
if (error && error != HA_ERR_END_OF_FILE)
|
}
|
||||||
{
|
}
|
||||||
error= report_error(table, error);
|
else
|
||||||
break;
|
{
|
||||||
}
|
if (!check_null || null_finding)
|
||||||
}
|
break; /* We don't need to check nulls */
|
||||||
else
|
*tab->ref.null_ref_key= 1;
|
||||||
{
|
null_finding= 1;
|
||||||
if (!check_null || null_finding)
|
/* Check if there exists a row with a null value in the index */
|
||||||
break; /* We don't need to check nulls */
|
if ((error= (safe_index_read(tab) == 1)))
|
||||||
*tab->ref.null_ref_key= 1;
|
break;
|
||||||
null_finding= 1;
|
|
||||||
/* Check if there exists a row with a null value in the index */
|
|
||||||
if ((error= (safe_index_read(tab) == 1)))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,8 @@ protected:
|
|||||||
table_map used_tables_cache;
|
table_map used_tables_cache;
|
||||||
/* allowed number of columns (1 for single value subqueries) */
|
/* allowed number of columns (1 for single value subqueries) */
|
||||||
uint max_columns;
|
uint max_columns;
|
||||||
|
/* where subquery is placed */
|
||||||
|
enum_parsing_place parsing_place;
|
||||||
/* work with 'substitution' */
|
/* work with 'substitution' */
|
||||||
bool have_to_be_excluded;
|
bool have_to_be_excluded;
|
||||||
/* cache of constant state */
|
/* cache of constant state */
|
||||||
|
15
sql/key.cc
15
sql/key.cc
@ -211,10 +211,17 @@ bool key_cmp_if_same(TABLE *table,const byte *key,uint idx,uint key_length)
|
|||||||
if (!(key_part->key_type & (FIELDFLAG_NUMBER+FIELDFLAG_BINARY+
|
if (!(key_part->key_type & (FIELDFLAG_NUMBER+FIELDFLAG_BINARY+
|
||||||
FIELDFLAG_PACK)))
|
FIELDFLAG_PACK)))
|
||||||
{
|
{
|
||||||
if (my_strnncoll(key_part->field->charset(),
|
CHARSET_INFO *cs= key_part->field->charset();
|
||||||
(const uchar*) key, length,
|
uint char_length= key_part->length / cs->mbmaxlen;
|
||||||
(const uchar*) table->record[0]+key_part->offset,
|
const byte *pos= table->record[0] + key_part->offset;
|
||||||
length))
|
if (length > char_length)
|
||||||
|
{
|
||||||
|
char_length= my_charpos(cs, pos, pos + length, char_length);
|
||||||
|
set_if_smaller(char_length, length);
|
||||||
|
}
|
||||||
|
if (cs->coll->strnncollsp(cs,
|
||||||
|
(const uchar*) key, length,
|
||||||
|
(const uchar*) pos, char_length))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if (memcmp(key,table->record[0]+key_part->offset,length))
|
else if (memcmp(key,table->record[0]+key_part->offset,length))
|
||||||
|
@ -293,6 +293,13 @@ void debug_sync_point(const char* lock_name, uint lock_timeout);
|
|||||||
*/
|
*/
|
||||||
#define MAX_DATE_REP_LENGTH 30
|
#define MAX_DATE_REP_LENGTH 30
|
||||||
|
|
||||||
|
enum enum_parsing_place
|
||||||
|
{
|
||||||
|
NO_MATTER,
|
||||||
|
IN_HAVING,
|
||||||
|
SELECT_LIST
|
||||||
|
};
|
||||||
|
|
||||||
struct st_table;
|
struct st_table;
|
||||||
class THD;
|
class THD;
|
||||||
class Item_arena;
|
class Item_arena;
|
||||||
|
@ -6004,11 +6004,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
|||||||
have_ndbcluster= SHOW_OPTION_DISABLED;
|
have_ndbcluster= SHOW_OPTION_DISABLED;
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
#ifdef HAVE_NDBCLUSTER_DB
|
|
||||||
case OPT_NDB_CONNECTSTRING:
|
|
||||||
have_ndbcluster= SHOW_OPTION_YES;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case OPT_INNODB:
|
case OPT_INNODB:
|
||||||
#ifdef HAVE_INNOBASE_DB
|
#ifdef HAVE_INNOBASE_DB
|
||||||
if (opt_innodb)
|
if (opt_innodb)
|
||||||
|
@ -1017,7 +1017,7 @@ void st_select_lex::init_query()
|
|||||||
select_n_having_items= 0;
|
select_n_having_items= 0;
|
||||||
prep_where= 0;
|
prep_where= 0;
|
||||||
subquery_in_having= explicit_limit= 0;
|
subquery_in_having= explicit_limit= 0;
|
||||||
parsing_place= SELECT_LEX_NODE::NO_MATTER;
|
parsing_place= NO_MATTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
void st_select_lex::init_select()
|
void st_select_lex::init_select()
|
||||||
|
@ -220,12 +220,6 @@ protected:
|
|||||||
*master, *slave, /* vertical links */
|
*master, *slave, /* vertical links */
|
||||||
*link_next, **link_prev; /* list of whole SELECT_LEX */
|
*link_next, **link_prev; /* list of whole SELECT_LEX */
|
||||||
public:
|
public:
|
||||||
enum enum_parsing_place
|
|
||||||
{
|
|
||||||
NO_MATTER,
|
|
||||||
IN_HAVING,
|
|
||||||
SELECT_LIST
|
|
||||||
};
|
|
||||||
|
|
||||||
ulong options;
|
ulong options;
|
||||||
/*
|
/*
|
||||||
|
@ -4190,7 +4190,10 @@ change_cond_ref_to_const(I_List<COND_CMP> *save_list,Item *and_father,
|
|||||||
Item *right_item= func->arguments()[1];
|
Item *right_item= func->arguments()[1];
|
||||||
Item_func::Functype functype= func->functype();
|
Item_func::Functype functype= func->functype();
|
||||||
|
|
||||||
if (right_item->eq(field,0) && left_item != value)
|
if (right_item->eq(field,0) && left_item != value &&
|
||||||
|
(left_item->result_type() != STRING_RESULT ||
|
||||||
|
value->result_type() != STRING_RESULT ||
|
||||||
|
left_item->collation.collation == value->collation.collation))
|
||||||
{
|
{
|
||||||
Item *tmp=value->new_item();
|
Item *tmp=value->new_item();
|
||||||
if (tmp)
|
if (tmp)
|
||||||
@ -4208,7 +4211,10 @@ change_cond_ref_to_const(I_List<COND_CMP> *save_list,Item *and_father,
|
|||||||
func->set_cmp_func();
|
func->set_cmp_func();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (left_item->eq(field,0) && right_item != value)
|
else if (left_item->eq(field,0) && right_item != value &&
|
||||||
|
(right_item->result_type() != STRING_RESULT ||
|
||||||
|
value->result_type() != STRING_RESULT ||
|
||||||
|
right_item->collation.collation == value->collation.collation))
|
||||||
{
|
{
|
||||||
Item *tmp=value->new_item();
|
Item *tmp=value->new_item();
|
||||||
if (tmp)
|
if (tmp)
|
||||||
|
@ -1113,11 +1113,11 @@ create_select:
|
|||||||
lex->sql_command= SQLCOM_REPLACE_SELECT;
|
lex->sql_command= SQLCOM_REPLACE_SELECT;
|
||||||
lex->current_select->table_list.save_and_clear(&lex->save_list);
|
lex->current_select->table_list.save_and_clear(&lex->save_list);
|
||||||
mysql_init_select(lex);
|
mysql_init_select(lex);
|
||||||
lex->current_select->parsing_place= SELECT_LEX_NODE::SELECT_LIST;
|
lex->current_select->parsing_place= SELECT_LIST;
|
||||||
}
|
}
|
||||||
select_options select_item_list
|
select_options select_item_list
|
||||||
{
|
{
|
||||||
Select->parsing_place= SELECT_LEX_NODE::NO_MATTER;
|
Select->parsing_place= NO_MATTER;
|
||||||
}
|
}
|
||||||
opt_select_from
|
opt_select_from
|
||||||
{ Lex->current_select->table_list.push_front(&Lex->save_list); }
|
{ Lex->current_select->table_list.push_front(&Lex->save_list); }
|
||||||
@ -2376,11 +2376,11 @@ select_part2:
|
|||||||
lex->lock_option= TL_READ;
|
lex->lock_option= TL_READ;
|
||||||
if (sel->linkage != UNION_TYPE)
|
if (sel->linkage != UNION_TYPE)
|
||||||
mysql_init_select(lex);
|
mysql_init_select(lex);
|
||||||
lex->current_select->parsing_place= SELECT_LEX_NODE::SELECT_LIST;
|
lex->current_select->parsing_place= SELECT_LIST;
|
||||||
}
|
}
|
||||||
select_options select_item_list
|
select_options select_item_list
|
||||||
{
|
{
|
||||||
Select->parsing_place= SELECT_LEX_NODE::NO_MATTER;
|
Select->parsing_place= NO_MATTER;
|
||||||
}
|
}
|
||||||
select_into select_lock_type;
|
select_into select_lock_type;
|
||||||
|
|
||||||
@ -3444,11 +3444,11 @@ select_derived:
|
|||||||
YYABORT;
|
YYABORT;
|
||||||
mysql_init_select(lex);
|
mysql_init_select(lex);
|
||||||
lex->current_select->linkage= DERIVED_TABLE_TYPE;
|
lex->current_select->linkage= DERIVED_TABLE_TYPE;
|
||||||
lex->current_select->parsing_place= SELECT_LEX_NODE::SELECT_LIST;
|
lex->current_select->parsing_place= SELECT_LIST;
|
||||||
}
|
}
|
||||||
select_options select_item_list
|
select_options select_item_list
|
||||||
{
|
{
|
||||||
Select->parsing_place= SELECT_LEX_NODE::NO_MATTER;
|
Select->parsing_place= NO_MATTER;
|
||||||
}
|
}
|
||||||
opt_select_from union_opt
|
opt_select_from union_opt
|
||||||
;
|
;
|
||||||
@ -3578,13 +3578,13 @@ having_clause:
|
|||||||
/* empty */
|
/* empty */
|
||||||
| HAVING
|
| HAVING
|
||||||
{
|
{
|
||||||
Select->parsing_place= SELECT_LEX_NODE::IN_HAVING;
|
Select->parsing_place= IN_HAVING;
|
||||||
}
|
}
|
||||||
expr
|
expr
|
||||||
{
|
{
|
||||||
SELECT_LEX *sel= Select;
|
SELECT_LEX *sel= Select;
|
||||||
sel->having= $3;
|
sel->having= $3;
|
||||||
sel->parsing_place= SELECT_LEX_NODE::NO_MATTER;
|
sel->parsing_place= NO_MATTER;
|
||||||
if ($3)
|
if ($3)
|
||||||
$3->top_level_item();
|
$3->top_level_item();
|
||||||
}
|
}
|
||||||
@ -4819,7 +4819,7 @@ simple_ident:
|
|||||||
ident
|
ident
|
||||||
{
|
{
|
||||||
SELECT_LEX *sel=Select;
|
SELECT_LEX *sel=Select;
|
||||||
$$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING ||
|
$$= (sel->parsing_place != IN_HAVING ||
|
||||||
sel->get_in_sum_expr() > 0) ?
|
sel->get_in_sum_expr() > 0) ?
|
||||||
(Item*) new Item_field(NullS,NullS,$1.str) :
|
(Item*) new Item_field(NullS,NullS,$1.str) :
|
||||||
(Item*) new Item_ref(0,0, NullS,NullS,$1.str);
|
(Item*) new Item_ref(0,0, NullS,NullS,$1.str);
|
||||||
@ -4835,7 +4835,7 @@ simple_ident:
|
|||||||
ER(ER_TABLENAME_NOT_ALLOWED_HERE),
|
ER(ER_TABLENAME_NOT_ALLOWED_HERE),
|
||||||
MYF(0), $1.str, thd->where);
|
MYF(0), $1.str, thd->where);
|
||||||
}
|
}
|
||||||
$$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING ||
|
$$= (sel->parsing_place != IN_HAVING ||
|
||||||
sel->get_in_sum_expr() > 0) ?
|
sel->get_in_sum_expr() > 0) ?
|
||||||
(Item*) new Item_field(NullS,$1.str,$3.str) :
|
(Item*) new Item_field(NullS,$1.str,$3.str) :
|
||||||
(Item*) new Item_ref(0,0,NullS,$1.str,$3.str);
|
(Item*) new Item_ref(0,0,NullS,$1.str,$3.str);
|
||||||
@ -4851,7 +4851,7 @@ simple_ident:
|
|||||||
ER(ER_TABLENAME_NOT_ALLOWED_HERE),
|
ER(ER_TABLENAME_NOT_ALLOWED_HERE),
|
||||||
MYF(0), $2.str, thd->where);
|
MYF(0), $2.str, thd->where);
|
||||||
}
|
}
|
||||||
$$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING ||
|
$$= (sel->parsing_place != IN_HAVING ||
|
||||||
sel->get_in_sum_expr() > 0) ?
|
sel->get_in_sum_expr() > 0) ?
|
||||||
(Item*) new Item_field(NullS,$2.str,$4.str) :
|
(Item*) new Item_field(NullS,$2.str,$4.str) :
|
||||||
(Item*) new Item_ref(0,0,NullS,$2.str,$4.str);
|
(Item*) new Item_ref(0,0,NullS,$2.str,$4.str);
|
||||||
@ -4867,7 +4867,7 @@ simple_ident:
|
|||||||
ER(ER_TABLENAME_NOT_ALLOWED_HERE),
|
ER(ER_TABLENAME_NOT_ALLOWED_HERE),
|
||||||
MYF(0), $3.str, thd->where);
|
MYF(0), $3.str, thd->where);
|
||||||
}
|
}
|
||||||
$$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING ||
|
$$= (sel->parsing_place != IN_HAVING ||
|
||||||
sel->get_in_sum_expr() > 0) ?
|
sel->get_in_sum_expr() > 0) ?
|
||||||
(Item*) new Item_field((YYTHD->client_capabilities &
|
(Item*) new Item_field((YYTHD->client_capabilities &
|
||||||
CLIENT_NO_SCHEMA ? NullS : $1.str),
|
CLIENT_NO_SCHEMA ? NullS : $1.str),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user