You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2013/02/28 19:32:18 UTC

svn commit: r1451282 - in /subversion/trunk/subversion: libsvn_wc/copy.c libsvn_wc/wc-queries.sql libsvn_wc/wc_db.c tests/libsvn_wc/op-depth-test.c

Author: rhuijben
Date: Thu Feb 28 18:32:17 2013
New Revision: 1451282

URL: http://svn.apache.org/r1451282
Log:
Split a query used for updating moves after a delete in two separate
queries that are easier to understand to us and to the query optimizer.

This resolves a segfault when using the delete wc_db operation with
a path moved back to its original location.

* subversion/libsvn_wc/copy.c
  (copy_or_move): Stop reporting moved back nodes as degraded to delete.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_SELECT_MOVED_PAIR): Remove selection of moves into the target
    tree.
  (STMT_UPDATE_MOVED_TO): New query, updating all moved-to's in a tree.

* subversion/libsvn_wc/wc_db.c
  (delete_node): Split usage of STMT_SELECT_MOVED_PAIR and replace some
    usage with STMT_UPDATE_MOVED_TO.

* subversion/tests/libsvn_wc/op-depth-test.c
  (test_funcs): Remove XFail from move_back test.

Modified:
    subversion/trunk/subversion/libsvn_wc/copy.c
    subversion/trunk/subversion/libsvn_wc/wc-queries.sql
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c

Modified: subversion/trunk/subversion/libsvn_wc/copy.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/copy.c?rev=1451282&r1=1451281&r2=1451282&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/copy.c (original)
+++ subversion/trunk/subversion/libsvn_wc/copy.c Thu Feb 28 18:32:17 2013
@@ -813,7 +813,7 @@ copy_or_move(svn_boolean_t *move_degrade
 
   if (is_move)
     err = svn_error_compose_create(err,
-                svn_wc__db_op_handle_move_back(move_degraded_to_copy,
+                svn_wc__db_op_handle_move_back(NULL,
                                                db, dst_abspath, src_abspath,
                                                NULL /* work_items */,
                                                scratch_pool));

Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1451282&r1=1451281&r2=1451282&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Thu Feb 28 18:32:17 2013
@@ -1496,9 +1496,13 @@ WHERE wc_id = ?1 AND op_depth > 0
 -- STMT_SELECT_MOVED_PAIR
 SELECT local_relpath, moved_to, op_depth FROM nodes_current
 WHERE wc_id = ?1
-  AND (IS_STRICT_DESCENDANT_OF(moved_to, ?2)
-       OR (IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
-           AND moved_to IS NOT NULL))
+  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
+  AND moved_to IS NOT NULL
+
+-- STMT_UPDATE_MOVED_TO
+UPDATE nodes SET moved_to = RELPATH_SKIP_JOIN(?2, ?3, moved_to)
+ WHERE wc_id = ?1
+   AND IS_STRICT_DESCENDANT_OF(moved_to, ?2)
 
 /* This statement returns pairs of move-roots below the path ?2 in WC_ID ?1,
  * where the source of the move is within the subtree rooted at path ?2, and

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1451282&r1=1451281&r2=1451282&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Thu Feb 28 18:32:17 2013
@@ -7497,39 +7497,50 @@ delete_node(void *baton,
 
   if (b->moved_to_relpath)
     {
-      const char *moved_from_op_root_relpath;
-      struct moved_node_t *moved_node
-        = apr_palloc(scratch_pool, sizeof(struct moved_node_t));
+      const char *moved_from_relpath = NULL;
+      const char *moved_from_op_root_relpath = NULL;
+      struct moved_node_t *moved_node;
+      int move_op_depth;
+
+      moved_nodes = apr_array_make(scratch_pool, 1,
+                                   sizeof(struct moved_node_t *));
 
       /* The node is being moved-away.
        * Figure out if the node was moved-here before, or whether this
        * is the first time the node is moved. */
       if (status == svn_wc__db_status_added)
         SVN_ERR(scan_addition(&status, NULL, NULL, NULL, NULL, NULL, NULL,
-                              &moved_node->local_relpath,
+                              &moved_from_relpath,
                               &moved_from_op_root_relpath,
-                              &moved_node->op_depth,
+                              &move_op_depth,
                               wcroot, local_relpath,
                               scratch_pool, scratch_pool));
 
-      if (status != svn_wc__db_status_moved_here ||
-          strcmp(moved_from_op_root_relpath, moved_node->local_relpath) != 0)
+      moved_node = apr_palloc(scratch_pool, sizeof(struct moved_node_t));
+      if (!moved_from_relpath
+          || status != svn_wc__db_status_moved_here
+          || strcmp(moved_from_op_root_relpath, moved_from_relpath))
         {
           /* The node is becoming a move-root for the first time,
            * possibly because of a nested move operation. */
+          moved_node = apr_palloc(scratch_pool, sizeof(struct moved_node_t));
           moved_node->local_relpath = local_relpath;
           moved_node->op_depth = delete_depth;
+          moved_node->moved_to_relpath = b->moved_to_relpath;
+
+          APR_ARRAY_PUSH(moved_nodes, const struct moved_node_t *) = moved_node;
         }
-      moved_node->moved_to_relpath = b->moved_to_relpath;
+      else
+        {
+          moved_node->local_relpath = moved_from_relpath;
+          moved_node->op_depth = move_op_depth;
+          moved_node->moved_to_relpath = b->moved_to_relpath;
 
-      /* ### Use array of struct rather than pointers? */
-      moved_nodes = apr_array_make(scratch_pool, 1,
-                                   sizeof(struct moved_node_t *));
-      APR_ARRAY_PUSH(moved_nodes, const struct moved_node_t *) = moved_node;
+          APR_ARRAY_PUSH(moved_nodes, const struct moved_node_t *) = moved_node;
+        }
 
-      /* If a subtree is being moved-away, we need to update moved-to
-       * information for all children that were moved into, within or
-       * from this subtree. */
+      /* If a subtree is being moved-away from this subtree,
+       * update moved-to information after the delete */
       if (kind == svn_kind_dir)
         {
           SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
@@ -7584,6 +7595,15 @@ delete_node(void *baton,
             }
           SVN_ERR(svn_sqlite__reset(stmt));
         }
+
+      /* And update all moved_to values still pointing to this location */
+
+      SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
+                                        STMT_UPDATE_MOVED_TO));
+      SVN_ERR(svn_sqlite__bindf(stmt, "iss", wcroot->wc_id,
+                                             local_relpath,
+                                             b->moved_to_relpath));
+      SVN_ERR(svn_sqlite__update(NULL, stmt));
     }
 
   /* Find children that were moved out of the subtree rooted at this node.

Modified: subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c?rev=1451282&r1=1451281&r2=1451282&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/op-depth-test.c Thu Feb 28 18:32:17 2013
@@ -7522,7 +7522,7 @@ struct svn_test_descriptor_t test_funcs[
                        "moved_to op_depth"),
     SVN_TEST_OPTS_PASS(new_basemove,
                        "new_basemove"),
-    SVN_TEST_OPTS_XFAIL(move_back,
+    SVN_TEST_OPTS_PASS(move_back,
                        "move_back (issue 4302)"),
     SVN_TEST_NULL
   };