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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
18448bc0
Commit
18448bc0
authored
Nov 24, 2009
by
Tatiana A. Nurnberg
Browse files
Options
Browse Files
Download
Plain Diff
auto-merge
parents
22d03452
8af68021
Changes
11
Show 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 @
18448bc0
...
@@ -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 @
18448bc0
...
@@ -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 @
18448bc0
...
@@ -6955,7 +6955,7 @@ Item_cache* Item_cache::get_cache(const Item *item, const Item_result type)
...
@@ -6955,7 +6955,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
:
...
@@ -6973,8 +6973,9 @@ Item_cache* Item_cache::get_cache(const Item *item, const Item_result type)
...
@@ -6973,8 +6973,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
;
}
}
...
@@ -6988,12 +6989,15 @@ void Item_cache::print(String *str, enum_query_type query_type)
...
@@ -6988,12 +6989,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
;
}
}
...
@@ -7010,8 +7014,8 @@ void Item_cache_int::store(Item *item, longlong val_arg)
...
@@ -7010,8 +7014,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
;
}
}
...
@@ -7020,8 +7024,8 @@ String *Item_cache_int::val_str(String *str)
...
@@ -7020,8 +7024,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
;
}
}
...
@@ -7029,40 +7033,43 @@ my_decimal *Item_cache_int::val_decimal(my_decimal *decimal_val)
...
@@ -7029,40 +7033,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
);
}
}
...
@@ -7070,8 +7077,8 @@ longlong Item_cache_real::val_int()
...
@@ -7070,8 +7077,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
;
}
}
...
@@ -7080,27 +7087,30 @@ String* Item_cache_real::val_str(String *str)
...
@@ -7080,27 +7087,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
;
}
}
...
@@ -7109,8 +7119,8 @@ longlong Item_cache_decimal::val_int()
...
@@ -7109,8 +7119,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
;
}
}
...
@@ -7118,8 +7128,8 @@ longlong Item_cache_decimal::val_int()
...
@@ -7118,8 +7128,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
);
...
@@ -7129,14 +7139,16 @@ String* Item_cache_decimal::val_str(String *str)
...
@@ -7129,14 +7139,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
);
...
@@ -7155,6 +7167,7 @@ void Item_cache_str::cache_value()
...
@@ -7155,6 +7167,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
()
...
@@ -7162,8 +7175,8 @@ double Item_cache_str::val_real()
...
@@ -7162,8 +7175,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
);
...
@@ -7175,8 +7188,8 @@ longlong Item_cache_str::val_int()
...
@@ -7175,8 +7188,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
);
...
@@ -7188,8 +7201,8 @@ longlong Item_cache_str::val_int()
...
@@ -7188,8 +7201,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
;
}
}
...
@@ -7197,8 +7210,8 @@ String* Item_cache_str::val_str(String *str)
...
@@ -7197,8 +7210,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
...
@@ -7209,8 +7222,8 @@ my_decimal *Item_cache_str::val_decimal(my_decimal *decimal_val)
...
@@ -7209,8 +7222,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
;
...
@@ -7245,13 +7258,21 @@ bool Item_cache_row::setup(Item * item)
...
@@ -7245,13 +7258,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
();
...
@@ -7260,6 +7281,7 @@ void Item_cache_row::cache_value()
...
@@ -7260,6 +7281,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 @
18448bc0
...
@@ -2138,6 +2138,23 @@ public:
...
@@ -2138,6 +2138,23 @@ public:
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 @@ public:
...
@@ -2947,7 +2964,7 @@ public:
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 @@ public:
...
@@ -2968,7 +2985,7 @@ public:
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 @@ public:
...
@@ -2984,7 +3001,7 @@ public:
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 @@ public:
...
@@ -3000,7 +3017,7 @@ public:
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 @@ public:
...
@@ -3025,7 +3042,7 @@ public:
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 @@ public:
...
@@ -3094,7 +3111,7 @@ public:
values
=
0
;
values
=
0
;
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
void
cache_value
();
bool
cache_value
();
};
};
...
...
sql/item_cmpfunc.cc
View file @
18448bc0
...
@@ -30,6 +30,9 @@
...
@@ -30,6 +30,9 @@
#include "sql_select.h"
#include "sql_select.h"
static
bool
convert_constant_item
(
THD
*
,
Item_field
*
,
Item
**
);
static
bool
convert_constant_item
(
THD
*
,
Item_field
*
,
Item
**
);
static
longlong
get_year_value
(
THD
*
thd
,
Item
***
item_arg
,
Item
**
cache_arg
,
Item
*
warn_item
,
bool
*
is_null
);
static
Item_result
item_store_type
(
Item_result
a
,
Item
*
item
,
static
Item_result
item_store_type
(
Item_result
a
,
Item
*
item
,
my_bool
unsigned_flag
)
my_bool
unsigned_flag
)
...
@@ -533,11 +536,12 @@ void Item_bool_func2::fix_length_and_dec()
...
@@ -533,11 +536,12 @@ void Item_bool_func2::fix_length_and_dec()
}
}
int
Arg_comparator
::
set_compare_func
(
Item_
bool_func2
*
item
,
Item_result
type
)
int
Arg_comparator
::
set_compare_func
(
Item_
result_field
*
item
,
Item_result
type
)
{
{
owner
=
item
;
owner
=
item
;
func
=
comparator_matrix
[
type
]
func
=
comparator_matrix
[
type
]
[
test
(
owner
->
functype
()
==
Item_func
::
EQUAL_FUNC
)];
[
is_owner_equal_func
()];
switch
(
type
)
{
switch
(
type
)
{
case
ROW_RESULT
:
case
ROW_RESULT
:
{
{
...
@@ -557,7 +561,8 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
...
@@ -557,7 +561,8 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
my_error
(
ER_OPERAND_COLUMNS
,
MYF
(
0
),
(
*
a
)
->
element_index
(
i
)
->
cols
());
my_error
(
ER_OPERAND_COLUMNS
,
MYF
(
0
),
(
*
a
)
->
element_index
(
i
)
->
cols
());
return
1
;
return
1
;
}
}
if
(
comparators
[
i
].
set_cmp_func
(
owner
,
(
*
a
)
->
addr
(
i
),
(
*
b
)
->
addr
(
i
)))
if
(
comparators
[
i
].
set_cmp_func
(
owner
,
(
*
a
)
->
addr
(
i
),
(
*
b
)
->
addr
(
i
),
set_null
))
return
1
;
return
1
;
}
}
break
;
break
;
...
@@ -571,7 +576,8 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
...
@@ -571,7 +576,8 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type)
if
(
cmp_collation
.
set
((
*
a
)
->
collation
,
(
*
b
)
->
collation
)
||
if
(
cmp_collation
.
set
((
*
a
)
->
collation
,
(
*
b
)
->
collation
)
||
cmp_collation
.
derivation
==
DERIVATION_NONE
)
cmp_collation
.
derivation
==
DERIVATION_NONE
)
{
{
my_coll_agg_error
((
*
a
)
->
collation
,
(
*
b
)
->
collation
,
owner
->
func_name
());
my_coll_agg_error
((
*
a
)
->
collation
,
(
*
b
)
->
collation
,
owner
->
func_name
());
return
1
;
return
1
;
}
}
if
(
cmp_collation
.
collation
==
&
my_charset_bin
)
if
(
cmp_collation
.
collation
==
&
my_charset_bin
)
...
@@ -881,7 +887,7 @@ get_time_value(THD *thd, Item ***item_arg, Item **cache_arg,
...
@@ -881,7 +887,7 @@ get_time_value(THD *thd, Item ***item_arg, Item **cache_arg,
}
}
int
Arg_comparator
::
set_cmp_func
(
Item_
bool_func2
*
owner_arg
,
int
Arg_comparator
::
set_cmp_func
(
Item_
result_field
*
owner_arg
,
Item
**
a1
,
Item
**
a2
,
Item
**
a1
,
Item
**
a2
,
Item_result
type
)
Item_result
type
)
{
{
...
@@ -891,6 +897,8 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
...
@@ -891,6 +897,8 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
owner
=
owner_arg
;
owner
=
owner_arg
;
a
=
a1
;
a
=
a1
;
b
=
a2
;
b
=
a2
;
owner
=
owner_arg
;
thd
=
current_thd
;
if
((
cmp_type
=
can_compare_as_dates
(
*
a
,
*
b
,
&
const_value
)))
if
((
cmp_type
=
can_compare_as_dates
(
*
a
,
*
b
,
&
const_value
)))
{
{
...
@@ -921,9 +929,10 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
...
@@ -921,9 +929,10 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
b
=
(
Item
**
)
&
b_cache
;
b
=
(
Item
**
)
&
b_cache
;
}
}
}
}
is_nulls_eq
=
test
(
owner
&&
owner
->
functype
()
==
Item_func
::
EQUAL_FUNC
);
is_nulls_eq
=
is_owner_equal_func
(
);
func
=
&
Arg_comparator
::
compare_datetime
;
func
=
&
Arg_comparator
::
compare_datetime
;
get_value_func
=
&
get_datetime_value
;
get_value_a_func
=
&
get_datetime_value
;
get_value_b_func
=
&
get_datetime_value
;
return
0
;
return
0
;
}
}
else
if
(
type
==
STRING_RESULT
&&
(
*
a
)
->
field_type
()
==
MYSQL_TYPE_TIME
&&
else
if
(
type
==
STRING_RESULT
&&
(
*
a
)
->
field_type
()
==
MYSQL_TYPE_TIME
&&
...
@@ -932,9 +941,10 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
...
@@ -932,9 +941,10 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
/* Compare TIME values as integers. */
/* Compare TIME values as integers. */
a_cache
=
0
;
a_cache
=
0
;
b_cache
=
0
;
b_cache
=
0
;
is_nulls_eq
=
test
(
owner
&&
owner
->
functype
()
==
Item_func
::
EQUAL_FUNC
);
is_nulls_eq
=
is_owner_equal_func
(
);
func
=
&
Arg_comparator
::
compare_datetime
;
func
=
&
Arg_comparator
::
compare_datetime
;
get_value_func
=
&
get_time_value
;
get_value_a_func
=
&
get_time_value
;
get_value_b_func
=
&
get_time_value
;
return
0
;
return
0
;
}
}
else
if
(
type
==
STRING_RESULT
&&
else
if
(
type
==
STRING_RESULT
&&
...
@@ -943,9 +953,29 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
...
@@ -943,9 +953,29 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
{
{
DTCollation
coll
;
DTCollation
coll
;
coll
.
set
((
*
a
)
->
collation
.
collation
);
coll
.
set
((
*
a
)
->
collation
.
collation
);
if
(
agg_item_set_converter
(
coll
,
owner
_arg
->
func_name
(),
if
(
agg_item_set_converter
(
coll
,
owner
->
func_name
(),
b
,
1
,
MY_COLL_CMP_CONV
,
1
))
b
,
1
,
MY_COLL_CMP_CONV
,
1
))
return
1
;
return
1
;
}
else
if
(
type
!=
ROW_RESULT
&&
((
*
a
)
->
field_type
()
==
MYSQL_TYPE_YEAR
||
(
*
b
)
->
field_type
()
==
MYSQL_TYPE_YEAR
))
{
is_nulls_eq
=
is_owner_equal_func
();
if
((
*
a
)
->
is_datetime
())
{
year_as_datetime
=
TRUE
;
get_value_a_func
=
&
get_datetime_value
;
}
else
if
((
*
a
)
->
field_type
()
==
MYSQL_TYPE_YEAR
)
get_value_a_func
=
&
get_year_value
;
if
((
*
b
)
->
is_datetime
())
{
year_as_datetime
=
TRUE
;
get_value_b_func
=
&
get_datetime_value
;
}
else
if
((
*
b
)
->
field_type
()
==
MYSQL_TYPE_YEAR
)
get_value_b_func
=
&
get_year_value
;
func
=
&
Arg_comparator
::
compare_year
;
return
0
;
}
}
a
=
cache_converted_constant
(
thd
,
a
,
&
a_cache
,
type
);
a
=
cache_converted_constant
(
thd
,
a
,
&
a_cache
,
type
);
...
@@ -988,11 +1018,11 @@ Item** Arg_comparator::cache_converted_constant(THD *thd, Item **value,
...
@@ -988,11 +1018,11 @@ Item** Arg_comparator::cache_converted_constant(THD *thd, Item **value,
}
}
void
Arg_comparator
::
set_datetime_cmp_func
(
Item
**
a1
,
Item
**
b1
)
void
Arg_comparator
::
set_datetime_cmp_func
(
Item_result_field
*
owner_arg
,
Item
**
a1
,
Item
**
b1
)
{
{
thd
=
current_thd
;
thd
=
current_thd
;
/* A caller will handle null values by itself. */
owner
=
owner_arg
;
owner
=
NULL
;
a
=
a1
;
a
=
a1
;
b
=
b1
;
b
=
b1
;
a_type
=
(
*
a
)
->
field_type
();
a_type
=
(
*
a
)
->
field_type
();
...
@@ -1001,7 +1031,8 @@ void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
...
@@ -1001,7 +1031,8 @@ void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
b_cache
=
0
;
b_cache
=
0
;
is_nulls_eq
=
FALSE
;
is_nulls_eq
=
FALSE
;
func
=
&
Arg_comparator
::
compare_datetime
;
func
=
&
Arg_comparator
::
compare_datetime
;
get_value_func
=
&
get_datetime_value
;
get_value_a_func
=
&
get_datetime_value
;
get_value_b_func
=
&
get_datetime_value
;
}
}
...
@@ -1101,6 +1132,51 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
...
@@ -1101,6 +1132,51 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
return
value
;
return
value
;
}
}
/*
Retrieves YEAR value of 19XX form from given item.
SYNOPSIS
get_year_value()
thd thread handle
item_arg [in/out] item to retrieve YEAR value from
cache_arg [in/out] pointer to place to store the caching item to
warn_item [in] item for issuing the conversion warning
is_null [out] TRUE <=> the item_arg is null
DESCRIPTION
Retrieves the YEAR value of 19XX form from given item for comparison by the
compare_year() function.
RETURN
obtained value
*/
static
longlong
get_year_value
(
THD
*
thd
,
Item
***
item_arg
,
Item
**
cache_arg
,
Item
*
warn_item
,
bool
*
is_null
)
{
longlong
value
=
0
;
Item
*
item
=
**
item_arg
;
value
=
item
->
val_int
();
*
is_null
=
item
->
null_value
;
if
(
*
is_null
)
return
~
(
ulonglong
)
0
;
/*
Coerce value to the 19XX form in order to correctly compare
YEAR(2) & YEAR(4) types.
*/
if
(
value
<
70
)
value
+=
100
;
if
(
value
<=
1900
)
value
+=
1900
;
return
value
;
}
/*
/*
Compare items values as dates.
Compare items values as dates.
...
@@ -1133,25 +1209,25 @@ int Arg_comparator::compare_datetime()
...
@@ -1133,25 +1209,25 @@ int Arg_comparator::compare_datetime()
longlong
a_value
,
b_value
;
longlong
a_value
,
b_value
;
/* Get DATE/DATETIME/TIME value of the 'a' item. */
/* Get DATE/DATETIME/TIME value of the 'a' item. */
a_value
=
(
*
get_value_func
)(
thd
,
&
a
,
&
a_cache
,
*
b
,
&
a_is_null
);
a_value
=
(
*
get_value_
a_
func
)(
thd
,
&
a
,
&
a_cache
,
*
b
,
&
a_is_null
);
if
(
!
is_nulls_eq
&&
a_is_null
)
if
(
!
is_nulls_eq
&&
a_is_null
)
{
{
if
(
owner
)
if
(
set_null
)
owner
->
null_value
=
1
;
owner
->
null_value
=
1
;
return
-
1
;
return
-
1
;
}
}
/* Get DATE/DATETIME/TIME value of the 'b' item. */
/* Get DATE/DATETIME/TIME value of the 'b' item. */
b_value
=
(
*
get_value_func
)(
thd
,
&
b
,
&
b_cache
,
*
a
,
&
b_is_null
);
b_value
=
(
*
get_value_
b_
func
)(
thd
,
&
b
,
&
b_cache
,
*
a
,
&
b_is_null
);
if
(
a_is_null
||
b_is_null
)
if
(
a_is_null
||
b_is_null
)
{
{
if
(
owner
)
if
(
set_null
)
owner
->
null_value
=
is_nulls_eq
?
0
:
1
;
owner
->
null_value
=
is_nulls_eq
?
0
:
1
;
return
is_nulls_eq
?
(
a_is_null
==
b_is_null
)
:
-
1
;
return
is_nulls_eq
?
(
a_is_null
==
b_is_null
)
:
-
1
;
}
}
/* Here we have two not-NULL values. */
/* Here we have two not-NULL values. */
if
(
owner
)
if
(
set_null
)
owner
->
null_value
=
0
;
owner
->
null_value
=
0
;
/* Compare values. */
/* Compare values. */
...
@@ -1164,14 +1240,16 @@ int Arg_comparator::compare_datetime()
...
@@ -1164,14 +1240,16 @@ int Arg_comparator::compare_datetime()
int
Arg_comparator
::
compare_string
()
int
Arg_comparator
::
compare_string
()
{
{
String
*
res1
,
*
res2
;
String
*
res1
,
*
res2
;
if
((
res1
=
(
*
a
)
->
val_str
(
&
owner
->
tmp_
value1
)))
if
((
res1
=
(
*
a
)
->
val_str
(
&
value1
)))
{
{
if
((
res2
=
(
*
b
)
->
val_str
(
&
owner
->
tmp_
value2
)))
if
((
res2
=
(
*
b
)
->
val_str
(
&
value2
)))
{
{
if
(
set_null
)
owner
->
null_value
=
0
;
owner
->
null_value
=
0
;
return
sortcmp
(
res1
,
res2
,
cmp_collation
.
collation
);
return
sortcmp
(
res1
,
res2
,
cmp_collation
.
collation
);
}
}
}
}
if
(
set_null
)
owner
->
null_value
=
1
;
owner
->
null_value
=
1
;
return
-
1
;
return
-
1
;
}
}
...
@@ -1191,10 +1269,11 @@ int Arg_comparator::compare_string()
...
@@ -1191,10 +1269,11 @@ int Arg_comparator::compare_string()
int
Arg_comparator
::
compare_binary_string
()
int
Arg_comparator
::
compare_binary_string
()
{
{
String
*
res1
,
*
res2
;
String
*
res1
,
*
res2
;
if
((
res1
=
(
*
a
)
->
val_str
(
&
owner
->
tmp_
value1
)))
if
((
res1
=
(
*
a
)
->
val_str
(
&
value1
)))
{
{
if
((
res2
=
(
*
b
)
->
val_str
(
&
owner
->
tmp_
value2
)))
if
((
res2
=
(
*
b
)
->
val_str
(
&
value2
)))
{
{
if
(
set_null
)
owner
->
null_value
=
0
;
owner
->
null_value
=
0
;
uint
res1_length
=
res1
->
length
();
uint
res1_length
=
res1
->
length
();
uint
res2_length
=
res2
->
length
();
uint
res2_length
=
res2
->
length
();
...
@@ -1202,6 +1281,7 @@ int Arg_comparator::compare_binary_string()
...
@@ -1202,6 +1281,7 @@ int Arg_comparator::compare_binary_string()
return
cmp
?
cmp
:
(
int
)
(
res1_length
-
res2_length
);
return
cmp
?
cmp
:
(
int
)
(
res1_length
-
res2_length
);
}
}
}
}
if
(
set_null
)
owner
->
null_value
=
1
;
owner
->
null_value
=
1
;
return
-
1
;
return
-
1
;
}
}
...
@@ -1215,8 +1295,8 @@ int Arg_comparator::compare_binary_string()
...
@@ -1215,8 +1295,8 @@ int Arg_comparator::compare_binary_string()
int
Arg_comparator
::
compare_e_string
()
int
Arg_comparator
::
compare_e_string
()
{
{
String
*
res1
,
*
res2
;
String
*
res1
,
*
res2
;
res1
=
(
*
a
)
->
val_str
(
&
owner
->
tmp_
value1
);
res1
=
(
*
a
)
->
val_str
(
&
value1
);
res2
=
(
*
b
)
->
val_str
(
&
owner
->
tmp_
value2
);
res2
=
(
*
b
)
->
val_str
(
&
value2
);
if
(
!
res1
||
!
res2
)
if
(
!
res1
||
!
res2
)
return
test
(
res1
==
res2
);
return
test
(
res1
==
res2
);
return
test
(
sortcmp
(
res1
,
res2
,
cmp_collation
.
collation
)
==
0
);
return
test
(
sortcmp
(
res1
,
res2
,
cmp_collation
.
collation
)
==
0
);
...
@@ -1226,8 +1306,8 @@ int Arg_comparator::compare_e_string()
...
@@ -1226,8 +1306,8 @@ int Arg_comparator::compare_e_string()
int
Arg_comparator
::
compare_e_binary_string
()
int
Arg_comparator
::
compare_e_binary_string
()
{
{
String
*
res1
,
*
res2
;
String
*
res1
,
*
res2
;
res1
=
(
*
a
)
->
val_str
(
&
owner
->
tmp_
value1
);
res1
=
(
*
a
)
->
val_str
(
&
value1
);
res2
=
(
*
b
)
->
val_str
(
&
owner
->
tmp_
value2
);
res2
=
(
*
b
)
->
val_str
(
&
value2
);
if
(
!
res1
||
!
res2
)
if
(
!
res1
||
!
res2
)
return
test
(
res1
==
res2
);
return
test
(
res1
==
res2
);
return
test
(
stringcmp
(
res1
,
res2
)
==
0
);
return
test
(
stringcmp
(
res1
,
res2
)
==
0
);
...
@@ -1248,12 +1328,14 @@ int Arg_comparator::compare_real()
...
@@ -1248,12 +1328,14 @@ int Arg_comparator::compare_real()
val2
=
(
*
b
)
->
val_real
();
val2
=
(
*
b
)
->
val_real
();
if
(
!
(
*
b
)
->
null_value
)
if
(
!
(
*
b
)
->
null_value
)
{
{
if
(
set_null
)
owner
->
null_value
=
0
;
owner
->
null_value
=
0
;
if
(
val1
<
val2
)
return
-
1
;
if
(
val1
<
val2
)
return
-
1
;
if
(
val1
==
val2
)
return
0
;
if
(
val1
==
val2
)
return
0
;
return
1
;
return
1
;
}
}
}
}
if
(
set_null
)
owner
->
null_value
=
1
;
owner
->
null_value
=
1
;
return
-
1
;
return
-
1
;
}
}
...
@@ -1268,10 +1350,12 @@ int Arg_comparator::compare_decimal()
...
@@ -1268,10 +1350,12 @@ int Arg_comparator::compare_decimal()
my_decimal
*
val2
=
(
*
b
)
->
val_decimal
(
&
value2
);
my_decimal
*
val2
=
(
*
b
)
->
val_decimal
(
&
value2
);
if
(
!
(
*
b
)
->
null_value
)
if
(
!
(
*
b
)
->
null_value
)
{
{
if
(
set_null
)
owner
->
null_value
=
0
;
owner
->
null_value
=
0
;
return
my_decimal_cmp
(
val1
,
val2
);
return
my_decimal_cmp
(
val1
,
val2
);
}
}
}
}
if
(
set_null
)
owner
->
null_value
=
1
;
owner
->
null_value
=
1
;
return
-
1
;
return
-
1
;
}
}
...
@@ -1310,6 +1394,7 @@ int Arg_comparator::compare_real_fixed()
...
@@ -1310,6 +1394,7 @@ int Arg_comparator::compare_real_fixed()
val2
=
(
*
b
)
->
val_real
();
val2
=
(
*
b
)
->
val_real
();
if
(
!
(
*
b
)
->
null_value
)
if
(
!
(
*
b
)
->
null_value
)
{
{
if
(
set_null
)
owner
->
null_value
=
0
;
owner
->
null_value
=
0
;
if
(
val1
==
val2
||
fabs
(
val1
-
val2
)
<
precision
)
if
(
val1
==
val2
||
fabs
(
val1
-
val2
)
<
precision
)
return
0
;
return
0
;
...
@@ -1318,6 +1403,7 @@ int Arg_comparator::compare_real_fixed()
...
@@ -1318,6 +1403,7 @@ int Arg_comparator::compare_real_fixed()
return
1
;
return
1
;
}
}
}
}
if
(
set_null
)
owner
->
null_value
=
1
;
owner
->
null_value
=
1
;
return
-
1
;
return
-
1
;
}
}
...
@@ -1341,12 +1427,14 @@ int Arg_comparator::compare_int_signed()
...
@@ -1341,12 +1427,14 @@ int Arg_comparator::compare_int_signed()
longlong
val2
=
(
*
b
)
->
val_int
();
longlong
val2
=
(
*
b
)
->
val_int
();
if
(
!
(
*
b
)
->
null_value
)
if
(
!
(
*
b
)
->
null_value
)
{
{
if
(
set_null
)
owner
->
null_value
=
0
;
owner
->
null_value
=
0
;
if
(
val1
<
val2
)
return
-
1
;
if
(
val1
<
val2
)
return
-
1
;
if
(
val1
==
val2
)
return
0
;
if
(
val1
==
val2
)
return
0
;
return
1
;
return
1
;
}
}
}
}
if
(
set_null
)
owner
->
null_value
=
1
;
owner
->
null_value
=
1
;
return
-
1
;
return
-
1
;
}
}
...
@@ -1364,12 +1452,14 @@ int Arg_comparator::compare_int_unsigned()
...
@@ -1364,12 +1452,14 @@ int Arg_comparator::compare_int_unsigned()
ulonglong
val2
=
(
*
b
)
->
val_int
();
ulonglong
val2
=
(
*
b
)
->
val_int
();
if
(
!
(
*
b
)
->
null_value
)
if
(
!
(
*
b
)
->
null_value
)
{
{
if
(
set_null
)
owner
->
null_value
=
0
;
owner
->
null_value
=
0
;
if
(
val1
<
val2
)
return
-
1
;
if
(
val1
<
val2
)
return
-
1
;
if
(
val1
==
val2
)
return
0
;
if
(
val1
==
val2
)
return
0
;
return
1
;
return
1
;
}
}
}
}
if
(
set_null
)
owner
->
null_value
=
1
;
owner
->
null_value
=
1
;
return
-
1
;
return
-
1
;
}
}
...
@@ -1387,6 +1477,7 @@ int Arg_comparator::compare_int_signed_unsigned()
...
@@ -1387,6 +1477,7 @@ int Arg_comparator::compare_int_signed_unsigned()
ulonglong
uval2
=
(
ulonglong
)(
*
b
)
->
val_int
();
ulonglong
uval2
=
(
ulonglong
)(
*
b
)
->
val_int
();
if
(
!
(
*
b
)
->
null_value
)
if
(
!
(
*
b
)
->
null_value
)
{
{
if
(
set_null
)
owner
->
null_value
=
0
;
owner
->
null_value
=
0
;
if
(
sval1
<
0
||
(
ulonglong
)
sval1
<
uval2
)
if
(
sval1
<
0
||
(
ulonglong
)
sval1
<
uval2
)
return
-
1
;
return
-
1
;
...
@@ -1395,6 +1486,7 @@ int Arg_comparator::compare_int_signed_unsigned()
...
@@ -1395,6 +1486,7 @@ int Arg_comparator::compare_int_signed_unsigned()
return
1
;
return
1
;
}
}
}
}
if
(
set_null
)
owner
->
null_value
=
1
;
owner
->
null_value
=
1
;
return
-
1
;
return
-
1
;
}
}
...
@@ -1412,6 +1504,7 @@ int Arg_comparator::compare_int_unsigned_signed()
...
@@ -1412,6 +1504,7 @@ int Arg_comparator::compare_int_unsigned_signed()
longlong
sval2
=
(
*
b
)
->
val_int
();
longlong
sval2
=
(
*
b
)
->
val_int
();
if
(
!
(
*
b
)
->
null_value
)
if
(
!
(
*
b
)
->
null_value
)
{
{
if
(
set_null
)
owner
->
null_value
=
0
;
owner
->
null_value
=
0
;
if
(
sval2
<
0
)
if
(
sval2
<
0
)
return
1
;
return
1
;
...
@@ -1422,6 +1515,7 @@ int Arg_comparator::compare_int_unsigned_signed()
...
@@ -1422,6 +1515,7 @@ int Arg_comparator::compare_int_unsigned_signed()
return
1
;
return
1
;
}
}
}
}
if
(
set_null
)
owner
->
null_value
=
1
;
owner
->
null_value
=
1
;
return
-
1
;
return
-
1
;
}
}
...
@@ -1458,10 +1552,11 @@ int Arg_comparator::compare_row()
...
@@ -1458,10 +1552,11 @@ int Arg_comparator::compare_row()
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
{
{
res
=
comparators
[
i
].
compare
();
res
=
comparators
[
i
].
compare
();
if
(
owner
->
null_value
)
/* Aggregate functions don't need special null handling. */
if
(
owner
->
null_value
&&
owner
->
type
()
==
Item
::
FUNC_ITEM
)
{
{
// NULL was compared
// NULL was compared
switch
(
owner
->
functype
())
{
switch
(
((
Item_func
*
)
owner
)
->
functype
())
{
case
Item_func
:
:
NE_FUNC
:
case
Item_func
:
:
NE_FUNC
:
break
;
// NE never aborts on NULL even if abort_on_null is set
break
;
// NE never aborts on NULL even if abort_on_null is set
case
Item_func
:
:
LT_FUNC
:
case
Item_func
:
:
LT_FUNC
:
...
@@ -1470,7 +1565,7 @@ int Arg_comparator::compare_row()
...
@@ -1470,7 +1565,7 @@ int Arg_comparator::compare_row()
case
Item_func
:
:
GE_FUNC
:
case
Item_func
:
:
GE_FUNC
:
return
-
1
;
// <, <=, > and >= always fail on NULL
return
-
1
;
// <, <=, > and >= always fail on NULL
default:
// EQ_FUNC
default:
// EQ_FUNC
if
(
owner
->
abort_on_null
)
if
(
((
Item_bool_func2
*
)
owner
)
->
abort_on_null
)
return
-
1
;
// We do not need correct NULL returning
return
-
1
;
// We do not need correct NULL returning
}
}
was_null
=
1
;
was_null
=
1
;
...
@@ -1507,6 +1602,67 @@ int Arg_comparator::compare_e_row()
...
@@ -1507,6 +1602,67 @@ int Arg_comparator::compare_e_row()
}
}
/**
Compare values as YEAR.
@details
Compare items as YEAR for EQUAL_FUNC and for other comparison functions.
The YEAR values of form 19XX are obtained with help of the get_year_value()
function.
If one of arguments is of DATE/DATETIME type its value is obtained
with help of the get_datetime_value function. In this case YEAR values
prior to comparison are converted to the ulonglong YYYY-00-00 00:00:00
DATETIME form.
If an argument type neither YEAR nor DATE/DATEIME then val_int function
is used to obtain value for comparison.
RETURN
If is_nulls_eq is TRUE:
1 if items are equal or both are null
0 otherwise
If is_nulls_eq is FALSE:
-1 a < b
0 a == b or at least one of items is null
1 a > b
See the table:
is_nulls_eq | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
a_is_null | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
b_is_null | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 |
result | 1 | 0 | 0 |0/1| 0 | 0 | 0 |-1/0/1|
*/
int
Arg_comparator
::
compare_year
()
{
bool
a_is_null
,
b_is_null
;
ulonglong
val1
=
get_value_a_func
?
(
*
get_value_a_func
)(
thd
,
&
a
,
&
a_cache
,
*
b
,
&
a_is_null
)
:
(
*
a
)
->
val_int
();
ulonglong
val2
=
get_value_b_func
?
(
*
get_value_b_func
)(
thd
,
&
b
,
&
b_cache
,
*
a
,
&
b_is_null
)
:
(
*
b
)
->
val_int
();
if
(
!
(
*
a
)
->
null_value
)
{
if
(
!
(
*
b
)
->
null_value
)
{
if
(
set_null
)
owner
->
null_value
=
0
;
/* Convert year to DATETIME of form YYYY-00-00 00:00:00 when necessary. */
if
((
*
a
)
->
field_type
()
==
MYSQL_TYPE_YEAR
&&
year_as_datetime
)
val1
*=
10000000000LL
;
if
((
*
b
)
->
field_type
()
==
MYSQL_TYPE_YEAR
&&
year_as_datetime
)
val2
*=
10000000000LL
;
if
(
val1
<
val2
)
return
is_nulls_eq
?
0
:
-
1
;
if
(
val1
==
val2
)
return
is_nulls_eq
?
1
:
0
;
return
is_nulls_eq
?
0
:
1
;
}
}
if
(
set_null
)
owner
->
null_value
=
is_nulls_eq
?
0
:
1
;
return
(
is_nulls_eq
&&
(
*
a
)
->
null_value
==
(
*
b
)
->
null_value
)
?
1
:
0
;
}
void
Item_func_truth
::
fix_length_and_dec
()
void
Item_func_truth
::
fix_length_and_dec
()
{
{
maybe_null
=
0
;
maybe_null
=
0
;
...
@@ -1794,8 +1950,8 @@ longlong Item_func_lt::val_int()
...
@@ -1794,8 +1950,8 @@ longlong Item_func_lt::val_int()
longlong
Item_func_strcmp
::
val_int
()
longlong
Item_func_strcmp
::
val_int
()
{
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
String
*
a
=
args
[
0
]
->
val_str
(
&
tmp_
value1
);
String
*
a
=
args
[
0
]
->
val_str
(
&
cmp
.
value1
);
String
*
b
=
args
[
1
]
->
val_str
(
&
tmp_
value2
);
String
*
b
=
args
[
1
]
->
val_str
(
&
cmp
.
value2
);
if
(
!
a
||
!
b
)
if
(
!
a
||
!
b
)
{
{
null_value
=
1
;
null_value
=
1
;
...
@@ -2078,8 +2234,8 @@ void Item_func_between::fix_length_and_dec()
...
@@ -2078,8 +2234,8 @@ void Item_func_between::fix_length_and_dec()
if
(
compare_as_dates
)
if
(
compare_as_dates
)
{
{
ge_cmp
.
set_datetime_cmp_func
(
args
,
args
+
1
);
ge_cmp
.
set_datetime_cmp_func
(
this
,
args
,
args
+
1
);
le_cmp
.
set_datetime_cmp_func
(
args
,
args
+
2
);
le_cmp
.
set_datetime_cmp_func
(
this
,
args
,
args
+
2
);
}
}
else
if
(
time_items_found
==
3
)
else
if
(
time_items_found
==
3
)
{
{
...
@@ -4407,13 +4563,13 @@ void Item_func_isnotnull::print(String *str, enum_query_type query_type)
...
@@ -4407,13 +4563,13 @@ void Item_func_isnotnull::print(String *str, enum_query_type query_type)
longlong
Item_func_like
::
val_int
()
longlong
Item_func_like
::
val_int
()
{
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
String
*
res
=
args
[
0
]
->
val_str
(
&
tmp_
value1
);
String
*
res
=
args
[
0
]
->
val_str
(
&
cmp
.
value1
);
if
(
args
[
0
]
->
null_value
)
if
(
args
[
0
]
->
null_value
)
{
{
null_value
=
1
;
null_value
=
1
;
return
0
;
return
0
;
}
}
String
*
res2
=
args
[
1
]
->
val_str
(
&
tmp_
value2
);
String
*
res2
=
args
[
1
]
->
val_str
(
&
cmp
.
value2
);
if
(
args
[
1
]
->
null_value
)
if
(
args
[
1
]
->
null_value
)
{
{
null_value
=
1
;
null_value
=
1
;
...
@@ -4437,7 +4593,7 @@ Item_func::optimize_type Item_func_like::select_optimize() const
...
@@ -4437,7 +4593,7 @@ Item_func::optimize_type Item_func_like::select_optimize() const
{
{
if
(
args
[
1
]
->
const_item
())
if
(
args
[
1
]
->
const_item
())
{
{
String
*
res2
=
args
[
1
]
->
val_str
((
String
*
)
&
tmp_
value2
);
String
*
res2
=
args
[
1
]
->
val_str
((
String
*
)
&
cmp
.
value2
);
if
(
!
res2
)
if
(
!
res2
)
return
OPTIMIZE_NONE
;
return
OPTIMIZE_NONE
;
...
@@ -4468,7 +4624,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref)
...
@@ -4468,7 +4624,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref)
if
(
escape_item
->
const_item
())
if
(
escape_item
->
const_item
())
{
{
/* If we are on execution stage */
/* If we are on execution stage */
String
*
escape_str
=
escape_item
->
val_str
(
&
tmp_
value1
);
String
*
escape_str
=
escape_item
->
val_str
(
&
cmp
.
value1
);
if
(
escape_str
)
if
(
escape_str
)
{
{
if
(
escape_used_in_parsing
&&
(
if
(
escape_used_in_parsing
&&
(
...
@@ -4523,7 +4679,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref)
...
@@ -4523,7 +4679,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref)
if
(
args
[
1
]
->
const_item
()
&&
!
use_strnxfrm
(
collation
.
collation
)
&&
if
(
args
[
1
]
->
const_item
()
&&
!
use_strnxfrm
(
collation
.
collation
)
&&
!
(
specialflag
&
SPECIAL_NO_NEW_FUNC
))
!
(
specialflag
&
SPECIAL_NO_NEW_FUNC
))
{
{
String
*
res2
=
args
[
1
]
->
val_str
(
&
tmp_
value2
);
String
*
res2
=
args
[
1
]
->
val_str
(
&
cmp
.
value2
);
if
(
!
res2
)
if
(
!
res2
)
return
FALSE
;
// Null argument
return
FALSE
;
// Null argument
...
...
sql/item_cmpfunc.h
View file @
18448bc0
...
@@ -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
);
longlong
(
*
get_value_b_func
)(
THD
*
thd
,
Item
***
item_arg
,
Item
**
cache_arg
,
Item
*
warn_item
,
bool
*
is_null
);
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 @@ public:
...
@@ -89,14 +101,20 @@ public:
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 @@ public:
...
@@ -335,7 +352,7 @@ public:
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 @
18448bc0
...
@@ -124,17 +124,6 @@ public:
...
@@ -124,17 +124,6 @@ public:
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 @
18448bc0
...
@@ -511,8 +511,8 @@ err:
...
@@ -511,8 +511,8 @@ err:
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 @
18448bc0
...
@@ -132,6 +132,7 @@ public:
...
@@ -132,6 +132,7 @@ public:
@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 @
18448bc0
...
@@ -614,35 +614,6 @@ Item_sum_num::fix_fields(THD *thd, Item **ref)
...
@@ -614,35 +614,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
)
{
{
...
@@ -662,15 +633,12 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
...
@@ -662,15 +633,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
;
...
@@ -679,10 +647,10 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
...
@@ -679,10 +647,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
();
...
@@ -700,6 +668,30 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
...
@@ -700,6 +668,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
)
{
{
...
@@ -1590,19 +1582,7 @@ void Item_sum_variance::update_field()
...
@@ -1590,19 +1582,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
;
}
}
...
@@ -1611,30 +1591,7 @@ double Item_sum_hybrid::val_real()
...
@@ -1611,30 +1591,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
()
...
@@ -1642,18 +1599,7 @@ longlong Item_sum_hybrid::val_int()
...
@@ -1642,18 +1599,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
());
}
}
}
...
@@ -1662,26 +1608,7 @@ my_decimal *Item_sum_hybrid::val_decimal(my_decimal *val)
...
@@ -1662,26 +1608,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
}
}
...
@@ -1691,25 +1618,7 @@ Item_sum_hybrid::val_str(String *str)
...
@@ -1691,25 +1618,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
}
}
...
@@ -1718,7 +1627,9 @@ void Item_sum_hybrid::cleanup()
...
@@ -1718,7 +1627,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.
...
@@ -1739,128 +1650,46 @@ void Item_sum_hybrid::no_rows_in_result()
...
@@ -1739,128 +1650,46 @@ 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
();
{
String
*
result
=
args
[
0
]
->
val_str
(
&
tmp_value
);
if
(
!
args
[
0
]
->
null_value
&&
if
(
!
args
[
0
]
->
null_value
&&
(
null_value
||
sortcmp
(
&
value
,
result
,
collation
.
collation
)
>
0
))
(
null_value
||
res
<
0
))
{
value
.
copy
(
*
result
);
null_value
=
0
;
}
}
break
;
case
INT_RESULT
:
{
{
longlong
nr
=
args
[
0
]
->
val_int
();
value
->
store
(
args
[
0
]);
if
(
!
args
[
0
]
->
null_value
&&
(
null_value
||
value
->
cache_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
;
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
;
}
}
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
();
{
String
*
result
=
args
[
0
]
->
val_str
(
&
tmp_value
);
if
(
!
args
[
0
]
->
null_value
&&
if
(
!
args
[
0
]
->
null_value
&&
(
null_value
||
sortcmp
(
&
value
,
result
,
collation
.
collation
)
<
0
))
(
null_value
||
res
>
0
))
{
{
value
.
copy
(
*
result
);
value
->
store
(
args
[
0
]);
null_value
=
0
;
value
->
cache_value
();
}
}
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
;
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
;
}
}
...
@@ -2224,14 +2053,15 @@ void Item_sum_hybrid::update_field()
...
@@ -2224,14 +2053,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 @
18448bc0
...
@@ -323,22 +323,6 @@ public:
...
@@ -323,22 +323,6 @@ public:
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 @@ public:
...
@@ -664,6 +648,7 @@ public:
}
}
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 @@ public:
...
@@ -732,6 +717,7 @@ public:
}
}
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 @@ public:
...
@@ -807,6 +793,7 @@ public:
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 @@ protected:
...
@@ -847,12 +833,17 @@ protected:
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