← Back to team overview

maria-developers team mailing list archive

Re: 7c782988845: MDEV-16240: Assertion `0' failed in row_sel_convert_mysql_key_to_innobase

 

Hi, Oleksandr!

On Dec 13, Oleksandr Byelkin wrote:
> revision-id: 7c782988845dec9f0f26a539911f66ed8cecdf83 (mariadb-10.2.19-51-g7c782988845)
> parent(s): ad3346dddf419aed3e5d16066471fd5022af1795
> author: Oleksandr Byelkin
> committer: Oleksandr Byelkin
> timestamp: 2018-12-13 15:29:52 +0100
> message:
> 
> MDEV-16240: Assertion `0' failed in row_sel_convert_mysql_key_to_innobase
> 
> Set table in row ID position mode before using this function.
> 
> ---
>  mysql-test/r/multi_update_innodb.result | 40 +++++++++++++++++++++++++++
>  mysql-test/t/multi_update_innodb.test   | 49 +++++++++++++++++++++++++++++++++
>  sql/sql_update.cc                       |  4 +++
>  3 files changed, 93 insertions(+)
> 
> diff --git a/mysql-test/r/multi_update_innodb.result b/mysql-test/r/multi_update_innodb.result
> index 5890fd24f5f..535c5a41d9f 100644
> --- a/mysql-test/r/multi_update_innodb.result
> +++ b/mysql-test/r/multi_update_innodb.result
> @@ -151,3 +151,43 @@ create table t2 like t1;
>  insert into t2 select * from t1;
>  delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b;
>  drop table t1,t2;
> +#
> +# MDEV-16240: Assertion `0' failed in
> +# row_sel_convert_mysql_key_to_innobase
> +#
> +SET @save_sql_mode=@@sql_mode;
> +set sql_mode='';

why sql_mode matters here?

> +CREATE TABLE `t3` (
> +`col_varchar_nokey` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE current_timestamp(),
> +`col_varchar_key` datetime DEFAULT '2000-01-01 00:00:00' ON UPDATE current_timestamp(),
> +`col_int_nokey` TIMESTAMP NULL DEFAULT '2000-01-01 00:00:00',
> +`pk` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
> +`col_int_key` datetime DEFAULT current_timestamp(),
> +PRIMARY KEY (`pk`),
> +UNIQUE KEY `col_varchar_key` (`col_varchar_key`),
> +KEY `col_int_key` (`col_int_key`)
> +) ENGINE=InnoDB;
> +INSERT INTO `t3` VALUES ('2018-05-18 15:08:07','2018-05-18 17:08:07','0000-00-00 00:00:00','0000-00-00 00:00:00','0000-00-00 00:00:00'),('0000-00-00 00:00:00','0000-00-00 00:00:00','1999-12-31 23:00:00','2002-07-03 23:04:40','0000-00-00 00:00:00');
> +CREATE VIEW `v1` AS
> +SELECT `t3`.`pk` AS `pk`,
> +`t3`.`col_int_nokey` AS `col_int_nokey`,
> +`t3`.`col_int_key` AS `col_int_key`,
> +`t3`.`col_varchar_key` AS `col_varchar_key`,
> +`t3`.`col_varchar_nokey` AS `col_varchar_nokey`
> +FROM `t3`;
> +CREATE TABLE `t4` (
> +`col_varchar_nokey` datetime DEFAULT current_timestamp() ON UPDATE current_timestamp(),
> +`col_int_nokey` timestamp NULL DEFAULT NULL,
> +`col_varchar_key` timestamp NULL DEFAULT '1999-12-31 23:00:00' ON UPDATE current_timestamp(),
> +`pk` int(11) NOT NULL,
> +`col_int_key` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
> +PRIMARY KEY (`pk`)
> +) ENGINE=InnoDB;
> +INSERT INTO `t4` VALUES ('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,1,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,2,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,3,'2018-05-18 15:08:06'),('0000-00-00 00:00:00','0000-00-00 00:00:00',NULL,1976,'0000-00-00 00:00:00'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,2000,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,2001,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,2002,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,2003,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00',NULL,2004,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00','2018-05-18 15:08:06',2005,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00','2018-05-18 15:08:06',2018,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00','2018-05-18 15:08:06',2019,'2018-05-1
>  8 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00','2018-05-18 15:08:06',2024,'2018-05-18 15:08:06'),('2018-05-18 17:08:06','0000-00-00 00:00:00','1999-12-31 23:00:00',2025,'2018-05-18 15:08:06'),('0000-00-00 00:00:00',NULL,'2018-05-18 15:08:06',2026,'2018-05-18 15:08:06'),('2018-05-18 17:08:07','0000-00-00 00:00:00','0000-00-00 00:00:00',2027,'0000-00-00 00:00:00');
> +UPDATE `v1` t1, `t4` t2
> +SET t1.`col_varchar_key` = 6452736 WHERE t1.`col_int_key` = 6272000;
> +ERROR 23000: Duplicate entry '0000-00-00 00:00:00' for key 'col_varchar_key'

please, rename all columns in the test to have unique names. What
col_varchar_key is meant in the error message?

> +DROP VIEW v1;
> +DROP TABLE t3,t4;
> +SET @@sql_mode=@save_sql_mode;
> +# End of 10.2 tests
> diff --git a/sql/sql_update.cc b/sql/sql_update.cc
> index 11ffa684216..6d4c11d494a 100644
> --- a/sql/sql_update.cc
> +++ b/sql/sql_update.cc
> @@ -211,6 +211,10 @@ static void prepare_record_for_error_message(int error, TABLE *table)
>    bitmap_union(table->read_set, &unique_map);
>    /* Tell the engine about the new set. */
>    table->file->column_bitmaps_signal();
> +  /* Prepare table for random positioning (importent for innodb) */

This definitely needs a more detailed comment. I suspect (remembering
your questions on slack) that rnd_pos() in InnoDB ends up using
whatever active_index was at the moment, not the primary key. I'm not
sure, though.

And you have a typo in the word "important".

By the way, why using rnd_pos() after index_init() didn't trigger an
assert?.. Okay, I see why :) please fix it too.

Hmm, with the assert you won't need a detailed comment in sql_update.cc
anymore, assert will be a sufficient explanation.

> +  if (table->file->ha_index_or_rnd_end() ||
> +      table->file->ha_rnd_init(0))
> +    DBUG_VOID_RETURN;
>    /* Read record that is identified by table->file->ref. */
>    (void) table->file->ha_rnd_pos(table->record[1], table->file->ref);
>    /* Copy the newly read columns into the new record. */

Regards,
Sergei
Chief Architect MariaDB
and security@xxxxxxxxxxx


Follow ups