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)
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),
interval(NULL),
charset(field->charset()), // May be NULL ptr
......@@ -10682,6 +10682,8 @@ Column_definition::Column_definition(THD *thd, Field *old_field,
compression_method_ptr= 0;
versioning= VERSIONING_NOT_SET;
invisible= old_field->invisible;
interval_list.empty(); // prepare_interval_field() needs this
char_length= (uint) length;
if (orig_field)
{
......@@ -10699,61 +10701,7 @@ Column_definition::Column_definition(THD *thd, Field *old_field,
check_constraint= 0;
}
switch (real_field_type()) {
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_reuse_fix_attributes(thd, this, old_field);
type_handler()->Column_definition_implicit_upgrade(this);
......@@ -10837,11 +10785,11 @@ Column_definition::redefine_stage1_common(const Column_definition *dup_field,
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)
{
......
......@@ -1484,12 +1484,21 @@ class Field: public Value_source
/* convert decimal to longlong with overflow check */
longlong convert_decimal2longlong(const my_decimal *val, bool unsigned_flag,
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 */
virtual uint32 char_length() const
{
return field_length / charset()->mbmaxlen;
}
virtual geometry_type get_geometry_type()
{
/* shouldn't get here. */
......@@ -1812,6 +1821,7 @@ class Field_str :public Field {
enum Derivation derivation(void) const { return field_derivation; }
bool binary() const { return field_charset == &my_charset_bin; }
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; }
Information_schema_character_attributes
information_schema_character_attributes() const
......@@ -3571,6 +3581,7 @@ class Field_varstring_compressed: public Field_varstring {
str.append(STRING_WITH_LEN(" /*!100301 COMPRESSED*/"));
}
uint32 max_display_length() const { return field_length - 1; }
uint32 character_octet_length() const { return field_length - 1; }
uint32 char_length() const
{
return (field_length - 1) / field_charset->mbmaxlen;
......@@ -3703,7 +3714,7 @@ class Field_blob :public Field_longstr {
Information_schema_character_attributes
information_schema_character_attributes() const
{
uint32 octets= Field_blob::octet_length();
uint32 octets= Field_blob::character_octet_length();
uint32 chars= octets / field_charset->mbminlen;
return Information_schema_character_attributes(octets, chars);
}
......@@ -3869,7 +3880,7 @@ class Field_blob :public Field_longstr {
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
uint32 max_display_length() const;
uint32 char_length() const;
uint32 octet_length() const;
uint32 character_octet_length() const;
uint is_equal(Create_field *new_field);
friend void TABLE::remember_blob_values(String *blob_storage);
......
......@@ -1640,6 +1640,70 @@ bool Type_handler_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::
......
......@@ -1275,7 +1275,17 @@ class Type_handler
// Automatic upgrade, e.g. for ALTER TABLE t1 FORCE
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;
/*
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,
MEM_ROOT *mem_root,
Column_definition *c,
......@@ -1630,6 +1640,12 @@ class Type_handler_row: public Type_handler
{
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,
MEM_ROOT *mem_root,
Column_definition *c,
......@@ -1934,6 +1950,9 @@ class Type_handler_real_result: public Type_handler_numeric
Item_result cmp_type() const { return REAL_RESULT; }
virtual ~Type_handler_real_result() {}
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;
bool subquery_type_allows_materialization(const Item *inner,
const Item *outer) const;
......@@ -2766,6 +2785,9 @@ class Type_handler_year: public Type_handler_int_result
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) 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,
handler *file,
ulonglong table_flags) const
......@@ -3605,6 +3627,9 @@ class Type_handler_blob_common: public Type_handler_longstr
}
bool is_param_long_data_type() const { return true; }
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,
handler *file,
ulonglong table_flags) const;
......@@ -3732,6 +3757,9 @@ class Type_handler_geometry: public Type_handler_string_result
const uchar *buffer,
LEX_CUSTRING *gis_options) 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,
MEM_ROOT *mem_root,
Column_definition *c,
......@@ -3802,6 +3830,9 @@ class Type_handler_typelib: public Type_handler_general_purpose_string
Type_handler_hybrid_field_type *,
Type_all_attributes *atrr,
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,
MEM_ROOT *mem_root,
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