|
|
|
@ -2373,101 +2373,6 @@ static bool strcmp_null(const char *a, const char *b) |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
Assign INTERVAL and STARTS for SYSTEM_TIME partitions. |
|
|
|
|
|
|
|
@return true on error |
|
|
|
*/ |
|
|
|
|
|
|
|
bool partition_info::vers_set_interval(THD* thd, Item* interval, |
|
|
|
interval_type int_type, Item* starts, |
|
|
|
const char *table_name) |
|
|
|
{ |
|
|
|
DBUG_ASSERT(part_type == VERSIONING_PARTITION); |
|
|
|
|
|
|
|
MYSQL_TIME ltime; |
|
|
|
uint err; |
|
|
|
vers_info->interval.type= int_type; |
|
|
|
|
|
|
|
/* 1. assign INTERVAL to interval.step */ |
|
|
|
if (interval->fix_fields_if_needed_for_scalar(thd, &interval)) |
|
|
|
return true; |
|
|
|
bool error= get_interval_value(thd, interval, int_type, &vers_info->interval.step) || |
|
|
|
vers_info->interval.step.neg || vers_info->interval.step.second_part || |
|
|
|
!(vers_info->interval.step.year || vers_info->interval.step.month || |
|
|
|
vers_info->interval.step.day || vers_info->interval.step.hour || |
|
|
|
vers_info->interval.step.minute || vers_info->interval.step.second); |
|
|
|
if (error) |
|
|
|
{ |
|
|
|
my_error(ER_PART_WRONG_VALUE, MYF(0), table_name, "INTERVAL"); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
/* 2. assign STARTS to interval.start */ |
|
|
|
if (starts) |
|
|
|
{ |
|
|
|
if (starts->fix_fields_if_needed_for_scalar(thd, &starts)) |
|
|
|
return true; |
|
|
|
switch (starts->result_type()) |
|
|
|
{ |
|
|
|
case INT_RESULT: |
|
|
|
case DECIMAL_RESULT: |
|
|
|
case REAL_RESULT: |
|
|
|
/* When table member is defined, we are inside mysql_unpack_partition(). */ |
|
|
|
if (!table || starts->val_int() > TIMESTAMP_MAX_VALUE) |
|
|
|
goto interval_starts_error; |
|
|
|
vers_info->interval.start= (my_time_t) starts->val_int(); |
|
|
|
break; |
|
|
|
case STRING_RESULT: |
|
|
|
case TIME_RESULT: |
|
|
|
{ |
|
|
|
Datetime::Options opt(TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE, thd); |
|
|
|
starts->get_date(thd, <ime, opt); |
|
|
|
vers_info->interval.start= TIME_to_timestamp(thd, <ime, &err); |
|
|
|
if (err) |
|
|
|
goto interval_starts_error; |
|
|
|
break; |
|
|
|
} |
|
|
|
case ROW_RESULT: |
|
|
|
default: |
|
|
|
goto interval_starts_error; |
|
|
|
} |
|
|
|
if (!table) |
|
|
|
{ |
|
|
|
if (thd->query_start() < vers_info->interval.start) { |
|
|
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
|
|
|
ER_PART_STARTS_BEYOND_INTERVAL, |
|
|
|
ER_THD(thd, ER_PART_STARTS_BEYOND_INTERVAL), |
|
|
|
table_name); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else // calculate default STARTS depending on INTERVAL
|
|
|
|
{ |
|
|
|
thd->variables.time_zone->gmt_sec_to_TIME(<ime, thd->query_start()); |
|
|
|
if (vers_info->interval.step.second) |
|
|
|
goto interval_set_starts; |
|
|
|
ltime.second= 0; |
|
|
|
if (vers_info->interval.step.minute) |
|
|
|
goto interval_set_starts; |
|
|
|
ltime.minute= 0; |
|
|
|
if (vers_info->interval.step.hour) |
|
|
|
goto interval_set_starts; |
|
|
|
ltime.hour= 0; |
|
|
|
|
|
|
|
interval_set_starts: |
|
|
|
vers_info->interval.start= TIME_to_timestamp(thd, <ime, &err); |
|
|
|
if (err) |
|
|
|
goto interval_starts_error; |
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
interval_starts_error: |
|
|
|
my_error(ER_PART_WRONG_VALUE, MYF(0), table_name, "STARTS"); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Check if the new part_info has the same partitioning. |
|
|
|
@ -2791,6 +2696,102 @@ bool partition_info::vers_init_info(THD * thd) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
Assign INTERVAL and STARTS for SYSTEM_TIME partitions. |
|
|
|
|
|
|
|
@return true on error |
|
|
|
*/ |
|
|
|
|
|
|
|
bool partition_info::vers_set_interval(THD* thd, Item* interval, |
|
|
|
interval_type int_type, Item* starts, |
|
|
|
const char *table_name) |
|
|
|
{ |
|
|
|
DBUG_ASSERT(part_type == VERSIONING_PARTITION); |
|
|
|
|
|
|
|
MYSQL_TIME ltime; |
|
|
|
uint err; |
|
|
|
vers_info->interval.type= int_type; |
|
|
|
|
|
|
|
/* 1. assign INTERVAL to interval.step */ |
|
|
|
if (interval->fix_fields_if_needed_for_scalar(thd, &interval)) |
|
|
|
return true; |
|
|
|
bool error= get_interval_value(thd, interval, int_type, &vers_info->interval.step) || |
|
|
|
vers_info->interval.step.neg || vers_info->interval.step.second_part || |
|
|
|
!(vers_info->interval.step.year || vers_info->interval.step.month || |
|
|
|
vers_info->interval.step.day || vers_info->interval.step.hour || |
|
|
|
vers_info->interval.step.minute || vers_info->interval.step.second); |
|
|
|
if (error) |
|
|
|
{ |
|
|
|
my_error(ER_PART_WRONG_VALUE, MYF(0), table_name, "INTERVAL"); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
/* 2. assign STARTS to interval.start */ |
|
|
|
if (starts) |
|
|
|
{ |
|
|
|
if (starts->fix_fields_if_needed_for_scalar(thd, &starts)) |
|
|
|
return true; |
|
|
|
switch (starts->result_type()) |
|
|
|
{ |
|
|
|
case INT_RESULT: |
|
|
|
case DECIMAL_RESULT: |
|
|
|
case REAL_RESULT: |
|
|
|
/* When table member is defined, we are inside mysql_unpack_partition(). */ |
|
|
|
if (!table || starts->val_int() > TIMESTAMP_MAX_VALUE) |
|
|
|
goto interval_starts_error; |
|
|
|
vers_info->interval.start= (my_time_t) starts->val_int(); |
|
|
|
break; |
|
|
|
case STRING_RESULT: |
|
|
|
case TIME_RESULT: |
|
|
|
{ |
|
|
|
Datetime::Options opt(TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE, thd); |
|
|
|
starts->get_date(thd, <ime, opt); |
|
|
|
vers_info->interval.start= TIME_to_timestamp(thd, <ime, &err); |
|
|
|
if (err) |
|
|
|
goto interval_starts_error; |
|
|
|
break; |
|
|
|
} |
|
|
|
case ROW_RESULT: |
|
|
|
default: |
|
|
|
goto interval_starts_error; |
|
|
|
} |
|
|
|
if (!table) |
|
|
|
{ |
|
|
|
if (thd->query_start() < vers_info->interval.start) { |
|
|
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
|
|
|
ER_PART_STARTS_BEYOND_INTERVAL, |
|
|
|
ER_THD(thd, ER_PART_STARTS_BEYOND_INTERVAL), |
|
|
|
table_name); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else // calculate default STARTS depending on INTERVAL
|
|
|
|
{ |
|
|
|
thd->variables.time_zone->gmt_sec_to_TIME(<ime, thd->query_start()); |
|
|
|
if (vers_info->interval.step.second) |
|
|
|
goto interval_set_starts; |
|
|
|
ltime.second= 0; |
|
|
|
if (vers_info->interval.step.minute) |
|
|
|
goto interval_set_starts; |
|
|
|
ltime.minute= 0; |
|
|
|
if (vers_info->interval.step.hour) |
|
|
|
goto interval_set_starts; |
|
|
|
ltime.hour= 0; |
|
|
|
|
|
|
|
interval_set_starts: |
|
|
|
vers_info->interval.start= TIME_to_timestamp(thd, <ime, &err); |
|
|
|
if (err) |
|
|
|
goto interval_starts_error; |
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
interval_starts_error: |
|
|
|
my_error(ER_PART_WRONG_VALUE, MYF(0), table_name, "STARTS"); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool partition_info::error_if_requires_values() const |
|
|
|
{ |
|
|
|
switch (part_type) { |
|
|
|
|