Commit 998c97e8 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-16823 Add Type_handler::Column_definition_reuse_fix_attributes()

Adding new methods:

- virtual void Type_handler::Column_definition_reuse_fix_attributes()
  according to the MDEV description

- virtual uint32 Field::character_octet_length()
  To simplify handling of Column_definition::length for
  TEXT and VARCHAR columns (with and without compression).
parent 9c0f5a25
...@@ -10653,7 +10653,7 @@ bool Field_vers_trx_id::test_if_equality_guarantees_uniqueness(const Item* item) ...@@ -10653,7 +10653,7 @@ bool Field_vers_trx_id::test_if_equality_guarantees_uniqueness(const Item* item)
Column_definition_attributes::Column_definition_attributes(const Field *field) Column_definition_attributes::Column_definition_attributes(const Field *field)
:length(field->field_length), :length(field->character_octet_length() / field->charset()->mbmaxlen),
unireg_check(field->unireg_check), unireg_check(field->unireg_check),
interval(NULL), interval(NULL),
charset(field->charset()), // May be NULL ptr charset(field->charset()), // May be NULL ptr
...@@ -10682,6 +10682,8 @@ Column_definition::Column_definition(THD *thd, Field *old_field, ...@@ -10682,6 +10682,8 @@ Column_definition::Column_definition(THD *thd, Field *old_field,
compression_method_ptr= 0; compression_method_ptr= 0;
versioning= VERSIONING_NOT_SET; versioning= VERSIONING_NOT_SET;
invisible= old_field->invisible; invisible= old_field->invisible;
interval_list.empty(); // prepare_interval_field() needs this
char_length= (uint) length;
if (orig_field) if (orig_field)
{ {
...@@ -10699,61 +10701,7 @@ Column_definition::Column_definition(THD *thd, Field *old_field, ...@@ -10699,61 +10701,7 @@ Column_definition::Column_definition(THD *thd, Field *old_field,
check_constraint= 0; check_constraint= 0;
} }
switch (real_field_type()) { type_handler()->Column_definition_reuse_fix_attributes(thd, this, old_field);
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
length/= charset->mbmaxlen;
key_length/= charset->mbmaxlen;
break;
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_VAR_STRING:
/* This is corrected in create_length_to_internal_length */
length= (length+charset->mbmaxlen-1) / charset->mbmaxlen -
MY_TEST(old_field->compression_method());
break;
#ifdef HAVE_SPATIAL
case MYSQL_TYPE_GEOMETRY:
geom_type= ((Field_geom*)old_field)->geom_type;
srid= ((Field_geom*)old_field)->srid;
break;
#endif
case MYSQL_TYPE_YEAR:
if (length != 4)
{
char buff[sizeof("YEAR()") + MY_INT64_NUM_DECIMAL_DIGITS + 1];
my_snprintf(buff, sizeof(buff), "YEAR(%llu)", length);
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_WARN_DEPRECATED_SYNTAX,
ER_THD(thd, ER_WARN_DEPRECATED_SYNTAX),
buff, "YEAR(4)");
}
break;
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE:
/*
Floating points are stored with FLOATING_POINT_DECIMALS but internally
in MariaDB used with NOT_FIXED_DEC, which is >= FLOATING_POINT_DECIMALS.
*/
if (decimals >= FLOATING_POINT_DECIMALS)
decimals= NOT_FIXED_DEC;
break;
default:
break;
}
if (flags & (ENUM_FLAG | SET_FLAG))
interval= ((Field_enum*) old_field)->typelib;
else
interval=0;
interval_list.empty(); // prepare_interval_field() needs this
char_length= (uint)length;
type_handler()->Column_definition_implicit_upgrade(this); type_handler()->Column_definition_implicit_upgrade(this);
...@@ -10837,11 +10785,11 @@ Column_definition::redefine_stage1_common(const Column_definition *dup_field, ...@@ -10837,11 +10785,11 @@ Column_definition::redefine_stage1_common(const Column_definition *dup_field,
uint32 Field_blob::char_length() const uint32 Field_blob::char_length() const
{ {
return Field_blob::octet_length(); return Field_blob::character_octet_length();
} }
uint32 Field_blob::octet_length() const uint32 Field_blob::character_octet_length() const
{ {
switch (packlength) switch (packlength)
{ {
......
...@@ -1484,12 +1484,21 @@ class Field: public Value_source ...@@ -1484,12 +1484,21 @@ class Field: public Value_source
/* convert decimal to longlong with overflow check */ /* convert decimal to longlong with overflow check */
longlong convert_decimal2longlong(const my_decimal *val, bool unsigned_flag, longlong convert_decimal2longlong(const my_decimal *val, bool unsigned_flag,
int *err); int *err);
/*
Maximum number of bytes in character representation.
- For string types it is equal to the field capacity, in bytes.
- For non-string types it represents the longest possible string length
after conversion to string.
*/
virtual uint32 character_octet_length() const
{
return field_length;
}
/* The max. number of characters */ /* The max. number of characters */
virtual uint32 char_length() const virtual uint32 char_length() const
{ {
return field_length / charset()->mbmaxlen; return field_length / charset()->mbmaxlen;
} }
virtual geometry_type get_geometry_type() virtual geometry_type get_geometry_type()
{ {
/* shouldn't get here. */ /* shouldn't get here. */
...@@ -1812,6 +1821,7 @@ class Field_str :public Field { ...@@ -1812,6 +1821,7 @@ class Field_str :public Field {
enum Derivation derivation(void) const { return field_derivation; } enum Derivation derivation(void) const { return field_derivation; }
bool binary() const { return field_charset == &my_charset_bin; } bool binary() const { return field_charset == &my_charset_bin; }
uint32 max_display_length() const { return field_length; } uint32 max_display_length() const { return field_length; }
uint32 character_octet_length() const { return field_length; }
uint32 char_length() const { return field_length / field_charset->mbmaxlen; } uint32 char_length() const { return field_length / field_charset->mbmaxlen; }
Information_schema_character_attributes Information_schema_character_attributes
information_schema_character_attributes() const information_schema_character_attributes() const
...@@ -3571,6 +3581,7 @@ class Field_varstring_compressed: public Field_varstring { ...@@ -3571,6 +3581,7 @@ class Field_varstring_compressed: public Field_varstring {
str.append(STRING_WITH_LEN(" /*!100301 COMPRESSED*/")); str.append(STRING_WITH_LEN(" /*!100301 COMPRESSED*/"));
} }
uint32 max_display_length() const { return field_length - 1; } uint32 max_display_length() const { return field_length - 1; }
uint32 character_octet_length() const { return field_length - 1; }
uint32 char_length() const uint32 char_length() const
{ {
return (field_length - 1) / field_charset->mbmaxlen; return (field_length - 1) / field_charset->mbmaxlen;
...@@ -3703,7 +3714,7 @@ class Field_blob :public Field_longstr { ...@@ -3703,7 +3714,7 @@ class Field_blob :public Field_longstr {
Information_schema_character_attributes Information_schema_character_attributes
information_schema_character_attributes() const information_schema_character_attributes() const
{ {
uint32 octets= Field_blob::octet_length(); uint32 octets= Field_blob::character_octet_length();
uint32 chars= octets / field_charset->mbminlen; uint32 chars= octets / field_charset->mbminlen;
return Information_schema_character_attributes(octets, chars); return Information_schema_character_attributes(octets, chars);
} }
...@@ -3869,7 +3880,7 @@ class Field_blob :public Field_longstr { ...@@ -3869,7 +3880,7 @@ class Field_blob :public Field_longstr {
{ return charset() == &my_charset_bin ? FALSE : TRUE; } { return charset() == &my_charset_bin ? FALSE : TRUE; }
uint32 max_display_length() const; uint32 max_display_length() const;
uint32 char_length() const; uint32 char_length() const;
uint32 octet_length() const; uint32 character_octet_length() const;
uint is_equal(Create_field *new_field); uint is_equal(Create_field *new_field);
friend void TABLE::remember_blob_values(String *blob_storage); friend void TABLE::remember_blob_values(String *blob_storage);
......
...@@ -1640,6 +1640,70 @@ bool Type_handler_bit:: ...@@ -1640,6 +1640,70 @@ bool Type_handler_bit::
return def->fix_attributes_bit(); return def->fix_attributes_bit();
} }
/*************************************************************************/
void Type_handler_blob_common::
Column_definition_reuse_fix_attributes(THD *thd,
Column_definition *def,
const Field *field) const
{
DBUG_ASSERT(def->key_length == 0);
}
void Type_handler_typelib::
Column_definition_reuse_fix_attributes(THD *thd,
Column_definition *def,
const Field *field) const
{
DBUG_ASSERT(def->flags & (ENUM_FLAG | SET_FLAG));
def->interval= field->get_typelib();
}
#ifdef HAVE_SPATIAL
void Type_handler_geometry::
Column_definition_reuse_fix_attributes(THD *thd,
Column_definition *def,
const Field *field) const
{
def->geom_type= ((Field_geom*) field)->geom_type;
def->srid= ((Field_geom*) field)->srid;
}
#endif
void Type_handler_year::
Column_definition_reuse_fix_attributes(THD *thd,
Column_definition *def,
const Field *field) const
{
if (def->length != 4)
{
char buff[sizeof("YEAR()") + MY_INT64_NUM_DECIMAL_DIGITS + 1];
my_snprintf(buff, sizeof(buff), "YEAR(%llu)", def->length);
push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_WARN_DEPRECATED_SYNTAX,
ER_THD(thd, ER_WARN_DEPRECATED_SYNTAX),
buff, "YEAR(4)");
}
}
void Type_handler_real_result::
Column_definition_reuse_fix_attributes(THD *thd,
Column_definition *def,
const Field *field) const
{
/*
Floating points are stored with FLOATING_POINT_DECIMALS but internally
in MariaDB used with NOT_FIXED_DEC, which is >= FLOATING_POINT_DECIMALS.
*/
if (def->decimals >= FLOATING_POINT_DECIMALS)
def->decimals= NOT_FIXED_DEC;
}
/*************************************************************************/ /*************************************************************************/
bool Type_handler:: bool Type_handler::
......
...@@ -1275,7 +1275,17 @@ class Type_handler ...@@ -1275,7 +1275,17 @@ class Type_handler
// Automatic upgrade, e.g. for ALTER TABLE t1 FORCE // Automatic upgrade, e.g. for ALTER TABLE t1 FORCE
virtual void Column_definition_implicit_upgrade(Column_definition *c) const virtual void Column_definition_implicit_upgrade(Column_definition *c) const
{ } { }
// Fix attributes after the parser
virtual bool Column_definition_fix_attributes(Column_definition *c) const= 0; virtual bool Column_definition_fix_attributes(Column_definition *c) const= 0;
/*
Fix attributes from an existing field. Used for:
- ALTER TABLE (for columns that do not change)
- DECLARE var TYPE OF t1.col1; (anchored SP variables)
*/
virtual void Column_definition_reuse_fix_attributes(THD *thd,
Column_definition *c,
const Field *field) const
{ }
virtual bool Column_definition_prepare_stage1(THD *thd, virtual bool Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root,
Column_definition *c, Column_definition *c,
...@@ -1630,6 +1640,12 @@ class Type_handler_row: public Type_handler ...@@ -1630,6 +1640,12 @@ class Type_handler_row: public Type_handler
{ {
return false; return false;
} }
void Column_definition_reuse_fix_attributes(THD *thd,
Column_definition *c,
const Field *field) const
{
DBUG_ASSERT(0);
}
bool Column_definition_prepare_stage1(THD *thd, bool Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root,
Column_definition *c, Column_definition *c,
...@@ -1934,6 +1950,9 @@ class Type_handler_real_result: public Type_handler_numeric ...@@ -1934,6 +1950,9 @@ class Type_handler_real_result: public Type_handler_numeric
Item_result cmp_type() const { return REAL_RESULT; } Item_result cmp_type() const { return REAL_RESULT; }
virtual ~Type_handler_real_result() {} virtual ~Type_handler_real_result() {}
const Type_handler *type_handler_for_comparison() const; const Type_handler *type_handler_for_comparison() const;
void Column_definition_reuse_fix_attributes(THD *thd,
Column_definition *c,
const Field *field) const;
int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) const; int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) const;
bool subquery_type_allows_materialization(const Item *inner, bool subquery_type_allows_materialization(const Item *inner,
const Item *outer) const; const Item *outer) const;
...@@ -2766,6 +2785,9 @@ class Type_handler_year: public Type_handler_int_result ...@@ -2766,6 +2785,9 @@ class Type_handler_year: public Type_handler_int_result
Field *make_conversion_table_field(TABLE *, uint metadata, Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const; const Field *target) const;
bool Column_definition_fix_attributes(Column_definition *c) const; bool Column_definition_fix_attributes(Column_definition *c) const;
void Column_definition_reuse_fix_attributes(THD *thd,
Column_definition *c,
const Field *field) const;
bool Column_definition_prepare_stage2(Column_definition *c, bool Column_definition_prepare_stage2(Column_definition *c,
handler *file, handler *file,
ulonglong table_flags) const ulonglong table_flags) const
...@@ -3605,6 +3627,9 @@ class Type_handler_blob_common: public Type_handler_longstr ...@@ -3605,6 +3627,9 @@ class Type_handler_blob_common: public Type_handler_longstr
} }
bool is_param_long_data_type() const { return true; } bool is_param_long_data_type() const { return true; }
bool Column_definition_fix_attributes(Column_definition *c) const; bool Column_definition_fix_attributes(Column_definition *c) const;
void Column_definition_reuse_fix_attributes(THD *thd,
Column_definition *c,
const Field *field) const;
bool Column_definition_prepare_stage2(Column_definition *c, bool Column_definition_prepare_stage2(Column_definition *c,
handler *file, handler *file,
ulonglong table_flags) const; ulonglong table_flags) const;
...@@ -3732,6 +3757,9 @@ class Type_handler_geometry: public Type_handler_string_result ...@@ -3732,6 +3757,9 @@ class Type_handler_geometry: public Type_handler_string_result
const uchar *buffer, const uchar *buffer,
LEX_CUSTRING *gis_options) const; LEX_CUSTRING *gis_options) const;
bool Column_definition_fix_attributes(Column_definition *c) const; bool Column_definition_fix_attributes(Column_definition *c) const;
void Column_definition_reuse_fix_attributes(THD *thd,
Column_definition *c,
const Field *field) const;
bool Column_definition_prepare_stage1(THD *thd, bool Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root,
Column_definition *c, Column_definition *c,
...@@ -3802,6 +3830,9 @@ class Type_handler_typelib: public Type_handler_general_purpose_string ...@@ -3802,6 +3830,9 @@ class Type_handler_typelib: public Type_handler_general_purpose_string
Type_handler_hybrid_field_type *, Type_handler_hybrid_field_type *,
Type_all_attributes *atrr, Type_all_attributes *atrr,
Item **items, uint nitems) const; Item **items, uint nitems) const;
void Column_definition_reuse_fix_attributes(THD *thd,
Column_definition *c,
const Field *field) const;
bool Column_definition_prepare_stage1(THD *thd, bool Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root,
Column_definition *c, Column_definition *c,
......
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