Ticket #1833 (closed defect: fixed)

Opened 19 months ago

Last modified 14 months ago

Nested set: makeRoot query order is wrong

Reported by: weett Owned by: romanb
Priority: blocker Milestone: 1.0.7
Component: NestedSet Version: 1.0.4
Severity: abc Keywords:
Cc: Has Test: no
Status: Pending Core Response Has Patch: yes

Description

When calling makeRoot the order of things going on is wrong.

First step should be to extract all the nodes from the old tree and move them into the new tree. Then the old tree should be reordered.

Currently the steps are the other way around, which corrupts the tree if a node with subnodes is moved to the root.

I created a patch, see this diff. It only moves code around.

Index: Doctrine/Node/NestedSet.php
===================================================================
--- Doctrine/Node/NestedSet.php	(revision 5358)
+++ Doctrine/Node/NestedSet.php	(working copy)
@@ -803,17 +803,6 @@
         try {
             $conn->beginInternalTransaction();
             
-            // Detach from old tree (close gap in old tree)
-            $first = $oldRgt + 1;
-            $delta = $oldLft - $oldRgt - 1;
-            $this->shiftRLValues($first, $delta, $this->getRootValue());
-            
-            // Set new lft/rgt/root/level values for root node
-            $this->setLeftValue(1);
-            $this->setRightValue($oldRgt - $oldLft + 1);
-            $this->setRootValue($newRootId);
-            $this->record['level'] = 0;
-            
             // Update descendants lft/rgt/root/level values
             $diff = 1 - $oldLft;
             $newRoot = $newRootId;
@@ -830,6 +819,17 @@
             $q = $this->_tree->returnQueryWithRootId($q, $oldRoot);
             $q->execute();
             
+            // Detach from old tree (close gap in old tree)
+            $first = $oldRgt + 1;
+            $delta = $oldLft - $oldRgt - 1;
+            $this->shiftRLValues($first, $delta, $this->getRootValue());
+            
+            // Set new lft/rgt/root/level values for root node
+            $this->setLeftValue(1);
+            $this->setRightValue($oldRgt - $oldLft + 1);
+            $this->setRootValue($newRootId);
+            $this->record['level'] = 0;
+            
             $conn->commit();
             
             return true;

The version I use is the version currently included in the symfony plugin. I also checked the 1.1 branch; the error is still there.

I don't know how to make a test for this. I'll add some pictures of my test, these can be converted into a test quite easily I believe.

Attachments

Firefoxscr014.jpg Download (48.3 KB) - added by weett 19 months ago.
Original state
Firefoxscr016.jpg Download (51.0 KB) - added by weett 19 months ago.
old result
Firefoxscr015.jpg Download (51.0 KB) - added by weett 19 months ago.
correct output

Change History

Changed 19 months ago by weett

Original state

Changed 19 months ago by weett

old result

Changed 19 months ago by weett

correct output

  Changed 19 months ago by weett

info on the files: test-set = original state (14.jpg)

Action is calling makeroot on node id 99, child 2.

Old query produced, which results in incorrect output 16.jpg:

# UPDATE tree SET lft = lft + ? WHERE lft >= ? AND root_id = ? - (-8, 12, 95 )
# UPDATE tree SET rgt = rgt + ? WHERE rgt >= ? AND root_id = ? - (-8, 12, 95 )
# UPDATE tree SET lft = lft + ?, rgt = rgt + ?, level = level - ?, root_id = ? WHERE (lft > ? AND rgt < ?) AND root_id = ? - (-3, -3, 1, 99, 4, 11, 95 )
# UPDATE tree SET lft = ?, rgt = ?, root_id = ?, level = ? WHERE id = ? - (1, 8, 99, 0, 99 )

With patch: (produces correct result 15.jpg)

# UPDATE tree SET lft = lft + ?, rgt = rgt + ?, level = level - ?, root_id = ? WHERE (lft > ? AND rgt < ?) AND root_id = ? - (-3, -3, 1, 99, 4, 11, 95 )
# UPDATE tree SET lft = lft + ? WHERE lft >= ? AND root_id = ? - (-8, 12, 95 )
# UPDATE tree SET rgt = rgt + ? WHERE rgt >= ? AND root_id = ? - (-8, 12, 95 )
# UPDATE tree SET lft = ?, rgt = ?, root_id = ?, level = ? WHERE id = ? - (1, 8, 99, 0, 99 )

follow-up: ↓ 4   Changed 19 months ago by weett

PS. the screenshots are from a prototype admin-generator extension to add support for nested-set tables. Soon I'll post details on my blog: redotheoffice.org

  Changed 19 months ago by eXtreme

[OT] Holy s**t, this nested set manager looks awesome! /OT

in reply to: ↑ 2   Changed 19 months ago by weett

Replying to weett:

PS. the screenshots are from a prototype admin-generator extension to add support for nested-set tables. Soon I'll post details on my blog: redotheoffice.org

Yesterday I wrote this post too quickly; the correct url is redotheoffice.com :  http://redotheoffice.com/?p=74

  Changed 19 months ago by jwage

  • milestone changed from New to 1.0.7

  Changed 18 months ago by guilhermeblanco

  • status changed from new to closed
  • resolution set to fixed

(In [5424]) [1.0, 1.1] Fixes #1833. Fixed makeRoot that was not working correctly.

  Changed 14 months ago by sunrise

  • severity set to abc
This works ok for me.. but It probably needs feedback. Nike Air Yeezy Shoes
Note: See TracTickets for help on using tickets.