@ -865,28 +865,43 @@ bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
from the high end . This allows one to give :
from the high end . This allows one to give :
DAY_TO_SECOND as " D MM:HH:SS " , " MM:HH:SS " " HH:SS " or as seconds .
DAY_TO_SECOND as " D MM:HH:SS " , " MM:HH:SS " " HH:SS " or as seconds .
@ param length : length of str
@ param cs : charset of st r
@ param values : array of results
@ param args item expression which we convert to an ASCII string
@ param str_value string buffe r
@ param is_negative set to true if interval is prefixed by ' - '
@ param count : count of elements in result array
@ param count : count of elements in result array
@ param values : array of results
@ param transform_msec : if value is true we suppose
@ param transform_msec : if value is true we suppose
that the last part of string value is microseconds
that the last part of string value is microseconds
and we should transform value to six digit value .
and we should transform value to six digit value .
For example , ' 1.1 ' - > ' 1.100000 '
For example , ' 1.1 ' - > ' 1.100000 '
*/
*/
static bool get_interval_info ( const char * str , uint length , CHARSET_INFO * cs ,
static bool get_interval_info ( Item * args ,
String * str_value ,
bool * is_negative ,
uint count , ulonglong * values ,
uint count , ulonglong * values ,
bool transform_msec )
bool transform_msec )
{
{
const char * end = str + length ;
uint i ;
long msec_length = 0 ;
String * res ;
if ( ! ( res = args - > val_str_ascii ( str_value ) ) )
return true ;
while ( str ! = end & & ! my_isdigit ( cs , * str ) )
CHARSET_INFO * cs = res - > charset ( ) ;
const char * str = res - > ptr ( ) ;
const char * end = str + res - > length ( ) ;
str + = cs - > cset - > scan ( cs , str , end , MY_SEQ_SPACES ) ;
if ( str < end & & * str = = ' - ' )
{
* is_negative = true ;
str + + ;
}
while ( str < end & & ! my_isdigit ( cs , * str ) )
str + + ;
str + + ;
for ( i = 0 ; i < count ; i + + )
long msec_length = 0 ;
for ( uint i = 0 ; i < count ; i + + )
{
{
longlong value ;
longlong value ;
const char * start = str ;
const char * start = str ;
@ -1427,45 +1442,24 @@ longlong Item_func_time_to_sec::val_int()
To make code easy , allow interval objects without separators .
To make code easy , allow interval objects without separators .
*/
*/
bool get_interval_value ( Item * args , interval_type int_type ,
bool get_interval_value ( Item * args , interval_type int_type ,
String * str_value , INTERVAL * interval )
String * str_value , INTERVAL * interval )
{
{
ulonglong array [ 5 ] ;
ulonglong array [ 5 ] ;
longlong UNINIT_VAR ( value ) ;
longlong UNINIT_VAR ( value ) ;
const char * UNINIT_VAR ( str ) ;
size_t UNINIT_VAR ( length ) ;
CHARSET_INFO * cs = str_value - > charset ( ) ;
bzero ( ( char * ) interval , sizeof ( * interval ) ) ;
bzero ( ( char * ) interval , sizeof ( * interval ) ) ;
if ( ( int ) int_type < = INTERVAL_MICROSECOND )
if ( ( int ) int_type < = INTERVAL_MICROSECOND )
{
{
value = args - > val_int ( ) ;
value = args - > val_int ( ) ;
if ( args - > null_value )
if ( args - > null_value )
return 1 ;
return true ;
if ( value < 0 )
if ( value < 0 )
{
{
interval - > neg = 1 ;
interval - > neg = true ;
value = - value ;
value = - value ;
}
}
}
}
else
{
String * res ;
if ( ! ( res = args - > val_str_ascii ( str_value ) ) )
return ( 1 ) ;
/* record negative intervalls in interval->neg */
str = res - > ptr ( ) ;
const char * end = str + res - > length ( ) ;
while ( str ! = end & & my_isspace ( cs , * str ) )
str + + ;
if ( str ! = end & & * str = = ' - ' )
{
interval - > neg = 1 ;
str + + ;
}
length = ( size_t ) ( end - str ) ; // Set up pointers to new str
}
switch ( int_type ) {
switch ( int_type ) {
case INTERVAL_YEAR :
case INTERVAL_YEAR :
@ -1486,88 +1480,88 @@ bool get_interval_value(Item *args,interval_type int_type,
case INTERVAL_HOUR :
case INTERVAL_HOUR :
interval - > hour = ( ulong ) value ;
interval - > hour = ( ulong ) value ;
break ;
break ;
case INTERVAL_MICROSECOND :
interval - > second_part = value ;
break ;
case INTERVAL_MINUTE :
case INTERVAL_MINUTE :
interval - > minute = value ;
interval - > minute = value ;
break ;
break ;
case INTERVAL_SECOND :
case INTERVAL_SECOND :
interval - > second = value ;
interval - > second = value ;
break ;
break ;
case INTERVAL_MICROSECOND :
interval - > second_part = value ;
break ;
case INTERVAL_YEAR_MONTH : // Allow YEAR-MONTH YYYYYMM
case INTERVAL_YEAR_MONTH : // Allow YEAR-MONTH YYYYYMM
if ( get_interval_info ( str , length , cs , 2 , array , 0 ) )
return ( 1 ) ;
if ( get_interval_info ( arg s, str_va lu e, & interval - > neg , 2 , array , false ) )
return true ;
interval - > year = ( ulong ) array [ 0 ] ;
interval - > year = ( ulong ) array [ 0 ] ;
interval - > month = ( ulong ) array [ 1 ] ;
interval - > month = ( ulong ) array [ 1 ] ;
break ;
break ;
case INTERVAL_DAY_HOUR :
case INTERVAL_DAY_HOUR :
if ( get_interval_info ( str , length , cs , 2 , array , 0 ) )
return ( 1 ) ;
interval - > day = ( ulong ) array [ 0 ] ;
interval - > hour = ( ulong ) array [ 1 ] ;
break ;
case INTERVAL_DAY_MICROSECOND :
if ( get_interval_info ( str , length , cs , 5 , array , 1 ) )
return ( 1 ) ;
if ( get_interval_info ( args , str_value , & interval - > neg , 2 , array , false ) )
return true ;
interval - > day = ( ulong ) array [ 0 ] ;
interval - > day = ( ulong ) array [ 0 ] ;
interval - > hour = ( ulong ) array [ 1 ] ;
interval - > hour = ( ulong ) array [ 1 ] ;
interval - > minute = array [ 2 ] ;
interval - > second = array [ 3 ] ;
interval - > second_part = array [ 4 ] ;
break ;
break ;
case INTERVAL_DAY_MINUTE :
case INTERVAL_DAY_MINUTE :
if ( get_interval_info ( str , length , cs , 3 , array , 0 ) )
return ( 1 ) ;
if ( get_interval_info ( args , str_value , & interval - > neg , 3 , array , false ) )
return true ;
interval - > day = ( ulong ) array [ 0 ] ;
interval - > day = ( ulong ) array [ 0 ] ;
interval - > hour = ( ulong ) array [ 1 ] ;
interval - > hour = ( ulong ) array [ 1 ] ;
interval - > minute = array [ 2 ] ;
interval - > minute = array [ 2 ] ;
break ;
break ;
case INTERVAL_DAY_SECOND :
case INTERVAL_DAY_SECOND :
if ( get_interval_info ( str , length , cs , 4 , array , 0 ) )
return ( 1 ) ;
if ( get_interval_info ( arg s, str_va lu e, & interval - > neg , 4 , array , false ) )
return true ;
interval - > day = ( ulong ) array [ 0 ] ;
interval - > day = ( ulong ) array [ 0 ] ;
interval - > hour = ( ulong ) array [ 1 ] ;
interval - > hour = ( ulong ) array [ 1 ] ;
interval - > minute = array [ 2 ] ;
interval - > minute = array [ 2 ] ;
interval - > second = array [ 3 ] ;
interval - > second = array [ 3 ] ;
break ;
break ;
case INTERVAL_HOUR_MICROSECOND :
if ( get_interval_info ( str , length , cs , 4 , array , 1 ) )
return ( 1 ) ;
interval - > hour = ( ulong ) array [ 0 ] ;
interval - > minute = array [ 1 ] ;
interval - > second = array [ 2 ] ;
interval - > second_part = array [ 3 ] ;
break ;
case INTERVAL_HOUR_MINUTE :
case INTERVAL_HOUR_MINUTE :
if ( get_interval_info ( str , length , cs , 2 , array , 0 ) )
return ( 1 ) ;
if ( get_interval_info ( args , str_value , & interval - > neg , 2 , array , false ) )
return true ;
interval - > hour = ( ulong ) array [ 0 ] ;
interval - > hour = ( ulong ) array [ 0 ] ;
interval - > minute = array [ 1 ] ;
interval - > minute = array [ 1 ] ;
break ;
break ;
case INTERVAL_HOUR_SECOND :
case INTERVAL_HOUR_SECOND :
if ( get_interval_info ( str , length , cs , 3 , array , 0 ) )
return ( 1 ) ;
if ( get_interval_info ( args , str_value , & interval - > neg , 3 , array , false ) )
return true ;
interval - > hour = ( ulong ) array [ 0 ] ;
interval - > hour = ( ulong ) array [ 0 ] ;
interval - > minute = array [ 1 ] ;
interval - > minute = array [ 1 ] ;
interval - > second = array [ 2 ] ;
interval - > second = array [ 2 ] ;
break ;
break ;
case INTERVAL_MINUTE_MICRO SECOND :
if ( get_interval_info ( str , length , cs , 3 , array , 1 ) )
return ( 1 ) ;
case INTERVAL_MINUTE_SECOND :
if ( get_interval_info ( args , str_value , & interval - > neg , 2 , array , false ) )
return true ;
interval - > minute = array [ 0 ] ;
interval - > minute = array [ 0 ] ;
interval - > second = array [ 1 ] ;
interval - > second = array [ 1 ] ;
interval - > second_part = array [ 2 ] ;
break ;
break ;
case INTERVAL_MINUTE_SECOND :
if ( get_interval_info ( str , length , cs , 2 , array , 0 ) )
return ( 1 ) ;
case INTERVAL_DAY_MICROSECOND :
if ( get_interval_info ( args , str_value , & interval - > neg , 5 , array , true ) )
return true ;
interval - > day = ( ulong ) array [ 0 ] ;
interval - > hour = ( ulong ) array [ 1 ] ;
interval - > minute = array [ 2 ] ;
interval - > second = array [ 3 ] ;
interval - > second_part = array [ 4 ] ;
break ;
case INTERVAL_HOUR_MICROSECOND :
if ( get_interval_info ( args , str_value , & interval - > neg , 4 , array , true ) )
return true ;
interval - > hour = ( ulong ) array [ 0 ] ;
interval - > minute = array [ 1 ] ;
interval - > second = array [ 2 ] ;
interval - > second_part = array [ 3 ] ;
break ;
case INTERVAL_MINUTE_MICROSECOND :
if ( get_interval_info ( args , str_value , & interval - > neg , 3 , array , true ) )
return true ;
interval - > minute = array [ 0 ] ;
interval - > minute = array [ 0 ] ;
interval - > second = array [ 1 ] ;
interval - > second = array [ 1 ] ;
interval - > second_part = array [ 2 ] ;
break ;
break ;
case INTERVAL_SECOND_MICROSECOND :
case INTERVAL_SECOND_MICROSECOND :
if ( get_interval_info ( str , length , cs , 2 , array , 1 ) )
return ( 1 ) ;
if ( get_interval_info ( args , str_value , & interval - > neg , 2 , array , true ) )
return true ;
interval - > second = array [ 0 ] ;
interval - > second = array [ 0 ] ;
interval - > second_part = array [ 1 ] ;
interval - > second_part = array [ 1 ] ;
break ;
break ;
@ -1575,7 +1569,7 @@ bool get_interval_value(Item *args,interval_type int_type,
DBUG_ASSERT ( 0 ) ;
DBUG_ASSERT ( 0 ) ;
break ; /* purecov: end */
break ; /* purecov: end */
}
}
return 0 ;
return false ;
}
}