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
6297d1ab
Commit
6297d1ab
authored
Jun 13, 2006
by
unknown
Browse files
Options
Browse Files
Download
Plain Diff
Merge epotemkin@bk-internal.mysql.com:/home/bk/mysql-4.1-opt
into moonbone.local:/work/16377-bug-4.1-opt-mysql
parents
e815f93b
47311e8e
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
293 additions
and
42 deletions
+293
-42
mysql-test/r/cast.result
mysql-test/r/cast.result
+1
-1
mysql-test/r/func_time.result
mysql-test/r/func_time.result
+41
-0
mysql-test/t/func_time.test
mysql-test/t/func_time.test
+20
-0
sql/field.cc
sql/field.cc
+11
-5
sql/item.h
sql/item.h
+16
-0
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+122
-32
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+10
-4
sql/item_timefunc.cc
sql/item_timefunc.cc
+60
-0
sql/item_timefunc.h
sql/item_timefunc.h
+12
-0
No files found.
mysql-test/r/cast.result
View file @
6297d1ab
...
@@ -192,7 +192,7 @@ cast("2001-1-1" as datetime) = "2001-01-01 00:00:00"
...
@@ -192,7 +192,7 @@ cast("2001-1-1" as datetime) = "2001-01-01 00:00:00"
1
1
select cast("1:2:3" as TIME) = "1:02:03";
select cast("1:2:3" as TIME) = "1:02:03";
cast("1:2:3" as TIME) = "1:02:03"
cast("1:2:3" as TIME) = "1:02:03"
0
1
select cast(NULL as DATE);
select cast(NULL as DATE);
cast(NULL as DATE)
cast(NULL as DATE)
NULL
NULL
...
...
mysql-test/r/func_time.result
View file @
6297d1ab
...
@@ -630,3 +630,44 @@ select monthname(str_to_date(null, '%m')), monthname(str_to_date(null, '%m')),
...
@@ -630,3 +630,44 @@ select monthname(str_to_date(null, '%m')), monthname(str_to_date(null, '%m')),
monthname(str_to_date(1, '%m')), monthname(str_to_date(0, '%m'));
monthname(str_to_date(1, '%m')), monthname(str_to_date(0, '%m'));
monthname(str_to_date(null, '%m')) monthname(str_to_date(null, '%m')) monthname(str_to_date(1, '%m')) monthname(str_to_date(0, '%m'))
monthname(str_to_date(null, '%m')) monthname(str_to_date(null, '%m')) monthname(str_to_date(1, '%m')) monthname(str_to_date(0, '%m'))
NULL NULL January NULL
NULL NULL January NULL
create table t1(f1 date, f2 time, f3 datetime);
insert into t1 values ("2006-01-01", "12:01:01", "2006-01-01 12:01:01");
insert into t1 values ("2006-01-02", "12:01:02", "2006-01-02 12:01:02");
select f1 from t1 where f1 between "2006-1-1" and 20060101;
f1
2006-01-01
select f1 from t1 where f1 between "2006-1-1" and "2006.1.1";
f1
2006-01-01
select f1 from t1 where date(f1) between "2006-1-1" and "2006.1.1";
f1
2006-01-01
select f2 from t1 where f2 between "12:1:2" and "12:2:2";
f2
12:01:02
select f2 from t1 where time(f2) between "12:1:2" and "12:2:2";
f2
12:01:02
select f3 from t1 where f3 between "2006-1-1 12:1:1" and "2006-1-1 12:1:2";
f3
2006-01-01 12:01:01
select f3 from t1 where timestamp(f3) between "2006-1-1 12:1:1" and "2006-1-1 12:1:2";
f3
2006-01-01 12:01:01
select f1 from t1 where "2006-1-1" between f1 and f3;
f1
2006-01-01
select f1 from t1 where "2006-1-1" between date(f1) and date(f3);
f1
2006-01-01
select f1 from t1 where "2006-1-1" between f1 and 'zzz';
f1
Warnings:
Warning 1292 Truncated incorrect date value: 'zzz'
select f1 from t1 where makedate(2006,1) between date(f1) and date(f3);
f1
2006-01-01
select f1 from t1 where makedate(2006,2) between date(f1) and date(f3);
f1
2006-01-02
drop table t1;
mysql-test/t/func_time.test
View file @
6297d1ab
...
@@ -322,4 +322,24 @@ select last_day('2005-01-00');
...
@@ -322,4 +322,24 @@ select last_day('2005-01-00');
select
monthname
(
str_to_date
(
null
,
'%m'
)),
monthname
(
str_to_date
(
null
,
'%m'
)),
select
monthname
(
str_to_date
(
null
,
'%m'
)),
monthname
(
str_to_date
(
null
,
'%m'
)),
monthname
(
str_to_date
(
1
,
'%m'
)),
monthname
(
str_to_date
(
0
,
'%m'
));
monthname
(
str_to_date
(
1
,
'%m'
)),
monthname
(
str_to_date
(
0
,
'%m'
));
#
# Bug#16377 result of DATE/TIME functions were compared as strings which
# can lead to a wrong result.
#
create
table
t1
(
f1
date
,
f2
time
,
f3
datetime
);
insert
into
t1
values
(
"2006-01-01"
,
"12:01:01"
,
"2006-01-01 12:01:01"
);
insert
into
t1
values
(
"2006-01-02"
,
"12:01:02"
,
"2006-01-02 12:01:02"
);
select
f1
from
t1
where
f1
between
"2006-1-1"
and
20060101
;
select
f1
from
t1
where
f1
between
"2006-1-1"
and
"2006.1.1"
;
select
f1
from
t1
where
date
(
f1
)
between
"2006-1-1"
and
"2006.1.1"
;
select
f2
from
t1
where
f2
between
"12:1:2"
and
"12:2:2"
;
select
f2
from
t1
where
time
(
f2
)
between
"12:1:2"
and
"12:2:2"
;
select
f3
from
t1
where
f3
between
"2006-1-1 12:1:1"
and
"2006-1-1 12:1:2"
;
select
f3
from
t1
where
timestamp
(
f3
)
between
"2006-1-1 12:1:1"
and
"2006-1-1 12:1:2"
;
select
f1
from
t1
where
"2006-1-1"
between
f1
and
f3
;
select
f1
from
t1
where
"2006-1-1"
between
date
(
f1
)
and
date
(
f3
);
select
f1
from
t1
where
"2006-1-1"
between
f1
and
'zzz'
;
select
f1
from
t1
where
makedate
(
2006
,
1
)
between
date
(
f1
)
and
date
(
f3
);
select
f1
from
t1
where
makedate
(
2006
,
2
)
between
date
(
f1
)
and
date
(
f3
);
drop
table
t1
;
# End of 4.1 tests
# End of 4.1 tests
sql/field.cc
View file @
6297d1ab
...
@@ -6841,7 +6841,11 @@ create_field::create_field(Field *old_field,Field *orig_field)
...
@@ -6841,7 +6841,11 @@ create_field::create_field(Field *old_field,Field *orig_field)
bool
bool
Field
::
set_warning
(
const
uint
level
,
const
uint
code
,
int
cuted_increment
)
Field
::
set_warning
(
const
uint
level
,
const
uint
code
,
int
cuted_increment
)
{
{
THD
*
thd
=
table
->
in_use
;
/*
If this field was created only for type conversion purposes it
will have table == NULL.
*/
THD
*
thd
=
table
?
table
->
in_use
:
current_thd
;
if
(
thd
->
count_cuted_fields
)
if
(
thd
->
count_cuted_fields
)
{
{
thd
->
cuted_fields
+=
cuted_increment
;
thd
->
cuted_fields
+=
cuted_increment
;
...
@@ -6876,7 +6880,8 @@ Field::set_datetime_warning(const uint level, const uint code,
...
@@ -6876,7 +6880,8 @@ Field::set_datetime_warning(const uint level, const uint code,
timestamp_type
ts_type
,
int
cuted_increment
)
timestamp_type
ts_type
,
int
cuted_increment
)
{
{
if
(
set_warning
(
level
,
code
,
cuted_increment
))
if
(
set_warning
(
level
,
code
,
cuted_increment
))
make_truncated_value_warning
(
table
->
in_use
,
str
,
str_length
,
ts_type
);
make_truncated_value_warning
(
table
?
table
->
in_use
:
current_thd
,
str
,
str_length
,
ts_type
);
}
}
...
@@ -6905,8 +6910,8 @@ Field::set_datetime_warning(const uint level, const uint code,
...
@@ -6905,8 +6910,8 @@ Field::set_datetime_warning(const uint level, const uint code,
{
{
char
str_nr
[
22
];
char
str_nr
[
22
];
char
*
str_end
=
longlong10_to_str
(
nr
,
str_nr
,
-
10
);
char
*
str_end
=
longlong10_to_str
(
nr
,
str_nr
,
-
10
);
make_truncated_value_warning
(
table
->
in_use
,
str_nr
,
str_end
-
str_nr
,
make_truncated_value_warning
(
table
?
table
->
in_use
:
current_thd
,
ts_type
);
str_nr
,
str_end
-
str_nr
,
ts_type
);
}
}
}
}
...
@@ -6935,7 +6940,8 @@ Field::set_datetime_warning(const uint level, const uint code,
...
@@ -6935,7 +6940,8 @@ Field::set_datetime_warning(const uint level, const uint code,
/* DBL_DIG is enough to print '-[digits].E+###' */
/* DBL_DIG is enough to print '-[digits].E+###' */
char
str_nr
[
DBL_DIG
+
8
];
char
str_nr
[
DBL_DIG
+
8
];
uint
str_len
=
my_sprintf
(
str_nr
,
(
str_nr
,
"%g"
,
nr
));
uint
str_len
=
my_sprintf
(
str_nr
,
(
str_nr
,
"%g"
,
nr
));
make_truncated_value_warning
(
table
->
in_use
,
str_nr
,
str_len
,
ts_type
);
make_truncated_value_warning
(
table
?
table
->
in_use
:
current_thd
,
str_nr
,
str_len
,
ts_type
);
}
}
}
}
...
...
sql/item.h
View file @
6297d1ab
...
@@ -327,6 +327,14 @@ class Item {
...
@@ -327,6 +327,14 @@ class Item {
cleanup
();
cleanup
();
delete
this
;
delete
this
;
}
}
/*
result_as_longlong() must return TRUE for Items representing DATE/TIME
functions and DATE/TIME table fields.
Those Items have result_type()==STRING_RESULT (and not INT_RESULT), but
their values should be compared as integers (because the integer
representation is more precise than the string one).
*/
virtual
bool
result_as_longlong
()
{
return
FALSE
;
}
};
};
...
@@ -450,6 +458,10 @@ class Item_field :public Item_ident
...
@@ -450,6 +458,10 @@ class Item_field :public Item_ident
Item
*
get_tmp_table_item
(
THD
*
thd
);
Item
*
get_tmp_table_item
(
THD
*
thd
);
void
cleanup
();
void
cleanup
();
inline
uint32
max_disp_length
()
{
return
field
->
max_length
();
}
inline
uint32
max_disp_length
()
{
return
field
->
max_length
();
}
bool
result_as_longlong
()
{
return
field
->
can_be_compared_as_longlong
();
}
friend
class
Item_default_value
;
friend
class
Item_default_value
;
friend
class
Item_insert_value
;
friend
class
Item_insert_value
;
friend
class
st_select_lex_unit
;
friend
class
st_select_lex_unit
;
...
@@ -973,6 +985,10 @@ class Item_ref :public Item_ident
...
@@ -973,6 +985,10 @@ class Item_ref :public Item_ident
}
}
Item
*
real_item
()
{
return
*
ref
;
}
Item
*
real_item
()
{
return
*
ref
;
}
void
print
(
String
*
str
);
void
print
(
String
*
str
);
bool
result_as_longlong
()
{
return
(
*
ref
)
->
result_as_longlong
();
}
};
};
...
...
sql/item_cmpfunc.cc
View file @
6297d1ab
...
@@ -25,6 +25,8 @@
...
@@ -25,6 +25,8 @@
#include <m_ctype.h>
#include <m_ctype.h>
#include "sql_select.h"
#include "sql_select.h"
static
bool
convert_constant_item
(
THD
*
thd
,
Field
*
field
,
Item
**
item
);
static
Item_result
item_store_type
(
Item_result
a
,
Item_result
b
)
static
Item_result
item_store_type
(
Item_result
a
,
Item_result
b
)
{
{
if
(
a
==
STRING_RESULT
||
b
==
STRING_RESULT
)
if
(
a
==
STRING_RESULT
||
b
==
STRING_RESULT
)
...
@@ -64,6 +66,7 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems)
...
@@ -64,6 +66,7 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems)
SYNOPSIS:
SYNOPSIS:
agg_cmp_type()
agg_cmp_type()
thd thread handle
type [out] the aggregated type
type [out] the aggregated type
items array of items to aggregate the type from
items array of items to aggregate the type from
nitems number of items in the array
nitems number of items in the array
...
@@ -78,24 +81,133 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems)
...
@@ -78,24 +81,133 @@ static void agg_result_type(Item_result *type, Item **items, uint nitems)
If all items are constants the type will be aggregated from all items.
If all items are constants the type will be aggregated from all items.
If there are some non-constant items then only types of non-constant
If there are some non-constant items then only types of non-constant
items will be used for aggregation.
items will be used for aggregation.
If there are DATE/TIME fields/functions in the list and no string
fields/functions in the list then:
The INT_RESULT type will be used for aggregation instead of orginal
result type of any DATE/TIME field/function in the list
All constant items in the list will be converted to a DATE/TIME using
found field or result field of found function.
Implementation notes:
The code is equvalent to:
1. Check the list for presense of a STRING field/function.
Collect the is_const flag.
2. Get a Field* object to use for type coercion
3. Perform type conversion.
1 and 2 are implemented in 2 loops. The first searches for a DATE/TIME
field/function and checks presense of a STRING field/function.
The second loop works only if a DATE/TIME field/function is found.
It checks presense of a STRING field/function in the rest of the list.
TODO
1) The current implementation can produce false comparison results for
expressions like:
date_time_field BETWEEN string_field_with_dates AND string_constant
if the string_constant will omit some of leading zeroes.
In order to fully implement correct comparison of DATE/TIME the new
DATETIME_RESULT result type should be introduced and agg_cmp_type()
should return the DATE/TIME field used for the conversion. Later
this field can be used by comparison functions like Item_func_between to
convert string values to ints on the fly and thus return correct results.
This modification will affect functions BETWEEN, IN and CASE.
2) If in the list a DATE field/function and a DATETIME field/function
are present in the list then the first found field/function will be
used for conversion. This may lead to wrong results and probably should
be fixed.
*/
*/
static
void
agg_cmp_type
(
Item_result
*
type
,
Item
**
items
,
uint
nitems
)
static
void
agg_cmp_type
(
THD
*
thd
,
Item_result
*
type
,
Item
**
items
,
uint
nitems
)
{
{
uint
i
;
uint
i
;
type
[
0
]
=
items
[
0
]
->
result_type
();
Item
::
Type
res
;
char
*
buff
=
NULL
;
uchar
null_byte
;
Field
*
field
=
NULL
;
/* Search for date/time fields/functions */
for
(
i
=
0
;
i
<
nitems
;
i
++
)
{
if
(
!
items
[
i
]
->
result_as_longlong
())
{
/* Do not convert anything if a string field/function is present */
if
(
!
items
[
i
]
->
const_item
()
&&
items
[
i
]
->
result_type
()
==
STRING_RESULT
)
{
i
=
nitems
;
break
;
}
continue
;
}
if
((
res
=
items
[
i
]
->
real_item
()
->
type
())
==
Item
::
FIELD_ITEM
)
{
field
=
((
Item_field
*
)
items
[
i
]
->
real_item
())
->
field
;
break
;
}
else
if
(
res
==
Item
::
FUNC_ITEM
)
{
field
=
items
[
i
]
->
tmp_table_field_from_field_type
(
0
);
if
(
field
)
buff
=
alloc_root
(
thd
->
mem_root
,
field
->
max_length
());
if
(
!
buff
||
!
field
)
{
if
(
field
)
delete
field
;
if
(
buff
)
my_free
(
buff
,
MYF
(
MY_WME
));
field
=
0
;
}
else
field
->
move_field
(
buff
,
&
null_byte
,
0
);
break
;
}
}
if
(
field
)
{
/* Check the rest of the list for presense of a string field/function. */
for
(
i
++
;
i
<
nitems
;
i
++
)
{
if
(
!
items
[
i
]
->
const_item
()
&&
items
[
i
]
->
result_type
()
==
STRING_RESULT
&&
!
items
[
i
]
->
result_as_longlong
())
{
field
=
0
;
break
;
}
}
}
/* Reset to 0 on first occurence of non-const item. 1 otherwise */
/* Reset to 0 on first occurence of non-const item. 1 otherwise */
bool
is_const
=
items
[
0
]
->
const_item
();
bool
is_const
=
items
[
0
]
->
const_item
();
/*
If the first item is a date/time function then its result should be
compared as int
*/
if
(
field
)
{
/* Suppose we are comparing dates and some non-constant items are present. */
type
[
0
]
=
INT_RESULT
;
is_const
=
0
;
}
else
type
[
0
]
=
items
[
0
]
->
result_type
();
for
(
i
=
1
;
i
<
nitems
;
i
++
)
for
(
i
=
0
;
i
<
nitems
;
i
++
)
{
{
if
(
!
items
[
i
]
->
const_item
())
if
(
!
items
[
i
]
->
const_item
())
{
{
type
[
0
]
=
is_const
?
items
[
i
]
->
result_type
()
:
Item_result
result
=
field
&&
items
[
i
]
->
result_as_longlong
()
?
item_cmp_type
(
type
[
0
],
items
[
i
]
->
result_type
());
INT_RESULT
:
items
[
i
]
->
result_type
();
type
[
0
]
=
is_const
?
result
:
item_cmp_type
(
type
[
0
],
result
);
is_const
=
0
;
is_const
=
0
;
}
}
else
if
(
is_const
)
else
if
(
is_const
)
type
[
0
]
=
item_cmp_type
(
type
[
0
],
items
[
i
]
->
result_type
());
type
[
0
]
=
item_cmp_type
(
type
[
0
],
items
[
i
]
->
result_type
());
else
if
(
field
)
convert_constant_item
(
thd
,
field
,
&
items
[
i
]);
}
if
(
res
==
Item
::
FUNC_ITEM
&&
field
)
{
delete
field
;
my_free
(
buff
,
MYF
(
MY_WME
));
}
}
}
}
...
@@ -929,31 +1041,9 @@ void Item_func_between::fix_length_and_dec()
...
@@ -929,31 +1041,9 @@ void Item_func_between::fix_length_and_dec()
*/
*/
if
(
!
args
[
0
]
||
!
args
[
1
]
||
!
args
[
2
])
if
(
!
args
[
0
]
||
!
args
[
1
]
||
!
args
[
2
])
return
;
return
;
agg_cmp_type
(
&
cmp_type
,
args
,
3
);
agg_cmp_type
(
thd
,
&
cmp_type
,
args
,
3
);
if
(
cmp_type
==
STRING_RESULT
&&
if
(
cmp_type
==
STRING_RESULT
)
agg_arg_charsets
(
cmp_collation
,
args
,
3
,
MY_COLL_CMP_CONV
))
agg_arg_charsets
(
cmp_collation
,
args
,
3
,
MY_COLL_CMP_CONV
);
return
;
/*
Make a special case of compare with date/time and longlong fields.
They are compared as integers, so for const item this time-consuming
conversion can be done only once, not for every single comparison
*/
if
(
args
[
0
]
->
type
()
==
FIELD_ITEM
)
{
Field
*
field
=
((
Item_field
*
)
args
[
0
])
->
field
;
if
(
field
->
can_be_compared_as_longlong
())
{
/*
The following can't be recoded with || as convert_constant_item
changes the argument
*/
if
(
convert_constant_item
(
thd
,
field
,
&
args
[
1
]))
cmp_type
=
INT_RESULT
;
// Works for all types.
if
(
convert_constant_item
(
thd
,
field
,
&
args
[
2
]))
cmp_type
=
INT_RESULT
;
// Works for all types.
}
}
}
}
...
@@ -1477,7 +1567,7 @@ void Item_func_case::fix_length_and_dec()
...
@@ -1477,7 +1567,7 @@ void Item_func_case::fix_length_and_dec()
for
(
nagg
=
0
;
nagg
<
ncases
/
2
;
nagg
++
)
for
(
nagg
=
0
;
nagg
<
ncases
/
2
;
nagg
++
)
agg
[
nagg
+
1
]
=
args
[
nagg
*
2
];
agg
[
nagg
+
1
]
=
args
[
nagg
*
2
];
nagg
++
;
nagg
++
;
agg_cmp_type
(
&
cmp_type
,
agg
,
nagg
);
agg_cmp_type
(
current_thd
,
&
cmp_type
,
agg
,
nagg
);
if
((
cmp_type
==
STRING_RESULT
)
&&
if
((
cmp_type
==
STRING_RESULT
)
&&
agg_arg_charsets
(
cmp_collation
,
agg
,
nagg
,
MY_COLL_CMP_CONV
))
agg_arg_charsets
(
cmp_collation
,
agg
,
nagg
,
MY_COLL_CMP_CONV
))
return
;
return
;
...
@@ -1958,7 +2048,7 @@ void Item_func_in::fix_length_and_dec()
...
@@ -1958,7 +2048,7 @@ void Item_func_in::fix_length_and_dec()
uint
const_itm
=
1
;
uint
const_itm
=
1
;
THD
*
thd
=
current_thd
;
THD
*
thd
=
current_thd
;
agg_cmp_type
(
&
cmp_type
,
args
,
arg_count
);
agg_cmp_type
(
thd
,
&
cmp_type
,
args
,
arg_count
);
if
(
cmp_type
==
STRING_RESULT
&&
if
(
cmp_type
==
STRING_RESULT
&&
agg_arg_charsets
(
cmp_collation
,
args
,
arg_count
,
MY_COLL_CMP_CONV
))
agg_arg_charsets
(
cmp_collation
,
args
,
arg_count
,
MY_COLL_CMP_CONV
))
...
...
sql/item_cmpfunc.h
View file @
6297d1ab
...
@@ -43,8 +43,11 @@ class Arg_comparator: public Sql_alloc
...
@@ -43,8 +43,11 @@ class Arg_comparator: public Sql_alloc
int
set_compare_func
(
Item_bool_func2
*
owner
,
Item_result
type
);
int
set_compare_func
(
Item_bool_func2
*
owner
,
Item_result
type
);
inline
int
set_compare_func
(
Item_bool_func2
*
owner_arg
)
inline
int
set_compare_func
(
Item_bool_func2
*
owner_arg
)
{
{
return
set_compare_func
(
owner_arg
,
item_cmp_type
((
*
a
)
->
result_type
(),
Item_result
ar
=
(
*
a
)
->
result_as_longlong
()
&&
(
*
b
)
->
const_item
()
?
(
*
b
)
->
result_type
()));
INT_RESULT
:
(
*
a
)
->
result_type
();
Item_result
br
=
(
*
b
)
->
result_as_longlong
()
&&
(
*
a
)
->
const_item
()
?
INT_RESULT
:
(
*
b
)
->
result_type
();
return
set_compare_func
(
owner_arg
,
item_cmp_type
(
ar
,
br
));
}
}
inline
int
set_cmp_func
(
Item_bool_func2
*
owner_arg
,
inline
int
set_cmp_func
(
Item_bool_func2
*
owner_arg
,
Item
**
a1
,
Item
**
a2
,
Item
**
a1
,
Item
**
a2
,
...
@@ -57,8 +60,11 @@ class Arg_comparator: public Sql_alloc
...
@@ -57,8 +60,11 @@ class Arg_comparator: public Sql_alloc
inline
int
set_cmp_func
(
Item_bool_func2
*
owner_arg
,
inline
int
set_cmp_func
(
Item_bool_func2
*
owner_arg
,
Item
**
a1
,
Item
**
a2
)
Item
**
a1
,
Item
**
a2
)
{
{
return
set_cmp_func
(
owner_arg
,
a1
,
a2
,
item_cmp_type
((
*
a1
)
->
result_type
(),
Item_result
ar
=
(
*
a1
)
->
result_as_longlong
()
&&
(
*
a2
)
->
const_item
()
?
(
*
a2
)
->
result_type
()));
INT_RESULT
:
(
*
a1
)
->
result_type
();
Item_result
br
=
(
*
a2
)
->
result_as_longlong
()
&&
(
*
a1
)
->
const_item
()
?
INT_RESULT
:
(
*
a2
)
->
result_type
();
return
set_cmp_func
(
owner_arg
,
a1
,
a2
,
item_cmp_type
(
ar
,
br
));
}
}
inline
int
compare
()
{
return
(
this
->*
func
)();
}
inline
int
compare
()
{
return
(
this
->*
func
)();
}
...
...
sql/item_timefunc.cc
View file @
6297d1ab
...
@@ -2306,6 +2306,20 @@ String *Item_datetime_typecast::val_str(String *str)
...
@@ -2306,6 +2306,20 @@ String *Item_datetime_typecast::val_str(String *str)
}
}
longlong
Item_datetime_typecast
::
val_int
()
{
DBUG_ASSERT
(
fixed
==
1
);
TIME
ltime
;
if
(
get_arg0_date
(
&
ltime
,
1
))
{
null_value
=
1
;
return
0
;
}
return
TIME_to_ulonglong_datetime
(
&
ltime
);
}
bool
Item_time_typecast
::
get_time
(
TIME
*
ltime
)
bool
Item_time_typecast
::
get_time
(
TIME
*
ltime
)
{
{
bool
res
=
get_arg0_time
(
ltime
);
bool
res
=
get_arg0_time
(
ltime
);
...
@@ -2320,6 +2334,17 @@ bool Item_time_typecast::get_time(TIME *ltime)
...
@@ -2320,6 +2334,17 @@ bool Item_time_typecast::get_time(TIME *ltime)
}
}
longlong
Item_time_typecast
::
val_int
()
{
TIME
ltime
;
if
(
get_time
(
&
ltime
))
{
null_value
=
1
;
return
0
;
}
return
ltime
.
hour
*
10000L
+
ltime
.
minute
*
100
+
ltime
.
second
;
}
String
*
Item_time_typecast
::
val_str
(
String
*
str
)
String
*
Item_time_typecast
::
val_str
(
String
*
str
)
{
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
...
@@ -2359,6 +2384,14 @@ String *Item_date_typecast::val_str(String *str)
...
@@ -2359,6 +2384,14 @@ String *Item_date_typecast::val_str(String *str)
return
0
;
return
0
;
}
}
longlong
Item_date_typecast
::
val_int
()
{
DBUG_ASSERT
(
fixed
==
1
);
TIME
ltime
;
if
(
args
[
0
]
->
get_date
(
&
ltime
,
TIME_FUZZY_DATE
))
return
0
;
return
(
longlong
)
(
ltime
.
year
*
10000L
+
ltime
.
month
*
100
+
ltime
.
day
);
}
/*
/*
MAKEDATE(a,b) is a date function that creates a date value
MAKEDATE(a,b) is a date function that creates a date value
...
@@ -2395,6 +2428,33 @@ String *Item_func_makedate::val_str(String *str)
...
@@ -2395,6 +2428,33 @@ String *Item_func_makedate::val_str(String *str)
}
}
longlong
Item_func_makedate
::
val_int
()
{
DBUG_ASSERT
(
fixed
==
1
);
TIME
l_time
;
long
daynr
=
(
long
)
args
[
1
]
->
val_int
();
long
yearnr
=
(
long
)
args
[
0
]
->
val_int
();
long
days
;
if
(
args
[
0
]
->
null_value
||
args
[
1
]
->
null_value
||
yearnr
<
0
||
daynr
<=
0
)
goto
err
;
days
=
calc_daynr
(
yearnr
,
1
,
1
)
+
daynr
-
1
;
/* Day number from year 0 to 9999-12-31 */
if
(
days
>=
0
&&
days
<
MAX_DAY_NUMBER
)
{
null_value
=
0
;
get_date_from_daynr
(
days
,
&
l_time
.
year
,
&
l_time
.
month
,
&
l_time
.
day
);
return
(
longlong
)
(
l_time
.
year
*
10000L
+
l_time
.
month
*
100
+
l_time
.
day
);
}
err:
null_value
=
1
;
return
0
;
}
void
Item_func_add_time
::
fix_length_and_dec
()
void
Item_func_add_time
::
fix_length_and_dec
()
{
{
enum_field_types
arg0_field_type
;
enum_field_types
arg0_field_type
;
...
...
sql/item_timefunc.h
View file @
6297d1ab
...
@@ -339,6 +339,7 @@ class Item_date :public Item_func
...
@@ -339,6 +339,7 @@ class Item_date :public Item_func
{
{
return
(
new
Field_date
(
maybe_null
,
name
,
t_arg
,
&
my_charset_bin
));
return
(
new
Field_date
(
maybe_null
,
name
,
t_arg
,
&
my_charset_bin
));
}
}
bool
result_as_longlong
()
{
return
TRUE
;
}
};
};
...
@@ -354,6 +355,7 @@ class Item_date_func :public Item_str_func
...
@@ -354,6 +355,7 @@ class Item_date_func :public Item_str_func
{
{
return
(
new
Field_datetime
(
maybe_null
,
name
,
t_arg
,
&
my_charset_bin
));
return
(
new
Field_datetime
(
maybe_null
,
name
,
t_arg
,
&
my_charset_bin
));
}
}
bool
result_as_longlong
()
{
return
TRUE
;
}
};
};
...
@@ -383,6 +385,7 @@ class Item_func_curtime :public Item_func
...
@@ -383,6 +385,7 @@ class Item_func_curtime :public Item_func
TIME representation using UTC-SYSTEM or per-thread time zone.
TIME representation using UTC-SYSTEM or per-thread time zone.
*/
*/
virtual
void
store_now_in_TIME
(
TIME
*
now_time
)
=
0
;
virtual
void
store_now_in_TIME
(
TIME
*
now_time
)
=
0
;
bool
result_as_longlong
()
{
return
TRUE
;
}
};
};
...
@@ -588,6 +591,7 @@ class Item_func_sec_to_time :public Item_str_func
...
@@ -588,6 +591,7 @@ class Item_func_sec_to_time :public Item_str_func
{
{
return
(
new
Field_time
(
maybe_null
,
name
,
t_arg
,
&
my_charset_bin
));
return
(
new
Field_time
(
maybe_null
,
name
,
t_arg
,
&
my_charset_bin
));
}
}
bool
result_as_longlong
()
{
return
TRUE
;
}
};
};
/*
/*
...
@@ -715,6 +719,8 @@ class Item_date_typecast :public Item_typecast_maybe_null
...
@@ -715,6 +719,8 @@ class Item_date_typecast :public Item_typecast_maybe_null
max_length
=
10
;
max_length
=
10
;
maybe_null
=
1
;
maybe_null
=
1
;
}
}
bool
result_as_longlong
()
{
return
TRUE
;
}
longlong
val_int
();
};
};
...
@@ -731,6 +737,8 @@ class Item_time_typecast :public Item_typecast_maybe_null
...
@@ -731,6 +737,8 @@ class Item_time_typecast :public Item_typecast_maybe_null
{
{
return
(
new
Field_time
(
maybe_null
,
name
,
t_arg
,
&
my_charset_bin
));
return
(
new
Field_time
(
maybe_null
,
name
,
t_arg
,
&
my_charset_bin
));
}
}
bool
result_as_longlong
()
{
return
TRUE
;
}
longlong
val_int
();
};
};
...
@@ -746,6 +754,8 @@ class Item_datetime_typecast :public Item_typecast_maybe_null
...
@@ -746,6 +754,8 @@ class Item_datetime_typecast :public Item_typecast_maybe_null
{
{
return
(
new
Field_datetime
(
maybe_null
,
name
,
t_arg
,
&
my_charset_bin
));
return
(
new
Field_datetime
(
maybe_null
,
name
,
t_arg
,
&
my_charset_bin
));
}
}
bool
result_as_longlong
()
{
return
TRUE
;
}
longlong
val_int
();
};
};
class
Item_func_makedate
:
public
Item_str_func
class
Item_func_makedate
:
public
Item_str_func
...
@@ -764,6 +774,8 @@ class Item_func_makedate :public Item_str_func
...
@@ -764,6 +774,8 @@ class Item_func_makedate :public Item_str_func
{
{
return
(
new
Field_date
(
maybe_null
,
name
,
t_arg
,
&
my_charset_bin
));
return
(
new
Field_date
(
maybe_null
,
name
,
t_arg
,
&
my_charset_bin
));
}
}
bool
result_as_longlong
()
{
return
TRUE
;
}
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