Commit 1f5ca66e authored by Nikita Malyavin's avatar Nikita Malyavin Committed by Marko Mäkelä

MDEV-26866 FOREIGN KEY…SET NULL corrupts an index on a virtual column

The initial test case for MySQL Bug #33053297 is based on
mysql/mysql-server@27130e25078864b010d81266f9613d389d4a229b.

innobase_get_field_from_update_vector is not a suitable function to fetch
updated row info, as well as parent table's update vector is not always
suitable. For instance, in case of DELETE it contains undefined data.

castade->update vector seems to be good enough to fetch all base columns
update data, and besides faster, and less error-prone.
parent 3a9967d7
......@@ -826,3 +826,203 @@ DROP TABLE email_stats;
DROP TABLE emails_metadata;
DROP TABLE emails;
DROP DATABASE `a-b`;
USE test;
#
# Bug#33053297 VIRTUAL INDEX CORRUPTED DURING CASCADE UPDATE ON CHILD TABLE
#
# Test-Case 1
CREATE TABLE emails (
id int unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
) ENGINE=InnoDB;
CREATE TABLE email_stats (
id bigint unsigned NOT NULL AUTO_INCREMENT,
email_id int unsigned DEFAULT NULL,
date_sent datetime NOT NULL,
generated_sent_date date GENERATED ALWAYS AS
(concat(year(date_sent), '-', lpad(month(date_sent), 2, '0'),
'-', lpad(dayofmonth(date_sent), 2, '0'))),
PRIMARY KEY (id),
KEY IDX_ES1 (email_id),
KEY mautic_generated_sent_date_email_id(generated_sent_date, email_id),
FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE SET NULL
) ENGINE = InnoDB;
INSERT INTO emails VALUES (1);
INSERT INTO email_stats (id, email_id, date_sent)
VALUES (1, 1, '2020-10-22 13:32:41');
SELECT * FROM email_stats;
id email_id date_sent generated_sent_date
1 1 2020-10-22 13:32:41 2020-10-22
DELETE FROM emails;
DELETE FROM email_stats;
# Clean up.
DROP TABLE email_stats;
DROP TABLE emails;
# Test-Case 2
CREATE TABLE emails (
id int unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_unicode_ci
ROW_FORMAT = DYNAMIC;
CREATE TABLE email_stats (
id bigint unsigned NOT NULL AUTO_INCREMENT,
email_id int unsigned DEFAULT NULL,
date_sent datetime NOT NULL,
generated_sent_date date GENERATED ALWAYS AS
(concat(year(date_sent), '-', lpad(month(date_sent), 2, '0'),
'-', lpad(dayofmonth(date_sent), 2, '0'))),
PRIMARY KEY (id),
KEY IDX_ES1 (email_id),
KEY mautic_generated_sent_date_email_id(generated_sent_date, email_id),
FOREIGN KEY (email_id) REFERENCES emails (id)
ON DELETE SET NULL
ON UPDATE SET NULL
) ENGINE = InnoDB;
INSERT INTO emails VALUES (1);
INSERT INTO email_stats (id, email_id, date_sent)
VALUES (1, 1, '2020-10-22 13:32:41');
UPDATE emails SET id = 2 where id = 1;
SELECT id FROM email_stats WHERE generated_sent_date IS NULL;
id
SELECT * FROM email_stats;
id email_id date_sent generated_sent_date
1 NULL 2020-10-22 13:32:41 2020-10-22
UPDATE email_stats
SET email_id=2
WHERE DATE(generated_sent_date) = '2020-10-22';
SELECT * FROM email_stats;
id email_id date_sent generated_sent_date
1 2 2020-10-22 13:32:41 2020-10-22
# Clean up.
DROP TABLE email_stats;
DROP TABLE emails;
# Test-case 3
CREATE TABLE emails (
id int unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
) ENGINE = INNODB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_unicode_ci
ROW_FORMAT = DYNAMIC;
CREATE TABLE email_stats (
id bigint unsigned NOT NULL AUTO_INCREMENT,
email_id int unsigned DEFAULT NULL,
date_sent datetime NOT NULL,
generated_sent_email varchar(20) GENERATED ALWAYS AS
(CONCAT(YEAR(date_sent), '-', COALESCE(email_id, '$'))),
PRIMARY KEY (id),
KEY idx_es1 (email_id),
KEY mautic_generated_sent_date_email(generated_sent_email, email_id),
FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE SET NULL
) ENGINE = INNODB;
INSERT INTO emails VALUES (1);
INSERT INTO email_stats (id, email_id, date_sent)
VALUES (1, 1, '2020-10-22 13:32:41');
SELECT * FROM email_stats;
id email_id date_sent generated_sent_email
1 1 2020-10-22 13:32:41 2020-1
SELECT date_sent FROM email_stats WHERE generated_sent_email = '2020-1';
date_sent
2020-10-22 13:32:41
DELETE FROM emails;
SELECT * FROM email_stats;
id email_id date_sent generated_sent_email
1 NULL 2020-10-22 13:32:41 2020-$
SELECT date_sent FROM email_stats WHERE generated_sent_email = '2020-$';
date_sent
2020-10-22 13:32:41
# Clean up.
DROP TABLE email_stats;
DROP TABLE emails;
# Test-case 4
CREATE TABLE emails (
id int unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
) ENGINE = INNODB;
CREATE TABLE email_stats (
id bigint unsigned NOT NULL AUTO_INCREMENT,
email_id int unsigned DEFAULT NULL,
date_sent datetime NOT NULL,
generated_sent_email varchar(20) GENERATED ALWAYS AS
(CONCAT(YEAR(date_sent), '-', COALESCE(email_id, '$'))),
PRIMARY KEY (id),
KEY idx_es1 (email_id),
KEY mautic_generated_sent_date_email(generated_sent_email, email_id),
FOREIGN KEY (email_id) REFERENCES emails (id) ON UPDATE SET NULL
) ENGINE = INNODB;
INSERT INTO emails VALUES (1);
INSERT INTO email_stats (id, email_id, date_sent)
VALUES (1, 1, '2020-10-22 13:32:41');
SELECT * FROM email_stats;
id email_id date_sent generated_sent_email
1 1 2020-10-22 13:32:41 2020-1
SELECT date_sent FROM email_stats WHERE generated_sent_email = '2020-1';
date_sent
2020-10-22 13:32:41
UPDATE emails SET id = 2 WHERE id = 1;
SELECT * FROM email_stats;
id email_id date_sent generated_sent_email
1 NULL 2020-10-22 13:32:41 2020-$
SELECT date_sent FROM email_stats WHERE generated_sent_email = '2020-$';
date_sent
2020-10-22 13:32:41
DROP TABLE email_stats;
DROP TABLE emails;
CREATE TABLE emails (breaker int unsigned,
KEY (breaker),
id int unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE email_stats (
id bigint unsigned NOT NULL AUTO_INCREMENT,
email_id int unsigned DEFAULT NULL,
date_sent datetime NOT NULL,
generated_sent_email varchar(20) GENERATED ALWAYS AS
(CONCAT(YEAR(date_sent),
'-',
COALESCE(email_id, '$'))),
PRIMARY KEY (id),
KEY idx_es1 (email_id),
KEY mautic_generated_sent_date_email (generated_sent_email, email_id),
FOREIGN KEY fk_ea1 (email_id) REFERENCES emails (breaker)
ON DELETE SET NULL
) ENGINE=INNODB;
show create table email_stats;
Table Create Table
email_stats CREATE TABLE `email_stats` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`email_id` int(10) unsigned DEFAULT NULL,
`date_sent` datetime NOT NULL,
`generated_sent_email` varchar(20) GENERATED ALWAYS AS (concat(year(`date_sent`),'-',coalesce(`email_id`,'$'))) VIRTUAL,
PRIMARY KEY (`id`),
KEY `idx_es1` (`email_id`),
KEY `mautic_generated_sent_date_email` (`generated_sent_email`,`email_id`),
CONSTRAINT `fk_ea1` FOREIGN KEY (`email_id`) REFERENCES `emails` (`breaker`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
INSERT INTO emails VALUES (1,1);
INSERT INTO email_stats(id, email_id, date_sent)
VALUES (1, 1, '2020-10-22 13:32:41');
SELECT * FROM email_stats;
id email_id date_sent generated_sent_email
1 1 2020-10-22 13:32:41 2020-1
SELECT date_sent FROM email_stats WHERE generated_sent_email = '2020-1';
date_sent
2020-10-22 13:32:41
DELETE FROM emails;
SELECT * FROM email_stats;
id email_id date_sent generated_sent_email
1 NULL 2020-10-22 13:32:41 2020-$
SELECT date_sent
FROM email_stats force index (mautic_generated_sent_date_email)
WHERE generated_sent_email = '2020-$';
date_sent
2020-10-22 13:32:41
SELECT date_sent
FROM email_stats force index (idx_es1)
WHERE generated_sent_email = '2020-$';
date_sent
2020-10-22 13:32:41
DROP TABLE email_stats;
DROP TABLE emails;
......@@ -693,3 +693,187 @@ DROP TABLE email_stats;
DROP TABLE emails_metadata;
DROP TABLE emails;
DROP DATABASE `a-b`;
USE test;
--echo #
--echo # Bug#33053297 VIRTUAL INDEX CORRUPTED DURING CASCADE UPDATE ON CHILD TABLE
--echo #
--echo # Test-Case 1
CREATE TABLE emails (
id int unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
) ENGINE=InnoDB;
CREATE TABLE email_stats (
id bigint unsigned NOT NULL AUTO_INCREMENT,
email_id int unsigned DEFAULT NULL,
date_sent datetime NOT NULL,
generated_sent_date date GENERATED ALWAYS AS
(concat(year(date_sent), '-', lpad(month(date_sent), 2, '0'),
'-', lpad(dayofmonth(date_sent), 2, '0'))),
PRIMARY KEY (id),
KEY IDX_ES1 (email_id),
KEY mautic_generated_sent_date_email_id(generated_sent_date, email_id),
FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE SET NULL
) ENGINE = InnoDB;
INSERT INTO emails VALUES (1);
INSERT INTO email_stats (id, email_id, date_sent)
VALUES (1, 1, '2020-10-22 13:32:41');
SELECT * FROM email_stats;
DELETE FROM emails;
DELETE FROM email_stats;
--echo # Clean up.
DROP TABLE email_stats;
DROP TABLE emails;
--echo # Test-Case 2
CREATE TABLE emails (
id int unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_unicode_ci
ROW_FORMAT = DYNAMIC;
CREATE TABLE email_stats (
id bigint unsigned NOT NULL AUTO_INCREMENT,
email_id int unsigned DEFAULT NULL,
date_sent datetime NOT NULL,
generated_sent_date date GENERATED ALWAYS AS
(concat(year(date_sent), '-', lpad(month(date_sent), 2, '0'),
'-', lpad(dayofmonth(date_sent), 2, '0'))),
PRIMARY KEY (id),
KEY IDX_ES1 (email_id),
KEY mautic_generated_sent_date_email_id(generated_sent_date, email_id),
FOREIGN KEY (email_id) REFERENCES emails (id)
ON DELETE SET NULL
ON UPDATE SET NULL
) ENGINE = InnoDB;
INSERT INTO emails VALUES (1);
INSERT INTO email_stats (id, email_id, date_sent)
VALUES (1, 1, '2020-10-22 13:32:41');
UPDATE emails SET id = 2 where id = 1;
SELECT id FROM email_stats WHERE generated_sent_date IS NULL;
SELECT * FROM email_stats;
UPDATE email_stats
SET email_id=2
WHERE DATE(generated_sent_date) = '2020-10-22';
SELECT * FROM email_stats;
--echo # Clean up.
DROP TABLE email_stats;
DROP TABLE emails;
--echo # Test-case 3
CREATE TABLE emails (
id int unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
) ENGINE = INNODB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_unicode_ci
ROW_FORMAT = DYNAMIC;
CREATE TABLE email_stats (
id bigint unsigned NOT NULL AUTO_INCREMENT,
email_id int unsigned DEFAULT NULL,
date_sent datetime NOT NULL,
generated_sent_email varchar(20) GENERATED ALWAYS AS
(CONCAT(YEAR(date_sent), '-', COALESCE(email_id, '$'))),
PRIMARY KEY (id),
KEY idx_es1 (email_id),
KEY mautic_generated_sent_date_email(generated_sent_email, email_id),
FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE SET NULL
) ENGINE = INNODB;
INSERT INTO emails VALUES (1);
INSERT INTO email_stats (id, email_id, date_sent)
VALUES (1, 1, '2020-10-22 13:32:41');
SELECT * FROM email_stats;
SELECT date_sent FROM email_stats WHERE generated_sent_email = '2020-1';
DELETE FROM emails;
SELECT * FROM email_stats;
SELECT date_sent FROM email_stats WHERE generated_sent_email = '2020-$';
--echo # Clean up.
DROP TABLE email_stats;
DROP TABLE emails;
--echo # Test-case 4
CREATE TABLE emails (
id int unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
) ENGINE = INNODB;
CREATE TABLE email_stats (
id bigint unsigned NOT NULL AUTO_INCREMENT,
email_id int unsigned DEFAULT NULL,
date_sent datetime NOT NULL,
generated_sent_email varchar(20) GENERATED ALWAYS AS
(CONCAT(YEAR(date_sent), '-', COALESCE(email_id, '$'))),
PRIMARY KEY (id),
KEY idx_es1 (email_id),
KEY mautic_generated_sent_date_email(generated_sent_email, email_id),
FOREIGN KEY (email_id) REFERENCES emails (id) ON UPDATE SET NULL
) ENGINE = INNODB;
INSERT INTO emails VALUES (1);
INSERT INTO email_stats (id, email_id, date_sent)
VALUES (1, 1, '2020-10-22 13:32:41');
SELECT * FROM email_stats;
SELECT date_sent FROM email_stats WHERE generated_sent_email = '2020-1';
UPDATE emails SET id = 2 WHERE id = 1;
SELECT * FROM email_stats;
SELECT date_sent FROM email_stats WHERE generated_sent_email = '2020-$';
#clean up.
DROP TABLE email_stats;
DROP TABLE emails;
CREATE TABLE emails (breaker int unsigned,
KEY (breaker),
id int unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE email_stats (
id bigint unsigned NOT NULL AUTO_INCREMENT,
email_id int unsigned DEFAULT NULL,
date_sent datetime NOT NULL,
generated_sent_email varchar(20) GENERATED ALWAYS AS
(CONCAT(YEAR(date_sent),
'-',
COALESCE(email_id, '$'))),
PRIMARY KEY (id),
KEY idx_es1 (email_id),
KEY mautic_generated_sent_date_email (generated_sent_email, email_id),
FOREIGN KEY fk_ea1 (email_id) REFERENCES emails (breaker)
ON DELETE SET NULL
) ENGINE=INNODB;
show create table email_stats;
INSERT INTO emails VALUES (1,1);
INSERT INTO email_stats(id, email_id, date_sent)
VALUES (1, 1, '2020-10-22 13:32:41');
SELECT * FROM email_stats;
SELECT date_sent FROM email_stats WHERE generated_sent_email = '2020-1';
DELETE FROM emails;
SELECT * FROM email_stats;
SELECT date_sent
FROM email_stats force index (mautic_generated_sent_date_email)
WHERE generated_sent_email = '2020-$';
SELECT date_sent
FROM email_stats force index (idx_es1)
WHERE generated_sent_email = '2020-$';
DROP TABLE email_stats;
DROP TABLE emails;
......@@ -21795,48 +21795,6 @@ innobase_rename_vc_templ(
table->vc_templ->tb_name = t_tbname;
}
/** Get the updated parent field value from the update vector for the
given col_no.
@param[in] foreign foreign key information
@param[in] update updated parent vector.
@param[in] col_no base column position of the child table to check
@return updated field from the parent update vector, else NULL */
static
dfield_t*
innobase_get_field_from_update_vector(
dict_foreign_t* foreign,
upd_t* update,
ulint col_no)
{
dict_table_t* parent_table = foreign->referenced_table;
dict_index_t* parent_index = foreign->referenced_index;
ulint parent_field_no;
ulint parent_col_no;
ulint prefix_col_no;
for (ulint i = 0; i < foreign->n_fields; i++) {
if (dict_index_get_nth_col_no(foreign->foreign_index, i)
!= col_no) {
continue;
}
parent_col_no = dict_index_get_nth_col_no(parent_index, i);
parent_field_no = dict_table_get_nth_col_pos(
parent_table, parent_col_no, &prefix_col_no);
for (ulint j = 0; j < update->n_fields; j++) {
upd_field_t* parent_ufield
= &update->fields[j];
if (parent_ufield->field_no == parent_field_no) {
return(&parent_ufield->new_val);
}
}
}
return (NULL);
}
/**
Allocate a heap and record for calculating virtual fields
......@@ -21919,9 +21877,10 @@ void innobase_report_computed_value_failed(dtuple_t *row)
@param[in] ifield index field
@param[in] thd MySQL thread handle
@param[in,out] mysql_table mysql table object
@param[in,out] mysql_rec MariaDB record buffer
@param[in] old_table during ALTER TABLE, this is the old table
or NULL.
@param[in] parent_update update vector for the parent row
@param[in] update update vector for the row, if any
@param[in] foreign foreign key information
@return the field filled with computed value, or NULL if just want
to store the value in passed in "my_rec" */
......@@ -21937,8 +21896,7 @@ innobase_get_computed_value(
TABLE* mysql_table,
byte* mysql_rec,
const dict_table_t* old_table,
upd_t* parent_update,
dict_foreign_t* foreign)
const upd_t* update)
{
byte rec_buf2[REC_VERSION_56_MAX_INDEX_COL_LEN];
byte* buf;
......@@ -21951,6 +21909,8 @@ innobase_get_computed_value(
ulint ret = 0;
dict_index_t *clust_index= dict_table_get_first_index(index->table);
ut_ad(index->table->vc_templ);
ut_ad(thd != NULL);
ut_ad(mysql_table);
......@@ -21980,14 +21940,16 @@ innobase_get_computed_value(
= index->table->vc_templ->vtempl[col_no];
const byte* data;
if (parent_update != NULL) {
/** Get the updated field from update vector
of the parent table. */
row_field = innobase_get_field_from_update_vector(
foreign, parent_update, col_no);
if (update) {
ulint clust_no = dict_col_get_clust_pos(base_col,
clust_index);
if (const upd_field_t *uf = upd_get_field_by_field_no(
update, clust_no, false)) {
row_field = &uf->new_val;
}
}
if (row_field == NULL) {
if (!row_field) {
row_field = dtuple_get_nth_field(row, col_no);
}
......
......@@ -881,11 +881,12 @@ void innobase_report_computed_value_failed(dtuple_t *row);
@param[in,out] local_heap heap memory for processing large data etc.
@param[in,out] heap memory heap that copies the actual index row
@param[in] ifield index field
@param[in] thd MySQL thread handle
@param[in,out] mysql_table mysql table object
@param[in] thd connection handle
@param[in,out] mysql_table MariaDB table handle
@param[in,out] mysql_rec MariaDB record buffer
@param[in] old_table during ALTER TABLE, this is the old table
or NULL.
@param[in] parent_update update vector for the parent row
@param[in] update update vector for the parent row
@param[in] foreign foreign key information
@return the field filled with computed value */
dfield_t*
......@@ -900,8 +901,7 @@ innobase_get_computed_value(
TABLE* mysql_table,
byte* mysql_rec,
const dict_table_t* old_table,
upd_t* parent_update,
dict_foreign_t* foreign);
const upd_t* update);
/** Get the computed value by supplying the base column values.
@param[in,out] table the table whose virtual column
......
......@@ -898,7 +898,6 @@ row_ins_invalidate_query_cache(
innobase_invalidate_query_cache(thr_get_trx(thr), name, len);
}
/** Fill virtual column information in cascade node for the child table.
@param[out] cascade child update node
@param[in] rec clustered rec of child table
......@@ -945,6 +944,11 @@ row_ins_foreign_fill_virtual(
if (!record) {
return DB_OUT_OF_MEMORY;
}
ut_ad(!node->is_delete
|| (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL));
ut_ad(foreign->type & (DICT_FOREIGN_ON_DELETE_SET_NULL
| DICT_FOREIGN_ON_UPDATE_SET_NULL
| DICT_FOREIGN_ON_UPDATE_CASCADE));
for (ulint i = 0; i < n_v_fld; i++) {
......@@ -960,7 +964,7 @@ row_ins_foreign_fill_virtual(
dfield_t* vfield = innobase_get_computed_value(
update->old_vrow, col, index,
&vc.heap, update->heap, NULL, thd, mysql_table,
record, NULL, NULL, NULL);
record, NULL, NULL);
if (vfield == NULL) {
return DB_COMPUTE_VALUE_FAILED;
......@@ -976,16 +980,11 @@ row_ins_foreign_fill_virtual(
upd_field_set_v_field_no(upd_field, i, index);
bool set_null =
node->is_delete
? (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL)
: (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL);
dfield_t* new_vfield = innobase_get_computed_value(
update->old_vrow, col, index,
&vc.heap, update->heap, NULL, thd,
mysql_table, record, NULL,
set_null ? update : node->update, foreign);
update);
if (new_vfield == NULL) {
return DB_COMPUTE_VALUE_FAILED;
......
......@@ -600,8 +600,8 @@ row_merge_buf_add(
row_field = innobase_get_computed_value(
row, v_col, clust_index,
v_heap, NULL, ifield, trx->mysql_thd,
my_table, vcol_storage.innobase_record,
old_table, NULL, NULL);
my_table, vcol_storage.innobase_record,
old_table, NULL);
if (row_field == NULL) {
*err = DB_COMPUTE_VALUE_FAILED;
......
......@@ -328,7 +328,7 @@ row_sel_sec_rec_is_for_clust_rec(
&heap, NULL, NULL,
thr_get_trx(thr)->mysql_thd,
thr->prebuilt->m_mysql_table,
record, NULL, NULL, NULL);
record, NULL, NULL);
if (vfield == NULL) {
innobase_report_computed_value_failed(row);
......
......@@ -1149,7 +1149,7 @@ row_upd_build_difference_binary(
dfield_t* vfield = innobase_get_computed_value(
update->old_vrow, col, index,
&vc.heap, heap, NULL, thd, mysql_table, record,
NULL, NULL, NULL);
NULL, NULL);
if (vfield == NULL) {
*error = DB_COMPUTE_VALUE_FAILED;
return(NULL);
......@@ -2175,8 +2175,7 @@ row_upd_store_v_row(
node->row, col, index,
&vc.heap, node->heap,
NULL, thd, mysql_table,
record, NULL, NULL,
NULL);
record, NULL, NULL);
if (vfield == NULL) {
return false;
}
......
......@@ -491,7 +491,7 @@ row_vers_build_clust_v_col(
dfield_t *vfield = innobase_get_computed_value(
row, col, clust_index, &vc.heap,
heap, NULL, thd, maria_table, record, NULL,
NULL, NULL);
NULL);
if (vfield == NULL) {
innobase_report_computed_value_failed(row);
ut_ad(0);
......
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