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

CTE support for UPDATE and DELETE statements

Details

    Description

           CREATE TABLE tree (
             `Node` VARCHAR(3),
             `ParentNode` VARCHAR(3),
             `EmployeeID` INTEGER,
             `Depth` INTEGER,
             `Lineage` VARCHAR(16)
           );
       
           INSERT INTO tree
             (`Node`, `ParentNode`, `EmployeeID`, `Depth`, `Lineage`)
           VALUES
             ('100', NULL, '1001', 0, '/'),
             ('101', '100', '1002', NULL, NULL),
             ('102', '101', '1003', NULL, NULL),
             ('103', '102', '1004', NULL, NULL),
             ('104', '102', '1005', NULL, NULL),
             ('105', '102', '1006', NULL, NULL);
       
           WITH RECURSIVE prev AS (
           SELECT * FROM tree WHERE ParentNode IS NULL
           UNION
           SELECT t.Node,t.ParentNode,t.EmployeeID,p.Depth + 1 as Depth, CONCAT(p.Lineage, t.ParentNode, '/')
           FROM tree t JOIN prev p ON t.ParentNode = p.Node
           )
           SELECT * FROM prev;
           WITH RECURSIVE prev AS (
           SELECT * FROM tree WHERE ParentNode IS NULL
           UNION
           SELECT t.Node,t.ParentNode,t.EmployeeID,p.Depth + 1 as Depth, CONCAT(p.Lineage, t.ParentNode, '/')
           FROM prev p JOIN tree t ON t.ParentNode = p.Node
           )
           UPDATE tree t, prev p SET t.Depth=p.Depth, t.Lineage=p.Lineage WHERE t.Node=p.Node;
       
      You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'UPDATE tree t, prev p SET t.Depth=p.Depth, t.Lineage=p.Lineage WHERE t.Node=p.No' at line 7

      db<>fiddle here*

      supported in MySQL-8.0 and MSSQL

      Attachments

        Issue Links

          Activity

            ralf.gebhardt Ralf Gebhardt added a comment -

            valerii no, it is not. psergei and igor, can you estimate how much work is still needed to get this task done? I will change the status to stalled for now and will remove the fixVersion until we have a better idea about the task/open effort. It does not make sense to just add 11.2 as fixVersion for now, as this does not seem to be realistic

            ralf.gebhardt Ralf Gebhardt added a comment - valerii no, it is not. psergei and igor , can you estimate how much work is still needed to get this task done? I will change the status to stalled for now and will remove the fixVersion until we have a better idea about the task/open effort. It does not make sense to just add 11.2 as fixVersion for now, as this does not seem to be realistic
            PierreCar PierreCar added a comment -

            For people this bang their head on the wall in 2024 with this long time issue not resolved, like me, I finally found a solution that is not perfect but works, use a temporary table to save CTE result then update the main table. In the example above :

                CREATE TEMPORARY TABLE tmp_table
                 WITH RECURSIVE prev AS (
                 SELECT * FROM tree WHERE ParentNode IS NULL
                 UNION
                 SELECT t.Node,t.ParentNode,t.EmployeeID,p.Depth + 1 as Depth, CONCAT(p.Lineage, t.ParentNode, '/')
                 FROM prev p JOIN tree t ON t.ParentNode = p.Node
                 )
                SELECT * FROM prev;
             
                UPDATE tree t, tmp_table p SET t.Depth=p.Depth, t.Lineage=p.Lineage WHERE t.Node=p.Node;
            

            PierreCar PierreCar added a comment - For people this bang their head on the wall in 2024 with this long time issue not resolved, like me, I finally found a solution that is not perfect but works, use a temporary table to save CTE result then update the main table. In the example above : CREATE TEMPORARY TABLE tmp_table WITH RECURSIVE prev AS ( SELECT * FROM tree WHERE ParentNode IS NULL UNION SELECT t.Node,t.ParentNode,t.EmployeeID,p.Depth + 1 as Depth, CONCAT(p.Lineage, t.ParentNode, '/') FROM prev p JOIN tree t ON t.ParentNode = p.Node ) SELECT * FROM prev;   UPDATE tree t, tmp_table p SET t.Depth=p.Depth, t.Lineage=p.Lineage WHERE t.Node=p.Node;
            psergei Sergei Petrunia added a comment - - edited

            Note: the most common use case is when the UPDATE modifies a base table, not the CTE. This is what the examples in this MDEV do.

            It is also possible to think of UPDATE changing the CTE, which translates into changes to the table used in the CTE. Similar to updatable VIEWs.
            Example (also at https://dbfiddle.uk/Q1p7ImR2)

            create table t1 (pk int primary key, a int);
            insert into t1 values (1,1),(2,2),(3,3),(4,4);
            with T as (select pk, a from t1 where pk <3 ) update T set a=a*1000;
            select * from t1;
            

            pk	a
            1	1000
            2	2000
            3	3
            4	4
            

            SQL Server supports this, PostgreSQL doesn't. I haven't checked what the SQL Standard says about this.
            I think update-through-CTE should be outside of scope of this MDEV.

            psergei Sergei Petrunia added a comment - - edited Note: the most common use case is when the UPDATE modifies a base table, not the CTE. This is what the examples in this MDEV do. It is also possible to think of UPDATE changing the CTE, which translates into changes to the table used in the CTE. Similar to updatable VIEWs. Example (also at https://dbfiddle.uk/Q1p7ImR2 ) create table t1 (pk int primary key , a int ); insert into t1 values (1,1),(2,2),(3,3),(4,4); with T as ( select pk, a from t1 where pk <3 ) update T set a=a*1000; select * from t1; pk a 1 1000 2 2000 3 3 4 4 SQL Server supports this, PostgreSQL doesn't. I haven't checked what the SQL Standard says about this. I think update-through-CTE should be outside of scope of this MDEV.
            igor Igor Babaev (Inactive) added a comment - - edited

            A preliminary patch for this task that implemented UPDATE command with updatable CTEs was pushed into 10.5-mdev-18511 in October 2020. The patch contains a lot of test cases demonstrating how the feature worked for 10.5.
            Actually it was the patch for MDEV-23552. Unfortunately the code cannot be applied directly to the current 10.4+ because the upper level architecture for UPDATE/DELETE has been changed by MDEV-28883. However CTE related code was incorporated into 10.5 when the CTE implementation was redesigned. One of the reason why MDEV-28883 was initiated was the fact that I experienced serious difficulties with implementation of MDEV-23552. Even more difficulties were expected with implementation of a similar task for DELETE commands.
            serg, I've looked at at the support case 201775 and I don't understand what the ticket has to do with MDEV-18511.
            I also don't understand why MDEV-21012 is considered as a sub-task of this task.

            igor Igor Babaev (Inactive) added a comment - - edited A preliminary patch for this task that implemented UPDATE command with updatable CTEs was pushed into 10.5-mdev-18511 in October 2020. The patch contains a lot of test cases demonstrating how the feature worked for 10.5. Actually it was the patch for MDEV-23552 . Unfortunately the code cannot be applied directly to the current 10.4+ because the upper level architecture for UPDATE/DELETE has been changed by MDEV-28883 . However CTE related code was incorporated into 10.5 when the CTE implementation was redesigned. One of the reason why MDEV-28883 was initiated was the fact that I experienced serious difficulties with implementation of MDEV-23552 . Even more difficulties were expected with implementation of a similar task for DELETE commands. serg , I've looked at at the support case 201775 and I don't understand what the ticket has to do with MDEV-18511 . I also don't understand why MDEV-21012 is considered as a sub-task of this task.
            igor Igor Babaev (Inactive) added a comment - - edited

            MYSQL 8.0 does not allow update updatable CTE/derived tables.
            MYSQL 8.0 merges mergeable derived tables used in multi-update/multi-delete. MariaDB always materializes such derived tables.

            igor Igor Babaev (Inactive) added a comment - - edited MYSQL 8.0 does not allow update updatable CTE/derived tables. MYSQL 8.0 merges mergeable derived tables used in multi-update/multi-delete. MariaDB always materializes such derived tables.

            People

              psergei Sergei Petrunia
              danblack Daniel Black
              Votes:
              11 Vote for this issue
              Watchers:
              23 Start watching this issue

              Dates

                Created:
                Updated:

                Git Integration

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