From 22feb179ae166500ec91feec6246c8154e33f9a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 13 Feb 2019 17:39:05 +0200 Subject: MDEV-15563: Instant ROW_FORMAT=REDUNDANT column extension This was developed by Aleksey Midenkov based on my design. In the original InnoDB storage format (that was retroactively named ROW_FORMAT=REDUNDANT in MySQL 5.0.3), the length of each index field is stored explicitly. Because of this, we can and now will allow instant conversion from VARCHAR to CHAR or VARBINARY to BINARY of equal or greater size, as well as instant conversion of TINYINT to SMALLINT to MEDIUMINT to INT to BIGINT (while not changing between signed and unsigned). Theoretically, we could allow changing from an unsigned integer to a bigger unsigned integer, as well as changing CHAR to VARCHAR, but that would require additional metadata and conversions whenever reading old records. Field_str::is_equal(), Field_varstring::is_equal(), Field_num::is_equal(): Return the new result IS_EQUAL_PACK_LENGTH_EXT if the table advertises HA_EXTENDED_TYPES_CONVERSION capability and we are considering the above-mentioned conversions. ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT: A new ALTER TABLE flag, similar to ALTER_COLUMN_EQUAL_PACK_LENGTH but requiring conversions when reading the data. The Field::is_equal() result IS_EQUAL_PACK_LENGTH_EXT will map to this flag. dtype_get_fixed_size_low(): For BINARY, CHAR and integer columns in ROW_FORMAT=REDUNDANT, return 0 (variable length) from now on. dtype_get_sql_null_size(): Keep returning the current size for BINARY, CHAR and integer columns, so that in ROW_FORMAT=REDUNDANT it will remain possible to update in place between NULL and NOT NULL values. btr_index_rec_validate(): Relax a CHECK TABLE length check for ROW_FORMAT=REDUNDANT tables. btr_cur_instant_init_low(): No longer trust fixed_len for ROW_FORMAT=REDUNDANT tables. We cannot rely on fixed_len anymore because the record can have shorter length from before instant extension. Note that importing such tablespace into earlier MariaDB versions produces ER_TABLE_SCHEMA_MISMATCH when using a .cfg file. --- sql/sql_priv.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'sql/sql_priv.h') diff --git a/sql/sql_priv.h b/sql/sql_priv.h index fa12b645041..d5a69d740ea 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2018, Oracle and/or its affiliates. - Copyright (c) 2010, 2018, Monty Program Ab. + Copyright (c) 2010, 2019, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -345,11 +345,21 @@ #ifndef MYSQL_CLIENT /* - Some defines for exit codes for ::is_equal class functions. + Field::is_equal() return codes. */ #define IS_EQUAL_NO 0 #define IS_EQUAL_YES 1 +/** + new_field has compatible packed representation with old type, + so it is theoretically possible to perform change by only updating + data dictionary without changing table rows +*/ #define IS_EQUAL_PACK_LENGTH 2 +/** + new_field has a representation that is compatible with the old type + when the storage engine advertises HA_EXTENDED_TYPES_CONVERSION +*/ +#define IS_EQUAL_PACK_LENGTH_EXT 3 enum enum_parsing_place { -- cgit v1.2.1