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 2012/05/20 14:28:16 UTC

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

Author: rhuijben
Date: Sun May 20 12:28:16 2012
New Revision: 1340694

URL: http://svn.apache.org/viewvc?rev=1340694&view=rev
Log:
Avoid a table scan in the primary 'svn copy' database query by using a subquery
instead of a join.

This allows the sqlite optimizer to see that only one record is selected for
inserting.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_INSERT_WORKING_NODE_COPY_FROM_BASE,
   STMT_INSERT_WORKING_NODE_COPY_FROM_WORKING): As these queries were identical
     except for the op depth selection, they could be integrated and
     renamed to...
  (STMT_INSERT_WORKING_NODE_COPY_FROM): ... this. Remove src prefix as that is
     no longer necessary with a subquery.
  (STMT_INSERT_WORKING_NODE_COPY_FROM_DEPTH): Add the moved_to handling to this
     query, to make it match STMT_INSERT_WORKING_NODE_COPY_FROM behavior.

* subversion/libsvn_wc/wc_db.c
  (get_info_for_copy): Remove now unused have_work argument.
  (db_op_copy): Update caller. Remove common query.
  (db_op_copy_shadowed_layer): Simplify code, assuming that the copy from depth
    code now handles both cases.

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=1340694&r1=1340693&r2=1340694&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Sun May 20 12:28:16 2012
@@ -906,48 +906,40 @@ WHERE wc_id = ?1
   AND op_depth = 0
   AND presence = 'absent'
 
--- STMT_INSERT_WORKING_NODE_COPY_FROM_BASE
+/* Creates a copy from one top level NODE to a different location */
+-- STMT_INSERT_WORKING_NODE_COPY_FROM
 INSERT OR REPLACE INTO nodes (
     wc_id, local_relpath, op_depth, parent_relpath, repos_id,
     repos_path, revision, presence, depth, moved_here, kind, changed_revision,
     changed_date, changed_author, checksum, properties, translated_size,
     last_mod_time, symlink_target, moved_to )
-SELECT src.wc_id, ?3 /*local_relpath*/, ?4 /*op_depth*/, ?5 /*parent_relpath*/,
-    src.repos_id, src.repos_path, src.revision, ?6 /*presence*/, src.depth,
-    ?7/*moved_here*/, src.kind, src.changed_revision, src.changed_date,
-    src.changed_author, src.checksum, src.properties, src.translated_size,
-    src.last_mod_time, src.symlink_target, dst.moved_to
-FROM nodes AS src
-LEFT OUTER JOIN nodes_current dst ON dst.wc_id = src.wc_id
-  AND dst.local_relpath = ?3 AND dst.op_depth = ?4
-WHERE src.wc_id = ?1 AND src.local_relpath = ?2 AND src.op_depth = 0
+SELECT wc_id, ?3 /*local_relpath*/, ?4 /*op_depth*/, ?5 /*parent_relpath*/,
+    repos_id, repos_path, revision, ?6 /*presence*/, depth,
+    ?7/*moved_here*/, kind, changed_revision, changed_date,
+    changed_author, checksum, properties, translated_size,
+    last_mod_time, symlink_target,
+    (SELECT dst.moved_to FROM nodes_current AS dst
+                         WHERE dst.wc_id = ?1
+                         AND dst.local_relpath = ?3
+                         AND dst.op_depth = ?4)
+FROM nodes_current
+WHERE wc_id = ?1 AND local_relpath = ?2
 
--- STMT_INSERT_WORKING_NODE_COPY_FROM_WORKING
+-- STMT_INSERT_WORKING_NODE_COPY_FROM_DEPTH
 INSERT OR REPLACE INTO nodes (
     wc_id, local_relpath, op_depth, parent_relpath, repos_id,
     repos_path, revision, presence, depth, moved_here, kind, changed_revision,
     changed_date, changed_author, checksum, properties, translated_size,
     last_mod_time, symlink_target, moved_to )
-SELECT src.wc_id, ?3 /*local_relpath*/, ?4 /*op_depth*/, ?5 /*parent_relpath*/,
-    src.repos_id, src.repos_path, src.revision, ?6 /*presence*/, src.depth,
-    ?7 /*moved_here*/, src.kind, src.changed_revision, src.changed_date,
-    src.changed_author, src.checksum, src.properties, src.translated_size,
-    src.last_mod_time, src.symlink_target, dst.moved_to
-FROM nodes_current AS src
-LEFT OUTER JOIN nodes_current dst ON dst.wc_id = src.wc_id
-  AND dst.local_relpath = ?3  AND dst.op_depth = ?4
-WHERE src.wc_id = ?1 AND src.local_relpath = ?2 AND src.op_depth > 0
-
--- STMT_INSERT_WORKING_NODE_COPY_FROM_DEPTH
-INSERT OR REPLACE INTO nodes (
-    wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path,
-    revision, presence, depth, moved_here, kind, changed_revision, changed_date,
-    changed_author, checksum, properties, translated_size, last_mod_time,
-    symlink_target )
 SELECT wc_id, ?3 /*local_relpath*/, ?4 /*op_depth*/, ?5 /*parent_relpath*/,
-    repos_id, repos_path, revision, ?6 /*presence*/, depth, ?7 /*moved_here*/,
-    kind, changed_revision, changed_date, changed_author, checksum,
-    properties, translated_size, last_mod_time, symlink_target
+    repos_id, repos_path, revision, ?6 /*presence*/, depth,
+    ?7 /*moved_here*/, kind, changed_revision, changed_date,
+    changed_author, checksum, properties, translated_size,
+    last_mod_time, symlink_target,
+    (SELECT dst.moved_to FROM nodes_current AS dst
+                         WHERE dst.wc_id = ?1
+                         AND dst.local_relpath = ?3
+                         AND dst.op_depth = ?4)
 FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?8
 

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1340694&r1=1340693&r2=1340694&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Sun May 20 12:28:16 2012
@@ -3409,7 +3409,6 @@ get_info_for_copy(apr_int64_t *copyfrom_
                   svn_wc__db_status_t *status,
                   svn_kind_t *kind,
                   svn_boolean_t *op_root,
-                  svn_boolean_t *have_work,
                   svn_wc__db_wcroot_t *wcroot,
                   const char *local_relpath,
                   apr_pool_t *result_pool,
@@ -3424,7 +3423,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
                     NULL, NULL, NULL, NULL, NULL, op_root, NULL, NULL,
                     NULL /* have_base */,
                     NULL /* have_more_work */,
-                    have_work,
+                    NULL /* have_work */,
                     wcroot, local_relpath, result_pool, scratch_pool));
 
   if (node_status == svn_wc__db_status_excluded)
@@ -3436,7 +3435,7 @@ get_info_for_copy(apr_int64_t *copyfrom_
       svn_dirent_split(&parent_relpath, &base_name, local_relpath,
                        scratch_pool);
       SVN_ERR(get_info_for_copy(copyfrom_id, copyfrom_relpath, copyfrom_rev,
-                                NULL, NULL, NULL, NULL,
+                                NULL, NULL, NULL,
                                 wcroot, parent_relpath,
                                 scratch_pool, scratch_pool));
       if (*copyfrom_relpath)
@@ -3548,7 +3547,6 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
   svn_wc__db_status_t status;
   svn_wc__db_status_t dst_presence;
   svn_boolean_t op_root;
-  svn_boolean_t have_work;
   apr_int64_t copyfrom_id;
   int dst_op_depth;
   int dst_np_op_depth;
@@ -3556,7 +3554,7 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
   const apr_array_header_t *children;
 
   SVN_ERR(get_info_for_copy(&copyfrom_id, &copyfrom_relpath, &copyfrom_rev,
-                            &status, &kind, &op_root, &have_work, src_wcroot,
+                            &status, &kind, &op_root, src_wcroot,
                             src_relpath, scratch_pool, scratch_pool));
 
   SVN_ERR(op_depth_for_copy(&dst_op_depth, &dst_np_op_depth, copyfrom_id,
@@ -3651,12 +3649,8 @@ db_op_copy(svn_wc__db_wcroot_t *src_wcro
       const char *dst_parent_relpath = svn_relpath_dirname(dst_relpath,
                                                            scratch_pool);
 
-      if (have_work)
-        SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
-                          STMT_INSERT_WORKING_NODE_COPY_FROM_WORKING));
-      else
-        SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
-                          STMT_INSERT_WORKING_NODE_COPY_FROM_BASE));
+      SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
+                                        STMT_INSERT_WORKING_NODE_COPY_FROM));
 
       SVN_ERR(svn_sqlite__bindf(stmt, "issdst",
                     src_wcroot->wc_id, src_relpath,
@@ -3960,25 +3954,19 @@ db_op_copy_shadowed_layer(svn_wc__db_wcr
   if (dst_presence == svn_wc__db_status_normal
       && src_wcroot == dst_wcroot) /* ### Remove limitation */
     {
-      if (src_op_depth > 0)
-        SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
+      SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
                              STMT_INSERT_WORKING_NODE_COPY_FROM_DEPTH));
-      else
-        SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
-                             STMT_INSERT_WORKING_NODE_COPY_FROM_BASE));
 
       /* Perhaps we should avoid setting moved_here to 0 and leave it
          null instead? */
-      SVN_ERR(svn_sqlite__bindf(stmt, "issdstd",
+      SVN_ERR(svn_sqlite__bindf(stmt, "issdstdd",
                         src_wcroot->wc_id, src_relpath,
                         dst_relpath,
                         dst_op_depth,
                         svn_relpath_dirname(dst_relpath, iterpool),
                         presence_map, dst_presence,
-                        (is_move ? 1 : 0)));
-
-      if (src_op_depth > 0)
-        SVN_ERR(svn_sqlite__bind_int(stmt, 8, src_op_depth));
+                        (is_move ? 1 : 0),
+                        src_op_depth));
 
       SVN_ERR(svn_sqlite__step_done(stmt));