You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ph...@apache.org on 2010/12/16 17:01:35 UTC

svn commit: r1050019 - in /subversion/trunk/subversion: libsvn_wc/wc-queries.sql libsvn_wc/wc_db.c tests/cmdline/upgrade_tests.py tests/cmdline/upgrade_tests_data/replaced-files.tar.bz2

Author: philip
Date: Thu Dec 16 16:01:35 2010
New Revision: 1050019

URL: http://svn.apache.org/viewvc?rev=1050019&view=rev
Log:
Make upgrades handle revert properties for working-only replaced files.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_PLAN_PROP_UPGRADE): Remove.
  (STMT_SELECT_NODE_UPGRADE, STMT_UPDATE_NODE_PROPS): New.

* subversion/libsvn_wc/wc_db.c
  (prop_upgrade_trees): Remove.
  (svn_wc__db_upgrade_apply_props): Handle revert-props for working-only
   replaces.

* subversion/tests/cmdline/upgrade_tests.py
  (replaced_files): New.
  (test_list): Mark replaced_files PASS.

* subversion/tests/cmdline/upgrade_tests_data/replaced-files.tar.bz2: New.

Added:
    subversion/trunk/subversion/tests/cmdline/upgrade_tests_data/replaced-files.tar.bz2   (with props)
Modified:
    subversion/trunk/subversion/libsvn_wc/wc-queries.sql
    subversion/trunk/subversion/libsvn_wc/wc_db.c
    subversion/trunk/subversion/tests/cmdline/upgrade_tests.py

Modified: subversion/trunk/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-queries.sql?rev=1050019&r1=1050018&r2=1050019&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-queries.sql Thu Dec 16 16:01:35 2010
@@ -712,14 +712,15 @@ UPDATE actual_node SET tree_conflict_dat
 SELECT DISTINCT local_relpath FROM nodes
 WHERE kind = 'file' AND parent_relpath = ?1;
 
--- STMT_PLAN_PROP_UPGRADE
-SELECT 0, nodes_base.presence, nodes_base.wc_id FROM nodes nodes_base
-WHERE nodes_base.local_relpath = ?1 AND nodes_base.op_depth = 0
-UNION ALL
-SELECT 1, nodes_work.presence, nodes_work.wc_id FROM nodes nodes_work
-WHERE nodes_work.local_relpath = ?1
-  AND nodes_work.op_depth = (SELECT MAX(op_depth) FROM nodes
-                             WHERE local_relpath = ?1 AND op_depth > 0);
+-- STMT_SELECT_NODE_UPGRADE
+SELECT op_depth, presence, wc_id
+FROM nodes
+WHERE local_relpath = ?1
+ORDER BY op_depth DESC;
+
+-- STMT_UPDATE_NODE_PROPS
+UPDATE nodes SET properties = ?4
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3;
 
 -- STMT_HAS_WORKING_NODES
 SELECT 1 FROM nodes WHERE op_depth > 0;

Modified: subversion/trunk/subversion/libsvn_wc/wc_db.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc_db.c?rev=1050019&r1=1050018&r2=1050019&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/trunk/subversion/libsvn_wc/wc_db.c Thu Dec 16 16:01:35 2010
@@ -1244,73 +1244,6 @@ which_trees_exist(svn_boolean_t *base_ex
 }
 
 
-/* Determine which trees' nodes exist for a given LOCAL_RELPATH in the
-   specified SDB.
-
-   Note: this is VERY similar to the above which_trees_exist() except that
-   we return a WC_ID and verify some additional constraints.  */
-static svn_error_t *
-prop_upgrade_trees(svn_boolean_t *base_exists,
-                   svn_wc__db_status_t *base_presence,
-                   svn_boolean_t *working_exists,
-                   svn_wc__db_status_t *work_presence,
-                   apr_int64_t *wc_id,
-                   svn_sqlite__db_t *sdb,
-                   const char *local_relpath)
-{
-  svn_sqlite__stmt_t *stmt;
-  svn_boolean_t have_row;
-
-  *base_exists = FALSE;
-  *working_exists = FALSE;
-
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_PLAN_PROP_UPGRADE));
-  SVN_ERR(svn_sqlite__bindf(stmt, "s", local_relpath));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-
-  /* During a property upgrade, there better be a row corresponding to
-     the provided LOCAL_RELPATH. We shouldn't even be here without a
-     query for available rows.  */
-  SVN_ERR_ASSERT(have_row);
-
-  /* Use the first column to detect which table this row came from.  */
-  if (svn_sqlite__column_int(stmt, 0))
-    {
-      *working_exists = TRUE;  /* value == 1  */
-      *work_presence = svn_sqlite__column_token(stmt, 1, presence_map);
-    }
-  else
-    {
-      *base_exists = TRUE;  /* value == 0  */
-      *base_presence = svn_sqlite__column_token(stmt, 1, presence_map);
-    }
-
-  /* Return the WC_ID that was assigned.  */
-  *wc_id = svn_sqlite__column_int64(stmt, 2);
-
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-  if (have_row)
-    {
-      /* If both rows, then both tables.  */
-      *base_exists = TRUE;
-      *working_exists = TRUE;
-
-      /* If the second row came from WORKING_NODE, then we should also
-         fetch the 'presence' column value.  */
-      if (svn_sqlite__column_int(stmt, 0))
-        *work_presence = svn_sqlite__column_token(stmt, 1, presence_map);
-      else
-        *base_presence = svn_sqlite__column_token(stmt, 1, presence_map);
-
-      /* During an upgrade, there should be just one working copy, so both
-         rows should refer to the same value.  */
-      SVN_ERR_ASSERT(*wc_id == svn_sqlite__column_int64(stmt, 2));
-    }
-
-  return svn_error_return(svn_sqlite__reset(stmt));
-}
-
-
 /* */
 static svn_error_t *
 create_db(svn_sqlite__db_t **sdb,
@@ -7094,12 +7027,10 @@ svn_wc__db_upgrade_apply_props(svn_sqlit
                                int original_format,
                                apr_pool_t *scratch_pool)
 {
-  svn_boolean_t have_base;
-  svn_wc__db_status_t base_presence;
-  svn_boolean_t have_work;
-  svn_wc__db_status_t work_presence;
-  apr_int64_t wc_id;
   svn_sqlite__stmt_t *stmt;
+  svn_boolean_t have_row;
+  apr_int64_t wc_id, top_op_depth = -1, below_op_depth = -1;
+  svn_wc__db_status_t top_presence, below_presence;
   int affected_rows;
 
   /* ### working_props: use set_props_txn.
@@ -7129,19 +7060,31 @@ svn_wc__db_upgrade_apply_props(svn_sqlit
      the handling of our inputs, relative to the state of this node.
   */
 
-  /* Collect information about this node.  */
-  SVN_ERR(prop_upgrade_trees(&have_base, &base_presence,
-                             &have_work, &work_presence,
-                             &wc_id, sdb, local_relpath));
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_NODE_UPGRADE));
+  SVN_ERR(svn_sqlite__bindf(stmt, "s", local_relpath));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+  if (have_row)
+    {
+      top_op_depth = svn_sqlite__column_int64(stmt, 0);
+      top_presence = svn_sqlite__column_token(stmt, 1, presence_map);
+      wc_id = svn_sqlite__column_int64(stmt, 2);
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+      if (have_row)
+        {
+          below_op_depth = svn_sqlite__column_int64(stmt, 0);
+          below_presence = svn_sqlite__column_token(stmt, 1, presence_map);
+        }
+    }
+  SVN_ERR(svn_sqlite__reset(stmt));
 
   /* Detect the buggy scenario described above. We cannot upgrade this
      working copy if we have no idea where BASE_PROPS should go.  */
   if (original_format > SVN_WC__NO_REVERT_FILES
       && revert_props == NULL
-      && have_work
-      && work_presence == svn_wc__db_status_normal
-      && have_base
-      && base_presence != svn_wc__db_status_not_present)
+      && top_op_depth != -1
+      && top_presence == svn_wc__db_status_normal
+      && below_op_depth != -1
+      && below_presence != svn_wc__db_status_not_present)
     {
       /* There should be REVERT_PROPS, so it appears that we just ran into
          the described bug. Sigh.  */
@@ -7154,48 +7097,44 @@ svn_wc__db_upgrade_apply_props(svn_sqlit
                                                  scratch_pool), scratch_pool));
     }
 
-  if (have_base
-      && (base_presence == svn_wc__db_status_normal
-          || base_presence == svn_wc__db_status_incomplete))
-    {
-      apr_hash_t *props = revert_props ? revert_props : base_props;
+  /* Need at least one row, or two rows if there are revert props */
+  if (top_op_depth == -1
+      || (below_op_depth == -1 && revert_props))
+    return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL,
+                             _("Insufficient NODES rows for '%s'"),
+                             svn_dirent_local_style(
+                               svn_dirent_join(dir_abspath, local_relpath,
+                                               scratch_pool), scratch_pool));
+
+  /* one row, base props only: upper row gets base props
+     two rows, base props only: lower row gets base props
+     two rows, base and revert props: upper row gets base, lower gets revert */
+
 
+  if (revert_props || below_op_depth == -1)
+    {
       SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
-                                        STMT_UPDATE_NODE_BASE_PROPS));
-      SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
-      SVN_ERR(svn_sqlite__bind_properties(stmt, 3, props, scratch_pool));
+                                        STMT_UPDATE_NODE_PROPS));
+      SVN_ERR(svn_sqlite__bindf(stmt, "isi",
+                                wc_id, local_relpath, top_op_depth));
+      SVN_ERR(svn_sqlite__bind_properties(stmt, 4, base_props, scratch_pool));
       SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
 
-      /* ### should we provide a nicer error message?  */
       SVN_ERR_ASSERT(affected_rows == 1);
     }
 
-  if (have_work)
+  if (below_op_depth != -1)
     {
-      /* WORKING_NODE has very limited 'presence' values.  */
-      SVN_ERR_ASSERT(work_presence == svn_wc__db_status_normal
-                     || work_presence == svn_wc__db_status_not_present
-                     || work_presence == svn_wc__db_status_base_deleted
-                     || work_presence == svn_wc__db_status_incomplete);
+      apr_hash_t *props = revert_props ? revert_props : base_props;
 
-      /* Do we have a replaced node? It has properties: an empty set for
-         adds, and a non-empty set for copies/moves.  */
-      if (original_format > SVN_WC__NO_REVERT_FILES
-          && (work_presence == svn_wc__db_status_normal
-              || work_presence == svn_wc__db_status_incomplete))
-        {
-          SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
-                                            STMT_UPDATE_NODE_WORKING_PROPS));
-          SVN_ERR(svn_sqlite__bindf(stmt, "is", wc_id, local_relpath));
-          SVN_ERR(svn_sqlite__bind_properties(stmt, 3, base_props,
-                                              scratch_pool));
-          SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
+      SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                        STMT_UPDATE_NODE_PROPS));
+      SVN_ERR(svn_sqlite__bindf(stmt, "isi",
+                                wc_id, local_relpath, below_op_depth));
+      SVN_ERR(svn_sqlite__bind_properties(stmt, 4, props, scratch_pool));
+      SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
 
-          /* ### should we provide a nicer error message?  */
-          SVN_ERR_ASSERT(affected_rows == 1);
-        }
-      /* else other states should have no properties.  */
-      /* ### should we insert empty props for <= SVN_WC__NO_REVERT_FILES?  */
+      SVN_ERR_ASSERT(affected_rows == 1);
     }
 
   /* If there are WORKING_PROPS, then they always go into ACTUAL_NODE.  */

Modified: subversion/trunk/subversion/tests/cmdline/upgrade_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/upgrade_tests.py?rev=1050019&r1=1050018&r2=1050019&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/upgrade_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/upgrade_tests.py Thu Dec 16 16:01:35 2010
@@ -754,6 +754,47 @@ def delete_in_copy_upgrade(sbox):
       })
   run_and_verify_status_no_server(sbox.wc_dir, expected_status)
 
+def replaced_files(sbox):
+  "upgrade with base and working replaced files"
+
+  sbox.build(create_wc = False)
+  wc_dir = sbox.wc_dir
+  replace_sbox_with_tarfile(sbox, 'replaced-files.tar.bz2')
+
+  svntest.actions.run_and_verify_svn(None, None, [],
+                                     'upgrade', sbox.wc_dir)
+
+  # A/f is a base file that is replaced with a copy of A/g, B is a
+  # working-only copy of A, and B/f is a working-only file replaced
+  # with a copy of A/g
+  expected_status = svntest.wc.State(sbox.wc_dir,
+    {
+      ''    : Item(status='  ', wc_rev='5'),
+      'A'   : Item(status='  ', wc_rev='5'),
+      'A/f' : Item(status='R ', wc_rev='-', copied='+'),
+      'A/g' : Item(status='  ', wc_rev='5'),
+      'B'   : Item(status='A ', wc_rev='-', copied='+'),
+      'B/f' : Item(status='R ', wc_rev='-', copied='+'),
+      'B/g' : Item(status='  ', wc_rev='-', copied='+'),
+  })
+  run_and_verify_status_no_server(sbox.wc_dir, expected_status)
+
+  simple_property_verify(sbox.wc_dir, {
+      'A/f' : {'pAg' : 'vAg' },
+      'A/g' : {'pAg' : 'vAg' },
+      'B/f' : {'pAg' : 'vAg' },
+      'B/g' : {'pAg' : 'vAg' },
+      })
+
+  svntest.actions.run_and_verify_svn(None, 'Reverted.*', [], 'revert',
+                                     sbox.ospath('A/f'), sbox.ospath('B/f'))
+
+  simple_property_verify(sbox.wc_dir, {
+      'A/f' : {'pAf' : 'vAf' },
+      'A/g' : {'pAg' : 'vAg' },
+      'B/f' : {'pAf' : 'vAf' },
+      'B/g' : {'pAg' : 'vAg' },
+      })
 
 ########################################################################
 # Run the tests
@@ -778,6 +819,7 @@ test_list = [ None,
               dirs_only_upgrade,
               upgrade_tree_conflict_data,
               delete_in_copy_upgrade,
+              replaced_files,
              ]
 
 

Added: subversion/trunk/subversion/tests/cmdline/upgrade_tests_data/replaced-files.tar.bz2
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/upgrade_tests_data/replaced-files.tar.bz2?rev=1050019&view=auto
==============================================================================
Binary file - no diff available.

Propchange: subversion/trunk/subversion/tests/cmdline/upgrade_tests_data/replaced-files.tar.bz2
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream