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
7d00a27f
Commit
7d00a27f
authored
Nov 24, 2009
by
Tatiana A. Nurnberg
Browse files
Options
Browse Files
Download
Plain Diff
auto-merge
parents
0abb82b9
982bfdb0
Changes
11
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 @
7d00a27f
...
...
@@ -885,7 +885,7 @@ cast(sum(distinct df) as signed)
3
select cast(min(df) as signed) from t1;
cast(min(df) as signed)
0
1
select 1e8 * sum(distinct df) from t1;
1e8 * sum(distinct df)
330000000
...
...
@@ -1520,4 +1520,197 @@ max i
# Cleanup
#
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
mysql-test/t/func_group.test
View file @
7d00a27f
...
...
@@ -1053,4 +1053,35 @@ ORDER BY max;
--
echo
#
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
sql/item.cc
View file @
7d00a27f
...
...
@@ -6955,7 +6955,7 @@ Item_cache* Item_cache::get_cache(const Item *item, const Item_result type)
{
switch
(
type
)
{
case
INT_RESULT
:
return
new
Item_cache_int
();
return
new
Item_cache_int
(
item
->
field_type
()
);
case
REAL_RESULT
:
return
new
Item_cache_real
();
case
DECIMAL_RESULT
:
...
...
@@ -6973,8 +6973,9 @@ Item_cache* Item_cache::get_cache(const Item *item, const Item_result type)
void
Item_cache
::
store
(
Item
*
item
)
{
if
(
item
)
example
=
item
;
example
=
item
;
if
(
!
item
)
null_value
=
TRUE
;
value_cached
=
FALSE
;
}
...
...
@@ -6988,12 +6989,15 @@ void Item_cache::print(String *str, enum_query_type query_type)
str
->
append
(
')'
);
}
void
Item_cache_int
::
cache_value
()
bool
Item_cache_int
::
cache_value
()
{
if
(
!
example
)
return
FALSE
;
value_cached
=
TRUE
;
value
=
example
->
val_int_result
();
null_value
=
example
->
null_value
;
unsigned_flag
=
example
->
unsigned_flag
;
return
TRUE
;
}
...
...
@@ -7010,8 +7014,8 @@ void Item_cache_int::store(Item *item, longlong val_arg)
String
*
Item_cache_int
::
val_str
(
String
*
str
)
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
()
;
if
(
!
value_cached
&&
!
cache_value
()
)
return
NULL
;
str
->
set
(
value
,
default_charset
());
return
str
;
}
...
...
@@ -7020,8 +7024,8 @@ String *Item_cache_int::val_str(String *str)
my_decimal
*
Item_cache_int
::
val_decimal
(
my_decimal
*
decimal_val
)
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
()
;
if
(
!
value_cached
&&
!
cache_value
()
)
return
NULL
;
int2my_decimal
(
E_DEC_FATAL_ERROR
,
value
,
unsigned_flag
,
decimal_val
);
return
decimal_val
;
}
...
...
@@ -7029,40 +7033,43 @@ my_decimal *Item_cache_int::val_decimal(my_decimal *decimal_val)
double
Item_cache_int
::
val_real
()
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
()
;
if
(
!
value_cached
&&
!
cache_value
()
)
return
0.0
;
return
(
double
)
value
;
}
longlong
Item_cache_int
::
val_int
()
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
()
;
if
(
!
value_cached
&&
!
cache_value
()
)
return
0
;
return
value
;
}
void
Item_cache_real
::
cache_value
()
bool
Item_cache_real
::
cache_value
()
{
if
(
!
example
)
return
FALSE
;
value_cached
=
TRUE
;
value
=
example
->
val_result
();
null_value
=
example
->
null_value
;
return
TRUE
;
}
double
Item_cache_real
::
val_real
()
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
()
;
if
(
!
value_cached
&&
!
cache_value
()
)
return
0.0
;
return
value
;
}
longlong
Item_cache_real
::
val_int
()
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
()
;
if
(
!
value_cached
&&
!
cache_value
()
)
return
0
;
return
(
longlong
)
rint
(
value
);
}
...
...
@@ -7070,8 +7077,8 @@ longlong Item_cache_real::val_int()
String
*
Item_cache_real
::
val_str
(
String
*
str
)
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
()
;
if
(
!
value_cached
&&
!
cache_value
()
)
return
NULL
;
str
->
set_real
(
value
,
decimals
,
default_charset
());
return
str
;
}
...
...
@@ -7080,27 +7087,30 @@ String* Item_cache_real::val_str(String *str)
my_decimal
*
Item_cache_real
::
val_decimal
(
my_decimal
*
decimal_val
)
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
()
;
if
(
!
value_cached
&&
!
cache_value
()
)
return
NULL
;
double2my_decimal
(
E_DEC_FATAL_ERROR
,
value
,
decimal_val
);
return
decimal_val
;
}
void
Item_cache_decimal
::
cache_value
()
bool
Item_cache_decimal
::
cache_value
()
{
if
(
!
example
)
return
FALSE
;
value_cached
=
TRUE
;
my_decimal
*
val
=
example
->
val_decimal_result
(
&
decimal_value
);
if
(
!
(
null_value
=
example
->
null_value
)
&&
val
!=
&
decimal_value
)
my_decimal2decimal
(
val
,
&
decimal_value
);
return
TRUE
;
}
double
Item_cache_decimal
::
val_real
()
{
DBUG_ASSERT
(
fixed
);
double
res
;
if
(
!
value_cached
)
cache_value
()
;
if
(
!
value_cached
&&
!
cache_value
()
)
return
NULL
;
my_decimal2double
(
E_DEC_FATAL_ERROR
,
&
decimal_value
,
&
res
);
return
res
;
}
...
...
@@ -7109,8 +7119,8 @@ longlong Item_cache_decimal::val_int()
{
DBUG_ASSERT
(
fixed
);
longlong
res
;
if
(
!
value_cached
)
cache_value
()
;
if
(
!
value_cached
&&
!
cache_value
()
)
return
0
;
my_decimal2int
(
E_DEC_FATAL_ERROR
,
&
decimal_value
,
unsigned_flag
,
&
res
);
return
res
;
}
...
...
@@ -7118,8 +7128,8 @@ longlong Item_cache_decimal::val_int()
String
*
Item_cache_decimal
::
val_str
(
String
*
str
)
{
DBUG_ASSERT
(
fixed
);
if
(
!
value_cached
)
cache_value
()
;
if
(
!
value_cached
&&
!
cache_value
()
)
return
NULL
;
my_decimal_round
(
E_DEC_FATAL_ERROR
,
&
decimal_value
,
decimals
,
FALSE
,
&
decimal_value
);
my_decimal2string
(
E_DEC_FATAL_ERROR
,
&
decimal_value
,
0
,
0
,
0
,
str
);
...
...
@@ -7129,14 +7139,16 @@ String* Item_cache_decimal::val_str(String *str)
my_decimal
*
Item_cache_decimal
::
val_decimal
(
my_decimal
*
val
)
{
DBUG_ASSERT
(
fixed
);
if
(
!
value_cached
)
cache_value
()
;
if
(
!
value_cached
&&
!
cache_value
()
)
return
NULL
;
return
&
decimal_value
;
}
void
Item_cache_str
::
cache_value
()
bool
Item_cache_str
::
cache_value
()
{
if
(
!
example
)
return
FALSE
;
value_cached
=
TRUE
;
value_buff
.
set
(
buffer
,
sizeof
(
buffer
),
example
->
collation
.
collation
);
value
=
example
->
str_result
(
&
value_buff
);
...
...
@@ -7155,6 +7167,7 @@ void Item_cache_str::cache_value()
value_buff
.
copy
(
*
value
);
value
=
&
value_buff
;
}
return
TRUE
;
}
double
Item_cache_str
::
val_real
()
...
...
@@ -7162,8 +7175,8 @@ double Item_cache_str::val_real()
DBUG_ASSERT
(
fixed
==
1
);
int
err_not_used
;
char
*
end_not_used
;
if
(
!
value_cached
)
cache_value
()
;
if
(
!
value_cached
&&
!
cache_value
()
)
return
0.0
;
if
(
value
)
return
my_strntod
(
value
->
charset
(),
(
char
*
)
value
->
ptr
(),
value
->
length
(),
&
end_not_used
,
&
err_not_used
);
...
...
@@ -7175,8 +7188,8 @@ longlong Item_cache_str::val_int()
{
DBUG_ASSERT
(
fixed
==
1
);
int
err
;
if
(
!
value_cached
)
cache_value
()
;
if
(
!
value_cached
&&
!
cache_value
()
)
return
0
;
if
(
value
)
return
my_strntoll
(
value
->
charset
(),
value
->
ptr
(),
value
->
length
(),
10
,
(
char
**
)
0
,
&
err
);
...
...
@@ -7188,8 +7201,8 @@ longlong Item_cache_str::val_int()
String
*
Item_cache_str
::
val_str
(
String
*
str
)
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
()
;
if
(
!
value_cached
&&
!
cache_value
()
)
return
0
;
return
value
;
}
...
...
@@ -7197,8 +7210,8 @@ String* Item_cache_str::val_str(String *str)
my_decimal
*
Item_cache_str
::
val_decimal
(
my_decimal
*
decimal_val
)
{
DBUG_ASSERT
(
fixed
==
1
);
if
(
!
value_cached
)
cache_value
()
;
if
(
!
value_cached
&&
!
cache_value
()
)
return
NULL
;
if
(
value
)
string2my_decimal
(
E_DEC_FATAL_ERROR
,
value
,
decimal_val
);
else
...
...
@@ -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
)
{
if
(
!
value_cached
)
cache_value
()
;
if
(
!
value_cached
&&
!
cache_value
()
)
return
0
;
int
res
=
Item_cache
::
save_in_field
(
field
,
no_conversions
);
return
(
is_varbinary
&&
field
->
type
()
==
MYSQL_TYPE_STRING
&&
value
->
length
()
<
field
->
field_length
)
?
1
:
res
;
...
...
@@ -7245,13 +7258,21 @@ bool Item_cache_row::setup(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
++
)
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
;
null_value
=
0
;
example
->
bring_value
();
...
...
@@ -7260,6 +7281,7 @@ void Item_cache_row::cache_value()
values
[
i
]
->
cache_value
();
null_value
|=
values
[
i
]
->
null_value
;
}
return
TRUE
;
}
...
...
sql/item.h
View file @
7d00a27f
...
...
@@ -2138,6 +2138,23 @@ class Item_result_field :public Item /* Item with result field */
save_in_field
(
result_field
,
no_conversions
);
}
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
return
this
==
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
my_decimal
*
val_decimal
(
my_decimal
*
);
enum
Item_result
result_type
()
const
{
return
INT_RESULT
;
}
bool
result_as_longlong
()
{
return
TRUE
;
}
void
cache_value
();
bool
cache_value
();
};
...
...
@@ -2984,7 +3001,7 @@ class Item_cache_real: public Item_cache
String
*
val_str
(
String
*
str
);
my_decimal
*
val_decimal
(
my_decimal
*
);
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
String
*
val_str
(
String
*
str
);
my_decimal
*
val_decimal
(
my_decimal
*
);
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
enum
Item_result
result_type
()
const
{
return
STRING_RESULT
;
}
CHARSET_INFO
*
charset
()
const
{
return
value
->
charset
();
};
int
save_in_field
(
Field
*
field
,
bool
no_conversions
);
void
cache_value
();
bool
cache_value
();
};
class
Item_cache_row
:
public
Item_cache
...
...
@@ -3094,7 +3111,7 @@ class Item_cache_row: public Item_cache
values
=
0
;
DBUG_VOID_RETURN
;
}
void
cache_value
();
bool
cache_value
();
};
...
...
sql/item_cmpfunc.cc
View file @
7d00a27f
...
...
@@ -30,6 +30,9 @@
#include "sql_select.h"
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
,
my_bool
unsigned_flag
)
...
...
@@ -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
;
func
=
comparator_matrix
[
type
]
[
test
(
owner
->
functype
()
==
Item_func
::
EQUAL_FUNC
)];
[
is_owner_equal_func
()];
switch
(
type
)
{
case
ROW_RESULT
:
{
...
...
@@ -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
());
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
;
}
break
;
...
...
@@ -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
)
||
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
;
}
if
(
cmp_collation
.
collation
==
&
my_charset_bin
)
...
...
@@ -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_result
type
)
{
...
...
@@ -891,6 +897,8 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
owner
=
owner_arg
;
a
=
a1
;
b
=
a2
;
owner
=
owner_arg
;
thd
=
current_thd
;
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,
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
;
get_value_func
=
&
get_datetime_value
;
get_value_a_func
=
&
get_datetime_value
;
get_value_b_func
=
&
get_datetime_value
;
return
0
;
}
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,
/* Compare TIME values as integers. */
a_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
;
get_value_func
=
&
get_time_value
;
get_value_a_func
=
&
get_time_value
;
get_value_b_func
=
&
get_time_value
;
return
0
;
}
else
if
(
type
==
STRING_RESULT
&&
...
...
@@ -943,9 +953,29 @@ int Arg_comparator::set_cmp_func(Item_bool_func2 *owner_arg,
{
DTCollation
coll
;
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
))
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
);
...
...
@@ -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
;
/* A caller will handle null values by itself. */
owner
=
NULL
;
owner
=
owner_arg
;
a
=
a1
;
b
=
b1
;
a_type
=
(
*
a
)
->
field_type
();
...
...
@@ -1001,7 +1031,8 @@ void Arg_comparator::set_datetime_cmp_func(Item **a1, Item **b1)
b_cache
=
0
;
is_nulls_eq
=
FALSE
;
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,
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.
...
...
@@ -1133,25 +1209,25 @@ int Arg_comparator::compare_datetime()
longlong
a_value
,
b_value
;
/* 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
(
owner
)
if
(
set_null
)
owner
->
null_value
=
1
;
return
-
1
;
}
/* 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
(
owner
)
if
(
set_null
)
owner
->
null_value
=
is_nulls_eq
?
0
:
1
;
return
is_nulls_eq
?
(
a_is_null
==
b_is_null
)
:
-
1
;
}
/* Here we have two not-NULL values. */
if
(
owner
)
if
(
set_null
)
owner
->
null_value
=
0
;
/* Compare values. */
...
...
@@ -1164,15 +1240,17 @@ int Arg_comparator::compare_datetime()
int
Arg_comparator
::
compare_string
()
{
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
)))
{
owner
->
null_value
=
0
;
if
(
set_null
)
owner
->
null_value
=
0
;
return
sortcmp
(
res1
,
res2
,
cmp_collation
.
collation
);
}
}
owner
->
null_value
=
1
;
if
(
set_null
)
owner
->
null_value
=
1
;
return
-
1
;
}
...
...
@@ -1191,18 +1269,20 @@ int Arg_comparator::compare_string()
int
Arg_comparator
::
compare_binary_string
()
{
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
)))
{
owner
->
null_value
=
0
;
if
(
set_null
)
owner
->
null_value
=
0
;
uint
res1_length
=
res1
->
length
();
uint
res2_length
=
res2
->
length
();
int
cmp
=
memcmp
(
res1
->
ptr
(),
res2
->
ptr
(),
min
(
res1_length
,
res2_length
));
return
cmp
?
cmp
:
(
int
)
(
res1_length
-
res2_length
);
}
}
owner
->
null_value
=
1
;
if
(
set_null
)
owner
->
null_value
=
1
;
return
-
1
;
}
...
...
@@ -1215,8 +1295,8 @@ int Arg_comparator::compare_binary_string()
int
Arg_comparator
::
compare_e_string
()
{
String
*
res1
,
*
res2
;
res1
=
(
*
a
)
->
val_str
(
&
owner
->
tmp_
value1
);
res2
=
(
*
b
)
->
val_str
(
&
owner
->
tmp_
value2
);
res1
=
(
*
a
)
->
val_str
(
&
value1
);
res2
=
(
*
b
)
->
val_str
(
&
value2
);
if
(
!
res1
||
!
res2
)
return
test
(
res1
==
res2
);
return
test
(
sortcmp
(
res1
,
res2
,
cmp_collation
.
collation
)
==
0
);
...
...
@@ -1226,8 +1306,8 @@ int Arg_comparator::compare_e_string()
int
Arg_comparator
::
compare_e_binary_string
()
{
String
*
res1
,
*
res2
;
res1
=
(
*
a
)
->
val_str
(
&
owner
->
tmp_
value1
);
res2
=
(
*
b
)
->
val_str
(
&
owner
->
tmp_
value2
);
res1
=
(
*
a
)
->
val_str
(
&
value1
);
res2
=
(
*
b
)
->
val_str
(
&
value2
);
if
(
!
res1
||
!
res2
)
return
test
(
res1
==
res2
);
return
test
(
stringcmp
(
res1
,
res2
)
==
0
);
...
...
@@ -1248,13 +1328,15 @@ int Arg_comparator::compare_real()
val2
=
(
*
b
)
->
val_real
();
if
(
!
(
*
b
)
->
null_value
)
{
owner
->
null_value
=
0
;
if
(
set_null
)
owner
->
null_value
=
0
;
if
(
val1
<
val2
)
return
-
1
;
if
(
val1
==
val2
)
return
0
;
return
1
;
}
}
owner
->
null_value
=
1
;
if
(
set_null
)
owner
->
null_value
=
1
;
return
-
1
;
}
...
...
@@ -1268,11 +1350,13 @@ int Arg_comparator::compare_decimal()
my_decimal
*
val2
=
(
*
b
)
->
val_decimal
(
&
value2
);
if
(
!
(
*
b
)
->
null_value
)
{
owner
->
null_value
=
0
;
if
(
set_null
)
owner
->
null_value
=
0
;
return
my_decimal_cmp
(
val1
,
val2
);
}
}
owner
->
null_value
=
1
;
if
(
set_null
)
owner
->
null_value
=
1
;
return
-
1
;
}
...
...
@@ -1310,7 +1394,8 @@ int Arg_comparator::compare_real_fixed()
val2
=
(
*
b
)
->
val_real
();
if
(
!
(
*
b
)
->
null_value
)
{
owner
->
null_value
=
0
;
if
(
set_null
)
owner
->
null_value
=
0
;
if
(
val1
==
val2
||
fabs
(
val1
-
val2
)
<
precision
)
return
0
;
if
(
val1
<
val2
)
...
...
@@ -1318,7 +1403,8 @@ int Arg_comparator::compare_real_fixed()
return
1
;
}
}
owner
->
null_value
=
1
;
if
(
set_null
)
owner
->
null_value
=
1
;
return
-
1
;
}
...
...
@@ -1341,13 +1427,15 @@ int Arg_comparator::compare_int_signed()
longlong
val2
=
(
*
b
)
->
val_int
();
if
(
!
(
*
b
)
->
null_value
)
{
owner
->
null_value
=
0
;
if
(
set_null
)
owner
->
null_value
=
0
;
if
(
val1
<
val2
)
return
-
1
;
if
(
val1
==
val2
)
return
0
;
return
1
;
}
}
owner
->
null_value
=
1
;
if
(
set_null
)
owner
->
null_value
=
1
;
return
-
1
;
}
...
...
@@ -1364,13 +1452,15 @@ int Arg_comparator::compare_int_unsigned()
ulonglong
val2
=
(
*
b
)
->
val_int
();
if
(
!
(
*
b
)
->
null_value
)
{
owner
->
null_value
=
0
;
if
(
set_null
)
owner
->
null_value
=
0
;
if
(
val1
<
val2
)
return
-
1
;
if
(
val1
==
val2
)
return
0
;
return
1
;
}
}
owner
->
null_value
=
1
;
if
(
set_null
)
owner
->
null_value
=
1
;
return
-
1
;
}
...
...
@@ -1387,7 +1477,8 @@ int Arg_comparator::compare_int_signed_unsigned()
ulonglong
uval2
=
(
ulonglong
)(
*
b
)
->
val_int
();
if
(
!
(
*
b
)
->
null_value
)
{
owner
->
null_value
=
0
;
if
(
set_null
)
owner
->
null_value
=
0
;
if
(
sval1
<
0
||
(
ulonglong
)
sval1
<
uval2
)
return
-
1
;
if
((
ulonglong
)
sval1
==
uval2
)
...
...
@@ -1395,7 +1486,8 @@ int Arg_comparator::compare_int_signed_unsigned()
return
1
;
}
}
owner
->
null_value
=
1
;
if
(
set_null
)
owner
->
null_value
=
1
;
return
-
1
;
}
...
...
@@ -1412,7 +1504,8 @@ int Arg_comparator::compare_int_unsigned_signed()
longlong
sval2
=
(
*
b
)
->
val_int
();
if
(
!
(
*
b
)
->
null_value
)
{
owner
->
null_value
=
0
;
if
(
set_null
)
owner
->
null_value
=
0
;
if
(
sval2
<
0
)
return
1
;
if
(
uval1
<
(
ulonglong
)
sval2
)
...
...
@@ -1422,7 +1515,8 @@ int Arg_comparator::compare_int_unsigned_signed()
return
1
;
}
}
owner
->
null_value
=
1
;
if
(
set_null
)
owner
->
null_value
=
1
;
return
-
1
;
}
...
...
@@ -1458,10 +1552,11 @@ int Arg_comparator::compare_row()
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
{
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
switch
(
owner
->
functype
())
{
switch
(
((
Item_func
*
)
owner
)
->
functype
())
{
case
Item_func
:
:
NE_FUNC
:
break
;
// NE never aborts on NULL even if abort_on_null is set
case
Item_func
:
:
LT_FUNC
:
...
...
@@ -1470,7 +1565,7 @@ int Arg_comparator::compare_row()
case
Item_func
:
:
GE_FUNC
:
return
-
1
;
// <, <=, > and >= always fail on NULL
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
}
was_null
=
1
;
...
...
@@ -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
()
{
maybe_null
=
0
;
...
...
@@ -1794,8 +1950,8 @@ longlong Item_func_lt::val_int()
longlong
Item_func_strcmp
::
val_int
()
{
DBUG_ASSERT
(
fixed
==
1
);
String
*
a
=
args
[
0
]
->
val_str
(
&
tmp_
value1
);
String
*
b
=
args
[
1
]
->
val_str
(
&
tmp_
value2
);
String
*
a
=
args
[
0
]
->
val_str
(
&
cmp
.
value1
);
String
*
b
=
args
[
1
]
->
val_str
(
&
cmp
.
value2
);
if
(
!
a
||
!
b
)
{
null_value
=
1
;
...
...
@@ -2078,8 +2234,8 @@ void Item_func_between::fix_length_and_dec()
if
(
compare_as_dates
)
{
ge_cmp
.
set_datetime_cmp_func
(
args
,
args
+
1
);
le_cmp
.
set_datetime_cmp_func
(
args
,
args
+
2
);
ge_cmp
.
set_datetime_cmp_func
(
this
,
args
,
args
+
1
);
le_cmp
.
set_datetime_cmp_func
(
this
,
args
,
args
+
2
);
}
else
if
(
time_items_found
==
3
)
{
...
...
@@ -4407,13 +4563,13 @@ void Item_func_isnotnull::print(String *str, enum_query_type query_type)
longlong
Item_func_like
::
val_int
()
{
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
)
{
null_value
=
1
;
return
0
;
}
String
*
res2
=
args
[
1
]
->
val_str
(
&
tmp_
value2
);
String
*
res2
=
args
[
1
]
->
val_str
(
&
cmp
.
value2
);
if
(
args
[
1
]
->
null_value
)
{
null_value
=
1
;
...
...
@@ -4437,7 +4593,7 @@ Item_func::optimize_type Item_func_like::select_optimize() const
{
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
)
return
OPTIMIZE_NONE
;
...
...
@@ -4468,7 +4624,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref)
if
(
escape_item
->
const_item
())
{
/* 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_used_in_parsing
&&
(
...
...
@@ -4523,7 +4679,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref)
if
(
args
[
1
]
->
const_item
()
&&
!
use_strnxfrm
(
collation
.
collation
)
&&
!
(
specialflag
&
SPECIAL_NO_NEW_FUNC
))
{
String
*
res2
=
args
[
1
]
->
val_str
(
&
tmp_
value2
);
String
*
res2
=
args
[
1
]
->
val_str
(
&
cmp
.
value2
);
if
(
!
res2
)
return
FALSE
;
// Null argument
...
...
sql/item_cmpfunc.h
View file @
7d00a27f
...
...
@@ -32,7 +32,7 @@ class Arg_comparator: public Sql_alloc
{
Item
**
a
,
**
b
;
arg_cmp_func
func
;
Item_
bool_func2
*
owner
;
Item_
result_field
*
owner
;
Arg_comparator
*
comparators
;
// used only for compare_row()
double
precision
;
/* Fields used in DATE/DATETIME comparison. */
...
...
@@ -40,30 +40,42 @@ class Arg_comparator: public Sql_alloc
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
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
,
CMP_DATE_WITH_STR
,
CMP_STR_WITH_DATE
};
longlong
(
*
get_value_func
)(
THD
*
thd
,
Item
***
item_arg
,
Item
**
cache_arg
,
Item
*
warn_item
,
bool
*
is_null
);
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
);
public:
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
),
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
);
inline
int
set_compare_func
(
Item_
bool_func2
*
owner_arg
)
int
set_compare_func
(
Item_
result_field
*
owner
,
Item_result
type
);
inline
int
set_compare_func
(
Item_
result_field
*
owner_arg
)
{
return
set_compare_func
(
owner_arg
,
item_cmp_type
((
*
a
)
->
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_result
type
);
inline
int
set_cmp_func
(
Item_
bool_func2
*
owner_arg
,
Item
**
a1
,
Item
**
a2
)
inline
int
set_cmp_func
(
Item_
result_field
*
owner_arg
,
Item
**
a1
,
Item
**
a2
,
bool
set_null_arg
)
{
set_null
=
set_null_arg
;
return
set_cmp_func
(
owner_arg
,
a1
,
a2
,
item_cmp_type
((
*
a1
)
->
result_type
(),
(
*
a2
)
->
result_type
()));
...
...
@@ -89,14 +101,20 @@ class Arg_comparator: public Sql_alloc
int
compare_real_fixed
();
int
compare_e_real_fixed
();
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
,
ulonglong
*
const_val_arg
);
void
set_datetime_cmp_func
(
Item
**
a1
,
Item
**
b1
);
Item
**
cache_converted_constant
(
THD
*
thd
,
Item
**
value
,
Item
**
cache
,
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
];
inline
bool
is_owner_equal_func
()
{
return
(
owner
->
type
()
==
Item
::
FUNC_ITEM
&&
((
Item_func
*
)
owner
)
->
functype
()
==
Item_func
::
EQUAL_FUNC
);
}
friend
class
Item_func
;
};
...
...
@@ -326,7 +344,6 @@ class Item_bool_func2 :public Item_int_func
{
/* Bool with 2 string args */
protected:
Arg_comparator
cmp
;
String
tmp_value1
,
tmp_value2
;
bool
abort_on_null
;
public:
...
...
@@ -335,7 +352,7 @@ class Item_bool_func2 :public Item_int_func
void
fix_length_and_dec
();
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
;
}
virtual
enum
Functype
rev_functype
()
const
{
return
UNKNOWN_FUNC
;
}
...
...
sql/item_func.h
View file @
7d00a27f
...
...
@@ -124,17 +124,6 @@ class Item_func :public Item_result_field
virtual
optimize_type
select_optimize
()
const
{
return
OPTIMIZE_NONE
;
}
virtual
bool
have_rev_func
()
const
{
return
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
;
}
inline
Item
**
arguments
()
const
{
return
args
;
}
void
set_arguments
(
List
<
Item
>
&
list
);
...
...
sql/item_geofunc.cc
View file @
7d00a27f
...
...
@@ -511,8 +511,8 @@ String *Item_func_spatial_collection::val_str(String *str)
longlong
Item_func_spatial_rel
::
val_int
()
{
DBUG_ASSERT
(
fixed
==
1
);
String
*
res1
=
args
[
0
]
->
val_str
(
&
tmp_
value1
);
String
*
res2
=
args
[
1
]
->
val_str
(
&
tmp_
value2
);
String
*
res1
=
args
[
0
]
->
val_str
(
&
cmp
.
value1
);
String
*
res2
=
args
[
1
]
->
val_str
(
&
cmp
.
value2
);
Geometry_buffer
buffer1
,
buffer2
;
Geometry
*
g1
,
*
g2
;
MBR
mbr1
,
mbr2
;
...
...
sql/item_subselect.h
View file @
7d00a27f
...
...
@@ -132,6 +132,7 @@ class Item_subselect :public Item_result_field
@return the SELECT_LEX structure associated with this Item
*/
st_select_lex
*
get_select_lex
();
const
char
*
func_name
()
const
{
DBUG_ASSERT
(
0
);
return
"subselect"
;
}
friend
class
select_subselect
;
friend
class
Item_in_optimizer
;
...
...
sql/item_sum.cc
View file @
7d00a27f
...
...
@@ -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
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
())
{
case
INT_RESULT
:
max_length
=
20
;
sum_int
=
0
;
break
;
case
DECIMAL_RESULT
:
max_length
=
item
->
max_length
;
my_decimal_set_zero
(
&
sum_dec
);
break
;
case
REAL_RESULT
:
max_length
=
float_length
(
decimals
);
sum
=
0.0
;
break
;
case
STRING_RESULT
:
max_length
=
item
->
max_length
;
...
...
@@ -679,10 +647,10 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
default:
DBUG_ASSERT
(
0
);
};
setup
(
args
[
0
],
NULL
);
/* MIN/MAX can return NULL for empty set indepedent of the used column */
maybe_null
=
1
;
unsigned_flag
=
item
->
unsigned_flag
;
collation
.
set
(
item
->
collation
);
result_field
=
0
;
null_value
=
1
;
fix_length_and_dec
();
...
...
@@ -700,6 +668,30 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
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
,
uint
convert_blob_length
)
{
...
...
@@ -1590,19 +1582,7 @@ void Item_sum_variance::update_field()
void
Item_sum_hybrid
::
clear
()
{
switch
(
hybrid_type
)
{
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
);
}
value
->
null_value
=
1
;
null_value
=
1
;
}
...
...
@@ -1611,30 +1591,7 @@ double Item_sum_hybrid::val_real()
DBUG_ASSERT
(
fixed
==
1
);
if
(
null_value
)
return
0.0
;
switch
(
hybrid_type
)
{
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
;
}
return
value
->
val_real
();
}
longlong
Item_sum_hybrid
::
val_int
()
...
...
@@ -1642,18 +1599,7 @@ longlong Item_sum_hybrid::val_int()
DBUG_ASSERT
(
fixed
==
1
);
if
(
null_value
)
return
0
;
switch
(
hybrid_type
)
{
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
());
}
return
value
->
val_int
();
}
...
...
@@ -1662,26 +1608,7 @@ my_decimal *Item_sum_hybrid::val_decimal(my_decimal *val)
DBUG_ASSERT
(
fixed
==
1
);
if
(
null_value
)
return
0
;
switch
(
hybrid_type
)
{
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
return
value
->
val_decimal
(
val
);
}
...
...
@@ -1691,25 +1618,7 @@ Item_sum_hybrid::val_str(String *str)
DBUG_ASSERT
(
fixed
==
1
);
if
(
null_value
)
return
0
;
switch
(
hybrid_type
)
{
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
return
value
->
val_str
(
str
);
}
...
...
@@ -1718,7 +1627,9 @@ void Item_sum_hybrid::cleanup()
DBUG_ENTER
(
"Item_sum_hybrid::cleanup"
);
Item_sum
::
cleanup
();
forced_const
=
FALSE
;
if
(
cmp
)
delete
cmp
;
cmp
=
0
;
/*
by default it is TRUE to avoid TRUE reporting by
Item_func_not_all/Item_func_nop_all if this item was never called.
...
...
@@ -1739,63 +1650,22 @@ void Item_sum_hybrid::no_rows_in_result()
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
()
{
switch
(
hybrid_type
)
{
case
STRING_RESULT
:
/* args[0] < value */
int
res
=
cmp
->
compare
();
if
(
!
args
[
0
]
->
null_value
&&
(
null_value
||
res
<
0
))
{
String
*
result
=
args
[
0
]
->
val_str
(
&
tmp_value
);
if
(
!
args
[
0
]
->
null_value
&&
(
null_value
||
sortcmp
(
&
value
,
result
,
collation
.
collation
)
>
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
;
value
->
store
(
args
[
0
]);
value
->
cache_value
();
null_value
=
0
;
}
return
0
;
}
...
...
@@ -1803,63 +1673,22 @@ bool Item_sum_min::add()
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
()
{
switch
(
hybrid_type
)
{
case
STRING_RESULT
:
/* args[0] > value */
int
res
=
cmp
->
compare
();
if
(
!
args
[
0
]
->
null_value
&&
(
null_value
||
res
>
0
))
{
String
*
result
=
args
[
0
]
->
val_str
(
&
tmp_value
);
if
(
!
args
[
0
]
->
null_value
&&
(
null_value
||
sortcmp
(
&
value
,
result
,
collation
.
collation
)
<
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
;
value
->
store
(
args
[
0
]);
value
->
cache_value
();
null_value
=
0
;
}
return
0
;
}
...
...
@@ -2224,14 +2053,15 @@ void Item_sum_hybrid::update_field()
void
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
)
{
result_field
->
val_str
(
&
tmp_value
);
result_field
->
val_str
(
&
cmp
->
value2
);
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
->
set_notnull
();
}
...
...
sql/item_sum.h
View file @
7d00a27f
...
...
@@ -323,22 +323,6 @@ class Item_sum :public Item_result_field
virtual
void
update_field
()
=
0
;
virtual
bool
keep_field_type
(
void
)
const
{
return
0
;
}
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
)
{
return
new
Item_field
(
field
);
}
table_map
used_tables
()
const
{
return
used_tables_cache
;
}
...
...
@@ -664,6 +648,7 @@ class Item_avg_field :public Item_result_field
}
void
fix_length_and_dec
()
{}
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
}
void
fix_length_and_dec
()
{}
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
my_decimal
*
val_decimal
(
my_decimal
*
);
enum
Item_result
result_type
()
const
{
return
REAL_RESULT
;
}
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
};
// 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
{
protected:
String
value
,
tmp_value
;
double
sum
;
longlong
sum_int
;
my_decimal
sum_dec
;
Item_cache
*
value
;
Arg_comparator
*
cmp
;
Item_result
hybrid_type
;
enum_field_types
hybrid_field_type
;
int
cmp_sign
;
...
...
@@ -847,12 +833,17 @@ class Item_sum_hybrid :public Item_sum
public:
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
),
cmp_sign
(
sign
),
was_values
(
TRUE
)
{
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
**
);
void
setup
(
Item
*
item
,
Item
*
value_arg
);
void
clear
();
double
val_real
();
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