Commit 2ece3604 authored by malff/marcsql@weblab.(none)'s avatar malff/marcsql@weblab.(none)

Merge weblab.(none):/home/marcsql/TREE/mysql-5.0-24532

into  weblab.(none):/home/marcsql/TREE/mysql-5.1-24532-merge
parents 8a88e5c3 4e556b23
......@@ -128,3 +128,6 @@ f1 f2 if(f1, 40.0, 5.00)
0 0 5.00
1 1 40.00
drop table t1;
select if(0, 18446744073709551610, 18446744073709551610);
if(0, 18446744073709551610, 18446744073709551610)
18446744073709551610
......@@ -3035,6 +3035,131 @@ ERROR HY000: View's SELECT contains a subquery in the FROM clause
SELECT * FROM (SELECT 1) AS t;
1
1
drop view if exists view_24532_a;
drop view if exists view_24532_b;
drop table if exists table_24532;
create table table_24532 (
a int,
b bigint,
c int(4),
d bigint(48)
);
create view view_24532_a as
select
a IS TRUE,
a IS NOT TRUE,
a IS FALSE,
a IS NOT FALSE,
a IS UNKNOWN,
a IS NOT UNKNOWN,
a is NULL,
a IS NOT NULL,
ISNULL(a),
b IS TRUE,
b IS NOT TRUE,
b IS FALSE,
b IS NOT FALSE,
b IS UNKNOWN,
b IS NOT UNKNOWN,
b is NULL,
b IS NOT NULL,
ISNULL(b),
c IS TRUE,
c IS NOT TRUE,
c IS FALSE,
c IS NOT FALSE,
c IS UNKNOWN,
c IS NOT UNKNOWN,
c is NULL,
c IS NOT NULL,
ISNULL(c),
d IS TRUE,
d IS NOT TRUE,
d IS FALSE,
d IS NOT FALSE,
d IS UNKNOWN,
d IS NOT UNKNOWN,
d is NULL,
d IS NOT NULL,
ISNULL(d)
from table_24532;
describe view_24532_a;
Field Type Null Key Default Extra
a IS TRUE int(1) NO 0
a IS NOT TRUE int(1) NO 0
a IS FALSE int(1) NO 0
a IS NOT FALSE int(1) NO 0
a IS UNKNOWN int(1) NO 0
a IS NOT UNKNOWN int(1) NO 0
a is NULL int(1) NO 0
a IS NOT NULL int(1) NO 0
ISNULL(a) int(1) NO 0
b IS TRUE int(1) NO 0
b IS NOT TRUE int(1) NO 0
b IS FALSE int(1) NO 0
b IS NOT FALSE int(1) NO 0
b IS UNKNOWN int(1) NO 0
b IS NOT UNKNOWN int(1) NO 0
b is NULL int(1) NO 0
b IS NOT NULL int(1) NO 0
ISNULL(b) int(1) NO 0
c IS TRUE int(1) NO 0
c IS NOT TRUE int(1) NO 0
c IS FALSE int(1) NO 0
c IS NOT FALSE int(1) NO 0
c IS UNKNOWN int(1) NO 0
c IS NOT UNKNOWN int(1) NO 0
c is NULL int(1) NO 0
c IS NOT NULL int(1) NO 0
ISNULL(c) int(1) NO 0
d IS TRUE int(1) NO 0
d IS NOT TRUE int(1) NO 0
d IS FALSE int(1) NO 0
d IS NOT FALSE int(1) NO 0
d IS UNKNOWN int(1) NO 0
d IS NOT UNKNOWN int(1) NO 0
d is NULL int(1) NO 0
d IS NOT NULL int(1) NO 0
ISNULL(d) int(1) NO 0
create view view_24532_b as
select
a IS TRUE,
if(ifnull(a, 0), 1, 0) as old_istrue,
a IS NOT TRUE,
if(ifnull(a, 0), 0, 1) as old_isnottrue,
a IS FALSE,
if(ifnull(a, 1), 0, 1) as old_isfalse,
a IS NOT FALSE,
if(ifnull(a, 1), 1, 0) as old_isnotfalse
from table_24532;
describe view_24532_b;
Field Type Null Key Default Extra
a IS TRUE int(1) NO 0
old_istrue int(1) NO 0
a IS NOT TRUE int(1) NO 0
old_isnottrue int(1) NO 0
a IS FALSE int(1) NO 0
old_isfalse int(1) NO 0
a IS NOT FALSE int(1) NO 0
old_isnotfalse int(1) NO 0
show create view view_24532_b;
View Create View
view_24532_b CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `view_24532_b` AS select (`table_24532`.`a` is true) AS `a IS TRUE`,if(ifnull(`table_24532`.`a`,0),1,0) AS `old_istrue`,(`table_24532`.`a` is not true) AS `a IS NOT TRUE`,if(ifnull(`table_24532`.`a`,0),0,1) AS `old_isnottrue`,(`table_24532`.`a` is false) AS `a IS FALSE`,if(ifnull(`table_24532`.`a`,1),0,1) AS `old_isfalse`,(`table_24532`.`a` is not false) AS `a IS NOT FALSE`,if(ifnull(`table_24532`.`a`,1),1,0) AS `old_isnotfalse` from `table_24532`
insert into table_24532 values (0, 0, 0, 0);
select * from view_24532_b;
a IS TRUE old_istrue a IS NOT TRUE old_isnottrue a IS FALSE old_isfalse a IS NOT FALSE old_isnotfalse
0 0 1 1 1 1 0 0
update table_24532 set a=1;
select * from view_24532_b;
a IS TRUE old_istrue a IS NOT TRUE old_isnottrue a IS FALSE old_isfalse a IS NOT FALSE old_isnotfalse
1 1 0 0 0 0 1 1
update table_24532 set a=NULL;
select * from view_24532_b;
a IS TRUE old_istrue a IS NOT TRUE old_isnottrue a IS FALSE old_isfalse a IS NOT FALSE old_isnotfalse
0 0 1 1 0 0 1 1
drop view view_24532_a;
drop view view_24532_b;
drop table table_24532;
End of 5.0 tests.
DROP DATABASE IF EXISTS `d-1`;
CREATE DATABASE `d-1`;
......
......@@ -97,3 +97,14 @@ create table t1 (f1 int, f2 int);
insert into t1 values(1,1),(0,0);
select f1, f2, if(f1, 40.0, 5.00) from t1 group by f1 order by f2;
drop table t1;
#
# Bug#24532 (The return data type of IS TRUE is different from similar
# operations)
#
# IF(x, unsigned, unsigned) should be unsigned.
#
select if(0, 18446744073709551610, 18446744073709551610);
......@@ -768,6 +768,59 @@ int Arg_comparator::compare_e_row()
}
void Item_func_truth::fix_length_and_dec()
{
maybe_null= 0;
null_value= 0;
decimals= 0;
max_length= 1;
}
void Item_func_truth::print(String *str)
{
str->append('(');
args[0]->print(str);
str->append(STRING_WITH_LEN(" is "));
if (! affirmative)
str->append(STRING_WITH_LEN("not "));
if (value)
str->append(STRING_WITH_LEN("true"));
else
str->append(STRING_WITH_LEN("false"));
str->append(')');
}
bool Item_func_truth::val_bool()
{
bool val= args[0]->val_bool();
if (args[0]->null_value)
{
/*
NULL val IS {TRUE, FALSE} --> FALSE
NULL val IS NOT {TRUE, FALSE} --> TRUE
*/
return (! affirmative);
}
if (affirmative)
{
/* {TRUE, FALSE} val IS {TRUE, FALSE} value */
return (val == value);
}
/* {TRUE, FALSE} val IS NOT {TRUE, FALSE} value */
return (val != value);
}
longlong Item_func_truth::val_int()
{
return (val_bool() ? 1 : 0);
}
bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
{
if (!args[0]->fixed && args[0]->fix_fields(thd, args) ||
......@@ -1480,6 +1533,7 @@ Item_func_if::fix_length_and_dec()
{
maybe_null=args[1]->maybe_null || args[2]->maybe_null;
decimals= max(args[1]->decimals, args[2]->decimals);
unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
enum Item_result arg1_type=args[1]->result_type();
enum Item_result arg2_type=args[2]->result_type();
......@@ -1509,12 +1563,20 @@ Item_func_if::fix_length_and_dec()
collation.set(&my_charset_bin); // Number
}
}
max_length=
(cached_result_type == DECIMAL_RESULT || cached_result_type == INT_RESULT) ?
(max(args[1]->max_length - args[1]->decimals,
args[2]->max_length - args[2]->decimals) + decimals +
(unsigned_flag ? 0 : 1) ) :
max(args[1]->max_length, args[2]->max_length);
if ((cached_result_type == DECIMAL_RESULT )
|| (cached_result_type == INT_RESULT))
{
int len1= args[1]->max_length - args[1]->decimals
- (args[1]->unsigned_flag ? 0 : 1);
int len2= args[2]->max_length - args[2]->decimals
- (args[2]->unsigned_flag ? 0 : 1);
max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
}
else
max_length= max(args[1]->max_length, args[2]->max_length);
}
......
......@@ -98,6 +98,92 @@ public:
uint decimal_precision() const { return 1; }
};
/**
Abstract Item class, to represent <code>X IS [NOT] (TRUE | FALSE)</code>
boolean predicates.
*/
class Item_func_truth : public Item_bool_func
{
public:
virtual bool val_bool();
virtual longlong val_int();
virtual void fix_length_and_dec();
virtual void print(String *str);
protected:
Item_func_truth(Item *a, bool a_value, bool a_affirmative)
: Item_bool_func(a), value(a_value), affirmative(a_affirmative)
{}
~Item_func_truth()
{}
private:
/**
True for <code>X IS [NOT] TRUE</code>,
false for <code>X IS [NOT] FALSE</code> predicates.
*/
const bool value;
/**
True for <code>X IS Y</code>, false for <code>X IS NOT Y</code> predicates.
*/
const bool affirmative;
};
/**
This Item represents a <code>X IS TRUE</code> boolean predicate.
*/
class Item_func_istrue : public Item_func_truth
{
public:
Item_func_istrue(Item *a) : Item_func_truth(a, true, true) {}
~Item_func_istrue() {}
virtual const char* func_name() const { return "istrue"; }
};
/**
This Item represents a <code>X IS NOT TRUE</code> boolean predicate.
*/
class Item_func_isnottrue : public Item_func_truth
{
public:
Item_func_isnottrue(Item *a) : Item_func_truth(a, true, false) {}
~Item_func_isnottrue() {}
virtual const char* func_name() const { return "isnottrue"; }
};
/**
This Item represents a <code>X IS FALSE</code> boolean predicate.
*/
class Item_func_isfalse : public Item_func_truth
{
public:
Item_func_isfalse(Item *a) : Item_func_truth(a, false, true) {}
~Item_func_isfalse() {}
virtual const char* func_name() const { return "isfalse"; }
};
/**
This Item represents a <code>X IS NOT FALSE</code> boolean predicate.
*/
class Item_func_isnotfalse : public Item_func_truth
{
public:
Item_func_isnotfalse(Item *a) : Item_func_truth(a, false, false) {}
~Item_func_isnotfalse() {}
virtual const char* func_name() const { return "isnotfalse"; }
};
class Item_cache;
#define UNKNOWN ((my_bool)-1)
......
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