Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
9f638f53
Commit
9f638f53
authored
Nov 24, 2009
by
Evgeny Potemkin
Browse files
Options
Browse Files
Download
Plain Diff
Manual merge of the fix for bug#43668.
parents
fad34c34
bc43bff7
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
629 additions
and
382 deletions
+629
-382
mysql-test/r/func_group.result
mysql-test/r/func_group.result
+194
-1
mysql-test/t/func_group.test
mysql-test/t/func_group.test
+31
-0
sql/item.cc
sql/item.cc
+64
-42
sql/item.h
sql/item.h
+23
-6
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+213
-57
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+30
-13
sql/item_func.h
sql/item_func.h
+0
-11
sql/item_geofunc.cc
sql/item_geofunc.cc
+2
-2
sql/item_subselect.h
sql/item_subselect.h
+1
-0
sql/item_sum.cc
sql/item_sum.cc
+57
-227
sql/item_sum.h
sql/item_sum.h
+14
-23
No files found.
mysql-test/r/func_group.result
View file @
9f638f53
...
@@ -885,7 +885,7 @@ cast(sum(distinct df) as signed)
...
@@ -885,7 +885,7 @@ cast(sum(distinct df) as signed)
3
3
select cast(min(df) as signed) from t1;
select cast(min(df) as signed) from t1;
cast(min(df) as signed)
cast(min(df) as signed)
0
1
select 1e8 * sum(distinct df) from t1;
select 1e8 * sum(distinct df) from t1;
1e8 * sum(distinct df)
1e8 * sum(distinct df)
330000000
330000000
...
@@ -1520,4 +1520,197 @@ max i
...
@@ -1520,4 +1520,197 @@ max i
# Cleanup
# Cleanup
#
#
DROP TABLE t1;
DROP TABLE t1;
#
# Bug#43668: Wrong comparison and MIN/MAX for YEAR(2)
#
create table t1 (f1 year(2), f2 year(4), f3 date, f4 datetime);
insert into t1 values
(98,1998,19980101,"1998-01-01 00:00:00"),
(00,2000,20000101,"2000-01-01 00:00:01"),
(02,2002,20020101,"2002-01-01 23:59:59"),
(60,2060,20600101,"2060-01-01 11:11:11"),
(70,1970,19700101,"1970-11-11 22:22:22"),
(NULL,NULL,NULL,NULL);
select min(f1),max(f1) from t1;
min(f1) max(f1)
70 60
select min(f2),max(f2) from t1;
min(f2) max(f2)
1970 2060
select min(f3),max(f3) from t1;
min(f3) max(f3)
1970-01-01 2060-01-01
select min(f4),max(f4) from t1;
min(f4) max(f4)
1970-11-11 22:22:22 2060-01-01 11:11:11
select a.f1 as a, b.f1 as b, a.f1 > b.f1 as gt,
a.f1 < b.f1 as lt, a.f1<=>b.f1 as eq
from t1 a, t1 b;
a b gt lt eq
98 98 0 0 1
00 98 1 0 0
02 98 1 0 0
60 98 1 0 0
70 98 0 1 0
NULL 98 NULL NULL 0
98 00 0 1 0
00 00 0 0 1
02 00 1 0 0
60 00 1 0 0
70 00 0 1 0
NULL 00 NULL NULL 0
98 02 0 1 0
00 02 0 1 0
02 02 0 0 1
60 02 1 0 0
70 02 0 1 0
NULL 02 NULL NULL 0
98 60 0 1 0
00 60 0 1 0
02 60 0 1 0
60 60 0 0 1
70 60 0 1 0
NULL 60 NULL NULL 0
98 70 1 0 0
00 70 1 0 0
02 70 1 0 0
60 70 1 0 0
70 70 0 0 1
NULL 70 NULL NULL 0
98 NULL NULL NULL 0
00 NULL NULL NULL 0
02 NULL NULL NULL 0
60 NULL NULL NULL 0
70 NULL NULL NULL 0
NULL NULL NULL NULL 1
select a.f1 as a, b.f2 as b, a.f1 > b.f2 as gt,
a.f1 < b.f2 as lt, a.f1<=>b.f2 as eq
from t1 a, t1 b;
a b gt lt eq
98 1998 0 0 1
00 1998 1 0 0
02 1998 1 0 0
60 1998 1 0 0
70 1998 0 1 0
NULL 1998 NULL NULL 0
98 2000 0 1 0
00 2000 0 0 1
02 2000 1 0 0
60 2000 1 0 0
70 2000 0 1 0
NULL 2000 NULL NULL 0
98 2002 0 1 0
00 2002 0 1 0
02 2002 0 0 1
60 2002 1 0 0
70 2002 0 1 0
NULL 2002 NULL NULL 0
98 2060 0 1 0
00 2060 0 1 0
02 2060 0 1 0
60 2060 0 0 1
70 2060 0 1 0
NULL 2060 NULL NULL 0
98 1970 1 0 0
00 1970 1 0 0
02 1970 1 0 0
60 1970 1 0 0
70 1970 0 0 1
NULL 1970 NULL NULL 0
98 NULL NULL NULL 0
00 NULL NULL NULL 0
02 NULL NULL NULL 0
60 NULL NULL NULL 0
70 NULL NULL NULL 0
NULL NULL NULL NULL 1
select a.f1 as a, b.f3 as b, a.f1 > b.f3 as gt,
a.f1 < b.f3 as lt, a.f1<=>b.f3 as eq
from t1 a, t1 b;
a b gt lt eq
98 1998-01-01 0 1 0
00 1998-01-01 1 0 0
02 1998-01-01 1 0 0
60 1998-01-01 1 0 0
70 1998-01-01 0 1 0
NULL 1998-01-01 NULL NULL 0
98 2000-01-01 0 1 0
00 2000-01-01 0 1 0
02 2000-01-01 1 0 0
60 2000-01-01 1 0 0
70 2000-01-01 0 1 0
NULL 2000-01-01 NULL NULL 0
98 2002-01-01 0 1 0
00 2002-01-01 0 1 0
02 2002-01-01 0 1 0
60 2002-01-01 1 0 0
70 2002-01-01 0 1 0
NULL 2002-01-01 NULL NULL 0
98 2060-01-01 0 1 0
00 2060-01-01 0 1 0
02 2060-01-01 0 1 0
60 2060-01-01 0 1 0
70 2060-01-01 0 1 0
NULL 2060-01-01 NULL NULL 0
98 1970-01-01 1 0 0
00 1970-01-01 1 0 0
02 1970-01-01 1 0 0
60 1970-01-01 1 0 0
70 1970-01-01 0 1 0
NULL 1970-01-01 NULL NULL 0
98 NULL NULL NULL 0
00 NULL NULL NULL 0
02 NULL NULL NULL 0
60 NULL NULL NULL 0
70 NULL NULL NULL 0
NULL NULL NULL NULL 1
select a.f1 as a, b.f4 as b, a.f1 > b.f4 as gt,
a.f1 < b.f4 as lt, a.f1<=>b.f4 as eq
from t1 a, t1 b;
a b gt lt eq
98 1998-01-01 00:00:00 0 1 0
00 1998-01-01 00:00:00 1 0 0
02 1998-01-01 00:00:00 1 0 0
60 1998-01-01 00:00:00 1 0 0
70 1998-01-01 00:00:00 0 1 0
NULL 1998-01-01 00:00:00 NULL NULL 0
98 2000-01-01 00:00:01 0 1 0
00 2000-01-01 00:00:01 0 1 0
02 2000-01-01 00:00:01 1 0 0
60 2000-01-01 00:00:01 1 0 0
70 2000-01-01 00:00:01 0 1 0
NULL 2000-01-01 00:00:01 NULL NULL 0
98 2002-01-01 23:59:59 0 1 0
00 2002-01-01 23:59:59 0 1 0
02 2002-01-01 23:59:59 0 1 0
60 2002-01-01 23:59:59 1 0 0
70 2002-01-01 23:59:59 0 1 0
NULL 2002-01-01 23:59:59 NULL NULL 0
98 2060-01-01 11:11:11 0 1 0
00 2060-01-01 11:11:11 0 1 0
02 2060-01-01 11:11:11 0 1 0
60 2060-01-01 11:11:11 0 1 0
70 2060-01-01 11:11:11 0 1 0
NULL 2060-01-01 11:11:11 NULL NULL 0
98 1970-11-11 22:22:22 1 0 0
00 1970-11-11 22:22:22 1 0 0
02 1970-11-11 22:22:22 1 0 0
60 1970-11-11 22:22:22 1 0 0
70 1970-11-11 22:22:22 0 1 0
NULL 1970-11-11 22:22:22 NULL NULL 0
98 NULL NULL NULL 0
00 NULL NULL NULL 0
02 NULL NULL NULL 0
60 NULL NULL NULL 0
70 NULL NULL NULL 0
NULL NULL NULL NULL 1
select *, f1 = f2 from t1;
f1 f2 f3 f4 f1 = f2
98 1998 1998-01-01 1998-01-01 00:00:00 1
00 2000 2000-01-01 2000-01-01 00:00:01 1
02 2002 2002-01-01 2002-01-01 23:59:59 1
60 2060 2060-01-01 2060-01-01 11:11:11 1
70 1970 1970-01-01 1970-11-11 22:22:22 1
NULL NULL NULL NULL NULL
drop table t1;
#
End of 5.1 tests
End of 5.1 tests
mysql-test/t/func_group.test
View file @
9f638f53
...
@@ -1053,4 +1053,35 @@ ORDER BY max;
...
@@ -1053,4 +1053,35 @@ ORDER BY max;
--
echo
#
--
echo
#
DROP
TABLE
t1
;
DROP
TABLE
t1
;
--
echo
#
--
echo
# Bug#43668: Wrong comparison and MIN/MAX for YEAR(2)
--
echo
#
create
table
t1
(
f1
year
(
2
),
f2
year
(
4
),
f3
date
,
f4
datetime
);
insert
into
t1
values
(
98
,
1998
,
19980101
,
"1998-01-01 00:00:00"
),
(
00
,
2000
,
20000101
,
"2000-01-01 00:00:01"
),
(
02
,
2002
,
20020101
,
"2002-01-01 23:59:59"
),
(
60
,
2060
,
20600101
,
"2060-01-01 11:11:11"
),
(
70
,
1970
,
19700101
,
"1970-11-11 22:22:22"
),
(
NULL
,
NULL
,
NULL
,
NULL
);
select
min
(
f1
),
max
(
f1
)
from
t1
;
select
min
(
f2
),
max
(
f2
)
from
t1
;
select
min
(
f3
),
max
(
f3
)
from
t1
;
select
min
(
f4
),
max
(
f4
)
from
t1
;
select
a
.
f1
as
a
,
b
.
f1
as
b
,
a
.
f1
>
b
.
f1
as
gt
,
a
.
f1
<
b
.
f1
as
lt
,
a
.
f1
<=>
b
.
f1
as
eq
from
t1
a
,
t1
b
;
select
a
.
f1
as
a
,
b
.
f2
as
b
,
a
.
f1
>
b
.
f2
as
gt
,
a
.
f1
<
b
.
f2
as
lt
,
a
.
f1
<=>
b
.
f2
as
eq
from
t1
a
,
t1
b
;
select
a
.
f1
as
a
,
b
.
f3
as
b
,
a
.
f1
>
b
.
f3
as
gt
,
a
.
f1
<
b
.
f3
as
lt
,
a
.
f1
<=>
b
.
f3
as
eq
from
t1
a
,
t1
b
;
select
a
.
f1
as
a
,
b
.
f4
as
b
,
a
.
f1
>
b
.
f4
as
gt
,
a
.
f1
<
b
.
f4
as
lt
,
a
.
f1
<=>
b
.
f4
as
eq
from
t1
a
,
t1
b
;
select
*
,
f1
=
f2
from
t1
;
drop
table
t1
;
--
echo
#
--
echo
End
of
5.1
tests
--
echo
End
of
5.1
tests
sql/item.cc
View file @
9f638f53
...
@@ -6957,7 +6957,7 @@ Item_cache* Item_cache::get_cache(const Item *item, const Item_result type)
...
@@ -6957,7 +6957,7 @@ Item_cache* Item_cache::get_cache(const Item *item, const Item_result type)
{
{
switch
(
type
)
{
switch
(
type
)
{
case
INT_RESULT
:
case
INT_RESULT
:
return
new
Item_cache_int
();
return
new
Item_cache_int
(
item
->
field_type
()
);
case
REAL_RESULT
:
case
REAL_RESULT
:
return
new
Item_cache_real
();
return
new
Item_cache_real
();
case
DECIMAL_RESULT
:
case
DECIMAL_RESULT
:
...
@@ -6975,8 +6975,9 @@ Item_cache* Item_cache::get_cache(const Item *item, const Item_result type)
...
@@ -6975,8 +6975,9 @@ Item_cache* Item_cache::get_cache(const Item *item, const Item_result type)
void
Item_cache
::
store
(
Item
*
item
)
void
Item_cache
::
store
(
Item
*
item
)
{
{
if
(
item
)
example
=
item
;
example
=
item
;
if
(
!
item
)
null_value
=
TRUE
;
value_cached
=
FALSE
;
value_cached
=
FALSE
;
}
}
...
@@ -6990,12 +6991,15 @@ void Item_cache::print(String *str, enum_query_type query_type)
...
@@ -6990,12 +6991,15 @@ void Item_cache::print(String *str, enum_query_type query_type)
str
->
append
(
')'
);
str
->
append
(
')'
);
}
}
void
Item_cache_int
::
cache_value
()
bool
Item_cache_int
::
cache_value
()
{
{
if
(
!
example
)
return
FALSE
;
value_cached
=
TRUE
;
value_cached
=
TRUE
;
value
=
example
->
val_int_result
();
value
=
example
->
val_int_result
();
null_value
=
example
->
null_value
;
null_value
=
example
->
null_value
;
unsigned_flag
=
example
->
unsigned_flag
;
unsigned_flag
=
example
->
unsigned_flag
;
return
TRUE
;
}
}
...
@@ -7012,8 +7016,8 @@ void Item_cache_int::store(Item *item, longlong val_arg)
...
@@ -7012,8 +7016,8 @@ void Item_cache_int::store(Item *item, longlong val_arg)
String
*
Item_cache_int
::
val_str
(
String
*
str
)
String
*
Item_cache_int
::
val_str
(
String
*
str
)
{
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
if
(
!
value_cached
&&
!
cache_value
()
)
cache_value
()
;
return
NULL
;
str
->
set
(
value
,
default_charset
());
str
->
set
(
value
,
default_charset
());
return
str
;
return
str
;
}
}
...
@@ -7022,8 +7026,8 @@ String *Item_cache_int::val_str(String *str)
...
@@ -7022,8 +7026,8 @@ String *Item_cache_int::val_str(String *str)
my_decimal
*
Item_cache_int
::
val_decimal
(
my_decimal
*
decimal_val
)
my_decimal
*
Item_cache_int
::
val_decimal
(
my_decimal
*
decimal_val
)
{
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
if
(
!
value_cached
&&
!
cache_value
()
)
cache_value
()
;
return
NULL
;
int2my_decimal
(
E_DEC_FATAL_ERROR
,
value
,
unsigned_flag
,
decimal_val
);
int2my_decimal
(
E_DEC_FATAL_ERROR
,
value
,
unsigned_flag
,
decimal_val
);
return
decimal_val
;
return
decimal_val
;
}
}
...
@@ -7031,40 +7035,43 @@ my_decimal *Item_cache_int::val_decimal(my_decimal *decimal_val)
...
@@ -7031,40 +7035,43 @@ my_decimal *Item_cache_int::val_decimal(my_decimal *decimal_val)
double
Item_cache_int
::
val_real
()
double
Item_cache_int
::
val_real
()
{
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
if
(
!
value_cached
&&
!
cache_value
()
)
cache_value
()
;
return
0.0
;
return
(
double
)
value
;
return
(
double
)
value
;
}
}
longlong
Item_cache_int
::
val_int
()
longlong
Item_cache_int
::
val_int
()
{
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
if
(
!
value_cached
&&
!
cache_value
()
)
cache_value
()
;
return
0
;
return
value
;
return
value
;
}
}
void
Item_cache_real
::
cache_value
()
bool
Item_cache_real
::
cache_value
()
{
{
if
(
!
example
)
return
FALSE
;
value_cached
=
TRUE
;
value_cached
=
TRUE
;
value
=
example
->
val_result
();
value
=
example
->
val_result
();
null_value
=
example
->
null_value
;
null_value
=
example
->
null_value
;
return
TRUE
;
}
}
double
Item_cache_real
::
val_real
()
double
Item_cache_real
::
val_real
()
{
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
if
(
!
value_cached
&&
!
cache_value
()
)
cache_value
()
;
return
0.0
;
return
value
;
return
value
;
}
}
longlong
Item_cache_real
::
val_int
()
longlong
Item_cache_real
::
val_int
()
{
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
if
(
!
value_cached
&&
!
cache_value
()
)
cache_value
()
;
return
0
;
return
(
longlong
)
rint
(
value
);
return
(
longlong
)
rint
(
value
);
}
}
...
@@ -7072,8 +7079,8 @@ longlong Item_cache_real::val_int()
...
@@ -7072,8 +7079,8 @@ longlong Item_cache_real::val_int()
String
*
Item_cache_real
::
val_str
(
String
*
str
)
String
*
Item_cache_real
::
val_str
(
String
*
str
)
{
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
if
(
!
value_cached
&&
!
cache_value
()
)
cache_value
()
;
return
NULL
;
str
->
set_real
(
value
,
decimals
,
default_charset
());
str
->
set_real
(
value
,
decimals
,
default_charset
());
return
str
;
return
str
;
}
}
...
@@ -7082,27 +7089,30 @@ String* Item_cache_real::val_str(String *str)
...
@@ -7082,27 +7089,30 @@ String* Item_cache_real::val_str(String *str)
my_decimal
*
Item_cache_real
::
val_decimal
(
my_decimal
*
decimal_val
)
my_decimal
*
Item_cache_real
::
val_decimal
(
my_decimal
*
decimal_val
)
{
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
if
(
!
value_cached
&&
!
cache_value
()
)
cache_value
()
;
return
NULL
;
double2my_decimal
(
E_DEC_FATAL_ERROR
,
value
,
decimal_val
);
double2my_decimal
(
E_DEC_FATAL_ERROR
,
value
,
decimal_val
);
return
decimal_val
;
return
decimal_val
;
}
}
void
Item_cache_decimal
::
cache_value
()
bool
Item_cache_decimal
::
cache_value
()
{
{
if
(
!
example
)
return
FALSE
;
value_cached
=
TRUE
;
value_cached
=
TRUE
;
my_decimal
*
val
=
example
->
val_decimal_result
(
&
decimal_value
);
my_decimal
*
val
=
example
->
val_decimal_result
(
&
decimal_value
);
if
(
!
(
null_value
=
example
->
null_value
)
&&
val
!=
&
decimal_value
)
if
(
!
(
null_value
=
example
->
null_value
)
&&
val
!=
&
decimal_value
)
my_decimal2decimal
(
val
,
&
decimal_value
);
my_decimal2decimal
(
val
,
&
decimal_value
);
return
TRUE
;
}
}
double
Item_cache_decimal
::
val_real
()
double
Item_cache_decimal
::
val_real
()
{
{
DBUG_ASSERT
(
fixed
);
DBUG_ASSERT
(
fixed
);
double
res
;
double
res
;
if
(
!
value_cached
)
if
(
!
value_cached
&&
!
cache_value
()
)
cache_value
()
;
return
NULL
;
my_decimal2double
(
E_DEC_FATAL_ERROR
,
&
decimal_value
,
&
res
);
my_decimal2double
(
E_DEC_FATAL_ERROR
,
&
decimal_value
,
&
res
);
return
res
;
return
res
;
}
}
...
@@ -7111,8 +7121,8 @@ longlong Item_cache_decimal::val_int()
...
@@ -7111,8 +7121,8 @@ longlong Item_cache_decimal::val_int()
{
{
DBUG_ASSERT
(
fixed
);
DBUG_ASSERT
(
fixed
);
longlong
res
;
longlong
res
;
if
(
!
value_cached
)
if
(
!
value_cached
&&
!
cache_value
()
)
cache_value
()
;
return
0
;
my_decimal2int
(
E_DEC_FATAL_ERROR
,
&
decimal_value
,
unsigned_flag
,
&
res
);
my_decimal2int
(
E_DEC_FATAL_ERROR
,
&
decimal_value
,
unsigned_flag
,
&
res
);
return
res
;
return
res
;
}
}
...
@@ -7120,8 +7130,8 @@ longlong Item_cache_decimal::val_int()
...
@@ -7120,8 +7130,8 @@ longlong Item_cache_decimal::val_int()
String
*
Item_cache_decimal
::
val_str
(
String
*
str
)
String
*
Item_cache_decimal
::
val_str
(
String
*
str
)
{
{
DBUG_ASSERT
(
fixed
);
DBUG_ASSERT
(
fixed
);
if
(
!
value_cached
)
if
(
!
value_cached
&&
!
cache_value
()
)
cache_value
()
;
return
NULL
;
my_decimal_round
(
E_DEC_FATAL_ERROR
,
&
decimal_value
,
decimals
,
FALSE
,
my_decimal_round
(
E_DEC_FATAL_ERROR
,
&
decimal_value
,
decimals
,
FALSE
,
&
decimal_value
);
&
decimal_value
);
my_decimal2string
(
E_DEC_FATAL_ERROR
,
&
decimal_value
,
0
,
0
,
0
,
str
);
my_decimal2string
(
E_DEC_FATAL_ERROR
,
&
decimal_value
,
0
,
0
,
0
,
str
);
...
@@ -7131,14 +7141,16 @@ String* Item_cache_decimal::val_str(String *str)
...
@@ -7131,14 +7141,16 @@ String* Item_cache_decimal::val_str(String *str)
my_decimal
*
Item_cache_decimal
::
val_decimal
(
my_decimal
*
val
)
my_decimal
*
Item_cache_decimal
::
val_decimal
(
my_decimal
*
val
)
{
{
DBUG_ASSERT
(
fixed
);
DBUG_ASSERT
(
fixed
);
if
(
!
value_cached
)
if
(
!
value_cached
&&
!
cache_value
()
)
cache_value
()
;
return
NULL
;
return
&
decimal_value
;
return
&
decimal_value
;
}
}
void
Item_cache_str
::
cache_value
()
bool
Item_cache_str
::
cache_value
()
{
{
if
(
!
example
)
return
FALSE
;
value_cached
=
TRUE
;
value_cached
=
TRUE
;
value_buff
.
set
(
buffer
,
sizeof
(
buffer
),
example
->
collation
.
collation
);
value_buff
.
set
(
buffer
,
sizeof
(
buffer
),
example
->
collation
.
collation
);
value
=
example
->
str_result
(
&
value_buff
);
value
=
example
->
str_result
(
&
value_buff
);
...
@@ -7157,6 +7169,7 @@ void Item_cache_str::cache_value()
...
@@ -7157,6 +7169,7 @@ void Item_cache_str::cache_value()
value_buff
.
copy
(
*
value
);
value_buff
.
copy
(
*
value
);
value
=
&
value_buff
;
value
=
&
value_buff
;
}
}
return
TRUE
;
}
}
double
Item_cache_str
::
val_real
()
double
Item_cache_str
::
val_real
()
...
@@ -7164,8 +7177,8 @@ double Item_cache_str::val_real()
...
@@ -7164,8 +7177,8 @@ double Item_cache_str::val_real()
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
int
err_not_used
;
int
err_not_used
;
char
*
end_not_used
;
char
*
end_not_used
;
if
(
!
value_cached
)
if
(
!
value_cached
&&
!
cache_value
()
)
cache_value
()
;
return
0.0
;
if
(
value
)
if
(
value
)
return
my_strntod
(
value
->
charset
(),
(
char
*
)
value
->
ptr
(),
return
my_strntod
(
value
->
charset
(),
(
char
*
)
value
->
ptr
(),
value
->
length
(),
&
end_not_used
,
&
err_not_used
);
value
->
length
(),
&
end_not_used
,
&
err_not_used
);
...
@@ -7177,8 +7190,8 @@ longlong Item_cache_str::val_int()
...
@@ -7177,8 +7190,8 @@ longlong Item_cache_str::val_int()
{
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
int
err
;
int
err
;
if
(
!
value_cached
)
if
(
!
value_cached
&&
!
cache_value
()
)
cache_value
()
;
return
0
;
if
(
value
)
if
(
value
)
return
my_strntoll
(
value
->
charset
(),
value
->
ptr
(),
return
my_strntoll
(
value
->
charset
(),
value
->
ptr
(),
value
->
length
(),
10
,
(
char
**
)
0
,
&
err
);
value
->
length
(),
10
,
(
char
**
)
0
,
&
err
);
...
@@ -7190,8 +7203,8 @@ longlong Item_cache_str::val_int()
...
@@ -7190,8 +7203,8 @@ longlong Item_cache_str::val_int()
String
*
Item_cache_str
::
val_str
(
String
*
str
)
String
*
Item_cache_str
::
val_str
(
String
*
str
)
{
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
if
(
!
value_cached
&&
!
cache_value
()
)
cache_value
()
;
return
0
;
return
value
;
return
value
;
}
}
...
@@ -7199,8 +7212,8 @@ String* Item_cache_str::val_str(String *str)
...
@@ -7199,8 +7212,8 @@ String* Item_cache_str::val_str(String *str)
my_decimal
*
Item_cache_str
::
val_decimal
(
my_decimal
*
decimal_val
)
my_decimal
*
Item_cache_str
::
val_decimal
(
my_decimal
*
decimal_val
)
{
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
if
(
!
value_cached
&&
!
cache_value
()
)
cache_value
()
;
return
NULL
;
if
(
value
)
if
(
value
)
string2my_decimal
(
E_DEC_FATAL_ERROR
,
value
,
decimal_val
);
string2my_decimal
(
E_DEC_FATAL_ERROR
,
value
,
decimal_val
);
else
else
...
@@ -7211,8 +7224,8 @@ my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val)
...
@@ -7211,8 +7224,8 @@ my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val)
int
Item_cache_str
::
save_in_field
(
Field
*
field
,
bool
no_conversions
)
int
Item_cache_str
::
save_in_field
(
Field
*
field
,
bool
no_conversions
)
{
{
if
(
!
value_cached
)
if
(
!
value_cached
&&
!
cache_value
()
)
cache_value
()
;
return
0
;
int
res
=
Item_cache
::
save_in_field
(
field
,
no_conversions
);
int
res
=
Item_cache
::
save_in_field
(
field
,
no_conversions
);
return
(
is_varbinary
&&
field
->
type
()
==
MYSQL_TYPE_STRING
&&
return
(
is_varbinary
&&
field
->
type
()
==
MYSQL_TYPE_STRING
&&
value
->
length
()
<
field
->
field_length
)
?
1
:
res
;
value
->
length
()
<
field
->
field_length
)
?
1
:
res
;
...
@@ -7247,13 +7260,21 @@ bool Item_cache_row::setup(Item * item)
...
@@ -7247,13 +7260,21 @@ bool Item_cache_row::setup(Item * item)
void
Item_cache_row
::
store
(
Item
*
item
)
void
Item_cache_row
::
store
(
Item
*
item
)
{
{
example
=
item
;
if
(
!
item
)
{
null_value
=
TRUE
;
return
;
}
for
(
uint
i
=
0
;
i
<
item_count
;
i
++
)
for
(
uint
i
=
0
;
i
<
item_count
;
i
++
)
values
[
i
]
->
store
(
item
->
element_index
(
i
));
values
[
i
]
->
store
(
item
->
element_index
(
i
));
}
}
void
Item_cache_row
::
cache_value
()
bool
Item_cache_row
::
cache_value
()
{
{
if
(
!
example
)
return
FALSE
;
value_cached
=
TRUE
;
value_cached
=
TRUE
;
null_value
=
0
;
null_value
=
0
;
example
->
bring_value
();
example
->
bring_value
();
...
@@ -7262,6 +7283,7 @@ void Item_cache_row::cache_value()
...
@@ -7262,6 +7283,7 @@ void Item_cache_row::cache_value()
values
[
i
]
->
cache_value
();
values
[
i
]
->
cache_value
();
null_value
|=
values
[
i
]
->
null_value
;
null_value
|=
values
[
i
]
->
null_value
;
}
}
return
TRUE
;
}
}
...
...
sql/item.h
View file @
9f638f53
...
@@ -2138,6 +2138,23 @@ class Item_result_field :public Item /* Item with result field */
...
@@ -2138,6 +2138,23 @@ class Item_result_field :public Item /* Item with result field */
save_in_field
(
result_field
,
no_conversions
);
save_in_field
(
result_field
,
no_conversions
);
}
}
void
cleanup
();
void
cleanup
();
/*
This method is used for debug purposes to print the name of an
item to the debug log. The second use of this method is as
a helper function of print() and error messages, where it is
applicable. To suit both goals it should return a meaningful,
distinguishable and sintactically correct string. This method
should not be used for runtime type identification, use enum
{Sum}Functype and Item_func::functype()/Item_sum::sum_func()
instead.
Added here, to the parent class of both Item_func and Item_sum_func.
NOTE: for Items inherited from Item_sum, func_name() return part of
function name till first argument (including '(') to make difference in
names for functions with 'distinct' clause and without 'distinct' and
also to make printing of items inherited from Item_sum uniform.
*/
virtual
const
char
*
func_name
()
const
=
0
;
};
};
...
@@ -2947,7 +2964,7 @@ class Item_cache: public Item_basic_constant
...
@@ -2947,7 +2964,7 @@ class Item_cache: public Item_basic_constant
return
this
==
item
;
return
this
==
item
;
}
}
virtual
void
store
(
Item
*
item
);
virtual
void
store
(
Item
*
item
);
virtual
void
cache_value
()
=
0
;
virtual
bool
cache_value
()
=
0
;
};
};
...
@@ -2968,7 +2985,7 @@ class Item_cache_int: public Item_cache
...
@@ -2968,7 +2985,7 @@ class Item_cache_int: public Item_cache
my_decimal
*
val_decimal
(
my_decimal
*
);
my_decimal
*
val_decimal
(
my_decimal
*
);
enum
Item_result
result_type
()
const
{
return
INT_RESULT
;
}
enum
Item_result
result_type
()
const
{
return
INT_RESULT
;
}
bool
result_as_longlong
()
{
return
TRUE
;
}
bool
result_as_longlong
()
{
return
TRUE
;
}
void
cache_value
();
bool
cache_value
();
};
};
...
@@ -2984,7 +3001,7 @@ class Item_cache_real: public Item_cache
...
@@ -2984,7 +3001,7 @@ class Item_cache_real: public Item_cache
String
*
val_str
(
String
*
str
);
String
*
val_str
(
String
*
str
);
my_decimal
*
val_decimal
(
my_decimal
*
);
my_decimal
*
val_decimal
(
my_decimal
*
);
enum
Item_result
result_type
()
const
{
return
REAL_RESULT
;
}
enum
Item_result
result_type
()
const
{
return
REAL_RESULT
;
}
void
cache_value
();
bool
cache_value
();
};
};
...
@@ -3000,7 +3017,7 @@ class Item_cache_decimal: public Item_cache
...
@@ -3000,7 +3017,7 @@ class Item_cache_decimal: public Item_cache
String
*
val_str
(
String
*
str
);
String
*
val_str
(
String
*
str
);
my_decimal
*
val_decimal
(
my_decimal
*
);
my_decimal
*
val_decimal
(
my_decimal
*
);
enum
Item_result
result_type
()
const
{
return
DECIMAL_RESULT
;
}
enum
Item_result
result_type
()
const
{
return
DECIMAL_RESULT
;
}
void
cache_value
();
bool
cache_value
();
};
};
...
@@ -3025,7 +3042,7 @@ class Item_cache_str: public Item_cache
...
@@ -3025,7 +3042,7 @@ class Item_cache_str: public Item_cache
enum
Item_result
result_type
()
const
{
return
STRING_RESULT
;
}
enum
Item_result
result_type
()
const
{
return
STRING_RESULT
;
}
CHARSET_INFO
*
charset
()
const
{
return
value
->
charset
();
};
CHARSET_INFO
*
charset
()
const
{
return
value
->
charset
();
};
int
save_in_field
(
Field
*
field
,
bool
no_conversions
);
int
save_in_field
(
Field
*
field
,
bool
no_conversions
);
void
cache_value
();
bool
cache_value
();
};
};
class
Item_cache_row
:
public
Item_cache
class
Item_cache_row
:
public
Item_cache
...
@@ -3094,7 +3111,7 @@ class Item_cache_row: public Item_cache
...
@@ -3094,7 +3111,7 @@ class Item_cache_row: public Item_cache
values
=
0
;
values
=
0
;
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
void
cache_value
();
bool
cache_value
();
};
};
...
...
sql/item_cmpfunc.cc
View file @
9f638f53
This diff is collapsed.
Click to expand it.
sql/item_cmpfunc.h
View file @
9f638f53
...
@@ -32,7 +32,7 @@ class Arg_comparator: public Sql_alloc
...
@@ -32,7 +32,7 @@ class Arg_comparator: public Sql_alloc
{
{
Item
**
a
,
**
b
;
Item
**
a
,
**
b
;
arg_cmp_func
func
;
arg_cmp_func
func
;
Item_
bool_func2
*
owner
;
Item_
result_field
*
owner
;
Arg_comparator
*
comparators
;
// used only for compare_row()
Arg_comparator
*
comparators
;
// used only for compare_row()
double
precision
;
double
precision
;
/* Fields used in DATE/DATETIME comparison. */
/* Fields used in DATE/DATETIME comparison. */
...
@@ -40,30 +40,42 @@ class Arg_comparator: public Sql_alloc
...
@@ -40,30 +40,42 @@ class Arg_comparator: public Sql_alloc
enum_field_types
a_type
,
b_type
;
// Types of a and b items
enum_field_types
a_type
,
b_type
;
// Types of a and b items
Item
*
a_cache
,
*
b_cache
;
// Cached values of a and b items
Item
*
a_cache
,
*
b_cache
;
// Cached values of a and b items
bool
is_nulls_eq
;
// TRUE <=> compare for the EQUAL_FUNC
bool
is_nulls_eq
;
// TRUE <=> compare for the EQUAL_FUNC
bool
set_null
;
// TRUE <=> set owner->null_value
// when one of arguments is NULL.
bool
year_as_datetime
;
// TRUE <=> convert YEAR value to
// the YYYY-00-00 00:00:00 DATETIME
// format. See compare_year.
enum
enum_date_cmp_type
{
CMP_DATE_DFLT
=
0
,
CMP_DATE_WITH_DATE
,
enum
enum_date_cmp_type
{
CMP_DATE_DFLT
=
0
,
CMP_DATE_WITH_DATE
,
CMP_DATE_WITH_STR
,
CMP_STR_WITH_DATE
};
CMP_DATE_WITH_STR
,
CMP_STR_WITH_DATE
};
longlong
(
*
get_value_func
)(
THD
*
thd
,
Item
***
item_arg
,
Item
**
cache_arg
,
longlong
(
*
get_value_a_func
)(
THD
*
thd
,
Item
***
item_arg
,
Item
**
cache_arg
,
Item
*
warn_item
,
bool
*
is_null
);
Item
*
warn_item
,
bool
*
is_null
);
longlong
(
*
get_value_b_func
)(
THD
*
thd
,
Item
***
item_arg
,
Item
**
cache_arg
,
Item
*
warn_item
,
bool
*
is_null
);
public:
public:
DTCollation
cmp_collation
;
DTCollation
cmp_collation
;
/* Allow owner function to use string buffers. */
String
value1
,
value2
;
Arg_comparator
()
:
thd
(
0
),
a_cache
(
0
),
b_cache
(
0
)
{};
Arg_comparator
()
:
thd
(
0
),
a_cache
(
0
),
b_cache
(
0
),
set_null
(
0
),
year_as_datetime
(
0
),
get_value_a_func
(
0
),
get_value_b_func
(
0
)
{};
Arg_comparator
(
Item
**
a1
,
Item
**
a2
)
:
a
(
a1
),
b
(
a2
),
thd
(
0
),
Arg_comparator
(
Item
**
a1
,
Item
**
a2
)
:
a
(
a1
),
b
(
a2
),
thd
(
0
),
a_cache
(
0
),
b_cache
(
0
)
{};
a_cache
(
0
),
b_cache
(
0
),
set_null
(
0
),
year_as_datetime
(
0
),
get_value_a_func
(
0
),
get_value_b_func
(
0
)
{};
int
set_compare_func
(
Item_
bool_func2
*
owner
,
Item_result
type
);
int
set_compare_func
(
Item_
result_field
*
owner
,
Item_result
type
);
inline
int
set_compare_func
(
Item_
bool_func2
*
owner_arg
)
inline
int
set_compare_func
(
Item_
result_field
*
owner_arg
)
{
{
return
set_compare_func
(
owner_arg
,
item_cmp_type
((
*
a
)
->
result_type
(),
return
set_compare_func
(
owner_arg
,
item_cmp_type
((
*
a
)
->
result_type
(),
(
*
b
)
->
result_type
()));
(
*
b
)
->
result_type
()));
}
}
int
set_cmp_func
(
Item_
bool_func2
*
owner_arg
,
int
set_cmp_func
(
Item_
result_field
*
owner_arg
,
Item
**
a1
,
Item
**
a2
,
Item
**
a1
,
Item
**
a2
,
Item_result
type
);
Item_result
type
);
inline
int
set_cmp_func
(
Item_
bool_func2
*
owner_arg
,
inline
int
set_cmp_func
(
Item_
result_field
*
owner_arg
,
Item
**
a1
,
Item
**
a2
)
Item
**
a1
,
Item
**
a2
,
bool
set_null_arg
)
{
{
set_null
=
set_null_arg
;
return
set_cmp_func
(
owner_arg
,
a1
,
a2
,
return
set_cmp_func
(
owner_arg
,
a1
,
a2
,
item_cmp_type
((
*
a1
)
->
result_type
(),
item_cmp_type
((
*
a1
)
->
result_type
(),
(
*
a2
)
->
result_type
()));
(
*
a2
)
->
result_type
()));
...
@@ -89,14 +101,20 @@ class Arg_comparator: public Sql_alloc
...
@@ -89,14 +101,20 @@ class Arg_comparator: public Sql_alloc
int
compare_real_fixed
();
int
compare_real_fixed
();
int
compare_e_real_fixed
();
int
compare_e_real_fixed
();
int
compare_datetime
();
// compare args[0] & args[1] as DATETIMEs
int
compare_datetime
();
// compare args[0] & args[1] as DATETIMEs
int
compare_year
();
static
enum
enum_date_cmp_type
can_compare_as_dates
(
Item
*
a
,
Item
*
b
,
static
enum
enum_date_cmp_type
can_compare_as_dates
(
Item
*
a
,
Item
*
b
,
ulonglong
*
const_val_arg
);
ulonglong
*
const_val_arg
);
void
set_datetime_cmp_func
(
Item
**
a1
,
Item
**
b1
);
Item
**
cache_converted_constant
(
THD
*
thd
,
Item
**
value
,
Item
**
cache
,
Item
**
cache_converted_constant
(
THD
*
thd
,
Item
**
value
,
Item
**
cache
,
Item_result
type
);
Item_result
type
);
void
set_datetime_cmp_func
(
Item_result_field
*
owner_arg
,
Item
**
a1
,
Item
**
b1
);
static
arg_cmp_func
comparator_matrix
[
5
][
2
];
static
arg_cmp_func
comparator_matrix
[
5
][
2
];
inline
bool
is_owner_equal_func
()
{
return
(
owner
->
type
()
==
Item
::
FUNC_ITEM
&&
((
Item_func
*
)
owner
)
->
functype
()
==
Item_func
::
EQUAL_FUNC
);
}
friend
class
Item_func
;
friend
class
Item_func
;
};
};
...
@@ -326,7 +344,6 @@ class Item_bool_func2 :public Item_int_func
...
@@ -326,7 +344,6 @@ class Item_bool_func2 :public Item_int_func
{
/* Bool with 2 string args */
{
/* Bool with 2 string args */
protected:
protected:
Arg_comparator
cmp
;
Arg_comparator
cmp
;
String
tmp_value1
,
tmp_value2
;
bool
abort_on_null
;
bool
abort_on_null
;
public:
public:
...
@@ -335,7 +352,7 @@ class Item_bool_func2 :public Item_int_func
...
@@ -335,7 +352,7 @@ class Item_bool_func2 :public Item_int_func
void
fix_length_and_dec
();
void
fix_length_and_dec
();
void
set_cmp_func
()
void
set_cmp_func
()
{
{
cmp
.
set_cmp_func
(
this
,
tmp_arg
,
tmp_arg
+
1
);
cmp
.
set_cmp_func
(
this
,
tmp_arg
,
tmp_arg
+
1
,
TRUE
);
}
}
optimize_type
select_optimize
()
const
{
return
OPTIMIZE_OP
;
}
optimize_type
select_optimize
()
const
{
return
OPTIMIZE_OP
;
}
virtual
enum
Functype
rev_functype
()
const
{
return
UNKNOWN_FUNC
;
}
virtual
enum
Functype
rev_functype
()
const
{
return
UNKNOWN_FUNC
;
}
...
...
sql/item_func.h
View file @
9f638f53
...
@@ -124,17 +124,6 @@ class Item_func :public Item_result_field
...
@@ -124,17 +124,6 @@ class Item_func :public Item_result_field
virtual
optimize_type
select_optimize
()
const
{
return
OPTIMIZE_NONE
;
}
virtual
optimize_type
select_optimize
()
const
{
return
OPTIMIZE_NONE
;
}
virtual
bool
have_rev_func
()
const
{
return
0
;
}
virtual
bool
have_rev_func
()
const
{
return
0
;
}
virtual
Item
*
key_item
()
const
{
return
args
[
0
];
}
virtual
Item
*
key_item
()
const
{
return
args
[
0
];
}
/*
This method is used for debug purposes to print the name of an
item to the debug log. The second use of this method is as
a helper function of print(), where it is applicable.
To suit both goals it should return a meaningful,
distinguishable and sintactically correct string. This method
should not be used for runtime type identification, use enum
{Sum}Functype and Item_func::functype()/Item_sum::sum_func()
instead.
*/
virtual
const
char
*
func_name
()
const
=
0
;
virtual
bool
const_item
()
const
{
return
const_item_cache
;
}
virtual
bool
const_item
()
const
{
return
const_item_cache
;
}
inline
Item
**
arguments
()
const
{
return
args
;
}
inline
Item
**
arguments
()
const
{
return
args
;
}
void
set_arguments
(
List
<
Item
>
&
list
);
void
set_arguments
(
List
<
Item
>
&
list
);
...
...
sql/item_geofunc.cc
View file @
9f638f53
...
@@ -511,8 +511,8 @@ String *Item_func_spatial_collection::val_str(String *str)
...
@@ -511,8 +511,8 @@ String *Item_func_spatial_collection::val_str(String *str)
longlong
Item_func_spatial_rel
::
val_int
()
longlong
Item_func_spatial_rel
::
val_int
()
{
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
String
*
res1
=
args
[
0
]
->
val_str
(
&
tmp_
value1
);
String
*
res1
=
args
[
0
]
->
val_str
(
&
cmp
.
value1
);
String
*
res2
=
args
[
1
]
->
val_str
(
&
tmp_
value2
);
String
*
res2
=
args
[
1
]
->
val_str
(
&
cmp
.
value2
);
Geometry_buffer
buffer1
,
buffer2
;
Geometry_buffer
buffer1
,
buffer2
;
Geometry
*
g1
,
*
g2
;
Geometry
*
g1
,
*
g2
;
MBR
mbr1
,
mbr2
;
MBR
mbr1
,
mbr2
;
...
...
sql/item_subselect.h
View file @
9f638f53
...
@@ -132,6 +132,7 @@ class Item_subselect :public Item_result_field
...
@@ -132,6 +132,7 @@ class Item_subselect :public Item_result_field
@return the SELECT_LEX structure associated with this Item
@return the SELECT_LEX structure associated with this Item
*/
*/
st_select_lex
*
get_select_lex
();
st_select_lex
*
get_select_lex
();
const
char
*
func_name
()
const
{
DBUG_ASSERT
(
0
);
return
"subselect"
;
}
friend
class
select_subselect
;
friend
class
select_subselect
;
friend
class
Item_in_optimizer
;
friend
class
Item_in_optimizer
;
...
...
sql/item_sum.cc
View file @
9f638f53
...
@@ -615,35 +615,6 @@ Item_sum_num::fix_fields(THD *thd, Item **ref)
...
@@ -615,35 +615,6 @@ Item_sum_num::fix_fields(THD *thd, Item **ref)
}
}
Item_sum_hybrid
::
Item_sum_hybrid
(
THD
*
thd
,
Item_sum_hybrid
*
item
)
:
Item_sum
(
thd
,
item
),
value
(
item
->
value
),
hybrid_type
(
item
->
hybrid_type
),
hybrid_field_type
(
item
->
hybrid_field_type
),
cmp_sign
(
item
->
cmp_sign
),
was_values
(
item
->
was_values
)
{
/* copy results from old value */
switch
(
hybrid_type
)
{
case
INT_RESULT
:
sum_int
=
item
->
sum_int
;
break
;
case
DECIMAL_RESULT
:
my_decimal2decimal
(
&
item
->
sum_dec
,
&
sum_dec
);
break
;
case
REAL_RESULT
:
sum
=
item
->
sum
;
break
;
case
STRING_RESULT
:
/*
This can happen with ROLLUP. Note that the value is already
copied at function call.
*/
break
;
case
ROW_RESULT
:
default:
DBUG_ASSERT
(
0
);
}
collation
.
set
(
item
->
collation
);
}
bool
bool
Item_sum_hybrid
::
fix_fields
(
THD
*
thd
,
Item
**
ref
)
Item_sum_hybrid
::
fix_fields
(
THD
*
thd
,
Item
**
ref
)
{
{
...
@@ -663,15 +634,12 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
...
@@ -663,15 +634,12 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
switch
(
hybrid_type
=
item
->
result_type
())
{
switch
(
hybrid_type
=
item
->
result_type
())
{
case
INT_RESULT
:
case
INT_RESULT
:
max_length
=
20
;
max_length
=
20
;
sum_int
=
0
;
break
;
break
;
case
DECIMAL_RESULT
:
case
DECIMAL_RESULT
:
max_length
=
item
->
max_length
;
max_length
=
item
->
max_length
;
my_decimal_set_zero
(
&
sum_dec
);
break
;
break
;
case
REAL_RESULT
:
case
REAL_RESULT
:
max_length
=
float_length
(
decimals
);
max_length
=
float_length
(
decimals
);
sum
=
0.0
;
break
;
break
;
case
STRING_RESULT
:
case
STRING_RESULT
:
max_length
=
item
->
max_length
;
max_length
=
item
->
max_length
;
...
@@ -680,10 +648,10 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
...
@@ -680,10 +648,10 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
default:
default:
DBUG_ASSERT
(
0
);
DBUG_ASSERT
(
0
);
};
};
setup
(
args
[
0
],
NULL
);
/* MIN/MAX can return NULL for empty set indepedent of the used column */
/* MIN/MAX can return NULL for empty set indepedent of the used column */
maybe_null
=
1
;
maybe_null
=
1
;
unsigned_flag
=
item
->
unsigned_flag
;
unsigned_flag
=
item
->
unsigned_flag
;
collation
.
set
(
item
->
collation
);
result_field
=
0
;
result_field
=
0
;
null_value
=
1
;
null_value
=
1
;
fix_length_and_dec
();
fix_length_and_dec
();
...
@@ -701,6 +669,30 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
...
@@ -701,6 +669,30 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
return
FALSE
;
return
FALSE
;
}
}
/**
MIN/MAX function setup.
@param item argument of MIN/MAX function
@param value_arg calculated value of MIN/MAX function
@details
Setup cache/comparator of MIN/MAX functions. When called by the
copy_or_same function value_arg parameter contains calculated value
of the original MIN/MAX object and it is saved in this object's cache.
*/
void
Item_sum_hybrid
::
setup
(
Item
*
item
,
Item
*
value_arg
)
{
value
=
Item_cache
::
get_cache
(
item
);
value
->
setup
(
item
);
value
->
store
(
value_arg
);
cmp
=
new
Arg_comparator
();
cmp
->
set_cmp_func
(
this
,
args
,
(
Item
**
)
&
value
,
FALSE
);
collation
.
set
(
item
->
collation
);
}
Field
*
Item_sum_hybrid
::
create_tmp_field
(
bool
group
,
TABLE
*
table
,
Field
*
Item_sum_hybrid
::
create_tmp_field
(
bool
group
,
TABLE
*
table
,
uint
convert_blob_length
)
uint
convert_blob_length
)
{
{
...
@@ -1592,19 +1584,7 @@ void Item_sum_variance::update_field()
...
@@ -1592,19 +1584,7 @@ void Item_sum_variance::update_field()
void
Item_sum_hybrid
::
clear
()
void
Item_sum_hybrid
::
clear
()
{
{
switch
(
hybrid_type
)
{
value
->
null_value
=
1
;
case
INT_RESULT
:
sum_int
=
0
;
break
;
case
DECIMAL_RESULT
:
my_decimal_set_zero
(
&
sum_dec
);
break
;
case
REAL_RESULT
:
sum
=
0.0
;
break
;
default:
value
.
length
(
0
);
}
null_value
=
1
;
null_value
=
1
;
}
}
...
@@ -1613,30 +1593,7 @@ double Item_sum_hybrid::val_real()
...
@@ -1613,30 +1593,7 @@ double Item_sum_hybrid::val_real()
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
if
(
null_value
)
if
(
null_value
)
return
0.0
;
return
0.0
;
switch
(
hybrid_type
)
{
return
value
->
val_real
();
case
STRING_RESULT
:
{
char
*
end_not_used
;
int
err_not_used
;
String
*
res
;
res
=
val_str
(
&
str_value
);
return
(
res
?
my_strntod
(
res
->
charset
(),
(
char
*
)
res
->
ptr
(),
res
->
length
(),
&
end_not_used
,
&
err_not_used
)
:
0.0
);
}
case
INT_RESULT
:
if
(
unsigned_flag
)
return
ulonglong2double
(
sum_int
);
return
(
double
)
sum_int
;
case
DECIMAL_RESULT
:
my_decimal2double
(
E_DEC_FATAL_ERROR
,
&
sum_dec
,
&
sum
);
return
sum
;
case
REAL_RESULT
:
return
sum
;
case
ROW_RESULT
:
default:
// This case should never be choosen
DBUG_ASSERT
(
0
);
return
0
;
}
}
}
longlong
Item_sum_hybrid
::
val_int
()
longlong
Item_sum_hybrid
::
val_int
()
...
@@ -1644,18 +1601,7 @@ longlong Item_sum_hybrid::val_int()
...
@@ -1644,18 +1601,7 @@ longlong Item_sum_hybrid::val_int()
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
if
(
null_value
)
if
(
null_value
)
return
0
;
return
0
;
switch
(
hybrid_type
)
{
return
value
->
val_int
();
case
INT_RESULT
:
return
sum_int
;
case
DECIMAL_RESULT
:
{
longlong
result
;
my_decimal2int
(
E_DEC_FATAL_ERROR
,
&
sum_dec
,
unsigned_flag
,
&
result
);
return
sum_int
;
}
default:
return
(
longlong
)
rint
(
Item_sum_hybrid
::
val_real
());
}
}
}
...
@@ -1664,26 +1610,7 @@ my_decimal *Item_sum_hybrid::val_decimal(my_decimal *val)
...
@@ -1664,26 +1610,7 @@ my_decimal *Item_sum_hybrid::val_decimal(my_decimal *val)
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
if
(
null_value
)
if
(
null_value
)
return
0
;
return
0
;
switch
(
hybrid_type
)
{
return
value
->
val_decimal
(
val
);
case
STRING_RESULT
:
string2my_decimal
(
E_DEC_FATAL_ERROR
,
&
value
,
val
);
break
;
case
REAL_RESULT
:
double2my_decimal
(
E_DEC_FATAL_ERROR
,
sum
,
val
);
break
;
case
DECIMAL_RESULT
:
val
=
&
sum_dec
;
break
;
case
INT_RESULT
:
int2my_decimal
(
E_DEC_FATAL_ERROR
,
sum_int
,
unsigned_flag
,
val
);
break
;
case
ROW_RESULT
:
default:
// This case should never be choosen
DBUG_ASSERT
(
0
);
break
;
}
return
val
;
// Keep compiler happy
}
}
...
@@ -1693,25 +1620,7 @@ Item_sum_hybrid::val_str(String *str)
...
@@ -1693,25 +1620,7 @@ Item_sum_hybrid::val_str(String *str)
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
if
(
null_value
)
if
(
null_value
)
return
0
;
return
0
;
switch
(
hybrid_type
)
{
return
value
->
val_str
(
str
);
case
STRING_RESULT
:
return
&
value
;
case
REAL_RESULT
:
str
->
set_real
(
sum
,
decimals
,
&
my_charset_bin
);
break
;
case
DECIMAL_RESULT
:
my_decimal2string
(
E_DEC_FATAL_ERROR
,
&
sum_dec
,
0
,
0
,
0
,
str
);
return
str
;
case
INT_RESULT
:
str
->
set_int
(
sum_int
,
unsigned_flag
,
&
my_charset_bin
);
break
;
case
ROW_RESULT
:
default:
// This case should never be choosen
DBUG_ASSERT
(
0
);
break
;
}
return
str
;
// Keep compiler happy
}
}
...
@@ -1720,7 +1629,9 @@ void Item_sum_hybrid::cleanup()
...
@@ -1720,7 +1629,9 @@ void Item_sum_hybrid::cleanup()
DBUG_ENTER
(
"Item_sum_hybrid::cleanup"
);
DBUG_ENTER
(
"Item_sum_hybrid::cleanup"
);
Item_sum
::
cleanup
();
Item_sum
::
cleanup
();
forced_const
=
FALSE
;
forced_const
=
FALSE
;
if
(
cmp
)
delete
cmp
;
cmp
=
0
;
/*
/*
by default it is TRUE to avoid TRUE reporting by
by default it is TRUE to avoid TRUE reporting by
Item_func_not_all/Item_func_nop_all if this item was never called.
Item_func_not_all/Item_func_nop_all if this item was never called.
...
@@ -1741,63 +1652,22 @@ void Item_sum_hybrid::no_rows_in_result()
...
@@ -1741,63 +1652,22 @@ void Item_sum_hybrid::no_rows_in_result()
Item
*
Item_sum_min
::
copy_or_same
(
THD
*
thd
)
Item
*
Item_sum_min
::
copy_or_same
(
THD
*
thd
)
{
{
return
new
(
thd
->
mem_root
)
Item_sum_min
(
thd
,
this
);
Item_sum_min
*
item
=
new
(
thd
->
mem_root
)
Item_sum_min
(
thd
,
this
);
item
->
setup
(
args
[
0
],
value
);
return
item
;
}
}
bool
Item_sum_min
::
add
()
bool
Item_sum_min
::
add
()
{
{
switch
(
hybrid_type
)
{
/* args[0] < value */
case
STRING_RESULT
:
int
res
=
cmp
->
compare
();
if
(
!
args
[
0
]
->
null_value
&&
(
null_value
||
res
<
0
))
{
{
String
*
result
=
args
[
0
]
->
val_str
(
&
tmp_value
);
value
->
store
(
args
[
0
]);
if
(
!
args
[
0
]
->
null_value
&&
value
->
cache_value
();
(
null_value
||
sortcmp
(
&
value
,
result
,
collation
.
collation
)
>
0
))
null_value
=
0
;
{
value
.
copy
(
*
result
);
null_value
=
0
;
}
}
break
;
case
INT_RESULT
:
{
longlong
nr
=
args
[
0
]
->
val_int
();
if
(
!
args
[
0
]
->
null_value
&&
(
null_value
||
(
unsigned_flag
&&
(
ulonglong
)
nr
<
(
ulonglong
)
sum_int
)
||
(
!
unsigned_flag
&&
nr
<
sum_int
)))
{
sum_int
=
nr
;
null_value
=
0
;
}
}
break
;
case
DECIMAL_RESULT
:
{
my_decimal
value_buff
,
*
val
=
args
[
0
]
->
val_decimal
(
&
value_buff
);
if
(
!
args
[
0
]
->
null_value
&&
(
null_value
||
(
my_decimal_cmp
(
&
sum_dec
,
val
)
>
0
)))
{
my_decimal2decimal
(
val
,
&
sum_dec
);
null_value
=
0
;
}
}
break
;
case
REAL_RESULT
:
{
double
nr
=
args
[
0
]
->
val_real
();
if
(
!
args
[
0
]
->
null_value
&&
(
null_value
||
nr
<
sum
))
{
sum
=
nr
;
null_value
=
0
;
}
}
break
;
case
ROW_RESULT
:
default:
// This case should never be choosen
DBUG_ASSERT
(
0
);
break
;
}
}
return
0
;
return
0
;
}
}
...
@@ -1805,63 +1675,22 @@ bool Item_sum_min::add()
...
@@ -1805,63 +1675,22 @@ bool Item_sum_min::add()
Item
*
Item_sum_max
::
copy_or_same
(
THD
*
thd
)
Item
*
Item_sum_max
::
copy_or_same
(
THD
*
thd
)
{
{
return
new
(
thd
->
mem_root
)
Item_sum_max
(
thd
,
this
);
Item_sum_max
*
item
=
new
(
thd
->
mem_root
)
Item_sum_max
(
thd
,
this
);
item
->
setup
(
args
[
0
],
value
);
return
item
;
}
}
bool
Item_sum_max
::
add
()
bool
Item_sum_max
::
add
()
{
{
switch
(
hybrid_type
)
{
/* args[0] > value */
case
STRING_RESULT
:
int
res
=
cmp
->
compare
();
if
(
!
args
[
0
]
->
null_value
&&
(
null_value
||
res
>
0
))
{
{
String
*
result
=
args
[
0
]
->
val_str
(
&
tmp_value
);
value
->
store
(
args
[
0
]);
if
(
!
args
[
0
]
->
null_value
&&
value
->
cache_value
();
(
null_value
||
sortcmp
(
&
value
,
result
,
collation
.
collation
)
<
0
))
null_value
=
0
;
{
value
.
copy
(
*
result
);
null_value
=
0
;
}
}
break
;
case
INT_RESULT
:
{
longlong
nr
=
args
[
0
]
->
val_int
();
if
(
!
args
[
0
]
->
null_value
&&
(
null_value
||
(
unsigned_flag
&&
(
ulonglong
)
nr
>
(
ulonglong
)
sum_int
)
||
(
!
unsigned_flag
&&
nr
>
sum_int
)))
{
sum_int
=
nr
;
null_value
=
0
;
}
}
break
;
case
DECIMAL_RESULT
:
{
my_decimal
value_buff
,
*
val
=
args
[
0
]
->
val_decimal
(
&
value_buff
);
if
(
!
args
[
0
]
->
null_value
&&
(
null_value
||
(
my_decimal_cmp
(
val
,
&
sum_dec
)
>
0
)))
{
my_decimal2decimal
(
val
,
&
sum_dec
);
null_value
=
0
;
}
}
break
;
case
REAL_RESULT
:
{
double
nr
=
args
[
0
]
->
val_real
();
if
(
!
args
[
0
]
->
null_value
&&
(
null_value
||
nr
>
sum
))
{
sum
=
nr
;
null_value
=
0
;
}
}
break
;
case
ROW_RESULT
:
default:
// This case should never be choosen
DBUG_ASSERT
(
0
);
break
;
}
}
return
0
;
return
0
;
}
}
...
@@ -2226,14 +2055,15 @@ void Item_sum_hybrid::update_field()
...
@@ -2226,14 +2055,15 @@ void Item_sum_hybrid::update_field()
void
void
Item_sum_hybrid
::
min_max_update_str_field
()
Item_sum_hybrid
::
min_max_update_str_field
()
{
{
String
*
res_str
=
args
[
0
]
->
val_str
(
&
value
);
DBUG_ASSERT
(
cmp
);
String
*
res_str
=
args
[
0
]
->
val_str
(
&
cmp
->
value1
);
if
(
!
args
[
0
]
->
null_value
)
if
(
!
args
[
0
]
->
null_value
)
{
{
result_field
->
val_str
(
&
tmp_value
);
result_field
->
val_str
(
&
cmp
->
value2
);
if
(
result_field
->
is_null
()
||
if
(
result_field
->
is_null
()
||
(
cmp_sign
*
sortcmp
(
res_str
,
&
tmp_value
,
collation
.
collation
))
<
0
)
(
cmp_sign
*
sortcmp
(
res_str
,
&
cmp
->
value2
,
collation
.
collation
))
<
0
)
result_field
->
store
(
res_str
->
ptr
(),
res_str
->
length
(),
res_str
->
charset
());
result_field
->
store
(
res_str
->
ptr
(),
res_str
->
length
(),
res_str
->
charset
());
result_field
->
set_notnull
();
result_field
->
set_notnull
();
}
}
...
...
sql/item_sum.h
View file @
9f638f53
...
@@ -323,22 +323,6 @@ class Item_sum :public Item_result_field
...
@@ -323,22 +323,6 @@ class Item_sum :public Item_result_field
virtual
void
update_field
()
=
0
;
virtual
void
update_field
()
=
0
;
virtual
bool
keep_field_type
(
void
)
const
{
return
0
;
}
virtual
bool
keep_field_type
(
void
)
const
{
return
0
;
}
virtual
void
fix_length_and_dec
()
{
maybe_null
=
1
;
null_value
=
1
;
}
virtual
void
fix_length_and_dec
()
{
maybe_null
=
1
;
null_value
=
1
;
}
/*
This method is used for debug purposes to print the name of an
item to the debug log. The second use of this method is as
a helper function of print(), where it is applicable.
To suit both goals it should return a meaningful,
distinguishable and sintactically correct string. This method
should not be used for runtime type identification, use enum
{Sum}Functype and Item_func::functype()/Item_sum::sum_func()
instead.
NOTE: for Items inherited from Item_sum, func_name() return part of
function name till first argument (including '(') to make difference in
names for functions with 'distinct' clause and without 'distinct' and
also to make printing of items inherited from Item_sum uniform.
*/
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
used_tables_cache
;
}
table_map
used_tables
()
const
{
return
used_tables_cache
;
}
...
@@ -664,6 +648,7 @@ class Item_avg_field :public Item_result_field
...
@@ -664,6 +648,7 @@ class Item_avg_field :public Item_result_field
}
}
void
fix_length_and_dec
()
{}
void
fix_length_and_dec
()
{}
enum
Item_result
result_type
()
const
{
return
hybrid_type
;
}
enum
Item_result
result_type
()
const
{
return
hybrid_type
;
}
const
char
*
func_name
()
const
{
DBUG_ASSERT
(
0
);
return
"avg_field"
;
}
};
};
...
@@ -732,6 +717,7 @@ class Item_variance_field :public Item_result_field
...
@@ -732,6 +717,7 @@ class Item_variance_field :public Item_result_field
}
}
void
fix_length_and_dec
()
{}
void
fix_length_and_dec
()
{}
enum
Item_result
result_type
()
const
{
return
hybrid_type
;
}
enum
Item_result
result_type
()
const
{
return
hybrid_type
;
}
const
char
*
func_name
()
const
{
DBUG_ASSERT
(
0
);
return
"variance_field"
;
}
};
};
...
@@ -807,6 +793,7 @@ class Item_std_field :public Item_variance_field
...
@@ -807,6 +793,7 @@ class Item_std_field :public Item_variance_field
my_decimal
*
val_decimal
(
my_decimal
*
);
my_decimal
*
val_decimal
(
my_decimal
*
);
enum
Item_result
result_type
()
const
{
return
REAL_RESULT
;
}
enum
Item_result
result_type
()
const
{
return
REAL_RESULT
;
}
enum_field_types
field_type
()
const
{
return
MYSQL_TYPE_DOUBLE
;}
enum_field_types
field_type
()
const
{
return
MYSQL_TYPE_DOUBLE
;}
const
char
*
func_name
()
const
{
DBUG_ASSERT
(
0
);
return
"std_field"
;
}
};
};
/*
/*
...
@@ -832,14 +819,13 @@ class Item_sum_std :public Item_sum_variance
...
@@ -832,14 +819,13 @@ class Item_sum_std :public Item_sum_variance
};
};
// This class is a string or number function depending on num_func
// This class is a string or number function depending on num_func
class
Arg_comparator
;
class
Item_cache
;
class
Item_sum_hybrid
:
public
Item_sum
class
Item_sum_hybrid
:
public
Item_sum
{
{
protected:
protected:
String
value
,
tmp_value
;
Item_cache
*
value
;
double
sum
;
Arg_comparator
*
cmp
;
longlong
sum_int
;
my_decimal
sum_dec
;
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
;
...
@@ -847,12 +833,17 @@ class Item_sum_hybrid :public Item_sum
...
@@ -847,12 +833,17 @@ class Item_sum_hybrid :public Item_sum
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
),
value
(
0
),
cmp
(
0
),
hybrid_type
(
INT_RESULT
),
hybrid_field_type
(
MYSQL_TYPE_LONGLONG
),
hybrid_type
(
INT_RESULT
),
hybrid_field_type
(
MYSQL_TYPE_LONGLONG
),
cmp_sign
(
sign
),
was_values
(
TRUE
)
cmp_sign
(
sign
),
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
)
:
Item_sum
(
thd
,
item
),
value
(
item
->
value
),
hybrid_type
(
item
->
hybrid_type
),
hybrid_field_type
(
item
->
hybrid_field_type
),
cmp_sign
(
item
->
cmp_sign
),
was_values
(
item
->
was_values
)
{
}
bool
fix_fields
(
THD
*
,
Item
**
);
bool
fix_fields
(
THD
*
,
Item
**
);
void
setup
(
Item
*
item
,
Item
*
value_arg
);
void
clear
();
void
clear
();
double
val_real
();
double
val_real
();
longlong
val_int
();
longlong
val_int
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment