Merge tulin@bk-internal.mysql.com:/home/bk/mysql-4.1
into poseidon.ndb.mysql.com:/home/tomas/mysql-4.1
This commit is contained in:
commit
69ea046b06
@ -1007,3 +1007,4 @@ tests/mysql_client_test
|
|||||||
libmysqld/examples/mysql_client_test.c
|
libmysqld/examples/mysql_client_test.c
|
||||||
libmysqld/examples/mysql_client_test_embedded
|
libmysqld/examples/mysql_client_test_embedded
|
||||||
libmysqld/examples/mysqltest_embedded
|
libmysqld/examples/mysqltest_embedded
|
||||||
|
support-files/ndb-config-2-node.ini
|
||||||
|
@ -109,6 +109,12 @@ sub add_copyright
|
|||||||
$line_copyright= "! ";
|
$line_copyright= "! ";
|
||||||
$end_copyright= "";
|
$end_copyright= "";
|
||||||
}
|
}
|
||||||
|
elsif ($ARGV =~ /\.sql$/)
|
||||||
|
{
|
||||||
|
$start_copyright="-- ";
|
||||||
|
$line_copyright= "-- ";
|
||||||
|
$end_copyright= "";
|
||||||
|
}
|
||||||
elsif ($ARGV =~ /\.asm$/)
|
elsif ($ARGV =~ /\.asm$/)
|
||||||
{
|
{
|
||||||
$start_copyright="; ";
|
$start_copyright="; ";
|
||||||
|
@ -47,7 +47,7 @@ dist-hook:
|
|||||||
$(distdir)/std_data
|
$(distdir)/std_data
|
||||||
$(INSTALL_DATA) $(srcdir)/t/*.test $(srcdir)/t/*.opt $(srcdir)/t/*.sh $(srcdir)/t/*.slave-mi $(distdir)/t
|
$(INSTALL_DATA) $(srcdir)/t/*.test $(srcdir)/t/*.opt $(srcdir)/t/*.sh $(srcdir)/t/*.slave-mi $(distdir)/t
|
||||||
$(INSTALL_DATA) $(srcdir)/include/*.inc $(distdir)/include
|
$(INSTALL_DATA) $(srcdir)/include/*.inc $(distdir)/include
|
||||||
$(INSTALL_DATA) $(srcdir)/r/*.result $(srcdir)/r/*.require $(distdir)/r
|
$(INSTALL_DATA) $(srcdir)/r/*.result $(srcdir)/r/*.result.es $(srcdir)/r/*.require $(distdir)/r
|
||||||
$(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(distdir)/std_data
|
$(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(distdir)/std_data
|
||||||
$(INSTALL_DATA) $(srcdir)/std_data/*.dat $(srcdir)/std_data/*.000001 $(distdir)/std_data
|
$(INSTALL_DATA) $(srcdir)/std_data/*.dat $(srcdir)/std_data/*.000001 $(distdir)/std_data
|
||||||
$(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(distdir)/std_data
|
$(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(distdir)/std_data
|
||||||
@ -65,7 +65,7 @@ install-data-local:
|
|||||||
$(INSTALL_DATA) $(srcdir)/t/*.opt $(DESTDIR)$(testdir)/t
|
$(INSTALL_DATA) $(srcdir)/t/*.opt $(DESTDIR)$(testdir)/t
|
||||||
$(INSTALL_DATA) $(srcdir)/t/*.sh $(DESTDIR)$(testdir)/t
|
$(INSTALL_DATA) $(srcdir)/t/*.sh $(DESTDIR)$(testdir)/t
|
||||||
$(INSTALL_DATA) $(srcdir)/t/*.slave-mi $(DESTDIR)$(testdir)/t
|
$(INSTALL_DATA) $(srcdir)/t/*.slave-mi $(DESTDIR)$(testdir)/t
|
||||||
$(INSTALL_DATA) $(srcdir)/r/*.result $(DESTDIR)$(testdir)/r
|
$(INSTALL_DATA) $(srcdir)/r/*.result $(srcdir)/r/*.result.es $(DESTDIR)$(testdir)/r
|
||||||
$(INSTALL_DATA) $(srcdir)/r/*.require $(DESTDIR)$(testdir)/r
|
$(INSTALL_DATA) $(srcdir)/r/*.require $(DESTDIR)$(testdir)/r
|
||||||
$(INSTALL_DATA) $(srcdir)/include/*.inc $(DESTDIR)$(testdir)/include
|
$(INSTALL_DATA) $(srcdir)/include/*.inc $(DESTDIR)$(testdir)/include
|
||||||
$(INSTALL_DATA) $(srcdir)/std_data/*.dat $(DESTDIR)$(testdir)/std_data
|
$(INSTALL_DATA) $(srcdir)/std_data/*.dat $(DESTDIR)$(testdir)/std_data
|
||||||
|
@ -194,8 +194,8 @@ MY_LOG_DIR="$MYSQL_TEST_DIR/var/log"
|
|||||||
#
|
#
|
||||||
# Set LD_LIBRARY_PATH if we are using shared libraries
|
# Set LD_LIBRARY_PATH if we are using shared libraries
|
||||||
#
|
#
|
||||||
LD_LIBRARY_PATH="$BASEDIR/lib:$BASEDIR/libmysql/.libs:$LD_LIBRARY_PATH"
|
LD_LIBRARY_PATH="$BASEDIR/lib:$BASEDIR/libmysql/.libs:$BASEDIR/zlib/.libs:$LD_LIBRARY_PATH"
|
||||||
DYLD_LIBRARY_PATH="$BASEDIR/lib:$BASEDIR/libmysql/.libs:$DYLD_LIBRARY_PATH"
|
DYLD_LIBRARY_PATH="$BASEDIR/lib:$BASEDIR/libmysql/.libs:$BASEDIR/zlib/.libs:$DYLD_LIBRARY_PATH"
|
||||||
export LD_LIBRARY_PATH DYLD_LIBRARY_PATH
|
export LD_LIBRARY_PATH DYLD_LIBRARY_PATH
|
||||||
|
|
||||||
MASTER_RUNNING=0
|
MASTER_RUNNING=0
|
||||||
|
@ -655,9 +655,9 @@ insert into t1 (a,b) values (1,2),(1,3),(2,5);
|
|||||||
select a, 0.1*0+1 r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2=1;
|
select a, 0.1*0+1 r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2=1;
|
||||||
a r2 r1
|
a r2 r1
|
||||||
1 1.0 2
|
1 1.0 2
|
||||||
select a, rand()*0+1 r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2=1;
|
select a, round(rand(100)*10) r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2<=2;
|
||||||
a r2 r1
|
a r2 r1
|
||||||
1 1 2
|
1 2 2
|
||||||
select a,sum(b) from t1 where a=1 group by c;
|
select a,sum(b) from t1 where a=1 group by c;
|
||||||
a sum(b)
|
a sum(b)
|
||||||
1 5
|
1 5
|
||||||
|
@ -1425,7 +1425,7 @@ Note 1003 (select test.t1.s1 AS `s1` from test.t1)
|
|||||||
s1
|
s1
|
||||||
tttt
|
tttt
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (s1 char(5) not null, index s1(s1));
|
create table t1 (s1 char(5), index s1(s1));
|
||||||
create table t2 (s1 char(5), index s1(s1));
|
create table t2 (s1 char(5), index s1(s1));
|
||||||
insert into t1 values ('a1'),('a2'),('a3');
|
insert into t1 values ('a1'),('a2'),('a3');
|
||||||
insert into t2 values ('a1'),('a2');
|
insert into t2 values ('a1'),('a2');
|
||||||
@ -1451,25 +1451,25 @@ a2 1
|
|||||||
a3 1
|
a3 1
|
||||||
explain extended select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
|
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
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY t1 index NULL s1 5 NULL 3 Using index
|
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
|
||||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
||||||
Warnings:
|
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 chicking 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 chicking NULL)))) AS `s1 NOT IN (SELECT s1 FROM t2)` from test.t1
|
||||||
explain extended select s1, s1 = ANY (SELECT s1 FROM t2) from 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
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY t1 index NULL s1 5 NULL 3 Using index
|
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
|
||||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
||||||
Warnings:
|
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 chicking 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 chicking NULL))) AS `s1 = ANY (SELECT s1 FROM t2)` from test.t1
|
||||||
explain extended select s1, s1 <> ALL (SELECT s1 FROM t2) from 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
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY t1 index NULL s1 5 NULL 3 Using index
|
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
|
||||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 Using index
|
||||||
Warnings:
|
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 chicking 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 chicking NULL)))) AS `s1 <> ALL (SELECT s1 FROM t2)` from test.t1
|
||||||
explain extended select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
|
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
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 PRIMARY t1 index NULL s1 5 NULL 3 Using index
|
1 PRIMARY t1 index NULL s1 6 NULL 3 Using index
|
||||||
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 1 Using index; Using where
|
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 1 Using index; Using where
|
||||||
Warnings:
|
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 chicking 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 chicking NULL where (test.t2.s1 < _latin1'a2'))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from test.t1
|
||||||
@ -2125,34 +2125,6 @@ SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1
|
|||||||
c
|
c
|
||||||
Oceania
|
Oceania
|
||||||
drop table t1;
|
drop table t1;
|
||||||
CREATE TABLE t1 ( f1 BIGINT );
|
|
||||||
INSERT INTO t1 SET f1= NULL;
|
|
||||||
INSERT INTO t1 SET f1= 1;
|
|
||||||
CREATE TABLE t2 ( f1 BIGINT );
|
|
||||||
SELECT f1 FROM t1
|
|
||||||
WHERE f1 <> ALL ( SELECT f1 FROM t2 );
|
|
||||||
f1
|
|
||||||
NULL
|
|
||||||
1
|
|
||||||
INSERT INTO t2 VALUES (1), (2);
|
|
||||||
SELECT f1 FROM t1
|
|
||||||
WHERE f1 <> ALL ( SELECT f1 FROM t2 WHERE f1 > 2 );
|
|
||||||
f1
|
|
||||||
NULL
|
|
||||||
1
|
|
||||||
SELECT f1 FROM t1
|
|
||||||
WHERE f1 <> ALL ( SELECT f1 FROM t2 WHERE f1 > 2
|
|
||||||
UNION
|
|
||||||
SELECT f1 FROM t2 WHERE f1 > 3);
|
|
||||||
f1
|
|
||||||
NULL
|
|
||||||
1
|
|
||||||
SELECT f1 FROM t1
|
|
||||||
WHERE f1 <> ALL ( SELECT SUM(f1) AS sf1 FROM t2 HAVING sf1 > 10000);
|
|
||||||
f1
|
|
||||||
NULL
|
|
||||||
1
|
|
||||||
drop table t1,t2;
|
|
||||||
create table t1 (a1 int);
|
create table t1 (a1 int);
|
||||||
create table t2 (b1 int);
|
create table t2 (b1 int);
|
||||||
select * from t1 where a2 > any(select b1 from t2);
|
select * from t1 where a2 > any(select b1 from t2);
|
||||||
|
@ -109,8 +109,8 @@ select @a:=0;
|
|||||||
select @a, @a:=@a+count(*), count(*), @a from t1 group by i;
|
select @a, @a:=@a+count(*), count(*), @a from t1 group by i;
|
||||||
@a @a:=@a+count(*) count(*) @a
|
@a @a:=@a+count(*) count(*) @a
|
||||||
0 1 1 0
|
0 1 1 0
|
||||||
0 3 2 0
|
0 2 2 0
|
||||||
0 6 3 0
|
0 3 3 0
|
||||||
select @a:=0;
|
select @a:=0;
|
||||||
@a:=0
|
@a:=0
|
||||||
0
|
0
|
||||||
|
@ -480,7 +480,8 @@ drop table t1;
|
|||||||
create table t1 (a integer, b integer, c integer);
|
create table t1 (a integer, b integer, c integer);
|
||||||
insert into t1 (a,b) values (1,2),(1,3),(2,5);
|
insert into t1 (a,b) values (1,2),(1,3),(2,5);
|
||||||
select a, 0.1*0+1 r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2=1;
|
select a, 0.1*0+1 r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2=1;
|
||||||
select a, rand()*0+1 r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2=1;
|
# rand(100)*10 will be < 2 only for the first row (of 6)
|
||||||
|
select a, round(rand(100)*10) r2, sum(1) r1 from t1 where a = 1 group by a having r1>1 and r2<=2;
|
||||||
select a,sum(b) from t1 where a=1 group by c;
|
select a,sum(b) from t1 where a=1 group by c;
|
||||||
select a*sum(b) from t1 where a=1 group by c;
|
select a*sum(b) from t1 where a=1 group by c;
|
||||||
select sum(a)*sum(b) from t1 where a=1 group by c;
|
select sum(a)*sum(b) from t1 where a=1 group by c;
|
||||||
|
@ -889,7 +889,7 @@ drop table t1;
|
|||||||
#
|
#
|
||||||
# IN optimisation test results
|
# IN optimisation test results
|
||||||
#
|
#
|
||||||
create table t1 (s1 char(5) not null, index s1(s1));
|
create table t1 (s1 char(5), index s1(s1));
|
||||||
create table t2 (s1 char(5), index s1(s1));
|
create table t2 (s1 char(5), index s1(s1));
|
||||||
insert into t1 values ('a1'),('a2'),('a3');
|
insert into t1 values ('a1'),('a2'),('a3');
|
||||||
insert into t2 values ('a1'),('a2');
|
insert into t2 values ('a1'),('a2');
|
||||||
@ -1387,34 +1387,6 @@ INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','M
|
|||||||
SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200);
|
SELECT DISTINCT Continent AS c FROM t1 WHERE Code <> SOME ( SELECT Code FROM t1 WHERE Continent = c AND Population < 200);
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
#
|
|
||||||
# Test cases for bug #7351:
|
|
||||||
# quantified predicate with subquery returning empty result set
|
|
||||||
#
|
|
||||||
|
|
||||||
CREATE TABLE t1 ( f1 BIGINT );
|
|
||||||
INSERT INTO t1 SET f1= NULL;
|
|
||||||
INSERT INTO t1 SET f1= 1;
|
|
||||||
CREATE TABLE t2 ( f1 BIGINT );
|
|
||||||
|
|
||||||
SELECT f1 FROM t1
|
|
||||||
WHERE f1 <> ALL ( SELECT f1 FROM t2 );
|
|
||||||
|
|
||||||
INSERT INTO t2 VALUES (1), (2);
|
|
||||||
|
|
||||||
SELECT f1 FROM t1
|
|
||||||
WHERE f1 <> ALL ( SELECT f1 FROM t2 WHERE f1 > 2 );
|
|
||||||
|
|
||||||
SELECT f1 FROM t1
|
|
||||||
WHERE f1 <> ALL ( SELECT f1 FROM t2 WHERE f1 > 2
|
|
||||||
UNION
|
|
||||||
SELECT f1 FROM t2 WHERE f1 > 3);
|
|
||||||
|
|
||||||
SELECT f1 FROM t1
|
|
||||||
WHERE f1 <> ALL ( SELECT SUM(f1) AS sf1 FROM t2 HAVING sf1 > 10000);
|
|
||||||
|
|
||||||
drop table t1,t2;
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Test for BUG#7885: Server crash when 'any' subselect compared to
|
# Test for BUG#7885: Server crash when 'any' subselect compared to
|
||||||
# non-existant field.
|
# non-existant field.
|
||||||
|
@ -493,6 +493,24 @@ sub print_insert_header
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print <<EOF;
|
||||||
|
-- Copyright (C) 2000-2005 MySQL AB
|
||||||
|
--
|
||||||
|
-- This program is free software; you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU General Public License as published by
|
||||||
|
-- the Free Software Foundation; either version 2 of the License, or
|
||||||
|
-- (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- This program is distributed in the hope that it will be useful,
|
||||||
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
-- GNU General Public License for more details.
|
||||||
|
--
|
||||||
|
-- You should have received a copy of the GNU General Public License
|
||||||
|
-- along with this program; if not, write to the Free Software
|
||||||
|
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
EOF
|
||||||
print "delete from help_topic;\n";
|
print "delete from help_topic;\n";
|
||||||
print "delete from help_category;\n";
|
print "delete from help_category;\n";
|
||||||
print "delete from help_keyword;\n";
|
print "delete from help_keyword;\n";
|
||||||
|
52
sql/item.cc
52
sql/item.cc
@ -295,6 +295,58 @@ CHARSET_INFO *Item::default_charset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Move SUM items out from item tree and replace with reference
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
split_sum_func2()
|
||||||
|
thd Thread handler
|
||||||
|
ref_pointer_array Pointer to array of reference fields
|
||||||
|
fields All fields in select
|
||||||
|
ref Pointer to item
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
This is from split_sum_func2() for items that should be split
|
||||||
|
|
||||||
|
All found SUM items are added FIRST in the fields list and
|
||||||
|
we replace the item with a reference.
|
||||||
|
|
||||||
|
thd->fatal_error() may be called if we are out of memory
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
void Item::split_sum_func2(THD *thd, Item **ref_pointer_array,
|
||||||
|
List<Item> &fields, Item **ref)
|
||||||
|
{
|
||||||
|
if (type() != SUM_FUNC_ITEM && with_sum_func)
|
||||||
|
{
|
||||||
|
/* Will split complicated items and ignore simple ones */
|
||||||
|
split_sum_func(thd, ref_pointer_array, fields);
|
||||||
|
}
|
||||||
|
else if ((type() == SUM_FUNC_ITEM ||
|
||||||
|
(used_tables() & ~PARAM_TABLE_BIT)) &&
|
||||||
|
type() != REF_ITEM)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Replace item with a reference so that we can easily calculate
|
||||||
|
it (in case of sum functions) or copy it (in case of fields)
|
||||||
|
|
||||||
|
The test above is to ensure we don't do a reference for things
|
||||||
|
that are constants (PARAM_TABLE_BIT is in effect a constant)
|
||||||
|
or already referenced (for example an item in HAVING)
|
||||||
|
*/
|
||||||
|
uint el= fields.elements;
|
||||||
|
Item *new_item;
|
||||||
|
ref_pointer_array[el]= this;
|
||||||
|
if (!(new_item= new Item_ref(ref_pointer_array + el, 0, name)))
|
||||||
|
return; // fatal_error is set
|
||||||
|
fields.push_front(this);
|
||||||
|
ref_pointer_array[el]= this;
|
||||||
|
thd->change_item_tree(ref, new_item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Aggregate two collations together taking
|
Aggregate two collations together taking
|
||||||
into account their coercibility (aka derivation):
|
into account their coercibility (aka derivation):
|
||||||
|
@ -262,6 +262,9 @@ public:
|
|||||||
virtual void update_used_tables() {}
|
virtual void update_used_tables() {}
|
||||||
virtual void split_sum_func(THD *thd, Item **ref_pointer_array,
|
virtual void split_sum_func(THD *thd, Item **ref_pointer_array,
|
||||||
List<Item> &fields) {}
|
List<Item> &fields) {}
|
||||||
|
/* Called for items that really have to be split */
|
||||||
|
void split_sum_func2(THD *thd, Item **ref_pointer_array, List<Item> &fields,
|
||||||
|
Item **ref);
|
||||||
virtual bool get_date(TIME *ltime,uint fuzzydate);
|
virtual bool get_date(TIME *ltime,uint fuzzydate);
|
||||||
virtual bool get_time(TIME *ltime);
|
virtual bool get_time(TIME *ltime);
|
||||||
virtual bool get_date_result(TIME *ltime,uint fuzzydate)
|
virtual bool get_date_result(TIME *ltime,uint fuzzydate)
|
||||||
|
@ -636,13 +636,12 @@ longlong Item_in_optimizer::val_int()
|
|||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
cache->store(args[0]);
|
cache->store(args[0]);
|
||||||
longlong tmp= args[1]->val_int_result();
|
|
||||||
if (cache->null_value)
|
if (cache->null_value)
|
||||||
{
|
{
|
||||||
if (tmp)
|
|
||||||
null_value= 1;
|
null_value= 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
longlong tmp= args[1]->val_int_result();
|
||||||
null_value= args[1]->null_value;
|
null_value= args[1]->null_value;
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
@ -1982,16 +1981,6 @@ bool Item_cond::walk(Item_processor processor, byte *arg)
|
|||||||
so that we can easily find and calculate them.
|
so that we can easily find and calculate them.
|
||||||
(Calculation done by update_sum_func() and copy_sum_funcs() in
|
(Calculation done by update_sum_func() and copy_sum_funcs() in
|
||||||
sql_select.cc)
|
sql_select.cc)
|
||||||
|
|
||||||
All found SUM items are added FIRST in the fields list and
|
|
||||||
we replace the item with a reference.
|
|
||||||
|
|
||||||
We also replace all functions without side effects (like RAND() or UDF's)
|
|
||||||
that uses columns as arguments.
|
|
||||||
For functions with side effects, we just remember any fields referred
|
|
||||||
by the function to ensure that we get a copy of the field value for the
|
|
||||||
first accepted row. This ensures that we can do things like
|
|
||||||
SELECT a*SUM(b) FROM t1 WHERE a=1
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
|
void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
|
||||||
@ -1999,38 +1988,8 @@ void Item_cond::split_sum_func(THD *thd, Item **ref_pointer_array,
|
|||||||
{
|
{
|
||||||
List_iterator<Item> li(list);
|
List_iterator<Item> li(list);
|
||||||
Item *item;
|
Item *item;
|
||||||
used_tables_cache=0;
|
|
||||||
const_item_cache=0;
|
|
||||||
while ((item= li++))
|
while ((item= li++))
|
||||||
{
|
item->split_sum_func2(thd, ref_pointer_array, fields, li.ref());
|
||||||
/* with_sum_func is set for items that contains a SUM expression */
|
|
||||||
if (item->type() != SUM_FUNC_ITEM &&
|
|
||||||
(item->with_sum_func ||
|
|
||||||
(item->used_tables() & PSEUDO_TABLE_BITS)))
|
|
||||||
item->split_sum_func(thd, ref_pointer_array, fields);
|
|
||||||
else if (item->type() == SUM_FUNC_ITEM ||
|
|
||||||
(item->used_tables() && item->type() != REF_ITEM))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Replace item with a reference so that we can easily calculate
|
|
||||||
it (in case of sum functions) or copy it (in case of fields)
|
|
||||||
|
|
||||||
The test above is to ensure we don't do a reference for things
|
|
||||||
that are constants or are not yet calculated as in:
|
|
||||||
SELECT RAND() as r1, SUM(a) as r2 FROM t1 HAVING r1 > 1 AND r2 > 0
|
|
||||||
*/
|
|
||||||
Item **ref= li.ref();
|
|
||||||
uint el= fields.elements;
|
|
||||||
ref_pointer_array[el]= item;
|
|
||||||
Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name);
|
|
||||||
fields.push_front(item);
|
|
||||||
ref_pointer_array[el]= item;
|
|
||||||
thd->change_item_tree(ref, new_item);
|
|
||||||
}
|
|
||||||
item->update_used_tables();
|
|
||||||
used_tables_cache|=item->used_tables();
|
|
||||||
const_item_cache&=item->const_item();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -352,28 +352,14 @@ bool Item_func::walk (Item_processor processor, byte *argument)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* See comments in Item_cmp_func::split_sum_func() */
|
||||||
|
|
||||||
void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
|
void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
|
||||||
List<Item> &fields)
|
List<Item> &fields)
|
||||||
{
|
{
|
||||||
Item **arg, **arg_end;
|
Item **arg, **arg_end;
|
||||||
for (arg= args, arg_end= args+arg_count; arg != arg_end ; arg++)
|
for (arg= args, arg_end= args+arg_count; arg != arg_end ; arg++)
|
||||||
{
|
(*arg)->split_sum_func2(thd, ref_pointer_array, fields, arg);
|
||||||
Item *item=* arg;
|
|
||||||
if (item->type() != SUM_FUNC_ITEM &&
|
|
||||||
(item->with_sum_func ||
|
|
||||||
(item->used_tables() & PSEUDO_TABLE_BITS)))
|
|
||||||
item->split_sum_func(thd, ref_pointer_array, fields);
|
|
||||||
else if (item->type() == SUM_FUNC_ITEM ||
|
|
||||||
(item->used_tables() && item->type() != REF_ITEM))
|
|
||||||
{
|
|
||||||
uint el= fields.elements;
|
|
||||||
ref_pointer_array[el]= item;
|
|
||||||
Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name);
|
|
||||||
fields.push_front(item);
|
|
||||||
ref_pointer_array[el]= item;
|
|
||||||
thd->change_item_tree(arg, new_item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,25 +90,10 @@ void Item_row::split_sum_func(THD *thd, Item **ref_pointer_array,
|
|||||||
{
|
{
|
||||||
Item **arg, **arg_end;
|
Item **arg, **arg_end;
|
||||||
for (arg= items, arg_end= items+arg_count; arg != arg_end ; arg++)
|
for (arg= items, arg_end= items+arg_count; arg != arg_end ; arg++)
|
||||||
{
|
(*arg)->split_sum_func2(thd, ref_pointer_array, fields, arg);
|
||||||
Item *item= *arg;
|
|
||||||
if (item->type() != SUM_FUNC_ITEM &&
|
|
||||||
(item->with_sum_func ||
|
|
||||||
(item->used_tables() & PSEUDO_TABLE_BITS)))
|
|
||||||
item->split_sum_func(thd, ref_pointer_array, fields);
|
|
||||||
else if (item->type() == SUM_FUNC_ITEM ||
|
|
||||||
(item->used_tables() && item->type() != REF_ITEM))
|
|
||||||
{
|
|
||||||
uint el= fields.elements;
|
|
||||||
ref_pointer_array[el]=*arg;
|
|
||||||
Item *new_item= new Item_ref(ref_pointer_array + el, 0, (*arg)->name);
|
|
||||||
fields.push_front(*arg);
|
|
||||||
ref_pointer_array[el]= *arg;
|
|
||||||
thd->change_item_tree(arg, new_item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Item_row::update_used_tables()
|
void Item_row::update_used_tables()
|
||||||
{
|
{
|
||||||
used_tables_cache= 0;
|
used_tables_cache= 0;
|
||||||
|
@ -1758,20 +1758,7 @@ String *Item_func_elt::val_str(String *str)
|
|||||||
void Item_func_make_set::split_sum_func(THD *thd, Item **ref_pointer_array,
|
void Item_func_make_set::split_sum_func(THD *thd, Item **ref_pointer_array,
|
||||||
List<Item> &fields)
|
List<Item> &fields)
|
||||||
{
|
{
|
||||||
if (item->type() != SUM_FUNC_ITEM &&
|
item->split_sum_func2(thd, ref_pointer_array, fields, &item);
|
||||||
(item->with_sum_func ||
|
|
||||||
(item->used_tables() & PSEUDO_TABLE_BITS)))
|
|
||||||
item->split_sum_func(thd, ref_pointer_array, fields);
|
|
||||||
else if (item->type() == SUM_FUNC_ITEM ||
|
|
||||||
(item->used_tables() && item->type() != REF_ITEM))
|
|
||||||
{
|
|
||||||
uint el= fields.elements;
|
|
||||||
ref_pointer_array[el]=item;
|
|
||||||
Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name);
|
|
||||||
fields.push_front(item);
|
|
||||||
ref_pointer_array[el]= item;
|
|
||||||
thd->change_item_tree(&item, new_item);
|
|
||||||
}
|
|
||||||
Item_str_func::split_sum_func(thd, ref_pointer_array, fields);
|
Item_str_func::split_sum_func(thd, ref_pointer_array, fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -825,8 +825,6 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
|||||||
select_lex->ref_pointer_array,
|
select_lex->ref_pointer_array,
|
||||||
(char *)"<ref>",
|
(char *)"<ref>",
|
||||||
this->full_name()));
|
this->full_name()));
|
||||||
if (!abort_on_null && left_expr->maybe_null)
|
|
||||||
item= new Item_cond_or(new Item_func_isnull(left_expr), item);
|
|
||||||
/*
|
/*
|
||||||
AND and comparison functions can't be changed during fix_fields()
|
AND and comparison functions can't be changed during fix_fields()
|
||||||
we can assign select_lex->having here, and pass 0 as last
|
we can assign select_lex->having here, and pass 0 as last
|
||||||
@ -872,8 +870,6 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
|||||||
select_lex->having_fix_field= 0;
|
select_lex->having_fix_field= 0;
|
||||||
item= new Item_cond_or(item,
|
item= new Item_cond_or(item,
|
||||||
new Item_func_isnull(orig_item));
|
new Item_func_isnull(orig_item));
|
||||||
if (left_expr->maybe_null)
|
|
||||||
item= new Item_cond_or(new Item_func_isnull(left_expr), item);
|
|
||||||
}
|
}
|
||||||
item->name= (char *)in_additional_cond;
|
item->name= (char *)in_additional_cond;
|
||||||
/*
|
/*
|
||||||
@ -894,13 +890,12 @@ Item_in_subselect::single_value_transformer(JOIN *join,
|
|||||||
we can assign select_lex->having here, and pass 0 as last
|
we can assign select_lex->having here, and pass 0 as last
|
||||||
argument (reference) to fix_fields()
|
argument (reference) to fix_fields()
|
||||||
*/
|
*/
|
||||||
item= func->create(expr,
|
select_lex->having=
|
||||||
|
join->having=
|
||||||
|
func->create(expr,
|
||||||
new Item_null_helper(this, item,
|
new Item_null_helper(this, item,
|
||||||
(char *)"<no matter>",
|
(char *)"<no matter>",
|
||||||
(char *)"<result>"));
|
(char *)"<result>"));
|
||||||
if (!abort_on_null && left_expr->maybe_null)
|
|
||||||
item= new Item_cond_or(new Item_func_isnull(left_expr), item);
|
|
||||||
select_lex->having= join->having= item;
|
|
||||||
select_lex->having_fix_field= 1;
|
select_lex->having_fix_field= 1;
|
||||||
if (join->having->fix_fields(thd, join->tables_list,
|
if (join->having->fix_fields(thd, join->tables_list,
|
||||||
0))
|
0))
|
||||||
|
@ -134,6 +134,15 @@ public:
|
|||||||
if (!--elements)
|
if (!--elements)
|
||||||
last= &first;
|
last= &first;
|
||||||
}
|
}
|
||||||
|
inline void concat(base_list *list)
|
||||||
|
{
|
||||||
|
if (!list->is_empty())
|
||||||
|
{
|
||||||
|
*last= list->first;
|
||||||
|
last= list->last;
|
||||||
|
elements+= list->elements;
|
||||||
|
}
|
||||||
|
}
|
||||||
inline void *pop(void)
|
inline void *pop(void)
|
||||||
{
|
{
|
||||||
if (first == &end_of_list) return 0;
|
if (first == &end_of_list) return 0;
|
||||||
|
@ -8503,6 +8503,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
|
|||||||
res_selected_fields.empty();
|
res_selected_fields.empty();
|
||||||
res_all_fields.empty();
|
res_all_fields.empty();
|
||||||
List_iterator_fast<Item> itr(res_all_fields);
|
List_iterator_fast<Item> itr(res_all_fields);
|
||||||
|
List<Item> extra_funcs;
|
||||||
uint i, border= all_fields.elements - elements;
|
uint i, border= all_fields.elements - elements;
|
||||||
DBUG_ENTER("setup_copy_fields");
|
DBUG_ENTER("setup_copy_fields");
|
||||||
|
|
||||||
@ -8564,7 +8565,12 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
|
|||||||
*/
|
*/
|
||||||
if (!(pos=new Item_copy_string(pos)))
|
if (!(pos=new Item_copy_string(pos)))
|
||||||
goto err;
|
goto err;
|
||||||
if (param->copy_funcs.push_back(pos))
|
if (i < border) // HAVING, ORDER and GROUP BY
|
||||||
|
{
|
||||||
|
if (extra_funcs.push_back(pos))
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
else if (param->copy_funcs.push_back(pos))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
res_all_fields.push_back(pos);
|
res_all_fields.push_back(pos);
|
||||||
@ -8576,6 +8582,12 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
|
|||||||
for (i= 0; i < border; i++)
|
for (i= 0; i < border; i++)
|
||||||
itr++;
|
itr++;
|
||||||
itr.sublist(res_selected_fields, elements);
|
itr.sublist(res_selected_fields, elements);
|
||||||
|
/*
|
||||||
|
Put elements from HAVING, ORDER BY and GROUP BY last to ensure that any
|
||||||
|
reference used in these will resolve to a item that is already calculated
|
||||||
|
*/
|
||||||
|
param->copy_funcs.concat(&extra_funcs);
|
||||||
|
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user