diff options
Diffstat (limited to 'sql/item.cc')
-rw-r--r-- | sql/item.cc | 69 |
1 files changed, 68 insertions, 1 deletions
diff --git a/sql/item.cc b/sql/item.cc index 05d4cc86f7a..3dba0c42a85 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -932,6 +932,48 @@ bool Item_field::register_field_in_write_map(uchar *arg) return 0; } +/** + Check that we are not refering to any not yet initialized fields + + Fields are initialized in this order: + - All fields that have default value as a constant are initialized first. + - Then all fields that has a default expression, in field_index order. + - Last all virtual fields, in field_index order. + + This means: + - For default fields we can't access the same field or a field after + itself that doesn't have a non-constant default value. + - A virtual fields can't access itself or a virtual field after itself. + + This is used by fix_vcol_expr() when a table is opened + + We don't have to check fields that are marked as NO_DEFAULT_VALUE + as the upper level will ensure that all these will be given a value. +*/ + +bool Item_field::check_field_expression_processor(uchar *arg) +{ + if (field->flags & NO_DEFAULT_VALUE_FLAG) + return 0; + if ((field->default_value || field->has_insert_default_function() || + field->vcol_info)) + { + Field *org_field= (Field*) arg; + if (field == org_field || + (!org_field->vcol_info && field->vcol_info) || + (((field->vcol_info && org_field->vcol_info) || + (!field->vcol_info && !org_field->vcol_info)) && + field->field_index >= org_field->field_index)) + { + my_error(ER_EXPRESSION_REFERS_TO_UNINIT_FIELD, + MYF(0), + org_field->field_name, field->field_name); + return 1; + } + } + return 0; +} + bool Item::check_cols(uint c) { @@ -1345,6 +1387,30 @@ int Item::save_in_field_no_warnings(Field *field, bool no_conversions) return res; } +#ifndef DBUG_OFF +static inline +void mark_unsupported_func(const char *where, const char *processor_name) +{ + char buff[64]; + sprintf(buff, "%s::%s", where ? where: "", processor_name); + DBUG_ENTER(buff); + sprintf(buff, "%s returns TRUE: unsupported function", processor_name); + DBUG_PRINT("info", ("%s", buff)); + DBUG_VOID_RETURN; +} +#else +#define mark_unsupported_func(X,Y) {} +#endif + +bool mark_unsupported_function(const char *where, uchar *store, uint result) +{ + Item::vcol_func_processor_result *res= + (Item::vcol_func_processor_result*) store; + mark_unsupported_func(where, "check_vcol_func_processor"); + res->errors|= result; /* Store type of expression */ + res->name= where ? where : ""; + return false; +} /***************************************************************************** Item_sp_variable methods @@ -8135,7 +8201,8 @@ bool Item_default_value::fix_fields(THD *thd, Item **items) } field_arg= (Item_field *)real_arg; - if (field_arg->field->flags & NO_DEFAULT_VALUE_FLAG) + if ((field_arg->field->flags & NO_DEFAULT_VALUE_FLAG) || + field_arg->field->default_value) { my_error(ER_NO_DEFAULT_FOR_FIELD, MYF(0), field_arg->field->field_name); goto error; |