Commit 96793a96 authored by unknown's avatar unknown

Merge bk@192.168.21.1:mysql-5.0

into  mysql.com:/home/hf/work/mrg/mysql-5.0-opt


sql/item_cmpfunc.cc:
  Auto merged
parents bdb9b448 2b983572
...@@ -470,4 +470,9 @@ a ...@@ -470,4 +470,9 @@ a
Warnings: Warnings:
Warning 1292 Incorrect date value: '19772-07-29' for column 'a' at row 1 Warning 1292 Incorrect date value: '19772-07-29' for column 'a' at row 1
DROP TABLE t1,t2,t3,t4; DROP TABLE t1,t2,t3,t4;
CREATE TABLE t1 (id int not null);
INSERT INTO t1 VALUES (1),(2);
SELECT id FROM t1 WHERE id IN(4564, (SELECT IF(1=0,1,1/0)) );
id
DROP TABLE t1;
End of 5.0 tests End of 5.0 tests
...@@ -3880,3 +3880,28 @@ this is a test. 3 ...@@ -3880,3 +3880,28 @@ this is a test. 3
this is a test. 1 this is a test. 1
this is a test. 2 this is a test. 2
DROP table t1; DROP table t1;
CREATE TABLE t1 (a int, b int);
CREATE TABLE t2 (m int, n int);
INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
SELECT COUNT(*), a,
(SELECT m FROM t2 WHERE m = count(*) LIMIT 1)
FROM t1 GROUP BY a;
COUNT(*) a (SELECT m FROM t2 WHERE m = count(*) LIMIT 1)
2 2 2
3 3 3
1 4 1
SELECT COUNT(*), a,
(SELECT MIN(m) FROM t2 WHERE m = count(*))
FROM t1 GROUP BY a;
COUNT(*) a (SELECT MIN(m) FROM t2 WHERE m = count(*))
2 2 2
3 3 3
1 4 1
SELECT COUNT(*), a
FROM t1 GROUP BY a
HAVING (SELECT MIN(m) FROM t2 WHERE m = count(*)) > 1;
COUNT(*) a
2 2
3 3
DROP TABLE t1,t2;
...@@ -645,3 +645,56 @@ a b Z ...@@ -645,3 +645,56 @@ a b Z
2 2 0 2 2 0
3 3 1 3 3 1
drop table t1,t2; drop table t1,t2;
CREATE TABLE t1 (a int, b INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
INSERT INTO t1 VALUES (1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'),
(2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'),(3,3,'j'), (3,2,'k'), (3,1,'l'),
(1,9,'m');
CREATE TABLE t2 (a int, b INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
INSERT INTO t2 SELECT * FROM t1;
SELECT a, MAX(b), (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b))
as test FROM t1 GROUP BY a;
a MAX(b) test
1 9 m
2 3 h
3 4 i
SELECT * FROM t1 GROUP by t1.a
HAVING (MAX(t1.b) > (SELECT MAX(t2.b) FROM t2 WHERE t2.c < t1.c
HAVING MAX(t2.b+t1.a) < 10));
a b c
SELECT a, AVG(b), (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b))
AS test FROM t1 GROUP BY a;
a AVG(b) test
1 4.0000 NULL
2 2.0000 k
3 2.5000 NULL
SELECT a,b,c FROM t1 WHERE b in (9,3,4) ORDER BY b,c;
a b c
1 3 c
2 3 h
3 3 j
1 4 d
3 4 i
1 9 m
SELECT a, MAX(b),
(SELECT COUNT(DISTINCT t.c) FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)
LIMIT 1)
as cnt,
(SELECT t.b FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) LIMIT 1)
as t_b,
(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) LIMIT 1)
as t_b,
(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) ORDER BY t.c LIMIT 1)
as t_b
FROM t1 GROUP BY a;
a MAX(b) cnt t_b t_b t_b
1 9 1 9 m m
2 3 1 3 h h
3 4 1 4 i i
SELECT a, MAX(b),
(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) LIMIT 1) as test
FROM t1 GROUP BY a;
a MAX(b) test
1 9 m
2 3 h
3 4 i
DROP TABLE t1, t2;
...@@ -168,6 +168,9 @@ dt ...@@ -168,6 +168,9 @@ dt
0000-00-00 00:00:00 0000-00-00 00:00:00
0000-00-00 00:00:00 0000-00-00 00:00:00
drop table t1; drop table t1;
select cast('2006-12-05 22:10:10' as datetime) + 0;
cast('2006-12-05 22:10:10' as datetime) + 0
20061205221010.000000
CREATE TABLE t1(a DATETIME NOT NULL); CREATE TABLE t1(a DATETIME NOT NULL);
INSERT INTO t1 VALUES ('20060606155555'); INSERT INTO t1 VALUES ('20060606155555');
SELECT a FROM t1 WHERE a=(SELECT MAX(a) FROM t1) AND (a="20060606155555"); SELECT a FROM t1 WHERE a=(SELECT MAX(a) FROM t1) AND (a="20060606155555");
......
...@@ -1381,4 +1381,12 @@ a ...@@ -1381,4 +1381,12 @@ a
SELECT a FROM (SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY c) AS test; SELECT a FROM (SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY c) AS test;
ERROR 42S22: Unknown column 'c' in 'order clause' ERROR 42S22: Unknown column 'c' in 'order clause'
DROP TABLE t1; DROP TABLE t1;
(select 1 into @var) union (select 1);
ERROR HY000: Incorrect usage of UNION and INTO
(select 1) union (select 1 into @var);
select @var;
@var
1
(select 2) union (select 1 into @var);
ERROR 42000: Result consisted of more than one row
End of 5.0 tests End of 5.0 tests
...@@ -360,4 +360,15 @@ SELECT * FROM t4 WHERE a IN ('1972-02-06','19772-07-29'); ...@@ -360,4 +360,15 @@ SELECT * FROM t4 WHERE a IN ('1972-02-06','19772-07-29');
DROP TABLE t1,t2,t3,t4; DROP TABLE t1,t2,t3,t4;
#
# BUG#27362: IN with a decimal expression that may return NULL
#
CREATE TABLE t1 (id int not null);
INSERT INTO t1 VALUES (1),(2);
SELECT id FROM t1 WHERE id IN(4564, (SELECT IF(1=0,1,1/0)) );
DROP TABLE t1;
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -2741,4 +2741,25 @@ SELECT * FROM (SELECT 'this is ' 'a test.' AS col1, a AS t2 FROM t1) t; ...@@ -2741,4 +2741,25 @@ SELECT * FROM (SELECT 'this is ' 'a test.' AS col1, a AS t2 FROM t1) t;
DROP table t1; DROP table t1;
#
# Bug #27257: COUNT(*) aggregated in outer query
#
CREATE TABLE t1 (a int, b int);
CREATE TABLE t2 (m int, n int);
INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
SELECT COUNT(*), a,
(SELECT m FROM t2 WHERE m = count(*) LIMIT 1)
FROM t1 GROUP BY a;
SELECT COUNT(*), a,
(SELECT MIN(m) FROM t2 WHERE m = count(*))
FROM t1 GROUP BY a;
SELECT COUNT(*), a
FROM t1 GROUP BY a
HAVING (SELECT MIN(m) FROM t2 WHERE m = count(*)) > 1;
DROP TABLE t1,t2;
...@@ -489,3 +489,44 @@ select a, b, (a,b) in (select a, min(b) from t2 group by a) Z from t1; ...@@ -489,3 +489,44 @@ select a, b, (a,b) in (select a, min(b) from t2 group by a) Z from t1;
drop table t1,t2; drop table t1,t2;
#
# Bug #24484: Aggregate function used in column list subquery gives erroneous
# error
#
CREATE TABLE t1 (a int, b INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
INSERT INTO t1 VALUES (1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'),
(2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'),(3,3,'j'), (3,2,'k'), (3,1,'l'),
(1,9,'m');
CREATE TABLE t2 (a int, b INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
INSERT INTO t2 SELECT * FROM t1;
# Gives error, but should work since it is (a, b) is the PK so only one
# given match possible
SELECT a, MAX(b), (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b))
as test FROM t1 GROUP BY a;
SELECT * FROM t1 GROUP by t1.a
HAVING (MAX(t1.b) > (SELECT MAX(t2.b) FROM t2 WHERE t2.c < t1.c
HAVING MAX(t2.b+t1.a) < 10));
SELECT a, AVG(b), (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b))
AS test FROM t1 GROUP BY a;
SELECT a,b,c FROM t1 WHERE b in (9,3,4) ORDER BY b,c;
SELECT a, MAX(b),
(SELECT COUNT(DISTINCT t.c) FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)
LIMIT 1)
as cnt,
(SELECT t.b FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) LIMIT 1)
as t_b,
(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) LIMIT 1)
as t_b,
(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) ORDER BY t.c LIMIT 1)
as t_b
FROM t1 GROUP BY a;
SELECT a, MAX(b),
(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b) LIMIT 1) as test
FROM t1 GROUP BY a;
DROP TABLE t1, t2;
...@@ -113,6 +113,12 @@ insert into t1 values ("00-00-00"), ("00-00-00 00:00:00"); ...@@ -113,6 +113,12 @@ insert into t1 values ("00-00-00"), ("00-00-00 00:00:00");
select * from t1; select * from t1;
drop table t1; drop table t1;
#
# Bug #16546 DATETIME+0 not always coerced the same way
#
select cast('2006-12-05 22:10:10' as datetime) + 0;
# End of 4.1 tests # End of 4.1 tests
# #
......
...@@ -868,4 +868,13 @@ SELECT a FROM (SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY c) AS test; ...@@ -868,4 +868,13 @@ SELECT a FROM (SELECT a FROM t1 UNION SELECT a FROM t1 ORDER BY c) AS test;
DROP TABLE t1; DROP TABLE t1;
#
# Bug#23345: Wrongly allowed INTO in a non-last select of a UNION.
#
--error 1221
(select 1 into @var) union (select 1);
(select 1) union (select 1 into @var);
select @var;
--error 1172
(select 2) union (select 1 into @var);
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -1901,6 +1901,11 @@ public: ...@@ -1901,6 +1901,11 @@ public:
{ {
return depended_from ? OUTER_REF_TABLE_BIT : (*ref)->used_tables(); return depended_from ? OUTER_REF_TABLE_BIT : (*ref)->used_tables();
} }
void update_used_tables()
{
if (!depended_from)
(*ref)->update_used_tables();
}
table_map not_null_tables() const { return (*ref)->not_null_tables(); } table_map not_null_tables() const { return (*ref)->not_null_tables(); }
void set_result_field(Field *field) { result_field= field; } void set_result_field(Field *field) { result_field= field; }
bool is_result_field() { return 1; } bool is_result_field() { return 1; }
......
...@@ -2423,7 +2423,8 @@ void in_decimal::set(uint pos, Item *item) ...@@ -2423,7 +2423,8 @@ void in_decimal::set(uint pos, Item *item)
dec->len= DECIMAL_BUFF_LENGTH; dec->len= DECIMAL_BUFF_LENGTH;
dec->fix_buffer_pointer(); dec->fix_buffer_pointer();
my_decimal *res= item->val_decimal(dec); my_decimal *res= item->val_decimal(dec);
if (res != dec) /* if item->val_decimal() is evaluated to NULL then res == 0 */
if (!item->null_value && res != dec)
my_decimal2decimal(res, dec); my_decimal2decimal(res, dec);
} }
......
...@@ -61,6 +61,7 @@ bool Item_sum::init_sum_func_check(THD *thd) ...@@ -61,6 +61,7 @@ bool Item_sum::init_sum_func_check(THD *thd)
/* Save a pointer to object to be used in items for nested set functions */ /* Save a pointer to object to be used in items for nested set functions */
thd->lex->in_sum_func= this; thd->lex->in_sum_func= this;
nest_level= thd->lex->current_select->nest_level; nest_level= thd->lex->current_select->nest_level;
nest_level_tables_count= thd->lex->current_select->join->tables;
ref_by= 0; ref_by= 0;
aggr_level= -1; aggr_level= -1;
max_arg_level= -1; max_arg_level= -1;
...@@ -176,6 +177,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref) ...@@ -176,6 +177,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
*/ */
set_if_bigger(in_sum_func->max_sum_func_level, aggr_level); set_if_bigger(in_sum_func->max_sum_func_level, aggr_level);
} }
update_used_tables();
thd->lex->in_sum_func= in_sum_func; thd->lex->in_sum_func= in_sum_func;
return FALSE; return FALSE;
} }
...@@ -267,12 +269,13 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref) ...@@ -267,12 +269,13 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref)
sl= sl->master_unit()->outer_select() ) sl= sl->master_unit()->outer_select() )
sl->master_unit()->item->with_sum_func= 1; sl->master_unit()->item->with_sum_func= 1;
} }
thd->lex->current_select->mark_as_dependent(aggr_sl);
return FALSE; return FALSE;
} }
Item_sum::Item_sum(List<Item> &list) Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements),
:arg_count(list.elements) forced_const(FALSE)
{ {
if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count))) if ((args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
{ {
...@@ -296,7 +299,10 @@ Item_sum::Item_sum(List<Item> &list) ...@@ -296,7 +299,10 @@ Item_sum::Item_sum(List<Item> &list)
Item_sum::Item_sum(THD *thd, Item_sum *item): Item_sum::Item_sum(THD *thd, Item_sum *item):
Item_result_field(thd, item), arg_count(item->arg_count), Item_result_field(thd, item), arg_count(item->arg_count),
quick_group(item->quick_group) nest_level(item->nest_level), aggr_level(item->aggr_level),
quick_group(item->quick_group), used_tables_cache(item->used_tables_cache),
forced_const(item->forced_const),
nest_level_tables_count(item->nest_level_tables_count)
{ {
if (arg_count <= 2) if (arg_count <= 2)
args=tmp_args; args=tmp_args;
...@@ -426,6 +432,26 @@ case DECIMAL_RESULT: ...@@ -426,6 +432,26 @@ case DECIMAL_RESULT:
} }
void Item_sum::update_used_tables ()
{
if (!forced_const)
{
used_tables_cache= 0;
for (uint i=0 ; i < arg_count ; i++)
{
args[i]->update_used_tables();
used_tables_cache|= args[i]->used_tables();
}
used_tables_cache&= PSEUDO_TABLE_BITS;
/* the aggregate function is aggregated into its local context */
if (aggr_level == nest_level)
used_tables_cache |= (1 << nest_level_tables_count) - 1;
}
}
String * String *
Item_sum_num::val_str(String *str) Item_sum_num::val_str(String *str)
{ {
...@@ -485,7 +511,7 @@ Item_sum_num::fix_fields(THD *thd, Item **ref) ...@@ -485,7 +511,7 @@ Item_sum_num::fix_fields(THD *thd, Item **ref)
Item_sum_hybrid::Item_sum_hybrid(THD *thd, Item_sum_hybrid *item) Item_sum_hybrid::Item_sum_hybrid(THD *thd, Item_sum_hybrid *item)
:Item_sum(thd, item), value(item->value), hybrid_type(item->hybrid_type), :Item_sum(thd, item), value(item->value), hybrid_type(item->hybrid_type),
hybrid_field_type(item->hybrid_field_type), cmp_sign(item->cmp_sign), hybrid_field_type(item->hybrid_field_type), cmp_sign(item->cmp_sign),
used_table_cache(item->used_table_cache), was_values(item->was_values) was_values(item->was_values)
{ {
/* copy results from old value */ /* copy results from old value */
switch (hybrid_type) { switch (hybrid_type) {
...@@ -1073,7 +1099,6 @@ void Item_sum_count::cleanup() ...@@ -1073,7 +1099,6 @@ void Item_sum_count::cleanup()
DBUG_ENTER("Item_sum_count::cleanup"); DBUG_ENTER("Item_sum_count::cleanup");
count= 0; count= 0;
Item_sum_int::cleanup(); Item_sum_int::cleanup();
used_table_cache= ~(table_map) 0;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -1554,7 +1579,7 @@ void Item_sum_hybrid::cleanup() ...@@ -1554,7 +1579,7 @@ void Item_sum_hybrid::cleanup()
{ {
DBUG_ENTER("Item_sum_hybrid::cleanup"); DBUG_ENTER("Item_sum_hybrid::cleanup");
Item_sum::cleanup(); Item_sum::cleanup();
used_table_cache= ~(table_map) 0; forced_const= FALSE;
/* /*
by default it is TRUE to avoid TRUE reporting by by default it is TRUE to avoid TRUE reporting by
......
...@@ -217,6 +217,8 @@ ...@@ -217,6 +217,8 @@
*/ */
class st_select_lex;
class Item_sum :public Item_result_field class Item_sum :public Item_result_field
{ {
public: public:
...@@ -237,19 +239,26 @@ public: ...@@ -237,19 +239,26 @@ public:
int8 max_sum_func_level;/* max level of aggregation for embedded functions */ int8 max_sum_func_level;/* max level of aggregation for embedded functions */
bool quick_group; /* If incremental update of fields */ bool quick_group; /* If incremental update of fields */
protected:
table_map used_tables_cache;
bool forced_const;
byte nest_level_tables_count;
public:
void mark_as_sum_func(); void mark_as_sum_func();
Item_sum() :arg_count(0), quick_group(1) Item_sum() :arg_count(0), quick_group(1), forced_const(FALSE)
{ {
mark_as_sum_func(); mark_as_sum_func();
} }
Item_sum(Item *a) Item_sum(Item *a) :args(tmp_args), arg_count(1), quick_group(1),
:args(tmp_args), arg_count(1), quick_group(1) forced_const(FALSE)
{ {
args[0]=a; args[0]=a;
mark_as_sum_func(); mark_as_sum_func();
} }
Item_sum( Item *a, Item *b ) Item_sum( Item *a, Item *b ) :args(tmp_args), arg_count(2), quick_group(1),
:args(tmp_args), arg_count(2), quick_group(1) forced_const(FALSE)
{ {
args[0]=a; args[1]=b; args[0]=a; args[1]=b;
mark_as_sum_func(); mark_as_sum_func();
...@@ -319,10 +328,20 @@ public: ...@@ -319,10 +328,20 @@ public:
virtual const char *func_name() const= 0; virtual const char *func_name() const= 0;
virtual Item *result_item(Field *field) virtual Item *result_item(Field *field)
{ return new Item_field(field); } { return new Item_field(field); }
table_map used_tables() const { return ~(table_map) 0; } /* Not used */ table_map used_tables() const { return used_tables_cache; }
bool const_item() const { return 0; } void update_used_tables ();
void cleanup()
{
Item::cleanup();
forced_const= FALSE;
}
bool is_null() { return null_value; } bool is_null() { return null_value; }
void update_used_tables() { } void make_const ()
{
used_tables_cache= 0;
forced_const= TRUE;
}
virtual bool const_item() const { return forced_const; }
void make_field(Send_field *field); void make_field(Send_field *field);
void print(String *str); void print(String *str);
void fix_num_length_and_dec(); void fix_num_length_and_dec();
...@@ -509,23 +528,23 @@ public: ...@@ -509,23 +528,23 @@ public:
class Item_sum_count :public Item_sum_int class Item_sum_count :public Item_sum_int
{ {
longlong count; longlong count;
table_map used_table_cache;
public: public:
Item_sum_count(Item *item_par) Item_sum_count(Item *item_par)
:Item_sum_int(item_par),count(0),used_table_cache(~(table_map) 0) :Item_sum_int(item_par),count(0)
{} {}
Item_sum_count(THD *thd, Item_sum_count *item) Item_sum_count(THD *thd, Item_sum_count *item)
:Item_sum_int(thd, item), count(item->count), :Item_sum_int(thd, item), count(item->count)
used_table_cache(item->used_table_cache)
{} {}
table_map used_tables() const { return used_table_cache; }
bool const_item() const { return !used_table_cache; }
enum Sumfunctype sum_func () const { return COUNT_FUNC; } enum Sumfunctype sum_func () const { return COUNT_FUNC; }
void clear(); void clear();
void no_rows_in_result() { count=0; } void no_rows_in_result() { count=0; }
bool add(); bool add();
void make_const(longlong count_arg) { count=count_arg; used_table_cache=0; } void make_const(longlong count_arg)
{
count=count_arg;
Item_sum::make_const();
}
longlong val_int(); longlong val_int();
void reset_field(); void reset_field();
void cleanup(); void cleanup();
...@@ -805,28 +824,22 @@ protected: ...@@ -805,28 +824,22 @@ protected:
Item_result hybrid_type; Item_result hybrid_type;
enum_field_types hybrid_field_type; enum_field_types hybrid_field_type;
int cmp_sign; int cmp_sign;
table_map used_table_cache;
bool was_values; // Set if we have found at least one row (for max/min only) bool was_values; // Set if we have found at least one row (for max/min only)
public: public:
Item_sum_hybrid(Item *item_par,int sign) Item_sum_hybrid(Item *item_par,int sign)
:Item_sum(item_par), sum(0.0), sum_int(0), :Item_sum(item_par), sum(0.0), sum_int(0),
hybrid_type(INT_RESULT), hybrid_field_type(FIELD_TYPE_LONGLONG), hybrid_type(INT_RESULT), hybrid_field_type(FIELD_TYPE_LONGLONG),
cmp_sign(sign), used_table_cache(~(table_map) 0), cmp_sign(sign), was_values(TRUE)
was_values(TRUE)
{ collation.set(&my_charset_bin); } { collation.set(&my_charset_bin); }
Item_sum_hybrid(THD *thd, Item_sum_hybrid *item); Item_sum_hybrid(THD *thd, Item_sum_hybrid *item);
bool fix_fields(THD *, Item **); bool fix_fields(THD *, Item **);
table_map used_tables() const { return used_table_cache; }
bool const_item() const { return !used_table_cache; }
void clear(); void clear();
double val_real(); double val_real();
longlong val_int(); longlong val_int();
my_decimal *val_decimal(my_decimal *); my_decimal *val_decimal(my_decimal *);
void reset_field(); void reset_field();
String *val_str(String *); String *val_str(String *);
void make_const() { used_table_cache=0; }
bool keep_field_type(void) const { return 1; } bool keep_field_type(void) const { return 1; }
enum Item_result result_type () const { return hybrid_type; } enum Item_result result_type () const { return hybrid_type; }
enum enum_field_types field_type() const { return hybrid_field_type; } enum enum_field_types field_type() const { return hybrid_field_type; }
......
...@@ -330,7 +330,7 @@ public: ...@@ -330,7 +330,7 @@ public:
enum_field_types field_type() const { return MYSQL_TYPE_DATE; } enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
String *val_str(String *str); String *val_str(String *str);
longlong val_int(); longlong val_int();
double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); } double val_real() { return val_real_from_decimal(); }
const char *func_name() const { return "date"; } const char *func_name() const { return "date"; }
void fix_length_and_dec() void fix_length_and_dec()
{ {
...@@ -368,6 +368,7 @@ public: ...@@ -368,6 +368,7 @@ public:
return (new Field_datetime(maybe_null, name, t_arg, &my_charset_bin)); return (new Field_datetime(maybe_null, name, t_arg, &my_charset_bin));
} }
bool result_as_longlong() { return TRUE; } bool result_as_longlong() { return TRUE; }
double val_real() { return (double) val_int(); }
my_decimal *val_decimal(my_decimal *decimal_value) my_decimal *val_decimal(my_decimal *decimal_value)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
...@@ -390,13 +391,14 @@ public: ...@@ -390,13 +391,14 @@ public:
enum_field_types field_type() const { return MYSQL_TYPE_TIME; } enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
void fix_length_and_dec() void fix_length_and_dec()
{ {
decimals=0; decimals= DATETIME_DEC;
max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
} }
Field *tmp_table_field(TABLE *t_arg) Field *tmp_table_field(TABLE *t_arg)
{ {
return (new Field_time(maybe_null, name, t_arg, &my_charset_bin)); return (new Field_time(maybe_null, name, t_arg, &my_charset_bin));
} }
double val_real() { return val_real_from_decimal(); }
my_decimal *val_decimal(my_decimal *decimal_value) my_decimal *val_decimal(my_decimal *decimal_value)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
...@@ -504,7 +506,6 @@ public: ...@@ -504,7 +506,6 @@ public:
Item_func_now() :Item_date_func() {} Item_func_now() :Item_date_func() {}
Item_func_now(Item *a) :Item_date_func(a) {} Item_func_now(Item *a) :Item_date_func(a) {}
enum Item_result result_type () const { return STRING_RESULT; } enum Item_result result_type () const { return STRING_RESULT; }
double val_real() { DBUG_ASSERT(fixed == 1); return (double) value; }
longlong val_int() { DBUG_ASSERT(fixed == 1); return value; } longlong val_int() { DBUG_ASSERT(fixed == 1); return value; }
int save_in_field(Field *to, bool no_conversions); int save_in_field(Field *to, bool no_conversions);
String *val_str(String *str); String *val_str(String *str);
...@@ -592,11 +593,6 @@ class Item_func_from_unixtime :public Item_date_func ...@@ -592,11 +593,6 @@ class Item_func_from_unixtime :public Item_date_func
THD *thd; THD *thd;
public: public:
Item_func_from_unixtime(Item *a) :Item_date_func(a) {} Item_func_from_unixtime(Item *a) :Item_date_func(a) {}
double val_real()
{
DBUG_ASSERT(fixed == 1);
return (double) Item_func_from_unixtime::val_int();
}
longlong val_int(); longlong val_int();
String *val_str(String *str); String *val_str(String *str);
const char *func_name() const { return "from_unixtime"; } const char *func_name() const { return "from_unixtime"; }
...@@ -635,7 +631,6 @@ class Item_func_convert_tz :public Item_date_func ...@@ -635,7 +631,6 @@ class Item_func_convert_tz :public Item_date_func
Item_func_convert_tz(Item *a, Item *b, Item *c): Item_func_convert_tz(Item *a, Item *b, Item *c):
Item_date_func(a, b, c), from_tz_cached(0), to_tz_cached(0) {} Item_date_func(a, b, c), from_tz_cached(0), to_tz_cached(0) {}
longlong val_int(); longlong val_int();
double val_real() { return (double) val_int(); }
String *val_str(String *str); String *val_str(String *str);
const char *func_name() const { return "convert_tz"; } const char *func_name() const { return "convert_tz"; }
bool fix_fields(THD *, Item **); bool fix_fields(THD *, Item **);
...@@ -661,7 +656,6 @@ public: ...@@ -661,7 +656,6 @@ public:
Item_str_timefunc::fix_length_and_dec(); Item_str_timefunc::fix_length_and_dec();
collation.set(&my_charset_bin); collation.set(&my_charset_bin);
maybe_null=1; maybe_null=1;
decimals= DATETIME_DEC;
} }
const char *func_name() const { return "sec_to_time"; } const char *func_name() const { return "sec_to_time"; }
bool result_as_longlong() { return TRUE; } bool result_as_longlong() { return TRUE; }
...@@ -699,7 +693,6 @@ public: ...@@ -699,7 +693,6 @@ public:
const char *func_name() const { return "date_add_interval"; } const char *func_name() const { return "date_add_interval"; }
void fix_length_and_dec(); void fix_length_and_dec();
enum_field_types field_type() const { return cached_field_type; } enum_field_types field_type() const { return cached_field_type; }
double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); }
longlong val_int(); longlong val_int();
bool get_date(TIME *res, uint fuzzy_date); bool get_date(TIME *res, uint fuzzy_date);
bool eq(const Item *item, bool binary_cmp) const; bool eq(const Item *item, bool binary_cmp) const;
...@@ -800,6 +793,7 @@ public: ...@@ -800,6 +793,7 @@ public:
} }
bool result_as_longlong() { return TRUE; } bool result_as_longlong() { return TRUE; }
longlong val_int(); longlong val_int();
double val_real() { return (double) val_int(); }
my_decimal *val_decimal(my_decimal *decimal_value) my_decimal *val_decimal(my_decimal *decimal_value)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
...@@ -827,6 +821,7 @@ public: ...@@ -827,6 +821,7 @@ public:
} }
bool result_as_longlong() { return TRUE; } bool result_as_longlong() { return TRUE; }
longlong val_int(); longlong val_int();
double val_real() { return val_real_from_decimal(); }
my_decimal *val_decimal(my_decimal *decimal_value) my_decimal *val_decimal(my_decimal *decimal_value)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
...@@ -847,12 +842,20 @@ public: ...@@ -847,12 +842,20 @@ public:
String *val_str(String *str); String *val_str(String *str);
const char *cast_type() const { return "datetime"; } const char *cast_type() const { return "datetime"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
void fix_length_and_dec()
{
Item_typecast_maybe_null::fix_length_and_dec();
decimals= DATETIME_DEC;
}
Field *tmp_table_field(TABLE *t_arg) Field *tmp_table_field(TABLE *t_arg)
{ {
return (new Field_datetime(maybe_null, name, t_arg, &my_charset_bin)); return (new Field_datetime(maybe_null, name, t_arg, &my_charset_bin));
} }
bool result_as_longlong() { return TRUE; } bool result_as_longlong() { return TRUE; }
longlong val_int(); longlong val_int();
double val_real() { return val_real_from_decimal(); }
double val() { return (double) val_int(); }
my_decimal *val_decimal(my_decimal *decimal_value) my_decimal *val_decimal(my_decimal *decimal_value)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
...@@ -921,6 +924,7 @@ public: ...@@ -921,6 +924,7 @@ public:
} }
void print(String *str); void print(String *str);
const char *func_name() const { return "add_time"; } const char *func_name() const { return "add_time"; }
double val_real() { return val_real_from_decimal(); }
my_decimal *val_decimal(my_decimal *decimal_value) my_decimal *val_decimal(my_decimal *decimal_value)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
......
...@@ -7528,7 +7528,8 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) ...@@ -7528,7 +7528,8 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
else else
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
Item *expr= min_max_item->args[0]; /* The argument of MIN/MAX. */ /* The argument of MIN/MAX. */
Item *expr= min_max_item->args[0]->real_item();
if (expr->type() == Item::FIELD_ITEM) /* Is it an attribute? */ if (expr->type() == Item::FIELD_ITEM) /* Is it an attribute? */
{ {
if (! min_max_arg_item) if (! min_max_arg_item)
...@@ -7906,6 +7907,7 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item, ...@@ -7906,6 +7907,7 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
DBUG_ENTER("check_group_min_max_predicates"); DBUG_ENTER("check_group_min_max_predicates");
DBUG_ASSERT(cond && min_max_arg_item); DBUG_ASSERT(cond && min_max_arg_item);
cond= cond->real_item();
Item::Type cond_type= cond->type(); Item::Type cond_type= cond->type();
if (cond_type == Item::COND_ITEM) /* 'AND' or 'OR' */ if (cond_type == Item::COND_ITEM) /* 'AND' or 'OR' */
{ {
...@@ -7943,7 +7945,7 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item, ...@@ -7943,7 +7945,7 @@ check_group_min_max_predicates(COND *cond, Item_field *min_max_arg_item,
DBUG_PRINT("info", ("Analyzing: %s", pred->func_name())); DBUG_PRINT("info", ("Analyzing: %s", pred->func_name()));
for (uint arg_idx= 0; arg_idx < pred->argument_count (); arg_idx++) for (uint arg_idx= 0; arg_idx < pred->argument_count (); arg_idx++)
{ {
cur_arg= arguments[arg_idx]; cur_arg= arguments[arg_idx]->real_item();
DBUG_PRINT("info", ("cur_arg: %s", cur_arg->full_name())); DBUG_PRINT("info", ("cur_arg: %s", cur_arg->full_name()));
if (cur_arg->type() == Item::FIELD_ITEM) if (cur_arg->type() == Item::FIELD_ITEM)
{ {
......
...@@ -4865,6 +4865,7 @@ bool setup_tables_and_check_access(THD *thd, ...@@ -4865,6 +4865,7 @@ bool setup_tables_and_check_access(THD *thd,
TABLE_LIST *leaves_tmp = NULL; TABLE_LIST *leaves_tmp = NULL;
bool first_table= true; bool first_table= true;
thd->leaf_count= 0;
if (setup_tables (thd, context, from_clause, tables, conds, if (setup_tables (thd, context, from_clause, tables, conds,
&leaves_tmp, select_insert)) &leaves_tmp, select_insert))
return TRUE; return TRUE;
...@@ -4882,6 +4883,7 @@ bool setup_tables_and_check_access(THD *thd, ...@@ -4882,6 +4883,7 @@ bool setup_tables_and_check_access(THD *thd,
return TRUE; return TRUE;
} }
first_table= false; first_table= false;
thd->leaf_count++;
} }
return FALSE; return FALSE;
} }
......
...@@ -1492,6 +1492,9 @@ public: ...@@ -1492,6 +1492,9 @@ public:
query_id_t first_query_id; query_id_t first_query_id;
} binlog_evt_union; } binlog_evt_union;
/* pass up the count of "leaf" tables in a JOIN out of setup_tables() */
byte leaf_count;
THD(); THD();
~THD(); ~THD();
......
...@@ -2349,12 +2349,14 @@ bool mysql_insert_select_prepare(THD *thd) ...@@ -2349,12 +2349,14 @@ bool mysql_insert_select_prepare(THD *thd)
DBUG_ASSERT(select_lex->leaf_tables != 0); DBUG_ASSERT(select_lex->leaf_tables != 0);
lex->leaf_tables_insert= select_lex->leaf_tables; lex->leaf_tables_insert= select_lex->leaf_tables;
/* skip all leaf tables belonged to view where we are insert */ /* skip all leaf tables belonged to view where we are insert */
for (first_select_leaf_table= select_lex->leaf_tables->next_leaf; for (first_select_leaf_table= select_lex->leaf_tables->next_leaf,
thd->leaf_count --;
first_select_leaf_table && first_select_leaf_table &&
first_select_leaf_table->belong_to_view && first_select_leaf_table->belong_to_view &&
first_select_leaf_table->belong_to_view == first_select_leaf_table->belong_to_view ==
lex->leaf_tables_insert->belong_to_view; lex->leaf_tables_insert->belong_to_view;
first_select_leaf_table= first_select_leaf_table->next_leaf) first_select_leaf_table= first_select_leaf_table->next_leaf,
thd->leaf_count --)
{} {}
select_lex->leaf_tables= first_select_leaf_table; select_lex->leaf_tables= first_select_leaf_table;
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
......
...@@ -406,12 +406,15 @@ JOIN::prepare(Item ***rref_pointer_array, ...@@ -406,12 +406,15 @@ JOIN::prepare(Item ***rref_pointer_array,
/* Check that all tables, fields, conds and order are ok */ /* Check that all tables, fields, conds and order are ok */
if ((!(select_options & OPTION_SETUP_TABLES_DONE) && if (!(select_options & OPTION_SETUP_TABLES_DONE) &&
setup_tables_and_check_access(thd, &select_lex->context, join_list, setup_tables_and_check_access(thd, &select_lex->context, join_list,
tables_list, &conds, tables_list, &conds,
&select_lex->leaf_tables, FALSE, &select_lex->leaf_tables, FALSE,
SELECT_ACL, SELECT_ACL)) || SELECT_ACL, SELECT_ACL))
setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) || DBUG_RETURN(-1);
tables= thd->leaf_count;
if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
select_lex->setup_ref_array(thd, og_num) || select_lex->setup_ref_array(thd, og_num) ||
setup_fields(thd, (*rref_pointer_array), fields_list, 1, setup_fields(thd, (*rref_pointer_array), fields_list, 1,
&all_fields, 1) || &all_fields, 1) ||
...@@ -516,11 +519,6 @@ JOIN::prepare(Item ***rref_pointer_array, ...@@ -516,11 +519,6 @@ JOIN::prepare(Item ***rref_pointer_array,
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
} }
TABLE_LIST *table_ptr;
for (table_ptr= select_lex->leaf_tables;
table_ptr;
table_ptr= table_ptr->next_leaf)
tables++;
} }
{ {
/* Caclulate the number of groups */ /* Caclulate the number of groups */
...@@ -6461,7 +6459,8 @@ static void update_depend_map(JOIN *join, ORDER *order) ...@@ -6461,7 +6459,8 @@ static void update_depend_map(JOIN *join, ORDER *order)
order->item[0]->update_used_tables(); order->item[0]->update_used_tables();
order->depend_map=depend_map=order->item[0]->used_tables(); order->depend_map=depend_map=order->item[0]->used_tables();
// Not item_sum(), RAND() and no reference to table outside of sub select // Not item_sum(), RAND() and no reference to table outside of sub select
if (!(order->depend_map & (OUTER_REF_TABLE_BIT | RAND_TABLE_BIT))) if (!(order->depend_map & (OUTER_REF_TABLE_BIT | RAND_TABLE_BIT))
&& !order->item[0]->with_sum_func)
{ {
for (JOIN_TAB **tab=join->map2table; for (JOIN_TAB **tab=join->map2table;
depend_map ; depend_map ;
......
...@@ -9296,7 +9296,7 @@ union_list: ...@@ -9296,7 +9296,7 @@ union_list:
UNION_SYM union_option UNION_SYM union_option
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (lex->exchange) if (lex->result)
{ {
/* Only the last SELECT can have INTO...... */ /* Only the last SELECT can have INTO...... */
my_error(ER_WRONG_USAGE, MYF(0), "UNION", "INTO"); my_error(ER_WRONG_USAGE, MYF(0), "UNION", "INTO");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment