Skip to content

Commit

Permalink
split fix_vcol_expr()
Browse files Browse the repository at this point in the history
into "fix" and "check" parts
  • Loading branch information
vuvova committed Aug 27, 2016
1 parent ebf1e1d commit eb9bce5
Showing 1 changed file with 45 additions and 43 deletions.
88 changes: 45 additions & 43 deletions sql/table.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Perform semantic analysis of the defining expression for a virtual column
Expand Down Expand Up @@ -2529,53 +2557,38 @@ void TABLE_SHARE::free_frm_image(const uchar *frm)
FALSE Otherwise
*/

static bool fix_vcol_expr(THD *thd, TABLE *table, Field *field,
Virtual_column_info *vcol)
static bool fix_and_check_vcol_expr(THD *thd, TABLE *table, Field *field,
Virtual_column_info *vcol)
{
Item* func_expr= vcol->expr_item;
bool result= TRUE;
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_ENTER("fix_and_check_vcol_expr");
DBUG_PRINT("info", ("vcol: %p", vcol));
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;
thd->where= "virtual column function";
if (fix_vcol_expr(thd, vcol))
DBUG_RETURN(1);

/* Fix fields referenced to by the virtual column function */
thd->in_stored_expression= 1;
if (!func_expr->fixed)
error= func_expr->fix_fields(thd, &vcol->expr_item);
thd->in_stored_expression= 0;
if (vcol->flags)
DBUG_RETURN(0); // already checked, no need to do it again

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 */
func_expr= vcol->expr_item;

/* Number of columns will be checked later */
thd->where= save_where;
if (unlikely(func_expr->result_type() == ROW_RESULT))
{
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 */
if (field)
{
if (func_expr->walk(&Item::check_field_expression_processor, 0, field))
goto end;
DBUG_RETURN(1);
}

/*
Expand All @@ -2585,12 +2598,12 @@ static bool fix_vcol_expr(THD *thd, TABLE *table, Field *field,
Item::vcol_func_processor_result res;
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))
{ // this can only happen if the frm was corrupted
my_error(ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED, MYF(0), res.name,
"???", field ? field->field_name : "?????");
goto end;
DBUG_RETURN(1);
}
vcol->flags= res.errors;

Expand All @@ -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)
table->s->non_determinstic_insert= 1;

result= FALSE;

end:

thd->mark_used_columns= save_mark_used_columns;
table->map= 0; //Restore old value

DBUG_RETURN(result);
DBUG_RETURN(0);
}


/*
@brief
Unpack the definition of a virtual column from its linear representation
Expand All @@ -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
that is created. After this the function performs
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
special arena TABLE::expr_arena or in the thd memroot for INSERT DELAYED
Expand Down Expand Up @@ -2736,15 +2743,10 @@ Virtual_column_info *unpack_vcol_info_from_frm(THD *thd,
if (error)
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->name= vcol->name;
vcol_storage.vcol_info->utf8= vcol->utf8;
/* Validate the Item tree. */
if (!fix_vcol_expr(thd, table, field, vcol_storage.vcol_info))
if (!fix_and_check_vcol_expr(thd, table, field, vcol_storage.vcol_info))
{
vcol_info= vcol_storage.vcol_info; // Expression ok
goto end;
Expand Down

0 comments on commit eb9bce5

Please sign in to comment.