Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-32030

Error in restoring SQL dump with virtual columns after upgrade to version 10.6.15

Details

    • Bug
    • Status: Closed (View Workflow)
    • Major
    • Resolution: Not a Bug
    • 10.6.15
    • N/A
    • Virtual Columns
    • None
    • Ubuntu 22.04

    Description

      After upgrading to MariaDB 10.6.15 from 10.6.10, I tried restoring an SQL dump which worked on the previous version, but now fails with errors like:

      ERROR 1901 (HY000) at line 512844: Function or expression 'id_dipendente' cannot be used in the GENERATED ALWAYS AS clause of `tipo_persona`
      

      Here is the table which generated the error:

      CREATE TABLE `lin_98_68_persone` (
        `id_persona` int(10) unsigned NOT NULL AUTO_INCREMENT,
        `id_azienda` int(10) unsigned NOT NULL DEFAULT 1,
        `id_sede` int(10) unsigned NOT NULL DEFAULT 1,
        `revisione_documento` int(10) unsigned NOT NULL DEFAULT 0,
        `cognome_nome` varchar(255) DEFAULT NULL,
        `mansione_ruolo` text DEFAULT NULL,
        `ragione_sociale` varchar(255) DEFAULT NULL,
        `tipo_persona` enum('D','F','E') GENERATED ALWAYS AS (if(`id_dipendente` is not null,'D',if(`id_dipendente_fornitore` is not null,'F','E'))) STORED,
        `flag_consenso` tinyint(3) unsigned DEFAULT 2,
        `data_consenso` date DEFAULT NULL,
        `documento_tipo` enum('N','PAT','PAS','CI') DEFAULT 'N',
        `documento_codice` varchar(255) DEFAULT NULL,
        `documento_emissione` varchar(255) DEFAULT NULL,
        `documento_emissione_data` date DEFAULT NULL,
        `documento_scadenza_data` date DEFAULT NULL,
        `id_allegato` int(10) unsigned DEFAULT NULL,
        `id_dipendente` int(10) unsigned DEFAULT NULL,
        `id_dipendente_fornitore` int(10) unsigned DEFAULT NULL,
        `id_impresa` int(10) unsigned DEFAULT NULL,
        `flag_attivo` tinyint(1) DEFAULT NULL,
        PRIMARY KEY (`id_persona`,`id_azienda`,`id_sede`,`revisione_documento`),
        UNIQUE KEY `unique_id_dipendente_lin_98_68_persone` (`id_dipendente`,`id_azienda`,`id_sede`,`revisione_documento`),
        UNIQUE KEY `unique_id_dipendente_fornitore_lin_98_68_persone` (`id_dipendente_fornitore`,`id_azienda`,`id_sede`,`revisione_documento`),
        KEY `fk_main_lin_98_68_persone` (`id_azienda`,`id_sede`,`revisione_documento`),
        KEY `fk_id_dipendente_lin_98_68_persone` (`cognome_nome`,`id_azienda`,`id_sede`,`revisione_documento`,`id_dipendente`),
        KEY `fk_id_dipendente_fornitore_lin_98_68_persone` (`cognome_nome`,`id_azienda`,`id_sede`,`revisione_documento`,`id_dipendente_fornitore`,`id_impresa`),
        KEY `fk_id_impresa_lin_98_68_persone` (`id_impresa`,`id_azienda`,`id_sede`,`revisione_documento`,`ragione_sociale`),
        KEY `fk_id_allegato_lin_98_68_persone` (`id_allegato`)
      ) ENGINE=InnoDB AUTO_INCREMENT=75 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;
      

      if I change "STORED" to "VIRTUAL", I can then restore the SQL dump; however, I do not understand why a minor upgrade causes this problem.

      Attachments

        Issue Links

          Activity

            Finally (and sorry for the many comments), I just downgraded to

            mysql Ver 15.1 Distrib 10.6.13-MariaDB, for debian-linux-gnu (x86_64) using EditLine wrapper

            and now the dump loads correctly with the exact same settings.

            mtassinari Matteo Tassinari added a comment - Finally (and sorry for the many comments), I just downgraded to mysql Ver 15.1 Distrib 10.6.13-MariaDB, for debian-linux-gnu (x86_64) using EditLine wrapper and now the dump loads correctly with the exact same settings.
            elenst Elena Stepanova added a comment - - edited

            Thank you, the dump was very helpful.
            The reason of the error is a conflict between foreign keys with CASCADE action defined on the table in question, and the definition of a virtual column. We couldn't reproduce it with the table from the original description, because the table definition there is abridged, in doesn't have foreign keys (in the dump it does).

            The change was made in the scope of MDEV-18114 in 10.6.15 (and corresponding other releases in 10.5+). An example of a problematic structure is t2 here:

            --source include/have_innodb.inc
             
            CREATE TABLE t1 (a INT, KEY(a)) ENGINE=InnoDB;
            CREATE TABLE t2 (b INT, c INT AS(b) STORED, FOREIGN KEY (b) REFERENCES t1(a) ON UPDATE CASCADE) ENGINE=InnoDB;
             
            # Cleanup
            DROP TABLE t2, t1;
            

            Before the change, the structures were allowed in MariaDB, but as MDEV-18114 describes, didn't work correctly.
            Apparently the fix made them forbidden (as they were already, for example, in MySQL), but since I can't see clearly from the commit comment that it was intentional, I'll leave it to serg to confirm.

            elenst Elena Stepanova added a comment - - edited Thank you, the dump was very helpful. The reason of the error is a conflict between foreign keys with CASCADE action defined on the table in question, and the definition of a virtual column. We couldn't reproduce it with the table from the original description, because the table definition there is abridged, in doesn't have foreign keys (in the dump it does). The change was made in the scope of MDEV-18114 in 10.6.15 (and corresponding other releases in 10.5+). An example of a problematic structure is t2 here: --source include/have_innodb.inc   CREATE TABLE t1 (a INT , KEY (a)) ENGINE=InnoDB; CREATE TABLE t2 (b INT , c INT AS (b) STORED, FOREIGN KEY (b) REFERENCES t1(a) ON UPDATE CASCADE ) ENGINE=InnoDB;   # Cleanup DROP TABLE t2, t1; Before the change, the structures were allowed in MariaDB, but as MDEV-18114 describes, didn't work correctly. Apparently the fix made them forbidden (as they were already, for example, in MySQL), but since I can't see clearly from the commit comment that it was intentional, I'll leave it to serg to confirm.

            So, the end result is, if I understand correctly, that you cannot have a STORED computed column based on a field part of a foreign key defined with ON UPDATE CASCADE, right?

            I guess that, if this is intended, we'd need to re-define all those virtual columns....

            mtassinari Matteo Tassinari added a comment - So, the end result is, if I understand correctly, that you cannot have a STORED computed column based on a field part of a foreign key defined with ON UPDATE CASCADE, right? I guess that, if this is intended, we'd need to re-define all those virtual columns....

            Sorry I pasted a wrong sample before, fixed now.

            I do suppose that it was intentional, because the assumption is, if a user defines the virtual column and the foreign key this way, they expect them to work properly; so, if it's not possible, then the definition shouldn't be allowed. It is very unfortunate that it breaks the backward compatibility, we of course try to avoid it, but it's still better than to allow it produce erroneous results silently.

            elenst Elena Stepanova added a comment - Sorry I pasted a wrong sample before, fixed now. I do suppose that it was intentional, because the assumption is, if a user defines the virtual column and the foreign key this way, they expect them to work properly; so, if it's not possible, then the definition shouldn't be allowed. It is very unfortunate that it breaks the backward compatibility, we of course try to avoid it, but it's still better than to allow it produce erroneous results silently.

            If it's due to foreign keys then yes, indeed, it is intentional. The way MariaDB works, and always did, foreign key cascading actions are applied to child tables on a very low level where the server cannot update STORED generated column values anymore. In other words, if a STORED generated column depends on a column that can be modified via a cascade action, this STORED column can become out of sync with other columns. Basically, it'll have an incorrect value. That's why such a table structure is no longer allowed.

            We're planning to lift this restriction. MDEV-31942 (or MDEV-22361) when implemented, will allow us to recalculate STORED generated columns on UPDATE CASCADE and SET NULL actions.

            Note that ON DELETE CASCADE is fine, it's allowed, because it doesn't modify individual columns, but deletes the complete row.

            serg Sergei Golubchik added a comment - If it's due to foreign keys then yes, indeed, it is intentional. The way MariaDB works, and always did, foreign key cascading actions are applied to child tables on a very low level where the server cannot update STORED generated column values anymore. In other words, if a STORED generated column depends on a column that can be modified via a cascade action, this STORED column can become out of sync with other columns. Basically, it'll have an incorrect value. That's why such a table structure is no longer allowed. We're planning to lift this restriction. MDEV-31942 (or MDEV-22361 ) when implemented, will allow us to recalculate STORED generated columns on UPDATE CASCADE and SET NULL actions. Note that ON DELETE CASCADE is fine, it's allowed, because it doesn't modify individual columns, but deletes the complete row.

            People

              serg Sergei Golubchik
              mtassinari Matteo Tassinari
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.