Commit 5b4c8469 authored by Monty's avatar Monty

Added CHECK_FIELD_EXPRESSION

This is needed for MDEV 13679 Enabled sequences to be used in DEFAULT

Added new option for count_cuted_fields: CHECK_FIELD_EXPRESSION
which is used to check if a DEFAULT expression is correct before
ALTER TABLE starts

Changed also all test:
  if (thd->count_cuted_fields)
  to
  if (thd->count_cuted_fields > CHECK_FIELD_EXPRESSION)
parent 139e8afc
......@@ -1518,7 +1518,7 @@ bool Field_num::get_int(CHARSET_INFO *cs, const char *from, uint len,
goto out_of_range;
}
}
if (get_thd()->count_cuted_fields &&
if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION &&
check_int(cs, from, len, end, error))
return 1;
return 0;
......@@ -1539,7 +1539,7 @@ double Field_real::get_double(const char *str, uint length, CHARSET_INFO *cs,
set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1);
*error= 1;
}
else if (get_thd()->count_cuted_fields &&
else if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION &&
check_edom_and_truncation("double", str == end,
cs, str, length, end))
*error= 1;
......@@ -1874,7 +1874,7 @@ void Field::make_field(Send_field *field)
if (orig_table && orig_table->s->db.str && *orig_table->s->db.str)
{
field->db_name= orig_table->s->db.str;
if (orig_table->pos_in_table_list &&
if (orig_table->pos_in_table_list &&
orig_table->pos_in_table_list->schema_table)
field->org_table_name= (orig_table->pos_in_table_list->
schema_table->table_name);
......@@ -2492,7 +2492,7 @@ int Field_decimal::store(const char *from_arg, uint len, CHARSET_INFO *cs)
it makes the code easer to read.
*/
if (get_thd()->count_cuted_fields)
if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION)
{
// Skip end spaces
for (;from != end && my_isspace(&my_charset_bin, *from); from++) ;
......@@ -2662,7 +2662,8 @@ int Field_decimal::store(const char *from_arg, uint len, CHARSET_INFO *cs)
{
if (pos == right_wall)
{
if (get_thd()->count_cuted_fields && !is_cuted_fields_incr)
if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION &&
!is_cuted_fields_incr)
break; // Go on below to see if we lose non zero digits
return 0;
}
......@@ -3055,7 +3056,7 @@ int Field_new_decimal::store(const char *from, uint length,
DBUG_RETURN(1);
}
if (thd->count_cuted_fields)
if (thd->count_cuted_fields > CHECK_FIELD_EXPRESSION)
{
if (check_edom_and_important_data_truncation("decimal",
err && err != E_DEC_TRUNCATED,
......@@ -3100,7 +3101,7 @@ int Field_new_decimal::store(const char *from, uint length,
- in err2: store_value() truncated 1.123 to 1.12, e.g. for DECIMAL(10,2)
Also, we send a note if a string had some trailing spaces: '1.12 '
*/
if (thd->count_cuted_fields &&
if (thd->count_cuted_fields > CHECK_FIELD_EXPRESSION &&
(err == E_DEC_TRUNCATED ||
err2 == E_DEC_TRUNCATED ||
end < from + length))
......@@ -4177,7 +4178,7 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else if (get_thd()->count_cuted_fields &&
else if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION &&
check_int(cs, from, len, end, error))
error= 1;
else
......@@ -6077,7 +6078,7 @@ int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1);
return 1;
}
if (get_thd()->count_cuted_fields &&
if (get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION &&
(error= check_int(cs, from, len, end, error)))
{
if (error == 1) /* empty or incorrect string */
......@@ -6785,7 +6786,7 @@ Field_longstr::report_if_important_data(const char *pstr, const char *end,
bool count_spaces)
{
THD *thd= get_thd();
if ((pstr < end) && thd->count_cuted_fields)
if ((pstr < end) && thd->count_cuted_fields > CHECK_FIELD_EXPRESSION)
{
if (test_if_important_data(field_charset, pstr, end))
{
......@@ -8719,7 +8720,7 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
wkb_type > (uint32) Geometry::wkb_last)
goto err;
if (geom_type != Field::GEOM_GEOMETRY &&
if (geom_type != Field::GEOM_GEOMETRY &&
geom_type != Field::GEOM_GEOMETRYCOLLECTION &&
(uint32) geom_type != wkb_type)
{
......@@ -8859,7 +8860,7 @@ int Field_enum::store(const char *from,uint length,CHARSET_INFO *cs)
set_warning(WARN_DATA_TRUNCATED, 1);
err= 1;
}
if (!get_thd()->count_cuted_fields && !length)
if ((get_thd()->count_cuted_fields <= CHECK_FIELD_EXPRESSION) && !length)
err= 0;
}
else
......@@ -8886,7 +8887,7 @@ int Field_enum::store(longlong nr, bool unsigned_val)
if ((ulonglong) nr > typelib->count || nr == 0)
{
set_warning(WARN_DATA_TRUNCATED, 1);
if (nr != 0 || get_thd()->count_cuted_fields)
if (nr != 0 || get_thd()->count_cuted_fields > CHECK_FIELD_EXPRESSION)
{
nr= 0;
error= 1;
......@@ -10112,6 +10113,8 @@ bool check_expression(Virtual_column_info *vcol, LEX_CSTRING *name,
uint filter= VCOL_IMPOSSIBLE;
if (type != VCOL_GENERATED_VIRTUAL && type != VCOL_DEFAULT)
filter|= VCOL_NOT_STRICTLY_DETERMINISTIC;
if (type == VCOL_GENERATED_VIRTUAL)
filter|= VCOL_NOT_VIRTUAL;
if (ret || (res.errors & filter))
{
......@@ -10920,11 +10923,12 @@ uint32 Field_blob::max_display_length()
@param cut_increment - whenever we should increase cut fields count
@note
This function won't produce warning and increase cut fields counter
if count_cuted_fields == CHECK_FIELD_IGNORE for current thread.
This function won't produce warning or notes or increase cut fields counter
if count_cuted_fields == CHECK_FIELD_IGNORE or CHECK_FIELD_EXPRESSION
for the current thread.
if count_cuted_fields == CHECK_FIELD_IGNORE then we ignore notes.
This allows us to avoid notes in optimisation, like convert_constant_item().
This allows us to avoid notes in optimisation, like
convert_constant_item().
@retval
1 if count_cuted_fields == CHECK_FIELD_IGNORE and error level is not NOTE
......@@ -10941,7 +10945,7 @@ Field::set_warning(Sql_condition::enum_warning_level level, uint code,
will have table == NULL.
*/
THD *thd= get_thd();
if (thd->count_cuted_fields)
if (thd->count_cuted_fields > CHECK_FIELD_EXPRESSION)
{
thd->cuted_fields+= cut_increment;
push_warning_printf(thd, level, code, ER_THD(thd, code), field_name.str,
......
......@@ -50,8 +50,9 @@ class Virtual_tmp_table;
enum enum_check_fields
{
CHECK_FIELD_IGNORE,
CHECK_FIELD_EXPRESSION,
CHECK_FIELD_WARN,
CHECK_FIELD_ERROR_FOR_NULL
CHECK_FIELD_ERROR_FOR_NULL,
};
/*
......@@ -558,6 +559,7 @@ static inline const char *vcol_type_name(enum_vcol_info_type type)
#define VCOL_TIME_FUNC 8
#define VCOL_AUTO_INC 16
#define VCOL_IMPOSSIBLE 32
#define VCOL_NOT_VIRTUAL 64 /* Function can't be virtual */
#define VCOL_NOT_STRICTLY_DETERMINISTIC \
(VCOL_NON_DETERMINISTIC | VCOL_TIME_FUNC | VCOL_SESSION_FUNC)
......
......@@ -122,6 +122,7 @@ static int set_bad_null_error(Field *field, int err)
field->set_warning(Sql_condition::WARN_LEVEL_WARN, err, 1);
/* fall through */
case CHECK_FIELD_IGNORE:
case CHECK_FIELD_EXPRESSION:
return 0;
case CHECK_FIELD_ERROR_FOR_NULL:
if (!field->table->in_use->no_errors)
......@@ -528,7 +529,8 @@ static void do_varstring1(Copy_field *copy)
if (length > copy->to_length- 1)
{
length=copy->to_length - 1;
if (copy->from_field->table->in_use->count_cuted_fields &&
if (copy->from_field->table->in_use->count_cuted_fields >
CHECK_FIELD_EXPRESSION &&
copy->to_field)
copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, 1);
......@@ -547,7 +549,7 @@ static void do_varstring1_mb(Copy_field *copy)
Well_formed_prefix prefix(cs, (char*) from_ptr, from_length, to_char_length);
if (prefix.length() < from_length)
{
if (current_thd->count_cuted_fields)
if (current_thd->count_cuted_fields > CHECK_FIELD_EXPRESSION)
copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, 1);
}
......@@ -562,7 +564,8 @@ static void do_varstring2(Copy_field *copy)
if (length > copy->to_length- HA_KEY_BLOB_LENGTH)
{
length=copy->to_length-HA_KEY_BLOB_LENGTH;
if (copy->from_field->table->in_use->count_cuted_fields &&
if (copy->from_field->table->in_use->count_cuted_fields >
CHECK_FIELD_EXPRESSION &&
copy->to_field)
copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, 1);
......@@ -582,7 +585,7 @@ static void do_varstring2_mb(Copy_field *copy)
Well_formed_prefix prefix(cs, (char*) from_beg, from_length, char_length);
if (prefix.length() < from_length)
{
if (current_thd->count_cuted_fields)
if (current_thd->count_cuted_fields > CHECK_FIELD_EXPRESSION)
copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, 1);
}
......
......@@ -9311,10 +9311,12 @@ bool mysql_alter_table(THD *thd, const char *new_db, const char *new_name,
&altered_table->s->all_set);
restore_record(altered_table, s->default_values); // Create empty record
/* Check that we can call default functions with default field values */
thd->count_cuted_fields= CHECK_FIELD_EXPRESSION;
altered_table->reset_default_fields();
if (altered_table->default_field &&
altered_table->update_default_fields(0, 1))
goto err_new_table_cleanup;
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
// Ask storage engine whether to use copy or in-place
enum_alter_inplace_result inplace_supported=
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment