1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Merge branch '10.3' into 10.4

This commit is contained in:
Oleksandr Byelkin
2019-05-19 20:55:37 +02:00
3893 changed files with 11766 additions and 6460 deletions

View File

@ -11,8 +11,8 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
/** @file handler.cc
@ -4898,10 +4898,7 @@ void handler::get_dynamic_partition_info(PARTITION_STATS *stat_info,
stat_info->create_time= stats.create_time;
stat_info->update_time= stats.update_time;
stat_info->check_time= stats.check_time;
stat_info->check_sum= 0;
if (table_flags() & (HA_HAS_OLD_CHECKSUM | HA_HAS_NEW_CHECKSUM))
stat_info->check_sum= checksum();
return;
stat_info->check_sum= stats.checksum;
}
@ -5023,6 +5020,98 @@ end:
}
static void flush_checksum(ha_checksum *row_crc, uchar **checksum_start,
size_t *checksum_length)
{
if (*checksum_start)
{
*row_crc= my_checksum(*row_crc, *checksum_start, *checksum_length);
*checksum_start= NULL;
*checksum_length= 0;
}
}
/* calculating table's checksum */
int handler::calculate_checksum()
{
int error;
THD *thd=ha_thd();
DBUG_ASSERT(table->s->last_null_bit_pos < 8);
uchar null_mask= table->s->last_null_bit_pos
? 256 - (1 << table->s->last_null_bit_pos) : 0;
table->use_all_stored_columns();
stats.checksum= 0;
if ((error= ha_rnd_init(1)))
return error;
for (;;)
{
if (thd->killed)
return HA_ERR_ABORTED_BY_USER;
ha_checksum row_crc= 0;
error= table->file->ha_rnd_next(table->record[0]);
if (error)
break;
if (table->s->null_bytes)
{
/* fix undefined null bits */
table->record[0][table->s->null_bytes-1] |= null_mask;
if (!(table->s->db_create_options & HA_OPTION_PACK_RECORD))
table->record[0][0] |= 1;
row_crc= my_checksum(row_crc, table->record[0], table->s->null_bytes);
}
uchar *checksum_start= NULL;
size_t checksum_length= 0;
for (uint i= 0; i < table->s->fields; i++ )
{
Field *f= table->field[i];
if (! thd->variables.old_mode && f->is_real_null(0))
{
flush_checksum(&row_crc, &checksum_start, &checksum_length);
continue;
}
/*
BLOB and VARCHAR have pointers in their field, we must convert
to string; GEOMETRY is implemented on top of BLOB.
BIT may store its data among NULL bits, convert as well.
*/
switch (f->type()) {
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_VARCHAR:
case MYSQL_TYPE_GEOMETRY:
case MYSQL_TYPE_BIT:
{
flush_checksum(&row_crc, &checksum_start, &checksum_length);
String tmp;
f->val_str(&tmp);
row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(), tmp.length());
break;
}
default:
if (!checksum_start)
checksum_start= f->ptr;
DBUG_ASSERT(checksum_start + checksum_length == f->ptr);
checksum_length+= f->pack_length();
break;
}
}
flush_checksum(&row_crc, &checksum_start, &checksum_length);
stats.checksum+= row_crc;
}
table->file->ha_rnd_end();
return error == HA_ERR_END_OF_FILE ? 0 : error;
}
/****************************************************************************
** Some general functions that isn't in the handler class
****************************************************************************/
@ -6350,8 +6439,8 @@ int handler::ha_reset()
table->default_column_bitmaps();
pushed_cond= NULL;
tracker= NULL;
mark_trx_read_write_done= check_table_binlog_row_based_done=
check_table_binlog_row_based_result= 0;
mark_trx_read_write_done= 0;
clear_cached_table_binlog_row_based_flag();
/* Reset information about pushed engine conditions */
cancel_pushed_idx_cond();
/* Reset information about pushed index conditions */
@ -7339,8 +7428,9 @@ bool Table_scope_and_contents_source_st::vers_check_system_fields(
{
if (!(options & HA_VERSIONED_TABLE))
return false;
return vers_info.check_sys_fields(create_table.table_name, create_table.db,
alter_info);
return vers_info.check_sys_fields(
create_table.table_name, create_table.db, alter_info,
ha_check_storage_engine_flag(db_type, HTON_NATIVE_SYS_VERSIONING));
}
@ -7449,7 +7539,11 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info,
if (alter_info->flags & ALTER_ADD_SYSTEM_VERSIONING)
{
if (check_sys_fields(table_name, share->db, alter_info))
const bool can_native=
ha_check_storage_engine_flag(create_info->db_type,
HTON_NATIVE_SYS_VERSIONING) ||
create_info->db_type->db_type == DB_TYPE_PARTITION_DB;
if (check_sys_fields(table_name, share->db, alter_info, can_native))
return true;
}
@ -7554,80 +7648,86 @@ bool Vers_parse_info::check_conditions(const Lex_table_name &table_name,
return false;
}
static bool is_versioning_timestamp(const Create_field *f)
{
return (f->type_handler() == &type_handler_datetime2 ||
f->type_handler() == &type_handler_timestamp2) &&
f->length == MAX_DATETIME_FULL_WIDTH;
}
static bool is_some_bigint(const Create_field *f)
{
return f->type_handler() == &type_handler_longlong ||
f->type_handler() == &type_handler_vers_trx_id;
}
static bool is_versioning_bigint(const Create_field *f)
{
return is_some_bigint(f) && f->flags & UNSIGNED_FLAG &&
f->length == MY_INT64_NUM_DECIMAL_DIGITS - 1;
}
static bool require_timestamp(const Create_field *f, Lex_table_name table_name)
{
my_error(ER_VERS_FIELD_WRONG_TYPE, MYF(0), f->field_name.str, "TIMESTAMP(6)",
table_name.str);
return true;
}
static bool require_bigint(const Create_field *f, Lex_table_name table_name)
{
my_error(ER_VERS_FIELD_WRONG_TYPE, MYF(0), f->field_name.str,
"BIGINT(20) UNSIGNED", table_name.str);
return true;
}
bool Vers_parse_info::check_sys_fields(const Lex_table_name &table_name,
const Lex_table_name &db,
Alter_info *alter_info)
Alter_info *alter_info,
bool can_native) const
{
if (check_conditions(table_name, db))
return true;
const Create_field *row_start= NULL;
const Create_field *row_end= NULL;
List_iterator<Create_field> it(alter_info->create_list);
uint found_flag= 0;
while (Create_field *f= it++)
{
vers_sys_type_t f_check_unit= VERS_UNDEFINED;
uint sys_flag= f->flags & VERS_SYSTEM_FIELD;
if (!sys_flag)
continue;
if (sys_flag & found_flag)
{
my_error(ER_VERS_DUPLICATE_ROW_START_END, MYF(0),
found_flag & VERS_SYS_START_FLAG ? "START" : "END",
f->field_name.str);
return true;
}
sys_flag|= found_flag;
if ((f->type_handler() == &type_handler_datetime2 ||
f->type_handler() == &type_handler_timestamp2) &&
f->length == MAX_DATETIME_FULL_WIDTH)
{
f_check_unit= VERS_TIMESTAMP;
}
else if (f->type_handler() == &type_handler_longlong
&& (f->flags & UNSIGNED_FLAG)
&& f->length == (MY_INT64_NUM_DECIMAL_DIGITS - 1))
{
f_check_unit= VERS_TRX_ID;
}
else
{
if (!check_unit)
check_unit= VERS_TIMESTAMP;
goto error;
}
if (f_check_unit)
{
if (check_unit)
{
if (check_unit == f_check_unit)
{
if (check_unit == VERS_TRX_ID && !TR_table::use_transaction_registry)
{
my_error(ER_VERS_TRT_IS_DISABLED, MYF(0));
return true;
}
return false;
}
error:
my_error(ER_VERS_FIELD_WRONG_TYPE, MYF(0), f->field_name.str,
check_unit == VERS_TIMESTAMP ?
"TIMESTAMP(6)" :
"BIGINT(20) UNSIGNED",
table_name.str);
return true;
}
check_unit= f_check_unit;
}
if (!row_start && f->flags & VERS_SYS_START_FLAG)
row_start= f;
else if (!row_end && f->flags & VERS_SYS_END_FLAG)
row_end= f;
}
my_error(ER_MISSING, MYF(0), table_name.str, found_flag & VERS_SYS_START_FLAG ?
"ROW END" : found_flag ? "ROW START" : "ROW START/END");
return true;
const bool expect_timestamp=
!can_native || !is_some_bigint(row_start) || !is_some_bigint(row_end);
if (expect_timestamp)
{
if (!is_versioning_timestamp(row_start))
return require_timestamp(row_start, table_name);
if (!is_versioning_timestamp(row_end))
return require_timestamp(row_end, table_name);
}
else
{
if (!is_versioning_bigint(row_start))
return require_bigint(row_start, table_name);
if (!is_versioning_bigint(row_end))
return require_bigint(row_end, table_name);
}
if (is_versioning_bigint(row_start) && is_versioning_bigint(row_end) &&
!TR_table::use_transaction_registry)
{
my_error(ER_VERS_TRT_IS_DISABLED, MYF(0));
return true;
}
return false;
}
bool Table_period_info::check_field(const Create_field* f,