Commit eb9bce51 authored by Sergei Golubchik's avatar Sergei Golubchik

split fix_vcol_expr()

into "fix" and "check" parts
parent ebf1e1d6
...@@ -2502,6 +2502,34 @@ void TABLE_SHARE::free_frm_image(const uchar *frm) ...@@ -2502,6 +2502,34 @@ void TABLE_SHARE::free_frm_image(const uchar *frm)
} }
static bool fix_vcol_expr(THD *thd, Virtual_column_info *vcol)
{
DBUG_ENTER("fix_vcol_expr");
const enum enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
thd->mark_used_columns= MARK_COLUMNS_NONE;
const char *save_where= thd->where;
thd->where= "virtual column function";
thd->in_stored_expression= 1;
int error= vcol->expr_item->fix_fields(thd, &vcol->expr_item);
thd->in_stored_expression= 0;
thd->mark_used_columns= save_mark_used_columns;
thd->where= save_where;
if (unlikely(error))
{
my_error(ER_ERROR_EVALUATING_EXPRESSION, MYF(0), vcol->expr_str);
DBUG_RETURN(1);
}
DBUG_RETURN(0);
}
/* /*
@brief @brief
Perform semantic analysis of the defining expression for a virtual column Perform semantic analysis of the defining expression for a virtual column
...@@ -2529,53 +2557,38 @@ void TABLE_SHARE::free_frm_image(const uchar *frm) ...@@ -2529,53 +2557,38 @@ void TABLE_SHARE::free_frm_image(const uchar *frm)
FALSE Otherwise FALSE Otherwise
*/ */
static bool fix_vcol_expr(THD *thd, TABLE *table, Field *field, static bool fix_and_check_vcol_expr(THD *thd, TABLE *table, Field *field,
Virtual_column_info *vcol) Virtual_column_info *vcol)
{ {
Item* func_expr= vcol->expr_item; Item* func_expr= vcol->expr_item;
bool result= TRUE; DBUG_ENTER("fix_and_check_vcol_expr");
TABLE_LIST tables;
int error= 0;
const char *save_where;
enum_mark_columns save_mark_used_columns= thd->mark_used_columns;
DBUG_ENTER("fix_vcol_expr");
DBUG_PRINT("info", ("vcol: %p", vcol)); DBUG_PRINT("info", ("vcol: %p", vcol));
DBUG_ASSERT(func_expr); DBUG_ASSERT(func_expr);
thd->mark_used_columns= MARK_COLUMNS_NONE; if (func_expr->fixed)
DBUG_RETURN(0); // nothing to do
save_where= thd->where; if (fix_vcol_expr(thd, vcol))
thd->where= "virtual column function"; DBUG_RETURN(1);
/* Fix fields referenced to by the virtual column function */ if (vcol->flags)
thd->in_stored_expression= 1; DBUG_RETURN(0); // already checked, no need to do it again
if (!func_expr->fixed)
error= func_expr->fix_fields(thd, &vcol->expr_item);
thd->in_stored_expression= 0;
if (unlikely(error))
{
DBUG_PRINT("info",
("Field in virtual column expression does not belong to the table"));
my_error(ER_ERROR_EVALUATING_EXPRESSION, MYF(0), vcol->expr_str);
goto end;
}
/* fix_fields could've changed the expression */ /* fix_fields could've changed the expression */
func_expr= vcol->expr_item; func_expr= vcol->expr_item;
/* Number of columns will be checked later */ /* Number of columns will be checked later */
thd->where= save_where;
if (unlikely(func_expr->result_type() == ROW_RESULT)) if (unlikely(func_expr->result_type() == ROW_RESULT))
{ {
my_error(ER_ROW_EXPR_FOR_VCOL, MYF(0)); my_error(ER_ROW_EXPR_FOR_VCOL, MYF(0));
goto end; DBUG_RETURN(1);
} }
/* Check that we are not refering to any not yet initialized fields */ /* Check that we are not refering to any not yet initialized fields */
if (field) if (field)
{ {
if (func_expr->walk(&Item::check_field_expression_processor, 0, field)) if (func_expr->walk(&Item::check_field_expression_processor, 0, field))
goto end; DBUG_RETURN(1);
} }
/* /*
...@@ -2585,12 +2598,12 @@ static bool fix_vcol_expr(THD *thd, TABLE *table, Field *field, ...@@ -2585,12 +2598,12 @@ static bool fix_vcol_expr(THD *thd, TABLE *table, Field *field,
Item::vcol_func_processor_result res; Item::vcol_func_processor_result res;
res.errors= 0; res.errors= 0;
error= func_expr->walk(&Item::check_vcol_func_processor, 0, &res); int error= func_expr->walk(&Item::check_vcol_func_processor, 0, &res);
if (error || (res.errors & VCOL_IMPOSSIBLE)) if (error || (res.errors & VCOL_IMPOSSIBLE))
{ // this can only happen if the frm was corrupted { // this can only happen if the frm was corrupted
my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), res.name, my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), res.name,
"???", field ? field->field_name : "?????"); "???", field ? field->field_name : "?????");
goto end; DBUG_RETURN(1);
} }
vcol->flags= res.errors; vcol->flags= res.errors;
...@@ -2600,16 +2613,10 @@ static bool fix_vcol_expr(THD *thd, TABLE *table, Field *field, ...@@ -2600,16 +2613,10 @@ static bool fix_vcol_expr(THD *thd, TABLE *table, Field *field,
if (vcol->stored_in_db && vcol->flags & VCOL_NON_DETERMINISTIC) if (vcol->stored_in_db && vcol->flags & VCOL_NON_DETERMINISTIC)
table->s->non_determinstic_insert= 1; table->s->non_determinstic_insert= 1;
result= FALSE; DBUG_RETURN(0);
end:
thd->mark_used_columns= save_mark_used_columns;
table->map= 0; //Restore old value
DBUG_RETURN(result);
} }
/* /*
@brief @brief
Unpack the definition of a virtual column from its linear representation Unpack the definition of a virtual column from its linear representation
...@@ -2629,7 +2636,7 @@ static bool fix_vcol_expr(THD *thd, TABLE *table, Field *field, ...@@ -2629,7 +2636,7 @@ static bool fix_vcol_expr(THD *thd, TABLE *table, Field *field,
pointer to this item is placed into in a Virtual_column_info object pointer to this item is placed into in a Virtual_column_info object
that is created. After this the function performs that is created. After this the function performs
semantic analysis of the item by calling the the function semantic analysis of the item by calling the the function
fix_vcol_expr(). Since the defining expression is part of the table fix_and_check_vcol_expr(). Since the defining expression is part of the table
definition the item for it is created in table->memroot within the definition the item for it is created in table->memroot within the
special arena TABLE::expr_arena or in the thd memroot for INSERT DELAYED special arena TABLE::expr_arena or in the thd memroot for INSERT DELAYED
...@@ -2736,15 +2743,10 @@ Virtual_column_info *unpack_vcol_info_from_frm(THD *thd, ...@@ -2736,15 +2743,10 @@ Virtual_column_info *unpack_vcol_info_from_frm(THD *thd,
if (error) if (error)
goto err; goto err;
/*
mark if expression will be stored in the table. This is also used by
fix_vcol_expr() to mark if we are using non deterministic functions.
*/
vcol_storage.vcol_info->stored_in_db= vcol->stored_in_db; vcol_storage.vcol_info->stored_in_db= vcol->stored_in_db;
vcol_storage.vcol_info->name= vcol->name; vcol_storage.vcol_info->name= vcol->name;
vcol_storage.vcol_info->utf8= vcol->utf8; vcol_storage.vcol_info->utf8= vcol->utf8;
/* Validate the Item tree. */ if (!fix_and_check_vcol_expr(thd, table, field, vcol_storage.vcol_info))
if (!fix_vcol_expr(thd, table, field, vcol_storage.vcol_info))
{ {
vcol_info= vcol_storage.vcol_info; // Expression ok vcol_info= vcol_storage.vcol_info; // Expression ok
goto end; goto end;
......
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