Commit 5b034f1c authored by Alexander Barkov's avatar Alexander Barkov

MDEV-12833 Split Column_definition::create_length_to_internal_length() to...

MDEV-12833 Split Column_definition::create_length_to_internal_length() to virtual methods in Type_handler
parent 278c3ea7
......@@ -9805,61 +9805,6 @@ void Column_definition::create_length_to_internal_length_newdecimal()
}
/**
Convert create_field::length from number of characters to number of bytes.
*/
void Column_definition::create_length_to_internal_length(void)
{
switch (real_field_type()) {
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_GEOMETRY:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_VARCHAR:
create_length_to_internal_length_string();
break;
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
create_length_to_internal_length_typelib();
break;
case MYSQL_TYPE_BIT:
create_length_to_internal_length_bit();
break;
case MYSQL_TYPE_NEWDECIMAL:
create_length_to_internal_length_newdecimal();
break;
case MYSQL_TYPE_NULL:
create_length_to_internal_length_null();
break;
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_TINY:
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_LONGLONG:
case MYSQL_TYPE_YEAR:
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
case MYSQL_TYPE_TIME:
case MYSQL_TYPE_TIME2:
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_NEWDATE:
case MYSQL_TYPE_DATETIME:
case MYSQL_TYPE_DATETIME2:
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_TIMESTAMP2:
create_length_to_internal_length_simple();
break;
}
}
bool check_expression(Virtual_column_info *vcol, LEX_CSTRING *name,
enum_vcol_info_type type)
......@@ -10496,6 +10441,33 @@ Column_definition::Column_definition(THD *thd, Field *old_field,
}
/**
The common part for data type redefinition:
CREATE TABLE t1 (a INT) AS SELECT a FROM t2;
See Type_handler::Column_definition_redefine_stage1()
for data type specific code.
*/
void
Column_definition::redefine_stage1_common(const Column_definition *dup_field,
const handler *file,
const Schema_specification_st *schema)
{
set_handler(dup_field->type_handler());
default_value= dup_field->default_value;
charset= dup_field->charset ? dup_field->charset :
schema->default_table_charset;
length= dup_field->char_length;
pack_length= dup_field->pack_length;
key_length= dup_field->key_length;
decimals= dup_field->decimals;
unireg_check= dup_field->unireg_check;
flags= dup_field->flags;
interval= dup_field->interval;
vcol_info= dup_field->vcol_info;
}
/**
maximum possible character length for blob.
......
......@@ -3887,7 +3887,6 @@ class Column_definition: public Sql_alloc,
}
Column_definition(THD *thd, Field *field, Field *orig_field);
void set_attributes(const Lex_field_type_st &type, CHARSET_INFO *cs);
void create_length_to_internal_length(void);
void create_length_to_internal_length_null()
{
DBUG_ASSERT(length == 0);
......@@ -3955,6 +3954,16 @@ class Column_definition: public Sql_alloc,
bool prepare_stage1_bit(THD *thd, MEM_ROOT *mem_root,
handler *file, ulonglong table_flags);
void redefine_stage1_common(const Column_definition *dup_field,
const handler *file,
const Schema_specification_st *schema);
bool redefine_stage1(const Column_definition *dup_field, const handler *file,
const Schema_specification_st *schema)
{
const Type_handler *handler= dup_field->type_handler();
return handler->Column_definition_redefine_stage1(this, dup_field,
file, schema);
}
bool prepare_stage2(handler *handler, ulonglong table_flags);
bool prepare_stage2_blob(handler *handler,
ulonglong table_flags, uint field_flags);
......
......@@ -3355,30 +3355,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
file->ha_table_flags() & HA_CAN_BIT_FIELD)
total_uneven_bit_length-= sql_field->length & 7;
sql_field->default_value= dup_field->default_value;
sql_field->set_handler(dup_field->type_handler());
/*
If we are replacing a field with a BIT field, we need
to initialize pack_flag. Note that we do not need to
increment total_uneven_bit_length here as this dup_field
has already been processed.
*/
if (sql_field->real_field_type() == MYSQL_TYPE_BIT)
{
sql_field->pack_flag= FIELDFLAG_NUMBER;
if (!(file->ha_table_flags() & HA_CAN_BIT_FIELD))
sql_field->pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR;
}
sql_field->charset= (dup_field->charset ?
dup_field->charset :
create_info->default_table_charset);
sql_field->length= dup_field->char_length;
sql_field->pack_length= dup_field->pack_length;
sql_field->key_length= dup_field->key_length;
sql_field->decimals= dup_field->decimals;
sql_field->unireg_check= dup_field->unireg_check;
/*
We're making one field from two, the result field will have
dup_field->flags as flags. If we've incremented null_fields
......@@ -3386,10 +3362,10 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
*/
if (!(sql_field->flags & NOT_NULL_FLAG))
null_fields--;
sql_field->flags= dup_field->flags;
sql_field->create_length_to_internal_length();
sql_field->interval= dup_field->interval;
sql_field->vcol_info= dup_field->vcol_info;
if (sql_field->redefine_stage1(dup_field, file, create_info))
DBUG_RETURN(true);
it2.remove(); // Remove first (create) definition
select_field_pos--;
break;
......
......@@ -1634,6 +1634,93 @@ bool Type_handler_geometry::
#endif
/*************************************************************************/
bool Type_handler::
Column_definition_redefine_stage1(Column_definition *def,
const Column_definition *dup,
const handler *file,
const Schema_specification_st *schema)
const
{
def->redefine_stage1_common(dup, file, schema);
def->create_length_to_internal_length_simple();
return false;
}
bool Type_handler_null::
Column_definition_redefine_stage1(Column_definition *def,
const Column_definition *dup,
const handler *file,
const Schema_specification_st *schema)
const
{
def->redefine_stage1_common(dup, file, schema);
def->create_length_to_internal_length_null();
return false;
}
bool Type_handler_newdecimal::
Column_definition_redefine_stage1(Column_definition *def,
const Column_definition *dup,
const handler *file,
const Schema_specification_st *schema)
const
{
def->redefine_stage1_common(dup, file, schema);
def->create_length_to_internal_length_newdecimal();
return false;
}
bool Type_handler_string_result::
Column_definition_redefine_stage1(Column_definition *def,
const Column_definition *dup,
const handler *file,
const Schema_specification_st *schema)
const
{
def->redefine_stage1_common(dup, file, schema);
def->create_length_to_internal_length_string();
return false;
}
bool Type_handler_typelib::
Column_definition_redefine_stage1(Column_definition *def,
const Column_definition *dup,
const handler *file,
const Schema_specification_st *schema)
const
{
def->redefine_stage1_common(dup, file, schema);
def->create_length_to_internal_length_typelib();
return false;
}
bool Type_handler_bit::
Column_definition_redefine_stage1(Column_definition *def,
const Column_definition *dup,
const handler *file,
const Schema_specification_st *schema)
const
{
def->redefine_stage1_common(dup, file, schema);
/*
If we are replacing a field with a BIT field, we need
to initialize pack_flag.
*/
def->pack_flag= FIELDFLAG_NUMBER;
if (!(file->ha_table_flags() & HA_CAN_BIT_FIELD))
def->pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR;
def->create_length_to_internal_length_bit();
return false;
}
/*************************************************************************/
bool Type_handler::
......
......@@ -68,6 +68,7 @@ class Arg_comparator;
struct st_value;
class Protocol;
class handler;
struct Schema_specification_st;
struct TABLE;
struct SORT_FIELD_ATTR;
......@@ -707,6 +708,28 @@ class Type_handler
Column_definition *c,
handler *file,
ulonglong table_flags) const;
/*
This method is called on queries like:
CREATE TABLE t2 (a INT) AS SELECT a FROM t1;
I.e. column "a" is queried from another table,
but its data type is redefined.
@param OUT def - The column definition to be redefined
@param IN dup - The column definition to take the data type from
(i.e. "a INT" in the above example).
@param IN file - Table owner handler. If it does not support certain
data types, some conversion can be applied.
I.g. true BIT to BIT-AS-CHAR.
@param IN schema - the owner schema definition, e.g. for the default
character set and collation.
@retval true - on error
@retval false - on success
*/
virtual bool Column_definition_redefine_stage1(Column_definition *def,
const Column_definition *dup,
const handler *file,
const Schema_specification_st *
schema)
const;
virtual bool Column_definition_prepare_stage2(Column_definition *c,
handler *file,
ulonglong table_flags) const= 0;
......@@ -966,6 +989,15 @@ class Type_handler_row: public Type_handler
DBUG_ASSERT(0);
return true;
}
bool Column_definition_redefine_stage1(Column_definition *def,
const Column_definition *dup,
const handler *file,
const Schema_specification_st *schema)
const
{
DBUG_ASSERT(0);
return true;
}
bool Column_definition_prepare_stage2(Column_definition *c,
handler *file,
ulonglong table_flags) const
......@@ -1536,6 +1568,11 @@ class Type_handler_string_result: public Type_handler
Column_definition *c,
handler *file,
ulonglong table_flags) const;
bool Column_definition_redefine_stage1(Column_definition *def,
const Column_definition *dup,
const handler *file,
const Schema_specification_st *schema)
const;
uint32 max_display_length(const Item *item) const;
uint Item_time_precision(Item *item) const
{
......@@ -1830,6 +1867,11 @@ class Type_handler_bit: public Type_handler_int_result
Column_definition *c,
handler *file,
ulonglong table_flags) const;
bool Column_definition_redefine_stage1(Column_definition *def,
const Column_definition *dup,
const handler *file,
const Schema_specification_st *schema)
const;
bool Column_definition_prepare_stage2(Column_definition *c,
handler *file,
ulonglong table_flags) const;
......@@ -2250,6 +2292,11 @@ class Type_handler_newdecimal: public Type_handler_decimal_result
Column_definition *c,
handler *file,
ulonglong table_flags) const;
bool Column_definition_redefine_stage1(Column_definition *def,
const Column_definition *dup,
const handler *file,
const Schema_specification_st *schema)
const;
bool Column_definition_prepare_stage2(Column_definition *c,
handler *file,
ulonglong table_flags) const;
......@@ -2282,6 +2329,11 @@ class Type_handler_null: public Type_handler_string_result
Column_definition *c,
handler *file,
ulonglong table_flags) const;
bool Column_definition_redefine_stage1(Column_definition *def,
const Column_definition *dup,
const handler *file,
const Schema_specification_st *schema)
const;
bool Column_definition_prepare_stage2(Column_definition *c,
handler *file,
ulonglong table_flags) const
......@@ -2573,6 +2625,11 @@ class Type_handler_typelib: public Type_handler_string_result
Column_definition *c,
handler *file,
ulonglong table_flags) const;
bool Column_definition_redefine_stage1(Column_definition *def,
const Column_definition *dup,
const handler *file,
const Schema_specification_st *schema)
const;
};
......
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