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 23:53:06 UTC

svn commit: r1451413 - in /subversion/trunk/subversion/libsvn_wc: wc-queries.sql wc_db.c

Author: rhuijben
Date: Thu Feb 28 22:53:06 2013
New Revision: 1451413

URL: http://svn.apache.org/r1451413
Log:
Use a single query to determine which records need their moved_to updated
during delete. This should handle many issues currently not covered by tests
where moves are not stored in the highest op-depth.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_SELECT_MOVED_PAIR): Delete query.
  (STMT_SELECT_MOVED_FOR_DELETE): New query.

* subversion/libsvn_wc/wc_db.c
  (delete_node): Don't perform unnecessary double allocation. Remove specific
    query for special directory case. Process all moved descendants in one
    place instead.

Modified:
    subversion/trunk/subversion/libsvn_wc/wc-queries.sql
    subversion/trunk/subversion/libsvn_wc/wc_db.c

Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1451413&r1=1451412&r2=1451413&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Thu Feb 28 22:53:06 2013
@@ -1490,14 +1490,14 @@ SELECT moved_to, local_relpath FROM node
 WHERE wc_id = ?1 AND op_depth > 0
   AND IS_STRICT_DESCENDANT_OF(moved_to, ?2)
 
-/* This statement returns pairs of paths that define a move where the
-   destination of the move is within the subtree rooted at path ?2 or
-   the source of the move is within the subtree rooted at path ?2 */
--- STMT_SELECT_MOVED_PAIR
-SELECT local_relpath, moved_to, op_depth FROM nodes_current
+-- STMT_SELECT_MOVED_FOR_DELETE
+SELECT local_relpath, moved_to, op_depth FROM nodes
 WHERE wc_id = ?1
-  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
+  AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND moved_to IS NOT NULL
+  AND op_depth >= (SELECT MAX(op_depth) FROM nodes o
+                    WHERE o.wc_id = ?1
+                      AND o.local_relpath = ?2)
 
 -- STMT_UPDATE_MOVED_TO_DESCENDANTS
 UPDATE nodes SET moved_to = RELPATH_SKIP_JOIN(?2, ?3, moved_to)

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1451413&r1=1451412&r2=1451413&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Thu Feb 28 22:53:06 2013
@@ -7517,11 +7517,10 @@ delete_node(void *baton,
                               wcroot, local_relpath,
                               scratch_pool, scratch_pool));
 
-      moved_node = apr_palloc(scratch_pool, sizeof(struct moved_node_t));
-
       if (op_root && moved_from_relpath)
         {
           /* Existing move-root is moved to another location */
+          moved_node = apr_palloc(scratch_pool, sizeof(struct moved_node_t));
           moved_node->local_relpath = moved_from_relpath;
           moved_node->op_depth = move_op_depth;
           moved_node->moved_to_relpath = b->moved_to_relpath;
@@ -7544,65 +7543,7 @@ delete_node(void *baton,
       /* Else: We can't track history of local additions and/or of things we are
                about to delete. */
 
-      /* 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,
-                                            STMT_SELECT_MOVED_PAIR));
-          SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
-          SVN_ERR(svn_sqlite__step(&have_row, stmt));
-
-          while (have_row)
-            {
-              /* Source of move */
-              const char *move_relpath
-                = svn_sqlite__column_text(stmt, 0, NULL);
-              const char *move_subtree_relpath
-                = svn_relpath_skip_ancestor(local_relpath, move_relpath);
-              /* Destination of move */
-              const char *child_moved_to
-                = svn_sqlite__column_text(stmt, 1, NULL);
-              const char *child_moved_to_subtree_relpath
-                = svn_relpath_skip_ancestor(local_relpath, child_moved_to);
-              int child_op_depth = svn_sqlite__column_int(stmt, 2);
-
-              moved_node = apr_palloc(scratch_pool,
-                                      sizeof(struct moved_node_t));
-              if (move_subtree_relpath)
-                moved_node->local_relpath
-                  = svn_relpath_join(b->moved_to_relpath,
-                                     move_subtree_relpath, scratch_pool);
-              else
-                moved_node->local_relpath
-                  = apr_pstrdup(scratch_pool, move_relpath);
-
-              if (child_moved_to_subtree_relpath)
-                moved_node->moved_to_relpath
-                  = svn_relpath_join(b->moved_to_relpath,
-                                     child_moved_to_subtree_relpath,
-                                     scratch_pool);
-              else
-                moved_node->moved_to_relpath
-                  = apr_pstrdup(scratch_pool, child_moved_to);
-
-              if (child_op_depth > delete_depth
-                  && svn_relpath_skip_ancestor(local_relpath,
-                                               moved_node->local_relpath))
-                moved_node->op_depth = delete_depth;
-              else
-                moved_node->op_depth = relpath_depth(moved_node->local_relpath);
-
-              APR_ARRAY_PUSH(moved_nodes, const struct moved_node_t *)
-                = moved_node;
-
-              SVN_ERR(svn_sqlite__step(&have_row, stmt));
-            }
-          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_DESCENDANTS));
       SVN_ERR(svn_sqlite__bindf(stmt, "iss", wcroot->wc_id,
@@ -7626,27 +7567,54 @@ delete_node(void *baton,
       apr_pool_t *iterpool;
 
       SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb,
-                                        STMT_SELECT_MOVED_PAIR2));
+                                        STMT_SELECT_MOVED_FOR_DELETE));
       SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, local_relpath));
 
       SVN_ERR(svn_sqlite__step(&have_row, stmt));
-
       iterpool = svn_pool_create(scratch_pool);
       while (have_row)
         {
           struct moved_node_t *mn;
           const char *child_relpath = svn_sqlite__column_text(stmt, 0, NULL);
+          const char *mv_to_relpath = svn_sqlite__column_text(stmt, 1, NULL);
+          int child_op_depth = svn_sqlite__column_int(stmt, 2);
           svn_boolean_t fixup = FALSE;
 
-          if (!b->moved_to_relpath)
+          if (!b->moved_to_relpath
+              && ! svn_relpath_skip_ancestor(local_relpath, mv_to_relpath))
             {
+              /* Update the op-depth of an moved node below this tree */
               fixup = TRUE;
+              child_op_depth = delete_depth;
             }
-          else
+          else if (b->moved_to_relpath
+                   && delete_depth == child_op_depth)
             {
-              int child_op_depth = svn_sqlite__column_int(stmt, 2);
+              /* Update the op-depth of a tree shadowed by this tree */
+              fixup = TRUE;
+              child_op_depth = delete_depth;
+            }
+          else if (b->moved_to_relpath
+                   && child_op_depth >= delete_depth
+                   && !svn_relpath_skip_ancestor(local_relpath, mv_to_relpath))
+            {
+              /* Update the move destination of something that is now moved
+                 away further */
 
-              fixup = (delete_depth == child_op_depth);
+              child_relpath = svn_relpath_skip_ancestor(local_relpath, child_relpath);
+
+              if (child_relpath)
+                {
+                  child_relpath = svn_relpath_join(b->moved_to_relpath, child_relpath, scratch_pool);
+
+                  if (child_op_depth > delete_depth
+                      && svn_relpath_skip_ancestor(local_relpath, child_relpath))
+                    child_op_depth = delete_depth;
+                  else
+                    child_op_depth = relpath_depth(child_relpath);
+
+                  fixup = TRUE;
+                }
             }
 
           if (fixup)
@@ -7654,9 +7622,8 @@ delete_node(void *baton,
               mn = apr_pcalloc(scratch_pool, sizeof(struct moved_node_t));
 
               mn->local_relpath = apr_pstrdup(scratch_pool, child_relpath);
-              mn->moved_to_relpath = svn_sqlite__column_text(stmt, 1,
-                                                             scratch_pool);
-              mn->op_depth = delete_depth;
+              mn->moved_to_relpath = apr_pstrdup(scratch_pool, mv_to_relpath);
+              mn->op_depth = child_op_depth;
 
               if (!moved_nodes)
                 moved_nodes = apr_array_make(scratch_pool, 1,