mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
optimize constant default expressions
to be calculated at the CREATE TABLE time and stored in the default row image.
This commit is contained in:
@@ -409,7 +409,6 @@ create or replace table t1 (a int not null, b int default (a+1));
|
|||||||
create or replace table t1 (a int default a);
|
create or replace table t1 (a int default a);
|
||||||
ERROR 01000: Expression for field `a` is refering to uninitialized field `a`
|
ERROR 01000: Expression for field `a` is refering to uninitialized field `a`
|
||||||
create or replace table t1 (a int default b, b int default (1+1));
|
create or replace table t1 (a int default b, b int default (1+1));
|
||||||
ERROR 01000: Expression for field `a` is refering to uninitialized field `b`
|
|
||||||
create or replace table t1 (a int default 1, b int as (c), c int as (a+1));
|
create or replace table t1 (a int default 1, b int as (c), c int as (a+1));
|
||||||
ERROR 01000: Expression for field `b` is refering to uninitialized field `c`
|
ERROR 01000: Expression for field `b` is refering to uninitialized field `c`
|
||||||
CREATE TABLE t1 (a INT DEFAULT (DEFAULT(a)));
|
CREATE TABLE t1 (a INT DEFAULT (DEFAULT(a)));
|
||||||
@@ -3035,7 +3034,7 @@ t1 CREATE TABLE `t1` (
|
|||||||
`a` char(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT concat('A')
|
`a` char(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT concat('A')
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
create table t1 (a int default 1, b int default (1+1), c int);
|
create table t1 (a int default 1, b int default (rand()*0+2), c int);
|
||||||
insert t1 (c) values (a);
|
insert t1 (c) values (a);
|
||||||
insert t1 (c) values (b);
|
insert t1 (c) values (b);
|
||||||
select * from t1;
|
select * from t1;
|
||||||
|
@@ -295,7 +295,6 @@ create or replace table t1 (a int not null, b int default (a+1));
|
|||||||
|
|
||||||
--error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
|
--error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
|
||||||
create or replace table t1 (a int default a);
|
create or replace table t1 (a int default a);
|
||||||
--error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
|
|
||||||
create or replace table t1 (a int default b, b int default (1+1));
|
create or replace table t1 (a int default b, b int default (1+1));
|
||||||
--error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
|
--error ER_EXPRESSION_REFERS_TO_UNINIT_FIELD
|
||||||
create or replace table t1 (a int default 1, b int as (c), c int as (a+1));
|
create or replace table t1 (a int default 1, b int as (c), c int as (a+1));
|
||||||
@@ -1810,7 +1809,7 @@ DROP TABLE t1;
|
|||||||
#
|
#
|
||||||
# Order of evaluation:
|
# Order of evaluation:
|
||||||
#
|
#
|
||||||
create table t1 (a int default 1, b int default (1+1), c int);
|
create table t1 (a int default 1, b int default (rand()*0+2), c int);
|
||||||
insert t1 (c) values (a);
|
insert t1 (c) values (a);
|
||||||
insert t1 (c) values (b);
|
insert t1 (c) values (b);
|
||||||
select * from t1;
|
select * from t1;
|
||||||
|
@@ -574,7 +574,11 @@ inline bool is_temporal_type_with_time(enum_field_types type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bits for type of vcol expression */
|
/*
|
||||||
|
Flags for Virtual_column_info. If none is set, the expression must be
|
||||||
|
a constant with no side-effects, so it's calculated at CREATE TABLE time,
|
||||||
|
stored in table->record[2], and not recalculated for every statement.
|
||||||
|
*/
|
||||||
#define VCOL_FIELD_REF 1
|
#define VCOL_FIELD_REF 1
|
||||||
#define VCOL_NON_DETERMINISTIC 2
|
#define VCOL_NON_DETERMINISTIC 2
|
||||||
#define VCOL_SESSION_FUNC 4 /* uses session data, e.g. USER or DAYNAME */
|
#define VCOL_SESSION_FUNC 4 /* uses session data, e.g. USER or DAYNAME */
|
||||||
|
@@ -956,8 +956,8 @@ bool Item_field::check_field_expression_processor(void *arg)
|
|||||||
{
|
{
|
||||||
if (field->flags & NO_DEFAULT_VALUE_FLAG)
|
if (field->flags & NO_DEFAULT_VALUE_FLAG)
|
||||||
return 0;
|
return 0;
|
||||||
if ((field->default_value || field->has_insert_default_function() ||
|
if ((field->default_value && field->default_value->flags)
|
||||||
field->vcol_info))
|
|| field->has_insert_default_function() || field->vcol_info)
|
||||||
{
|
{
|
||||||
Field *org_field= (Field*) arg;
|
Field *org_field= (Field*) arg;
|
||||||
if (field == org_field ||
|
if (field == org_field ||
|
||||||
@@ -8232,7 +8232,7 @@ bool Item_default_value::fix_fields(THD *thd, Item **items)
|
|||||||
set_field(def_field);
|
set_field(def_field);
|
||||||
if (field->default_value)
|
if (field->default_value)
|
||||||
{
|
{
|
||||||
if (field->default_value->expr_item) // it's NULL during CREATE TABLE
|
if (thd->mark_used_columns != MARK_COLUMNS_NONE)
|
||||||
field->default_value->expr_item->walk(&Item::register_field_in_read_map, 1, 0);
|
field->default_value->expr_item->walk(&Item::register_field_in_read_map, 1, 0);
|
||||||
IF_DBUG(def_field->is_stat_field=1,); // a hack to fool ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED
|
IF_DBUG(def_field->is_stat_field=1,); // a hack to fool ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED
|
||||||
}
|
}
|
||||||
|
190
sql/sql_table.cc
190
sql/sql_table.cc
@@ -3255,35 +3255,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
!(sql_field->charset= find_bin_collation(sql_field->charset)))
|
!(sql_field->charset= find_bin_collation(sql_field->charset)))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
/*
|
|
||||||
Convert the default value from client character
|
|
||||||
set into the column character set if necessary.
|
|
||||||
We can only do this for constants as we have not yet run fix_fields.
|
|
||||||
*/
|
|
||||||
if (sql_field->default_value &&
|
|
||||||
sql_field->default_value->expr_item->basic_const_item() &&
|
|
||||||
save_cs != sql_field->default_value->expr_item->collation.collation &&
|
|
||||||
(sql_field->sql_type == MYSQL_TYPE_VAR_STRING ||
|
|
||||||
sql_field->sql_type == MYSQL_TYPE_STRING ||
|
|
||||||
sql_field->sql_type == MYSQL_TYPE_SET ||
|
|
||||||
sql_field->sql_type == MYSQL_TYPE_TINY_BLOB ||
|
|
||||||
sql_field->sql_type == MYSQL_TYPE_MEDIUM_BLOB ||
|
|
||||||
sql_field->sql_type == MYSQL_TYPE_LONG_BLOB ||
|
|
||||||
sql_field->sql_type == MYSQL_TYPE_BLOB ||
|
|
||||||
sql_field->sql_type == MYSQL_TYPE_ENUM))
|
|
||||||
{
|
|
||||||
Item *item;
|
|
||||||
if (!(item= sql_field->default_value->expr_item->
|
|
||||||
safe_charset_converter(thd, save_cs)))
|
|
||||||
{
|
|
||||||
/* Could not convert */
|
|
||||||
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
|
|
||||||
DBUG_RETURN(TRUE);
|
|
||||||
}
|
|
||||||
/* Fix for prepare statement */
|
|
||||||
thd->change_item_tree(&sql_field->default_value->expr_item, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sql_field->sql_type == MYSQL_TYPE_SET ||
|
if (sql_field->sql_type == MYSQL_TYPE_SET ||
|
||||||
sql_field->sql_type == MYSQL_TYPE_ENUM)
|
sql_field->sql_type == MYSQL_TYPE_ENUM)
|
||||||
{
|
{
|
||||||
@@ -3349,37 +3320,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
if (sql_field->sql_type == MYSQL_TYPE_SET)
|
if (sql_field->sql_type == MYSQL_TYPE_SET)
|
||||||
{
|
{
|
||||||
uint32 field_length;
|
uint32 field_length;
|
||||||
if (sql_field->default_value &&
|
|
||||||
sql_field->default_value->expr_item->basic_const_item())
|
|
||||||
{
|
|
||||||
char *not_used;
|
|
||||||
uint not_used2;
|
|
||||||
bool not_found= 0;
|
|
||||||
String str, *def= sql_field->default_value->expr_item->val_str(&str);
|
|
||||||
if (def == NULL) /* SQL "NULL" maps to NULL */
|
|
||||||
{
|
|
||||||
if ((sql_field->flags & NOT_NULL_FLAG) != 0)
|
|
||||||
{
|
|
||||||
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
|
|
||||||
DBUG_RETURN(TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* else, NULL is an allowed value */
|
|
||||||
(void) find_set(interval, NULL, 0,
|
|
||||||
cs, ¬_used, ¬_used2, ¬_found);
|
|
||||||
}
|
|
||||||
else /* not NULL */
|
|
||||||
{
|
|
||||||
(void) find_set(interval, def->ptr(), def->length(),
|
|
||||||
cs, ¬_used, ¬_used2, ¬_found);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (not_found)
|
|
||||||
{
|
|
||||||
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
|
|
||||||
DBUG_RETURN(TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
calculate_interval_lengths(cs, interval, &dummy, &field_length);
|
calculate_interval_lengths(cs, interval, &dummy, &field_length);
|
||||||
sql_field->length= field_length + (interval->count - 1);
|
sql_field->length= field_length + (interval->count - 1);
|
||||||
}
|
}
|
||||||
@@ -3387,30 +3327,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
{
|
{
|
||||||
uint32 field_length;
|
uint32 field_length;
|
||||||
DBUG_ASSERT(sql_field->sql_type == MYSQL_TYPE_ENUM);
|
DBUG_ASSERT(sql_field->sql_type == MYSQL_TYPE_ENUM);
|
||||||
if (sql_field->default_value &&
|
|
||||||
sql_field->default_value->expr_item->basic_const_item())
|
|
||||||
{
|
|
||||||
String str, *def= sql_field->default_value->expr_item->val_str(&str);
|
|
||||||
if (def == NULL) /* SQL "NULL" maps to NULL */
|
|
||||||
{
|
|
||||||
if ((sql_field->flags & NOT_NULL_FLAG) != 0)
|
|
||||||
{
|
|
||||||
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
|
|
||||||
DBUG_RETURN(TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* else, the defaults yield the correct length for NULLs. */
|
|
||||||
}
|
|
||||||
else /* not NULL */
|
|
||||||
{
|
|
||||||
def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
|
|
||||||
if (find_type2(interval, def->ptr(), def->length(), cs) == 0) /* not found */
|
|
||||||
{
|
|
||||||
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
|
|
||||||
DBUG_RETURN(TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
calculate_interval_lengths(cs, interval, &field_length, &dummy);
|
calculate_interval_lengths(cs, interval, &field_length, &dummy);
|
||||||
sql_field->length= field_length;
|
sql_field->length= field_length;
|
||||||
}
|
}
|
||||||
@@ -3430,6 +3346,112 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
if (prepare_blob_field(thd, sql_field))
|
if (prepare_blob_field(thd, sql_field))
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
|
if (sql_field->default_value)
|
||||||
|
{
|
||||||
|
Virtual_column_info *def= sql_field->default_value;
|
||||||
|
|
||||||
|
if (!sql_field->has_default_expression())
|
||||||
|
def->expr_str= null_lex_str;
|
||||||
|
|
||||||
|
if (!def->expr_item->basic_const_item() && !def->flags)
|
||||||
|
{
|
||||||
|
Item *expr= def->expr_item;
|
||||||
|
int err= !expr->fixed && // may be already fixed if ALTER TABLE
|
||||||
|
expr->fix_fields(thd, &expr);
|
||||||
|
if (!err)
|
||||||
|
{
|
||||||
|
if (expr->result_type() == REAL_RESULT)
|
||||||
|
{ // don't convert floats to string and back, it can be lossy
|
||||||
|
double res= expr->val_real();
|
||||||
|
if (expr->null_value)
|
||||||
|
expr= new (thd->mem_root) Item_null(thd);
|
||||||
|
else
|
||||||
|
expr= new (thd->mem_root) Item_float(thd, res, expr->decimals);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StringBuffer<MAX_FIELD_WIDTH> buf;
|
||||||
|
String *res= expr->val_str(&buf);
|
||||||
|
if (expr->null_value)
|
||||||
|
expr= new (thd->mem_root) Item_null(thd);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *str= (char*) thd->strmake(res->ptr(), res->length());
|
||||||
|
expr= new (thd->mem_root) Item_string(thd, str, res->length(), res->charset());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
thd->change_item_tree(&def->expr_item, expr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Convert the default value from client character
|
||||||
|
set into the column character set if necessary.
|
||||||
|
We can only do this for constants as we have not yet run fix_fields.
|
||||||
|
*/
|
||||||
|
if (sql_field->default_value &&
|
||||||
|
sql_field->default_value->expr_item->basic_const_item() &&
|
||||||
|
save_cs != sql_field->default_value->expr_item->collation.collation &&
|
||||||
|
(sql_field->sql_type == MYSQL_TYPE_VAR_STRING ||
|
||||||
|
sql_field->sql_type == MYSQL_TYPE_STRING ||
|
||||||
|
sql_field->sql_type == MYSQL_TYPE_SET ||
|
||||||
|
sql_field->sql_type == MYSQL_TYPE_TINY_BLOB ||
|
||||||
|
sql_field->sql_type == MYSQL_TYPE_MEDIUM_BLOB ||
|
||||||
|
sql_field->sql_type == MYSQL_TYPE_LONG_BLOB ||
|
||||||
|
sql_field->sql_type == MYSQL_TYPE_BLOB ||
|
||||||
|
sql_field->sql_type == MYSQL_TYPE_ENUM))
|
||||||
|
{
|
||||||
|
Item *item;
|
||||||
|
if (!(item= sql_field->default_value->expr_item->
|
||||||
|
safe_charset_converter(thd, save_cs)))
|
||||||
|
{
|
||||||
|
/* Could not convert */
|
||||||
|
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
/* Fix for prepare statement */
|
||||||
|
thd->change_item_tree(&sql_field->default_value->expr_item, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sql_field->default_value &&
|
||||||
|
sql_field->default_value->expr_item->basic_const_item() &&
|
||||||
|
(sql_field->sql_type == MYSQL_TYPE_SET ||
|
||||||
|
sql_field->sql_type == MYSQL_TYPE_ENUM))
|
||||||
|
{
|
||||||
|
StringBuffer<MAX_FIELD_WIDTH> str;
|
||||||
|
String *def= sql_field->default_value->expr_item->val_str(&str);
|
||||||
|
bool not_found;
|
||||||
|
if (def == NULL) /* SQL "NULL" maps to NULL */
|
||||||
|
{
|
||||||
|
not_found= sql_field->flags & NOT_NULL_FLAG;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
not_found= false;
|
||||||
|
if (sql_field->sql_type == MYSQL_TYPE_SET)
|
||||||
|
{
|
||||||
|
char *not_used;
|
||||||
|
uint not_used2;
|
||||||
|
find_set(sql_field->interval, def->ptr(), def->length(),
|
||||||
|
sql_field->charset, ¬_used, ¬_used2, ¬_found);
|
||||||
|
}
|
||||||
|
else /* MYSQL_TYPE_ENUM */
|
||||||
|
{
|
||||||
|
def->length(sql_field->charset->cset->lengthsp(sql_field->charset,
|
||||||
|
def->ptr(), def->length()));
|
||||||
|
not_found= !find_type2(sql_field->interval, def->ptr(),
|
||||||
|
def->length(), sql_field->charset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not_found)
|
||||||
|
{
|
||||||
|
my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!(sql_field->flags & NOT_NULL_FLAG))
|
if (!(sql_field->flags & NOT_NULL_FLAG))
|
||||||
null_fields++;
|
null_fields++;
|
||||||
|
|
||||||
|
47
sql/table.cc
47
sql/table.cc
@@ -2593,13 +2593,6 @@ static bool fix_and_check_vcol_expr(THD *thd, TABLE *table, Field *field,
|
|||||||
DBUG_RETURN(1);
|
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))
|
|
||||||
DBUG_RETURN(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Walk through the Item tree checking if all items are valid
|
Walk through the Item tree checking if all items are valid
|
||||||
to be part of the virtual column
|
to be part of the virtual column
|
||||||
@@ -2777,6 +2770,14 @@ end:
|
|||||||
DBUG_RETURN(vcol_info);
|
DBUG_RETURN(vcol_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool check_vcol_forward_refs(Field *field, Virtual_column_info *vcol)
|
||||||
|
{
|
||||||
|
bool res= vcol &&
|
||||||
|
vcol->expr_item->walk(&Item::check_field_expression_processor, 0,
|
||||||
|
field);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
|
Read data from a binary .frm file from MySQL 3.23 - 5.0 into TABLE_SHARE
|
||||||
*/
|
*/
|
||||||
@@ -3041,22 +3042,6 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
field->default_value= vcol;
|
field->default_value= vcol;
|
||||||
if (is_create_table && !vcol->flags)
|
|
||||||
{
|
|
||||||
enum_check_fields old_count_cuted_fields= thd->count_cuted_fields;
|
|
||||||
thd->count_cuted_fields= CHECK_FIELD_WARN; // To find wrong default values
|
|
||||||
my_ptrdiff_t off= share->default_values - outparam->record[0];
|
|
||||||
field->move_field_offset(off);
|
|
||||||
int res= vcol->expr_item->save_in_field(field, 1);
|
|
||||||
field->move_field_offset(-off);
|
|
||||||
thd->count_cuted_fields= old_count_cuted_fields;
|
|
||||||
if (res != 0 && res != 3)
|
|
||||||
{
|
|
||||||
my_error(ER_INVALID_DEFAULT, MYF(0), field->field_name);
|
|
||||||
error= OPEN_FRM_CORRUPTED;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*(dfield_ptr++)= *field_ptr;
|
*(dfield_ptr++)= *field_ptr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -3068,6 +3053,19 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
|
|||||||
*vfield_ptr= 0; // End marker
|
*vfield_ptr= 0; // End marker
|
||||||
*dfield_ptr= 0; // End marker
|
*dfield_ptr= 0; // End marker
|
||||||
|
|
||||||
|
/* Check that expressions aren't refering to not yet initialized fields */
|
||||||
|
for (field_ptr= outparam->field; *field_ptr; field_ptr++)
|
||||||
|
{
|
||||||
|
Field *field= *field_ptr;
|
||||||
|
if (check_vcol_forward_refs(field, field->vcol_info) ||
|
||||||
|
check_vcol_forward_refs(field, field->check_constraint) ||
|
||||||
|
check_vcol_forward_refs(field, field->default_value))
|
||||||
|
{
|
||||||
|
error= OPEN_FRM_CORRUPTED;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Update to use trigger fields */
|
/* Update to use trigger fields */
|
||||||
switch_defaults_to_nullable_trigger_fields(outparam);
|
switch_defaults_to_nullable_trigger_fields(outparam);
|
||||||
|
|
||||||
@@ -7316,7 +7314,8 @@ int TABLE::update_default_fields(bool update_command, bool ignore_errors)
|
|||||||
{
|
{
|
||||||
if (!update_command)
|
if (!update_command)
|
||||||
{
|
{
|
||||||
if (field->default_value)
|
if (field->default_value &&
|
||||||
|
(field->default_value->flags || field->flags & BLOB_FLAG))
|
||||||
res|= (field->default_value->expr_item->save_in_field(field, 0) < 0);
|
res|= (field->default_value->expr_item->save_in_field(field, 0) < 0);
|
||||||
else
|
else
|
||||||
res|= field->evaluate_insert_default_function();
|
res|= field->evaluate_insert_default_function();
|
||||||
|
@@ -634,7 +634,7 @@ static bool pack_header(THD *thd, uchar *forminfo,
|
|||||||
|
|
||||||
if (add_expr_length(thd, &field->vcol_info, &expression_length))
|
if (add_expr_length(thd, &field->vcol_info, &expression_length))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
if (field->has_default_expression())
|
if (field->default_value && field->default_value->expr_str.length)
|
||||||
if (add_expr_length(thd, &field->default_value, &expression_length))
|
if (add_expr_length(thd, &field->default_value, &expression_length))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
if (add_expr_length(thd, &field->check_constraint, &expression_length))
|
if (add_expr_length(thd, &field->check_constraint, &expression_length))
|
||||||
@@ -983,7 +983,7 @@ static bool pack_fields(uchar **buff_arg, List<Create_field> &create_fields,
|
|||||||
if (field->vcol_info)
|
if (field->vcol_info)
|
||||||
pack_expression(&buff, field->vcol_info, field_nr,
|
pack_expression(&buff, field->vcol_info, field_nr,
|
||||||
field->vcol_info->stored_in_db ? 1 : 0);
|
field->vcol_info->stored_in_db ? 1 : 0);
|
||||||
if (field->has_default_expression())
|
if (field->default_value && field->default_value->expr_str.length)
|
||||||
pack_expression(&buff, field->default_value, field_nr, 2);
|
pack_expression(&buff, field->default_value, field_nr, 2);
|
||||||
if (field->check_constraint)
|
if (field->check_constraint)
|
||||||
pack_expression(&buff, field->check_constraint, field_nr, 3);
|
pack_expression(&buff, field->check_constraint, field_nr, 3);
|
||||||
|
Reference in New Issue
Block a user