summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc69
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;