You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pb...@apache.org on 2012/06/26 21:28:22 UTC

svn commit: r1354186 [21/33] - in /subversion/branches/inheritable-props: ./ build/ build/ac-macros/ build/generator/ build/generator/templates/ build/win32/ contrib/client-side/emacs/ contrib/server-side/ notes/ notes/api-errata/1.8/ notes/directory-i...

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/node.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/node.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/node.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/node.c Tue Jun 26 19:26:49 2012
@@ -288,27 +288,18 @@ svn_wc_read_kind(svn_node_kind_t *kind,
                  svn_boolean_t show_hidden,
                  apr_pool_t *scratch_pool)
 {
-  svn_wc__db_status_t db_status;
   svn_kind_t db_kind;
-  svn_error_t *err;
 
-  err = svn_wc__db_read_info(&db_status, &db_kind, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                             NULL, NULL, NULL, NULL, NULL, NULL,
-                             wc_ctx->db, local_abspath,
-                             scratch_pool, scratch_pool);
+  SVN_ERR(svn_wc__db_read_kind(&db_kind,
+                             wc_ctx->db, local_abspath, TRUE, show_hidden,
+                             scratch_pool));
 
-  if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
-    {
-      svn_error_clear(err);
-      *kind = svn_node_none;
-      return SVN_NO_ERROR;
-    }
+  if (db_kind == svn_kind_dir)
+    *kind = svn_node_dir;
+  else if (db_kind == svn_kind_file || db_kind == svn_kind_symlink)
+    *kind = svn_node_file;
   else
-    SVN_ERR(err);
-
-  SVN_ERR(convert_db_kind_to_node_kind(kind, db_kind, db_status, show_hidden));
+    *kind = svn_node_none;
 
   return SVN_NO_ERROR;
 }
@@ -909,6 +900,10 @@ svn_wc__node_get_base(svn_revnum_t *revi
     }
   SVN_ERR(err);
 
+  SVN_ERR_ASSERT(!revision || SVN_IS_VALID_REVNUM(*revision));
+  SVN_ERR_ASSERT(!repos_relpath || *repos_relpath);
+  SVN_ERR_ASSERT(!repos_root_url || *repos_root_url);
+  SVN_ERR_ASSERT(!repos_uuid || *repos_uuid);
   return SVN_NO_ERROR;
 }
 
@@ -962,36 +957,54 @@ svn_wc__node_get_pre_ng_status_data(svn_
 
 
 svn_error_t *
-svn_wc__internal_get_commit_base_rev(svn_revnum_t *commit_base_revision,
-                                     svn_wc__db_t *db,
-                                     const char *local_abspath,
-                                     apr_pool_t *scratch_pool)
+svn_wc__internal_get_commit_base(svn_revnum_t *commit_base_revision,
+                                 const char **repos_relpath,
+                                 const char **repos_root_url,
+                                 const char **repos_uuid,
+                                 svn_wc__db_t *db,
+                                 const char *local_abspath,
+                                 apr_pool_t *result_pool,
+                                 apr_pool_t *scratch_pool)
 {
   svn_wc__db_status_t status;
   svn_boolean_t have_base;
   svn_boolean_t have_more_work;
   svn_revnum_t revision;
-  svn_revnum_t original_revision;
+  svn_revnum_t orig_revision;
+  const char *orig_repos_relpath;
+  const char *orig_repos_root_url;
+  const char *orig_repos_uuid;
 
   *commit_base_revision = SVN_INVALID_REVNUM;
 
-  SVN_ERR(svn_wc__db_read_info(&status, NULL, &revision, NULL, NULL, NULL,
+  SVN_ERR(svn_wc__db_read_info(&status, NULL,
+                               &revision, repos_relpath,
+                               repos_root_url, repos_uuid,
+                               NULL, NULL, NULL, NULL, NULL, NULL,
+                               &orig_repos_relpath, &orig_repos_root_url,
+                               &orig_repos_uuid, &orig_revision,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, &original_revision, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL,
                                &have_base, &have_more_work, NULL,
                                db, local_abspath, scratch_pool, scratch_pool));
 
   if (SVN_IS_VALID_REVNUM(revision))
     {
       /* We are looking directly at BASE */
-      *commit_base_revision = revision;
+      if (commit_base_revision)
+        *commit_base_revision = revision;
       return SVN_NO_ERROR;
     }
-  else if (SVN_IS_VALID_REVNUM(original_revision))
+  else if (SVN_IS_VALID_REVNUM(orig_revision))
     {
       /* We are looking at a copied node */
-      *commit_base_revision = original_revision;
+      if (commit_base_revision)
+        *commit_base_revision = orig_revision;
+      if (repos_relpath)
+        *repos_relpath = orig_repos_relpath;
+      if (repos_root_url)
+        *repos_root_url = orig_repos_root_url;
+      if (repos_uuid)
+        *repos_uuid = orig_repos_uuid;
       return SVN_NO_ERROR;
     }
 
@@ -999,8 +1012,9 @@ svn_wc__internal_get_commit_base_rev(svn
     {
       /* If the node was copied/moved-here, return the copy/move source
          revision (not this node's base revision). */
-      SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL, NULL,
-                                       NULL, NULL, commit_base_revision,
+      SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL,
+                                       repos_relpath, repos_root_url,
+                                       repos_uuid, commit_base_revision,
                                        NULL, NULL, db, local_abspath,
                                        scratch_pool, scratch_pool));
 
@@ -1021,10 +1035,10 @@ svn_wc__internal_get_commit_base_rev(svn
         {
           /* This is a deletion within a copied subtree. Get the copied-from
            * revision. */
-          SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL, NULL,
-                                           NULL, NULL,
-                                           commit_base_revision, NULL, NULL,
-                                           db,
+          SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL,
+                                           repos_relpath, repos_root_url,
+                                           repos_uuid, commit_base_revision,
+                                           NULL, NULL, db,
                                            svn_dirent_dirname(work_del_abspath,
                                                               scratch_pool),
                                            scratch_pool, scratch_pool));
@@ -1040,7 +1054,8 @@ svn_wc__internal_get_commit_base_rev(svn
   if (have_base && !have_more_work)
     {
       SVN_ERR(svn_wc__db_base_get_info(&status, NULL, commit_base_revision,
-                                       NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                                       repos_relpath, repos_root_url,
+                                       repos_uuid, NULL, NULL, NULL, NULL,
                                        NULL, NULL, NULL, NULL, NULL,
                                        db, local_abspath,
                                        scratch_pool, scratch_pool));
@@ -1053,14 +1068,19 @@ svn_wc__internal_get_commit_base_rev(svn
 }
 
 svn_error_t *
-svn_wc__node_get_commit_base_rev(svn_revnum_t *commit_base_revision,
-                                 svn_wc_context_t *wc_ctx,
-                                 const char *local_abspath,
-                                 apr_pool_t *scratch_pool)
-{
-  return svn_error_trace(svn_wc__internal_get_commit_base_rev(
-                           commit_base_revision, wc_ctx->db, local_abspath,
-                           scratch_pool));
+svn_wc__node_get_commit_base(svn_revnum_t *revision,
+                             const char **repos_relpath,
+                             const char **repos_root_url,
+                             const char **repos_uuid,
+                             svn_wc_context_t *wc_ctx,
+                             const char *local_abspath,
+                             apr_pool_t *result_pool,
+                             apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(svn_wc__internal_get_commit_base(
+                           revision, repos_relpath, repos_root_url, repos_uuid,
+                           wc_ctx->db, local_abspath,
+                           result_pool, scratch_pool));
 }
 
 svn_error_t *
@@ -1324,18 +1344,18 @@ svn_wc__node_get_lock_tokens_recursive(a
 }
 
 svn_error_t *
-svn_wc__get_server_excluded_subtrees(apr_hash_t **server_excluded_subtrees,
-                                     svn_wc_context_t *wc_ctx,
-                                     const char *local_abspath,
-                                     apr_pool_t *result_pool,
-                                     apr_pool_t *scratch_pool)
+svn_wc__get_excluded_subtrees(apr_hash_t **server_excluded_subtrees,
+                              svn_wc_context_t *wc_ctx,
+                              const char *local_abspath,
+                              apr_pool_t *result_pool,
+                              apr_pool_t *scratch_pool)
 {
   return svn_error_trace(
-           svn_wc__db_get_server_excluded_subtrees(server_excluded_subtrees,
-                                                   wc_ctx->db,
-                                                   local_abspath,
-                                                   result_pool,
-                                                   scratch_pool));
+           svn_wc__db_get_excluded_subtrees(server_excluded_subtrees,
+                                            wc_ctx->db,
+                                            local_abspath,
+                                            result_pool,
+                                            scratch_pool));
 }
 
 svn_error_t *
@@ -1477,68 +1497,38 @@ svn_wc__node_get_origin(svn_boolean_t *i
 }
 
 svn_error_t *
-svn_wc__node_get_commit_status(svn_node_kind_t *kind,
-                               svn_boolean_t *added,
+svn_wc__node_get_commit_status(svn_boolean_t *added,
                                svn_boolean_t *deleted,
                                svn_boolean_t *is_replace_root,
-                               svn_boolean_t *not_present,
-                               svn_boolean_t *excluded,
                                svn_boolean_t *is_op_root,
-                               svn_boolean_t *symlink,
                                svn_revnum_t *revision,
-                               const char **repos_relpath,
                                svn_revnum_t *original_revision,
                                const char **original_repos_relpath,
-                               svn_boolean_t *conflicted,
-                               const char **changelist,
-                               svn_boolean_t *props_mod,
-                               svn_boolean_t *update_root,
-                               const char **lock_token,
                                svn_wc_context_t *wc_ctx,
                                const char *local_abspath,
                                apr_pool_t *result_pool,
                                apr_pool_t *scratch_pool)
 {
   svn_wc__db_status_t status;
-  svn_kind_t db_kind;
-  svn_wc__db_lock_t *lock;
-  svn_boolean_t had_props;
-  svn_boolean_t props_mod_tmp;
   svn_boolean_t have_base;
   svn_boolean_t have_more_work;
   svn_boolean_t op_root;
 
-  if (!props_mod)
-    props_mod = &props_mod_tmp;
-
   /* ### All of this should be handled inside a single read transaction */
-  SVN_ERR(svn_wc__db_read_info(&status, &db_kind, revision, repos_relpath,
+  SVN_ERR(svn_wc__db_read_info(&status, NULL, revision, NULL,
                                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                                original_repos_relpath, NULL, NULL,
-                               original_revision, &lock, NULL, NULL,
-                               changelist, conflicted,
-                               &op_root, &had_props, props_mod,
+                               original_revision, NULL, NULL, NULL,
+                               NULL, NULL,
+                               &op_root, NULL, NULL,
                                &have_base, &have_more_work, NULL,
                                wc_ctx->db, local_abspath,
                                result_pool, scratch_pool));
 
-  if (kind)
-    {
-      if (db_kind == svn_kind_file)
-        *kind = svn_node_file;
-      else if (db_kind == svn_kind_dir)
-        *kind = svn_node_dir;
-      else
-        *kind = svn_node_unknown;
-    }
   if (added)
     *added = (status == svn_wc__db_status_added);
   if (deleted)
     *deleted = (status == svn_wc__db_status_deleted);
-  if (not_present)
-    *not_present = (status == svn_wc__db_status_not_present);
-  if (excluded)
-    *excluded = (status == svn_wc__db_status_excluded);
   if (is_op_root)
     *is_op_root = op_root;
 
@@ -1554,40 +1544,19 @@ svn_wc__node_get_commit_status(svn_node_
         *is_replace_root = FALSE;
     }
 
-  if (symlink)
-    {
-      apr_hash_t *props;
-      *symlink = FALSE;
-
-      if (db_kind == svn_kind_file
-          && (had_props || *props_mod))
-        {
-          SVN_ERR(svn_wc__db_read_props(&props, wc_ctx->db, local_abspath,
-                                        scratch_pool, scratch_pool));
-
-          *symlink = ((props != NULL)
-                      && (apr_hash_get(props, SVN_PROP_SPECIAL,
-                                       APR_HASH_KEY_STRING) != NULL));
-        }
-    }
-
   /* Retrieve some information from BASE which is needed for replacing
-     and/or deleting BASE nodes. (We don't need lock here) */
+     and/or deleting BASE nodes. */
   if (have_base
-      && ((revision && !SVN_IS_VALID_REVNUM(*revision))
-          || (update_root && status == svn_wc__db_status_normal)))
+      && !have_more_work
+      && op_root
+      && (revision && !SVN_IS_VALID_REVNUM(*revision)))
     {
       SVN_ERR(svn_wc__db_base_get_info(NULL, NULL, revision, NULL, NULL, NULL,
                                        NULL, NULL, NULL, NULL, NULL, NULL,
-                                       NULL, NULL, update_root,
+                                       NULL, NULL, NULL,
                                        wc_ctx->db, local_abspath,
                                        scratch_pool, scratch_pool));
     }
-  else if (update_root)
-    *update_root = FALSE;
-
-  if (lock_token)
-    *lock_token = lock ? lock->token : NULL;
 
   return SVN_NO_ERROR;
 }

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/old-and-busted.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/old-and-busted.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/old-and-busted.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/old-and-busted.c Tue Jun 26 19:26:49 2012
@@ -382,7 +382,7 @@ opt_revision_to_string(const char **str,
       *str = apr_pstrmemdup(pool, "HEAD", 4);
       break;
     case svn_opt_revision_number:
-      *str = apr_itoa(pool, rev->value.number);
+      *str = apr_ltoa(pool, rev->value.number);
       break;
     default:
       return svn_error_createf

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/props.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/props.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/props.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/props.c Tue Jun 26 19:26:49 2012
@@ -80,14 +80,12 @@ append_prop_conflict(svn_stream_t *strea
   /* TODO:  someday, perhaps prefix each conflict_description with a
      timestamp or something? */
   const svn_string_t *conflict_desc;
-  apr_size_t len;
   const char *native_text;
 
   SVN_ERR(prop_conflict_from_skel(&conflict_desc, prop_skel, pool, pool));
   native_text = svn_utf_cstring_from_utf8_fuzzy(conflict_desc->data, pool);
 
-  len = strlen(native_text);
-  return svn_stream_write(stream, native_text, &len);
+  return svn_stream_puts(stream, native_text);
 }
 
 
@@ -1845,7 +1843,6 @@ svn_wc__prop_list_recursive(svn_wc_conte
                             const char *local_abspath,
                             const char *propname,
                             svn_depth_t depth,
-                            svn_boolean_t base_props,
                             svn_boolean_t pristine,
                             const apr_array_header_t *changelists,
                             svn_wc__proplist_receiver_t receiver_func,
@@ -1856,8 +1853,11 @@ svn_wc__prop_list_recursive(svn_wc_conte
 {
   svn_wc__proplist_receiver_t receiver = receiver_func;
   void *baton = receiver_baton;
-  struct propname_filter_baton_t pfb = { receiver_func, receiver_baton,
-                                         propname };
+  struct propname_filter_baton_t pfb;
+
+  pfb.receiver_func = receiver_func;
+  pfb.receiver_baton = receiver_baton;
+  pfb.propname = propname;
 
   SVN_ERR_ASSERT(receiver_func);
 
@@ -1899,7 +1899,7 @@ svn_wc__prop_list_recursive(svn_wc_conte
     case svn_depth_infinity:
       {
         SVN_ERR(svn_wc__db_read_props_streamily(wc_ctx->db, local_abspath,
-                                                depth, base_props, pristine,
+                                                depth, pristine,
                                                 changelists, receiver, baton,
                                                 cancel_func, cancel_baton,
                                                 scratch_pool));
@@ -1913,6 +1913,22 @@ svn_wc__prop_list_recursive(svn_wc_conte
 }
 
 svn_error_t *
+svn_wc__prop_retrieve_recursive(apr_hash_t **values,
+                                svn_wc_context_t *wc_ctx,
+                                const char *local_abspath,
+                                const char *propname,
+                                apr_pool_t *result_pool,
+                                apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(
+            svn_wc__db_prop_retrieve_recursive(values,
+                                               wc_ctx->db,
+                                               local_abspath,
+                                               propname,
+                                               result_pool, scratch_pool));
+}
+
+svn_error_t *
 svn_wc__get_pristine_props(apr_hash_t **props,
                            svn_wc__db_t *db,
                            const char *local_abspath,
@@ -2211,32 +2227,11 @@ do_propset(svn_wc__db_t *db,
 {
   apr_hash_t *prophash;
   svn_wc_notify_action_t notify_action;
-  svn_wc__db_status_t status;
   svn_skel_t *work_item = NULL;
   svn_boolean_t clear_recorded_info = FALSE;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
-  /* Get the node status for this path. */
-  SVN_ERR(svn_wc__db_read_info(&status, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-                               NULL, NULL, NULL, NULL, NULL, NULL,
-                               db, local_abspath,
-                               scratch_pool, scratch_pool));
-
-  if (status != svn_wc__db_status_normal
-      && status != svn_wc__db_status_added
-      && status != svn_wc__db_status_incomplete)
-    return svn_error_createf(SVN_ERR_WC_INVALID_SCHEDULE, NULL,
-                             _("Can't set properties on '%s':"
-                               " invalid status for updating properties."),
-                             svn_dirent_local_style(local_abspath,
-                                                    scratch_pool));
-
-  /* Else, handle a regular property: */
-
-
   /* Setting an inappropriate property is not allowed (unless
      overridden by 'skip_checks', in some circumstances).  Deleting an
      inappropriate property is allowed, however, since older clients
@@ -2321,7 +2316,7 @@ do_propset(svn_wc__db_t *db,
     }
   else if (kind == svn_node_file && strcmp(name, SVN_PROP_EOL_STYLE) == 0)
     {
-      svn_string_t *old_value = apr_hash_get(prophash, SVN_PROP_KEYWORDS,
+      svn_string_t *old_value = apr_hash_get(prophash, SVN_PROP_EOL_STYLE,
                                              APR_HASH_KEY_STRING);
 
       if (((value == NULL) != (old_value == NULL))
@@ -2431,6 +2426,7 @@ svn_wc_prop_set4(svn_wc_context_t *wc_ct
                  apr_pool_t *scratch_pool)
 {
   enum svn_prop_kind prop_kind = svn_property_kind2(name);
+  svn_wc__db_status_t status;
   svn_kind_t kind;
   const char *dir_abspath;
 
@@ -2452,8 +2448,22 @@ svn_wc_prop_set4(svn_wc_context_t *wc_ct
      backward we never call this API with depth > empty, so we only need
      to do the write check once per call, here (and not for every node in
      the node walker). */
-  SVN_ERR(svn_wc__db_read_kind(&kind, wc_ctx->db, local_abspath, TRUE,
-                               scratch_pool));
+    /* Get the node status for this path. */
+  SVN_ERR(svn_wc__db_read_info(&status, &kind, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+                               NULL, NULL, NULL, NULL, NULL, NULL,
+                               wc_ctx->db, local_abspath,
+                               scratch_pool, scratch_pool));
+
+  if (status != svn_wc__db_status_normal
+      && status != svn_wc__db_status_added
+      && status != svn_wc__db_status_incomplete)
+    return svn_error_createf(SVN_ERR_WC_INVALID_SCHEDULE, NULL,
+                             _("Can't set properties on '%s':"
+                               " invalid status for updating properties."),
+                             svn_dirent_local_style(local_abspath,
+                                                    scratch_pool));
 
   if (kind == svn_kind_dir)
     dir_abspath = local_abspath;
@@ -2462,7 +2472,7 @@ svn_wc_prop_set4(svn_wc_context_t *wc_ct
 
   SVN_ERR(svn_wc__write_check(wc_ctx->db, dir_abspath, scratch_pool));
 
-  if (depth == svn_depth_empty)
+  if (depth == svn_depth_empty || kind != svn_kind_dir)
     {
       apr_hash_t *changelist_hash = NULL;
 
@@ -2483,8 +2493,14 @@ svn_wc_prop_set4(svn_wc_context_t *wc_ct
     }
   else
     {
-      struct propset_walk_baton wb = { name, value, wc_ctx->db, skip_checks,
-                                       notify_func, notify_baton };
+      struct propset_walk_baton wb;
+
+      wb.propname = name;
+      wb.propval = value;
+      wb.db = wc_ctx->db;
+      wb.force = skip_checks;
+      wb.notify_func = notify_func;
+      wb.notify_baton = notify_baton;
 
       SVN_ERR(svn_wc__internal_walk_children(wc_ctx->db, local_abspath,
                                              FALSE, changelist_filter,

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/questions.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/questions.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/questions.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/questions.c Tue Jun 26 19:26:49 2012
@@ -374,11 +374,9 @@ svn_error_t *
 svn_wc_text_modified_p2(svn_boolean_t *modified_p,
                         svn_wc_context_t *wc_ctx,
                         const char *local_abspath,
-                        svn_boolean_t force_comparison,
+                        svn_boolean_t unused,
                         apr_pool_t *scratch_pool)
 {
-  /* ### We ignore FORCE_COMPARISON, but we also fixed its only
-         remaining use-case */
   return svn_wc__internal_file_modified_p(modified_p, wc_ctx->db,
                                           local_abspath, FALSE, scratch_pool);
 }
@@ -398,6 +396,8 @@ svn_wc__internal_conflicted_p(svn_boolea
   const apr_array_header_t *conflicts;
   int i;
   svn_boolean_t conflicted;
+  svn_boolean_t resolved_text = FALSE;
+  svn_boolean_t resolved_props = FALSE;
 
   if (text_conflicted_p)
     *text_conflicted_p = FALSE;
@@ -466,7 +466,12 @@ svn_wc__internal_conflicted_p(svn_boolea
                                           scratch_pool));
 
                 *text_conflicted_p = (kind == svn_node_file);
+
+                if (*text_conflicted_p)
+                  break;
               }
+
+            resolved_text = TRUE; /* Remove in-db conflict marker */
             break;
 
           case svn_wc_conflict_kind_property:
@@ -479,8 +484,11 @@ svn_wc__internal_conflicted_p(svn_boolea
                                           scratch_pool));
 
                 *prop_conflicted_p = (kind == svn_node_file);
-              }
 
+                if (*prop_conflicted_p)
+                  break;
+              }
+            resolved_props = TRUE; /* Remove in-db conflict marker */
             break;
 
           case svn_wc_conflict_kind_tree:
@@ -494,6 +502,23 @@ svn_wc__internal_conflicted_p(svn_boolea
             break;
         }
     }
+
+  if (resolved_text || resolved_props)
+    {
+      svn_boolean_t own_lock;
+
+      /* The marker files are missing, so "repair" wc.db if we can */
+      SVN_ERR(svn_wc__db_wclock_owns_lock(&own_lock, db, local_abspath, FALSE,
+                                          scratch_pool));
+      if (own_lock)
+        SVN_ERR(svn_wc__db_op_mark_resolved(db, local_abspath,
+                                            resolved_text,
+                                            resolved_props,
+                                            FALSE /* resolved_tree */,
+                                            NULL /* work_items */,
+                                            scratch_pool));
+    }
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/status.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/status.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/status.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/status.c Tue Jun 26 19:26:49 2012
@@ -41,6 +41,7 @@
 #include "svn_config.h"
 #include "svn_time.h"
 #include "svn_hash.h"
+#include "svn_sorts.h"
 
 #include "svn_private_config.h"
 
@@ -949,6 +950,9 @@ send_status_structure(const struct walk_
    IGNORES is a list of patterns to include; typically this will
    be the default ignores as, for example, specified in a config file.
 
+   If MAY_HAVE_PROPS is false, local_abspath is assumed to have no
+   properties.
+
    LOCAL_ABSPATH and DB control how to access the ignore information.
 
    Allocate results in RESULT_POOL, temporary stuffs in SCRATCH_POOL.
@@ -960,11 +964,13 @@ collect_ignore_patterns(apr_array_header
                         svn_wc__db_t *db,
                         const char *local_abspath,
                         const apr_array_header_t *ignores,
+                        svn_boolean_t may_have_props,
                         apr_pool_t *result_pool,
                         apr_pool_t *scratch_pool)
 {
   int i;
   const svn_string_t *value;
+  apr_hash_t *props;
 
   /* ### assert we are passed a directory? */
 
@@ -978,9 +984,18 @@ collect_ignore_patterns(apr_array_header
                                                             ignore);
     }
 
+  if (!may_have_props)
+    return SVN_NO_ERROR;
+
   /* Then add any svn:ignore globs to the PATTERNS array. */
-  SVN_ERR(svn_wc__internal_propget(&value, db, local_abspath, SVN_PROP_IGNORE,
-                                   scratch_pool, scratch_pool));
+  SVN_ERR(svn_wc__db_read_props(&props, db, local_abspath,
+                                scratch_pool, scratch_pool));
+
+  if (!props)
+    return SVN_NO_ERROR;
+
+  value = apr_hash_get(props, SVN_PROP_IGNORE, APR_HASH_KEY_STRING);
+
   if (value != NULL)
     svn_cstring_split_append(*patterns, value->data, "\n\r", FALSE,
                              result_pool);
@@ -1120,6 +1135,8 @@ get_dir_status(const struct walk_status_
  * DIR_REPOS_* should reflect LOCAL_ABSPATH's parent URL, i.e. LOCAL_ABSPATH's
  * URL treated with svn_uri_dirname(). ### TODO verify this (externals)
  *
+ * DIR_HAS_PROPS is a boolean indicating whether PARENT_ABSPATH has properties.
+ *
  * If *COLLECTED_IGNORE_PATTERNS is NULL and ignore patterns are needed in
  * this call, *COLLECTED_IGNORE_PATTERNS will be set to an apr_array_header_t*
  * containing all ignore patterns, as returned by collect_ignore_patterns() on
@@ -1140,6 +1157,7 @@ one_child_status(const struct walk_statu
                  const char *dir_repos_root_url,
                  const char *dir_repos_relpath,
                  const char *dir_repos_uuid,
+                 svn_boolean_t dir_has_props,
                  svn_boolean_t unversioned_tree_conflicted,
                  apr_array_header_t **collected_ignore_patterns,
                  const apr_array_header_t *ignore_patterns,
@@ -1227,6 +1245,7 @@ one_child_status(const struct walk_statu
   if (ignore_patterns && ! *collected_ignore_patterns)
     SVN_ERR(collect_ignore_patterns(collected_ignore_patterns, wb->db,
                                     parent_abspath, ignore_patterns,
+                                    dir_has_props,
                                     result_pool, scratch_pool));
 
   SVN_ERR(send_unversioned_item(wb,
@@ -1280,14 +1299,16 @@ get_dir_status(const struct walk_status_
                void *cancel_baton,
                apr_pool_t *scratch_pool)
 {
-  apr_hash_index_t *hi;
   const char *dir_repos_root_url;
   const char *dir_repos_relpath;
   const char *dir_repos_uuid;
+  svn_boolean_t dir_has_props;
   apr_hash_t *dirents, *nodes, *conflicts, *all_children;
+  apr_array_header_t *sorted_children;
   apr_array_header_t *collected_ignore_patterns = NULL;
   apr_pool_t *iterpool, *subpool = svn_pool_create(scratch_pool);
   svn_error_t *err;
+  int i;
 
   if (cancel_func)
     SVN_ERR(cancel_func(cancel_baton));
@@ -1368,21 +1389,28 @@ get_dir_status(const struct walk_status_
   if (depth == svn_depth_empty)
     return SVN_NO_ERROR;
 
+  dir_has_props = (dir_info->had_props || dir_info->props_mod);
+
   /* Walk all the children of this directory. */
-  for (hi = apr_hash_first(subpool, all_children); hi; hi = apr_hash_next(hi))
+  sorted_children = svn_sort__hash(all_children,
+                                   svn_sort_compare_items_lexically,
+                                   subpool);
+  for (i = 0; i < sorted_children->nelts; i++)
     {
       const void *key;
       apr_ssize_t klen;
+      svn_sort__item_t item;
       const char *child_abspath;
       svn_io_dirent2_t *child_dirent;
       const struct svn_wc__db_info_t *child_info;
 
       svn_pool_clear(iterpool);
 
-      apr_hash_this(hi, &key, &klen, NULL);
+      item = APR_ARRAY_IDX(sorted_children, i, svn_sort__item_t);
+      key = item.key;
+      klen = item.klen;
 
       child_abspath = svn_dirent_join(local_abspath, key, iterpool);
-
       child_dirent = apr_hash_get(dirents, key, klen);
       child_info = apr_hash_get(nodes, key, klen);
 
@@ -1394,6 +1422,7 @@ get_dir_status(const struct walk_status_
                                dir_repos_root_url,
                                dir_repos_relpath,
                                dir_repos_uuid,
+                               dir_has_props,
                                apr_hash_get(conflicts, key, klen) != NULL,
                                &collected_ignore_patterns,
                                ignore_patterns,
@@ -1480,6 +1509,7 @@ get_child_status(const struct walk_statu
                            dir_repos_root_url,
                            dir_repos_relpath,
                            dir_repos_uuid,
+                           (dir_info->had_props || dir_info->props_mod),
                            FALSE, /* unversioned_tree_conflicted */
                            &collected_ignore_patterns,
                            ignore_patterns,
@@ -1553,7 +1583,6 @@ tweak_statushash(void *baton,
                  svn_boolean_t is_dir_baton,
                  svn_wc__db_t *db,
                  const char *local_abspath,
-                 svn_boolean_t is_dir,
                  enum svn_wc_status_kind repos_node_status,
                  enum svn_wc_status_kind repos_text_status,
                  enum svn_wc_status_kind repos_prop_status,
@@ -1642,7 +1671,7 @@ tweak_statushash(void *baton,
          isn't available. */
       if (statstruct->repos_node_status == svn_wc_status_deleted)
         {
-          statstruct->ood_kind = is_dir ? svn_node_dir : svn_node_file;
+          statstruct->ood_kind = statstruct->kind;
 
           /* Pre 1.5 servers don't provide the revision a path was deleted.
              So we punt and use the last committed revision of the path's
@@ -2038,16 +2067,13 @@ delete_entry(const char *path,
   struct dir_baton *db = parent_baton;
   struct edit_baton *eb = db->edit_baton;
   const char *local_abspath = svn_dirent_join(eb->anchor_abspath, path, pool);
-  svn_kind_t kind;
 
   /* Note:  when something is deleted, it's okay to tweak the
      statushash immediately.  No need to wait until close_file or
      close_dir, because there's no risk of having to honor the 'added'
      flag.  We already know this item exists in the working copy. */
-
-  SVN_ERR(svn_wc__db_read_kind(&kind, eb->db, local_abspath, FALSE, pool));
   SVN_ERR(tweak_statushash(db, db, TRUE, eb->db,
-                           local_abspath, kind == svn_kind_dir,
+                           local_abspath,
                            svn_wc_status_deleted, 0, 0, revision, NULL, pool));
 
   /* Mark the parent dir -- it lost an entry (unless that parent dir
@@ -2056,7 +2082,6 @@ delete_entry(const char *path,
   if (db->parent_baton && (! *eb->target_basename))
     SVN_ERR(tweak_statushash(db->parent_baton, db, TRUE,eb->db,
                              db->local_abspath,
-                             kind == svn_kind_dir,
                              svn_wc_status_modified, svn_wc_status_modified,
                              0, SVN_INVALID_REVNUM, NULL, pool));
 
@@ -2179,7 +2204,7 @@ close_directory(void *dir_baton,
           /* ### When we add directory locking, we need to find a
              ### directory lock here. */
           SVN_ERR(tweak_statushash(pb, db, TRUE, eb->db, db->local_abspath,
-                                   TRUE, repos_node_status, repos_text_status,
+                                   repos_node_status, repos_text_status,
                                    repos_prop_status, SVN_INVALID_REVNUM, NULL,
                                    pool));
         }
@@ -2424,7 +2449,7 @@ close_file(void *file_baton,
     }
 
   return tweak_statushash(fb, NULL, FALSE, fb->edit_baton->db,
-                          fb->local_abspath, FALSE, repos_node_status,
+                          fb->local_abspath, repos_node_status,
                           repos_text_status, repos_prop_status,
                           SVN_INVALID_REVNUM, repos_lock, pool);
 }
@@ -2619,9 +2644,6 @@ svn_wc__internal_walk_status(svn_wc__db_
   wb.repos_root = NULL;
   wb.repos_locks = NULL;
 
-  SVN_ERR(svn_wc__db_externals_defined_below(&wb.externals, db, local_abspath,
-                                             scratch_pool, scratch_pool));
-
   /* Use the caller-provided ignore patterns if provided; the build-time
      configured defaults otherwise. */
   if (!ignore_patterns)
@@ -2643,7 +2665,12 @@ svn_wc__internal_walk_status(svn_wc__db_
         }
       else
         return svn_error_trace(err);
+
+      wb.externals = apr_hash_make(scratch_pool);
     }
+  else
+    SVN_ERR(svn_wc__db_externals_defined_below(&wb.externals, db, local_abspath,
+                                               scratch_pool, scratch_pool));
 
   SVN_ERR(svn_io_stat_dirent(&dirent, local_abspath, TRUE,
                              scratch_pool, scratch_pool));
@@ -2673,15 +2700,27 @@ svn_wc__internal_walk_status(svn_wc__db_
       /* It may be a file or an unversioned item. And this is an explicit
        * target, so no ignoring. An unversioned item (file or dir) shows a
        * status like '?', and can yield a tree conflicted path. */
-      SVN_ERR(get_child_status(&wb,
-                               local_abspath,
-                               info,
-                               dirent,
-                               ignore_patterns,
-                               get_all,
-                               status_func, status_baton,
-                               cancel_func, cancel_baton,
-                               scratch_pool));
+      err = get_child_status(&wb,
+                             local_abspath,
+                             info,
+                             dirent,
+                             ignore_patterns,
+                             get_all,
+                             status_func, status_baton,
+                             cancel_func, cancel_baton,
+                             scratch_pool);
+
+      if (!info && err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+        {
+          /* The parent is also not versioned, but it is not nice to show
+             an error about a path a user didn't intend to touch. */
+          svn_error_clear(err);
+          return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
+                                   _("The node '%s' was not found."),
+                                   svn_dirent_local_style(local_abspath,
+                                                          scratch_pool));
+        }
+      SVN_ERR(err);
     }
 
   return SVN_NO_ERROR;
@@ -2937,6 +2976,6 @@ svn_wc_get_ignores2(apr_array_header_t *
   SVN_ERR(svn_wc_get_default_ignores(&default_ignores, config, scratch_pool));
   return svn_error_trace(collect_ignore_patterns(patterns, wc_ctx->db,
                                                  local_abspath,
-                                                 default_ignores,
+                                                 default_ignores, TRUE,
                                                  result_pool, scratch_pool));
 }

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/tree_conflicts.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/tree_conflicts.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/tree_conflicts.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/tree_conflicts.c Tue Jun 26 19:26:49 2012
@@ -158,15 +158,18 @@ read_node_version_info(const svn_wc_conf
                             _("Invalid version info in tree conflict "
                               "description"));
 
-  repos_root = apr_pstrmemdup(result_pool,
-                                           skel->children->next->data,
-                                           skel->children->next->len);
+  repos_root = apr_pstrmemdup(scratch_pool,
+                              skel->children->next->data,
+                              skel->children->next->len);
   if (*repos_root == '\0')
     {
       *version_info = NULL;
       return SVN_NO_ERROR;
     }
 
+  /* Apply the Subversion 1.7+ url canonicalization rules to a pre 1.7 url */
+  repos_root = svn_uri_canonicalize(repos_root, result_pool);
+
   peg_rev = SVN_STR_TO_REV(apr_pstrmemdup(scratch_pool,
                                           skel->children->next->next->data,
                                           skel->children->next->next->len));

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/update_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/update_editor.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/update_editor.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/update_editor.c Tue Jun 26 19:26:49 2012
@@ -3888,7 +3888,6 @@ merge_file(svn_skel_t **work_items,
   struct dir_baton *pb = fb->dir_baton;
   svn_boolean_t is_locally_modified;
   enum svn_wc_merge_outcome_t merge_outcome = svn_wc_merge_unchanged;
-  svn_skel_t *work_item;
   const char *working_abspath = fb->moved_to_abspath ? fb->moved_to_abspath
                                                      : fb->local_abspath;
 
@@ -4059,26 +4058,6 @@ merge_file(svn_skel_t **work_items,
         }
     }
 
-  /* Installing from a pristine will handle timestamps and recording.
-     However, if we are NOT creating a new working copy file, then create
-     work items to handle the recording of the timestamp and working-size. */
-  if (!*install_pristine
-      && !is_locally_modified)
-    {
-      apr_time_t set_date = 0;
-
-      if (eb->use_commit_times && last_changed_date != 0)
-        {
-          set_date = last_changed_date;
-        }
-
-      SVN_ERR(svn_wc__wq_build_record_fileinfo(&work_item,
-                                               eb->db, working_abspath,
-                                               set_date,
-                                               result_pool, scratch_pool));
-      *work_items = svn_wc__wq_merge(*work_items, work_item, result_pool);
-    }
-
   /* Set the returned content state. */
 
   /* This is kind of interesting.  Even if no new text was

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/upgrade.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/upgrade.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/upgrade.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/upgrade.c Tue Jun 26 19:26:49 2012
@@ -792,7 +792,7 @@ migrate_tree_conflict_data(svn_sqlite__d
      all of them into the new schema.  */
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
-                                    STMT_SELECT_OLD_TREE_CONFLICT));
+                                    STMT_UPGRADE_21_SELECT_OLD_TREE_CONFLICT));
 
   /* Get all the existing tree conflict data. */
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
@@ -819,7 +819,8 @@ migrate_tree_conflict_data(svn_sqlite__d
   SVN_ERR(svn_sqlite__reset(stmt));
 
   /* Erase all the old tree conflict data.  */
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_ERASE_OLD_CONFLICTS));
+  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
+                                    STMT_UPGRADE_21_ERASE_OLD_CONFLICTS));
   SVN_ERR(svn_sqlite__step_done(stmt));
 
   svn_pool_destroy(iterpool);
@@ -1211,7 +1212,7 @@ bump_to_27(void *baton, svn_sqlite__db_t
   svn_boolean_t have_row;
 
   SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
-                                    STMT_HAS_ACTUAL_NODES_CONFLICTS));
+                                  STMT_UPGRADE_27_HAS_ACTUAL_NODES_CONFLICTS));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
   SVN_ERR(svn_sqlite__reset(stmt));
   if (have_row)
@@ -1544,7 +1545,9 @@ svn_wc__upgrade_sdb(int *result_format,
                     int start_format,
                     apr_pool_t *scratch_pool)
 {
-  struct bump_baton bb = { wcroot_abspath };
+  struct bump_baton bb;
+
+  bb.wcroot_abspath = wcroot_abspath;
 
   if (start_format < SVN_WC__WC_NG_VERSION /* 12 */)
     return svn_error_createf(SVN_ERR_WC_UPGRADE_REQUIRED, NULL,

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/util.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/util.c?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/util.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/util.c Tue Jun 26 19:26:49 2012
@@ -546,7 +546,9 @@ svn_wc__fetch_kind_func(svn_kind_t *kind
   const char *local_abspath = svn_dirent_join(sfb->base_abspath, path,
                                               scratch_pool);
 
-  SVN_ERR(svn_wc__db_read_kind(kind, sfb->db, local_abspath, FALSE,
+  SVN_ERR(svn_wc__db_read_kind(kind, sfb->db, local_abspath,
+                               FALSE /* allow_missing */,
+                               FALSE /* show_hidden */,
                                scratch_pool));
 
   return SVN_NO_ERROR;

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/wc-metadata.sql
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/wc-metadata.sql?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/wc-metadata.sql (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/wc-metadata.sql Tue Jun 26 19:26:49 2012
@@ -169,7 +169,10 @@ CREATE TABLE ACTUAL_NODE (
   /* stsp: This is meant for text conflicts, right? What about property
            conflicts? Why do we need these in a column to refer to the
            pristine store? Can't we just parse the checksums from
-           conflict_data as well? */
+           conflict_data as well? 
+     rhuijben: Because that won't allow triggers to handle refcounts.
+               We would have to scan all conflict skels before cleaning up the
+               a single file from the pristine stor */
   older_checksum  TEXT REFERENCES PRISTINE (checksum),
   left_checksum  TEXT REFERENCES PRISTINE (checksum),
   right_checksum  TEXT REFERENCES PRISTINE (checksum),
@@ -462,24 +465,22 @@ CREATE TABLE NODES (
      node does not have any dav-cache. */
   dav_cache  BLOB,
 
-  /* The serialized file external information. */
-  /* ### hack.  hack.  hack.
-     ### This information is already stored in properties, but because the
-     ### current working copy implementation is such a pain, we can't
-     ### readily retrieve it, hence this temporary cache column.
-     ### When it is removed, be sure to remove the extra column from
-     ### the db-tests.
-
-     ### Note: This is only here as a hack, and should *NOT* be added
-     ### to any wc_db APIs.  */
-  file_external  TEXT,
-
+  /* Is there a file external in this location. NULL if there
+     is no file external, otherwise '1'  */
+  /* ### Originally we had a wc-1.0 like skel in this place, so we
+     ### check for NULL.
+     ### In Subversion 1.7 we defined this column as TEXT, but Sqlite
+     ### only uses this information for deciding how to optimize
+     ### anyway. */
+  file_external  INTEGER,
 
   PRIMARY KEY (wc_id, local_relpath, op_depth)
 
   );
 
 CREATE INDEX I_NODES_PARENT ON NODES (wc_id, parent_relpath, op_depth);
+/* I_NODES_MOVED is introduced in format 30 */
+CREATE UNIQUE INDEX I_NODES_MOVED ON NODES (wc_id, moved_to, op_depth);
 
 /* Many queries have to filter the nodes table to pick only that version
    of each node with the highest (most "current") op_depth.  This view
@@ -497,7 +498,7 @@ CREATE VIEW NODES_CURRENT AS
                         AND n2.local_relpath = n.local_relpath);
 
 /* Many queries have to filter the nodes table to pick only that version
-   of each node with the base (least "current") op_depth.  This view
+   of each node with the BASE ("as checked out") op_depth.  This view
    does the heavy lifting for such queries. */
 CREATE VIEW NODES_BASE AS
   SELECT * FROM nodes
@@ -666,6 +667,15 @@ PRAGMA user_version = 20;
 -- STMT_UPGRADE_TO_21
 PRAGMA user_version = 21;
 
+/* For format 21 bump code */
+-- STMT_UPGRADE_21_SELECT_OLD_TREE_CONFLICT
+SELECT wc_id, local_relpath, tree_conflict_data
+FROM actual_node
+WHERE tree_conflict_data IS NOT NULL
+
+/* For format 21 bump code */
+-- STMT_UPGRADE_21_ERASE_OLD_CONFLICTS
+UPDATE actual_node SET tree_conflict_data = NULL
 
 /* ------------------------------------------------------------------------- */
 
@@ -736,6 +746,15 @@ PRAGMA user_version = 26;
 -- STMT_UPGRADE_TO_27
 PRAGMA user_version = 27;
 
+/* For format 27 bump code */
+-- STMT_UPGRADE_27_HAS_ACTUAL_NODES_CONFLICTS
+SELECT 1 FROM actual_node
+WHERE NOT ((prop_reject IS NULL) AND (conflict_old IS NULL)
+           AND (conflict_new IS NULL) AND (conflict_working IS NULL)
+           AND (tree_conflict_data IS NULL))
+LIMIT 1
+
+
 /* ------------------------------------------------------------------------- */
 
 /* Format 28 involves no schema changes, it only converts MD5 pristine 
@@ -791,6 +810,18 @@ PRAGMA user_version = 29;
 
 /* ------------------------------------------------------------------------- */
 
+/* Format 30 currently just contains some nice to haves that should be included
+   with the next format bump  */
+-- STMT_UPGRADE_TO_30
+CREATE UNIQUE INDEX IF NOT EXISTS I_NODES_MOVED
+ON NODES (wc_id, moved_to, op_depth);
+
+/* Just to be sure clear out file external skels from pre 1.7.0 development
+   working copies that were never updated by 1.7.0+ style clients */
+UPDATE nodes SET file_external=1 WHERE file_external IS NOT NULL;
+
+/* ------------------------------------------------------------------------- */
+
 /* Format YYY introduces new handling for conflict information.  */
 -- format: YYY
 
@@ -803,9 +834,9 @@ PRAGMA user_version = 29;
    number will be, however, so we're just marking it as 99 for now.  */
 -- format: 99
 
-/* TODO: Rename the "absent" presence value to "server-excluded" before
-   the 1.7 release. wc_db.c and this file have references to "absent" which
-   still need to be changed to "server-excluded". */
+/* TODO: Rename the "absent" presence value to "server-excluded". wc_db.c
+   and this file have references to "absent" which still need to be changed
+   to "server-excluded". */
 /* TODO: Un-confuse *_revision column names in the EXTERNALS table to
    "-r<operative> foo@<peg>", as suggested by the patch attached to
    http://svn.haxx.se/dev/archive-2011-09/0478.shtml */

Modified: subversion/branches/inheritable-props/subversion/libsvn_wc/wc-queries.sql
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_wc/wc-queries.sql?rev=1354186&r1=1354185&r2=1354186&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_wc/wc-queries.sql (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_wc/wc-queries.sql Tue Jun 26 19:26:49 2012
@@ -51,14 +51,14 @@ ORDER BY op_depth DESC
 -- STMT_SELECT_BASE_NODE
 SELECT repos_id, repos_path, presence, kind, revision, checksum,
   translated_size, changed_revision, changed_date, changed_author, depth,
-  symlink_target, last_mod_time, properties, file_external IS NOT NULL
+  symlink_target, last_mod_time, properties, file_external
 FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
 
 -- STMT_SELECT_BASE_NODE_WITH_LOCK
 SELECT nodes.repos_id, nodes.repos_path, presence, kind, revision,
   checksum, translated_size, changed_revision, changed_date, changed_author,
-  depth, symlink_target, last_mod_time, properties, file_external IS NOT NULL,
+  depth, symlink_target, last_mod_time, properties, file_external,
   /* All the columns until now must match those returned by
      STMT_SELECT_BASE_NODE. The implementation of svn_wc__db_base_get_info()
      assumes that these columns are followed by the lock information) */
@@ -70,7 +70,7 @@ WHERE wc_id = ?1 AND local_relpath = ?2 
 
 -- STMT_SELECT_BASE_CHILDREN_INFO
 SELECT local_relpath, nodes.repos_id, nodes.repos_path, presence, kind,
-  revision, depth, file_external IS NOT NULL,
+  revision, depth, file_external,
   lock_token, lock_owner, lock_comment, lock_date
 FROM nodes
 LEFT OUTER JOIN lock ON nodes.repos_id = lock.repos_id
@@ -125,11 +125,10 @@ WHERE wc_id = ?1 AND local_relpath = ?2 
 SELECT op_depth, nodes.repos_id, nodes.repos_path, presence, kind, revision,
   checksum, translated_size, changed_revision, changed_date, changed_author,
   depth, symlink_target, last_mod_time, properties, lock_token, lock_owner,
-  lock_comment, lock_date, local_relpath, moved_here, moved_to, 
-  file_external IS NOT NULL
+  lock_comment, lock_date, local_relpath, moved_here, moved_to, file_external
 FROM nodes
 LEFT OUTER JOIN lock ON nodes.repos_id = lock.repos_id
-  AND nodes.repos_path = lock.repos_relpath
+  AND nodes.repos_path = lock.repos_relpath AND op_depth = 0
 WHERE wc_id = ?1 AND parent_relpath = ?2
 
 -- STMT_SELECT_NODE_CHILDREN_WALKER_INFO
@@ -174,23 +173,23 @@ WHERE wc_id = ?1 AND parent_relpath = ?2
 SELECT 1 FROM nodes
 WHERE wc_id = ?1 AND parent_relpath = ?2
   AND (op_depth > ?3 OR (op_depth = ?3 AND presence != 'base-deleted'))
-UNION
+UNION ALL
 SELECT 1 FROM ACTUAL_NODE
 WHERE wc_id = ?1 AND parent_relpath = ?2
 
+/* Delete the nodes shadowed by local_relpath. Not valid for the wc-root */
 -- STMT_DELETE_SHADOWED_RECURSIVE
 DELETE FROM nodes
 WHERE wc_id = ?1
-  AND (local_relpath = ?2
-       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
+  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
   AND (op_depth < ?3
        OR (op_depth = ?3 AND presence = 'base-deleted'))
 
+/* Get not-present descendants of a copied node. Not valid for the wc-root */
 -- STMT_SELECT_NOT_PRESENT_DESCENDANTS
 SELECT local_relpath FROM nodes
 WHERE wc_id = ?1 AND op_depth = ?3
-  AND (parent_relpath = ?2
-       OR IS_STRICT_DESCENDANT_OF(parent_relpath, ?2))
+  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
   AND presence == 'not-present'
 
 -- STMT_COMMIT_DESCENDANT_TO_BASE
@@ -259,15 +258,14 @@ INSERT OR REPLACE INTO lock
  lock_date)
 VALUES (?1, ?2, ?3, ?4, ?5, ?6)
 
+/* Not valid for the working copy root */
 -- STMT_SELECT_BASE_NODE_LOCK_TOKENS_RECURSIVE
 SELECT nodes.repos_id, nodes.repos_path, lock_token
 FROM nodes
 LEFT JOIN lock ON nodes.repos_id = lock.repos_id
   AND nodes.repos_path = lock.repos_relpath
 WHERE wc_id = ?1 AND op_depth = 0
-  AND (?2 = ''
-       OR local_relpath = ?2
-       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
+  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
 
 -- STMT_INSERT_WCROOT
 INSERT INTO wcroot (local_abspath)
@@ -281,34 +279,46 @@ WHERE wc_id = ?1 AND local_relpath = ?2 
 SELECT dav_cache FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
 
+-- STMT_SELECT_DELETION_INFO
+SELECT (SELECT b.presence FROM nodes AS b
+         WHERE b.wc_id = ?1 AND b.local_relpath = ?2 AND b.op_depth = 0),
+       work.presence, work.op_depth
+FROM nodes_current AS work
+WHERE work.wc_id = ?1 AND work.local_relpath = ?2 AND work.op_depth > 0
+LIMIT 1
+
+-- STMT_SELECT_DELETION_INFO_SCAN
 /* ### FIXME.  modes_move.moved_to IS NOT NULL works when there is
  only one move but we need something else when there are several. */
--- STMT_SELECT_DELETION_INFO
-SELECT nodes_base.presence, nodes_work.presence, nodes_move.moved_to,
-       nodes_work.op_depth
-FROM nodes AS nodes_work
-LEFT OUTER JOIN nodes nodes_move ON nodes_move.wc_id = nodes_work.wc_id
-  AND nodes_move.local_relpath = nodes_work.local_relpath
-  AND nodes_move.moved_to IS NOT NULL
-LEFT OUTER JOIN nodes nodes_base ON nodes_base.wc_id = nodes_work.wc_id
- AND nodes_base.local_relpath = nodes_work.local_relpath
- AND nodes_base.op_depth = 0
-WHERE nodes_work.wc_id = ?1 AND nodes_work.local_relpath = ?2
-  AND nodes_work.op_depth = (SELECT MAX(op_depth) FROM nodes
-                             WHERE wc_id = ?1 AND local_relpath = ?2
-                                              AND op_depth > 0)
+SELECT (SELECT b.presence FROM nodes AS b
+         WHERE b.wc_id = ?1 AND b.local_relpath = ?2 AND b.op_depth = 0),
+       work.presence, work.op_depth, moved.moved_to
+FROM nodes_current AS work
+LEFT OUTER JOIN nodes AS moved 
+  ON moved.wc_id = work.wc_id
+ AND moved.local_relpath = work.local_relpath
+ AND moved.moved_to IS NOT NULL
+WHERE work.wc_id = ?1 AND work.local_relpath = ?2 AND work.op_depth > 0
+LIMIT 1
 
 -- STMT_SELECT_OP_DEPTH_MOVED_TO
-SELECT op_depth, moved_to
+SELECT op_depth, moved_to, repos_path, revision
 FROM nodes
-WHERE nodes.wc_id = ?1 AND nodes.local_relpath = ?2
- AND op_depth = (SELECT MIN(op_depth) FROM nodes
+WHERE wc_id = ?1 AND local_relpath = ?2
+ AND op_depth <= (SELECT MIN(op_depth) FROM nodes
                   WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth > ?3)
+ORDER BY op_depth DESC
 
 -- STMT_SELECT_MOVED_TO
 SELECT moved_to
 FROM nodes
-WHERE nodes.wc_id = ?1 AND nodes.local_relpath = ?2 AND op_depth = ?3
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3
+
+-- STMT_SELECT_MOVED_HERE
+SELECT moved_here, presence, repos_path, revision
+FROM nodes
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth >= ?3
+ORDER BY op_depth
                   
 -- STMT_DELETE_LOCK
 DELETE FROM lock
@@ -317,17 +327,20 @@ WHERE repos_id = ?1 AND repos_relpath = 
 -- STMT_CLEAR_BASE_NODE_RECURSIVE_DAV_CACHE
 UPDATE nodes SET dav_cache = NULL
 WHERE dav_cache IS NOT NULL AND wc_id = ?1 AND op_depth = 0
-  AND (?2 = ''
-       OR local_relpath = ?2
+  AND (local_relpath = ?2
        OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
 
 -- STMT_RECURSIVE_UPDATE_NODE_REPO
 UPDATE nodes SET repos_id = ?4, dav_cache = NULL
-WHERE wc_id = ?1
-  AND repos_id = ?3
-  AND (?2 = ''
-       OR local_relpath = ?2
-       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
+/* ### The Sqlite optimizer needs help here ###
+ * WHERE wc_id = ?1
+ *   AND repos_id = ?3
+ *   AND (local_relpath = ?2
+ *        OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))*/
+WHERE (wc_id = ?1 AND local_relpath = ?2 AND repos_id = ?3)
+   OR (wc_id = ?1 AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
+       AND repos_id = ?3)
+ 
 
 -- STMT_UPDATE_LOCK_REPOS_ID
 UPDATE lock SET repos_id = ?2
@@ -339,6 +352,10 @@ WHERE wc_id = ?1 AND local_relpath = ?2
   AND op_depth = (SELECT MAX(op_depth) FROM nodes
                   WHERE wc_id = ?1 AND local_relpath = ?2)
 
+-- STMT_UPDATE_NODE_FILEINFO_OPDEPTH
+UPDATE nodes SET translated_size = ?3, last_mod_time = ?4
+WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?5
+
 -- STMT_UPDATE_ACTUAL_TREE_CONFLICTS
 UPDATE actual_node SET tree_conflict_data = ?3
 WHERE wc_id = ?1 AND local_relpath = ?2
@@ -369,9 +386,13 @@ INSERT INTO actual_node (
 VALUES (?1, ?2, ?3, ?4)
 
 -- STMT_UPDATE_ACTUAL_CHANGELISTS
-UPDATE actual_node SET changelist = ?2
-WHERE wc_id = ?1 AND local_relpath IN
-(SELECT local_relpath FROM targets_list WHERE kind = 'file' AND wc_id = ?1)
+UPDATE actual_node SET changelist = ?3
+WHERE wc_id = ?1
+  AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
+  AND local_relpath = (SELECT local_relpath FROM targets_list AS t
+                       WHERE wc_id = ?1
+                         AND t.local_relpath = actual_node.local_relpath
+                         AND kind = 'file')
 
 -- STMT_UPDATE_ACTUAL_CLEAR_CHANGELIST
 UPDATE actual_node SET changelist = NULL
@@ -380,7 +401,11 @@ UPDATE actual_node SET changelist = NULL
 -- STMT_MARK_SKIPPED_CHANGELIST_DIRS
 /* 7 corresponds to svn_wc_notify_skip */
 INSERT INTO changelist_list (wc_id, local_relpath, notify, changelist)
-SELECT wc_id, local_relpath, 7, ?1 FROM targets_list WHERE kind = 'dir'
+SELECT wc_id, local_relpath, 7, ?3
+FROM targets_list
+WHERE wc_id = ?1
+  AND (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
+  AND kind = 'dir'
 
 -- STMT_RESET_ACTUAL_WITH_CHANGELIST
 REPLACE INTO actual_node (
@@ -392,53 +417,31 @@ DROP TABLE IF EXISTS changelist_list;
 CREATE TEMPORARY TABLE changelist_list (
   wc_id  INTEGER NOT NULL,
   local_relpath TEXT NOT NULL,
-  notify INTEGER,
-  changelist TEXT NOT NULL
-  );
-CREATE INDEX changelist_list_index ON changelist_list(wc_id, local_relpath);
-/* We have four cases upon which we wish to notify.  The first is easy:
-
-        Action                                  Notification
-        ------                                  ------------
-        INSERT ACTUAL                           cl-set
-
-   The others are a bit more complex:
-        Action          Old CL      New CL      Notification
-        ------          ------      ------      ------------
-        UPDATE ACTUAL   NULL        NOT NULL    cl-set
-        UPDATE ACTUAL   NOT NULL    NOT NULL    cl-set
-        UPDATE ACTUAL   NOT NULL    NULL        cl-clear
-
-Of the following triggers, the first address the first case, and the second
-two address the last three cases.
+  notify INTEGER NOT NULL,
+  changelist TEXT NOT NULL,
+  /* Order NOTIFY descending to make us show clears (27) before adds (26) */
+  PRIMARY KEY (wc_id, local_relpath, notify DESC)
+)
+
+/* Create notify items for when a node is removed from a changelist and
+   when a node is added to a changelist. Make sure nothing is notified
+   if there were no changes.
 */
-DROP TRIGGER IF EXISTS   trigger_changelist_list_actual_cl_insert;
-CREATE TEMPORARY TRIGGER trigger_changelist_list_actual_cl_insert
-BEFORE INSERT ON actual_node
-BEGIN
-    /* 26 corresponds to svn_wc_notify_changelist_set */
-    INSERT INTO changelist_list(wc_id, local_relpath, notify, changelist)
-    VALUES (NEW.wc_id, NEW.local_relpath, 26, NEW.changelist);
-END;
-DROP TRIGGER IF EXISTS   trigger_changelist_list_actual_cl_clear;
-CREATE TEMPORARY TRIGGER trigger_changelist_list_actual_cl_clear
+-- STMT_CREATE_CHANGELIST_TRIGGER
+DROP TRIGGER IF EXISTS   trigger_changelist_list_change;
+CREATE TEMPORARY TRIGGER trigger_changelist_list_change
 BEFORE UPDATE ON actual_node
-WHEN OLD.changelist IS NOT NULL AND
-        (OLD.changelist != NEW.changelist OR NEW.changelist IS NULL)
+WHEN old.changelist IS NOT new.changelist
 BEGIN
-    /* 27 corresponds to svn_wc_notify_changelist_clear */
-    INSERT INTO changelist_list(wc_id, local_relpath, notify, changelist)
-    VALUES (OLD.wc_id, OLD.local_relpath, 27, OLD.changelist);
-END;
-DROP TRIGGER IF EXISTS   trigger_changelist_list_actual_cl_set;
-CREATE TEMPORARY TRIGGER trigger_changelist_list_actual_cl_set
-BEFORE UPDATE ON actual_node
-WHEN NEW.CHANGELIST IS NOT NULL AND
-        (OLD.changelist != NEW.changelist OR OLD.changelist IS NULL)
-BEGIN
-    /* 26 corresponds to svn_wc_notify_changelist_set */
-    INSERT INTO changelist_list(wc_id, local_relpath, notify, changelist)
-    VALUES (NEW.wc_id, NEW.local_relpath, 26, NEW.changelist);
+  /* 27 corresponds to svn_wc_notify_changelist_clear */
+  INSERT INTO changelist_list(wc_id, local_relpath, notify, changelist)
+  SELECT old.wc_id, old.local_relpath, 27, old.changelist
+   WHERE old.changelist is NOT NULL;
+
+  /* 26 corresponds to svn_wc_notify_changelist_set */
+  INSERT INTO changelist_list(wc_id, local_relpath, notify, changelist)
+  SELECT new.wc_id, new.local_relpath, 26, new.changelist
+   WHERE new.changelist IS NOT NULL;
 END
 
 -- STMT_INSERT_CHANGELIST_LIST
@@ -455,7 +458,7 @@ DROP TABLE IF EXISTS targets_list
 -- STMT_SELECT_CHANGELIST_LIST
 SELECT wc_id, local_relpath, notify, changelist
 FROM changelist_list
-ORDER BY wc_id, local_relpath
+ORDER BY wc_id, local_relpath ASC, notify DESC
 
 -- STMT_CREATE_TARGETS_LIST
 DROP TABLE IF EXISTS targets_list;
@@ -463,10 +466,9 @@ CREATE TEMPORARY TABLE targets_list (
   wc_id  INTEGER NOT NULL,
   local_relpath TEXT NOT NULL,
   parent_relpath TEXT,
-  kind TEXT NOT NULL
+  kind TEXT NOT NULL,
+  PRIMARY KEY (wc_id, local_relpath)
   );
-CREATE INDEX targets_list_kind
-  ON targets_list (kind)
 /* need more indicies? */
 
 -- STMT_DROP_TARGETS_LIST
@@ -475,52 +477,59 @@ DROP TABLE IF EXISTS targets_list
 -- STMT_INSERT_TARGET
 INSERT INTO targets_list(wc_id, local_relpath, parent_relpath, kind)
 SELECT wc_id, local_relpath, parent_relpath, kind
-FROM nodes_current WHERE wc_id = ?1 AND local_relpath = ?2
+FROM nodes_current
+WHERE wc_id = ?1
+  AND local_relpath = ?2
 
 -- STMT_INSERT_TARGET_DEPTH_FILES
 INSERT INTO targets_list(wc_id, local_relpath, parent_relpath, kind)
 SELECT wc_id, local_relpath, parent_relpath, kind
 FROM nodes_current
-WHERE wc_id = ?1 AND ((parent_relpath = ?2 AND kind = 'file')
-                      OR local_relpath = ?2)
+WHERE wc_id = ?1
+  AND parent_relpath = ?2
+  AND kind = 'file'
 
 -- STMT_INSERT_TARGET_DEPTH_IMMEDIATES
 INSERT INTO targets_list(wc_id, local_relpath, parent_relpath, kind)
 SELECT wc_id, local_relpath, parent_relpath, kind
 FROM nodes_current
-WHERE wc_id = ?1 AND (parent_relpath = ?2 OR local_relpath = ?2)
+WHERE wc_id = ?1
+  AND parent_relpath = ?2
 
 -- STMT_INSERT_TARGET_DEPTH_INFINITY
 INSERT INTO targets_list(wc_id, local_relpath, parent_relpath, kind)
 SELECT wc_id, local_relpath, parent_relpath, kind
 FROM nodes_current
 WHERE wc_id = ?1
-       AND (?2 = ''
-            OR local_relpath = ?2 
-            OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
+  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
 
 -- STMT_INSERT_TARGET_WITH_CHANGELIST
 INSERT INTO targets_list(wc_id, local_relpath, parent_relpath, kind)
 SELECT N.wc_id, N.local_relpath, N.parent_relpath, N.kind
   FROM actual_node AS A JOIN nodes_current AS N
     ON A.wc_id = N.wc_id AND A.local_relpath = N.local_relpath
- WHERE N.wc_id = ?1 AND A.changelist = ?3 AND N.local_relpath = ?2
+ WHERE N.wc_id = ?1
+   AND N.local_relpath = ?2
+   AND A.changelist = ?3
 
 -- STMT_INSERT_TARGET_WITH_CHANGELIST_DEPTH_FILES
 INSERT INTO targets_list(wc_id, local_relpath, parent_relpath, kind)
 SELECT N.wc_id, N.local_relpath, N.parent_relpath, N.kind
   FROM actual_node AS A JOIN nodes_current AS N
     ON A.wc_id = N.wc_id AND A.local_relpath = N.local_relpath
- WHERE N.wc_id = ?1 AND A.changelist = ?3
-       AND ((N.parent_relpath = ?2 AND kind = 'file') OR N.local_relpath = ?2)
+ WHERE N.wc_id = ?1
+   AND N.parent_relpath = ?2
+   AND kind = 'file'
+   AND A.changelist = ?3
 
 -- STMT_INSERT_TARGET_WITH_CHANGELIST_DEPTH_IMMEDIATES
 INSERT INTO targets_list(wc_id, local_relpath, parent_relpath, kind)
 SELECT N.wc_id, N.local_relpath, N.parent_relpath, N.kind
   FROM actual_node AS A JOIN nodes_current AS N
     ON A.wc_id = N.wc_id AND A.local_relpath = N.local_relpath
- WHERE N.wc_id = ?1 AND A.changelist = ?3
-       AND (N.parent_relpath = ?2 OR N.local_relpath = ?2)
+ WHERE N.wc_id = ?1
+   AND N.parent_relpath = ?2
+  AND A.changelist = ?3
 
 -- STMT_INSERT_TARGET_WITH_CHANGELIST_DEPTH_INFINITY
 INSERT INTO targets_list(wc_id, local_relpath, parent_relpath, kind)
@@ -528,13 +537,12 @@ SELECT N.wc_id, N.local_relpath, N.paren
   FROM actual_node AS A JOIN nodes_current AS N
     ON A.wc_id = N.wc_id AND A.local_relpath = N.local_relpath
  WHERE N.wc_id = ?1
-       AND (?2 = ''
-            OR N.local_relpath = ?2 
-            OR IS_STRICT_DESCENDANT_OF(N.local_relpath, ?2))
-       AND A.changelist = ?3
+   AND IS_STRICT_DESCENDANT_OF(N.local_relpath, ?2)
+   AND A.changelist = ?3
 
--- STMT_SELECT_TARGETS
-SELECT local_relpath, parent_relpath from targets_list
+/* Only used by commented dump_targets() in wc_db.c */
+/*-- STMT_SELECT_TARGETS
+SELECT local_relpath, parent_relpath from targets_list*/
 
 -- STMT_INSERT_ACTUAL_EMPTIES
 INSERT OR IGNORE INTO actual_node (
@@ -562,6 +570,7 @@ WHERE wc_id = ?1 AND local_relpath = ?2
 -- STMT_DELETE_ACTUAL_EMPTIES
 DELETE FROM actual_node
 WHERE wc_id = ?1
+  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
   AND properties IS NULL
   AND conflict_old IS NULL
   AND conflict_new IS NULL
@@ -594,11 +603,10 @@ WHERE wc_id = ?1 AND local_relpath = ?2
 DELETE FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2
 
--- STMT_DELETE_NODES_RECURSIVE
+-- STMT_DELETE_NODES_ABOVE_DEPTH_RECURSIVE
 DELETE FROM nodes
 WHERE wc_id = ?1
-  AND (?2 = ''
-       OR local_relpath = ?2
+  AND (local_relpath = ?2
        OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND op_depth >= ?3
 
@@ -606,11 +614,11 @@ WHERE wc_id = ?1
 DELETE FROM actual_node
 WHERE wc_id = ?1 AND local_relpath = ?2
 
+/* Will not delete recursive when run on the wcroot */
 -- STMT_DELETE_ACTUAL_NODE_RECURSIVE
 DELETE FROM actual_node
 WHERE wc_id = ?1
-  AND (?2 = ''
-       OR local_relpath = ?2
+  AND (local_relpath = ?2
        OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
 
 -- STMT_DELETE_ACTUAL_NODE_WITHOUT_CONFLICT
@@ -630,8 +638,7 @@ WHERE wc_id = ?1
 -- STMT_DELETE_ACTUAL_NODE_LEAVING_CHANGELIST_RECURSIVE
 DELETE FROM actual_node
 WHERE wc_id = ?1
-  AND (?2 = ''
-       OR local_relpath = ?2
+  AND (local_relpath = ?2
        OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND (changelist IS NULL
        OR NOT EXISTS (SELECT 1 FROM nodes_current c
@@ -666,8 +673,7 @@ SET properties = NULL,
     left_checksum = NULL,
     right_checksum = NULL
 WHERE wc_id = ?1
-  AND (?2 = ''
-       OR local_relpath = ?2
+  AND (local_relpath = ?2
        OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
 
 -- STMT_UPDATE_NODE_BASE_DEPTH
@@ -735,10 +741,17 @@ WHERE wc_id = ?1 AND parent_relpath = ?2
        AND (conflict_new IS NULL) AND (conflict_working IS NULL)
        AND (tree_conflict_data IS NULL))
 
--- STMT_SELECT_CONFLICT_MARKER_FILES
-SELECT prop_reject, conflict_old, conflict_new, conflict_working
+-- STMT_SELECT_CONFLICT_MARKER_FILES1
+SELECT prop_reject
 FROM actual_node
-WHERE wc_id = ?1 AND (local_relpath = ?2 OR parent_relpath = ?2)
+WHERE wc_id = ?1 AND local_relpath = ?2
+  AND ((prop_reject IS NOT NULL) OR (conflict_old IS NOT NULL)
+       OR (conflict_new IS NOT NULL) OR (conflict_working IS NOT NULL))
+
+-- STMT_SELECT_CONFLICT_MARKER_FILES2
+SELECT prop_reject
+FROM actual_node
+WHERE wc_id = ?1 AND parent_relpath = ?2
   AND ((prop_reject IS NOT NULL) OR (conflict_old IS NOT NULL)
        OR (conflict_new IS NOT NULL) OR (conflict_working IS NOT NULL))
 
@@ -776,9 +789,8 @@ WHERE wc_id = ?1 AND local_dir_relpath =
 -- STMT_SELECT_ANCESTOR_WCLOCKS
 SELECT local_dir_relpath, locked_levels FROM wc_lock
 WHERE wc_id = ?1
-  AND ((local_dir_relpath <= ?2 AND local_dir_relpath >= ?3)
+  AND ((local_dir_relpath >= ?3 AND local_dir_relpath <= ?2)
        OR local_dir_relpath = '')
-ORDER BY local_dir_relpath DESC
 
 -- STMT_DELETE_WC_LOCK
 DELETE FROM wc_lock
@@ -786,7 +798,8 @@ WHERE wc_id = ?1 AND local_dir_relpath =
 
 -- STMT_FIND_WC_LOCK
 SELECT local_dir_relpath FROM wc_lock
-WHERE wc_id = ?1 AND local_dir_relpath LIKE ?2 ESCAPE '#'
+WHERE wc_id = ?1
+  AND IS_STRICT_DESCENDANT_OF(local_dir_relpath, ?2)
 
 -- STMT_DELETE_WC_LOCK_ORPHAN
 DELETE FROM wc_lock
@@ -798,8 +811,7 @@ AND NOT EXISTS (SELECT 1 FROM nodes
 -- STMT_DELETE_WC_LOCK_ORPHAN_RECURSIVE
 DELETE FROM wc_lock
 WHERE wc_id = ?1
-  AND (?2 = ''
-       OR local_dir_relpath = ?2
+  AND (local_dir_relpath = ?2
        OR IS_STRICT_DESCENDANT_OF(local_dir_relpath, ?2))
   AND NOT EXISTS (SELECT 1 FROM nodes
                    WHERE nodes.wc_id = ?1
@@ -864,78 +876,66 @@ SELECT wc_id, local_relpath, ?3 /*op_dep
 FROM nodes
 WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0
 
+/* Not valid on the wc-root */
 -- STMT_UPDATE_OP_DEPTH_INCREASE_RECURSIVE
 UPDATE nodes SET op_depth = ?3 + 1
 WHERE wc_id = ?1
-  AND (?2 = ''
-       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
+ AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
  AND op_depth = ?3
 
 -- STMT_DOES_NODE_EXIST
 SELECT 1 FROM nodes WHERE wc_id = ?1 AND local_relpath = ?2
 LIMIT 1
 
--- STMT_HAS_SERVER_EXCLUDED_NODES
+-- STMT_HAS_SERVER_EXCLUDED_DESCENDANTS
 SELECT local_relpath FROM nodes
 WHERE wc_id = ?1
-  AND (?2 = ''
-       OR local_relpath = ?2
-       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
+  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
   AND op_depth = 0 AND presence = 'absent'
 LIMIT 1
 
-/* ### Select all server-excluded nodes. */
--- STMT_SELECT_ALL_SERVER_EXCLUDED_NODES
+/* Select all excluded nodes. Not valid on the WC-root */
+-- STMT_SELECT_ALL_EXCLUDED_DESCENDANTS
 SELECT local_relpath FROM nodes
 WHERE wc_id = ?1
-  AND (?2 = ''
-       OR local_relpath = ?2
-       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
+  AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
   AND op_depth = 0
-  AND presence = 'absent'
+  AND (presence = 'absent' OR presence = 'excluded')
 
--- 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 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 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
 
@@ -989,55 +989,76 @@ LIMIT 1
  * inside an unversioned dir, because commit still breaks on those.
  * Once that's been fixed, the conditions below "--->8---" become obsolete. */
 -- STMT_SELECT_COMMITTABLE_EXTERNALS_BELOW
-SELECT local_relpath, kind, repos_id, def_repos_relpath, repository.root
-FROM externals
-LEFT OUTER JOIN repository ON repository.id = externals.repos_id
-WHERE wc_id = ?1
-  AND def_revision IS NULL
-  AND repos_id = (SELECT repos_id FROM nodes
-                  WHERE nodes.local_relpath = ?2)
-  AND ( ((NOT ?3)
-         AND (?2 = ''
-              /* Want only the cildren of e.local_relpath;
-               * externals can't have a local_relpath = ''. */
-              OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2)))
-        OR
-        ((?3)
-         AND parent_relpath = ?2) )
+SELECT local_relpath, kind, def_repos_relpath,
+       (SELECT root FROM repository AS r
+         WHERE r.id = e.repos_id)
+FROM externals AS e
+WHERE e.wc_id = ?1
+  AND IS_STRICT_DESCENDANT_OF(e.local_relpath, ?2)
+  AND e.def_revision IS NULL
+  AND e.repos_id = (SELECT repos_id
+                    FROM nodes AS n
+                    WHERE n.wc_id = ?1
+                      AND n.local_relpath = ''
+                      AND n.op_depth = 0)
+  AND ( (NOT ?3) OR (parent_relpath = ?2) )
   /* ------>8----- */
   AND (EXISTS (SELECT 1 FROM nodes
-               WHERE nodes.wc_id = externals.wc_id
-               AND nodes.local_relpath = externals.parent_relpath))
+               WHERE nodes.wc_id = e.wc_id
+               AND nodes.local_relpath = e.parent_relpath))
 
 -- STMT_SELECT_EXTERNALS_DEFINED
 SELECT local_relpath, def_local_relpath
 FROM externals
-WHERE wc_id = ?1 
-  AND (?2 = ''
-       OR def_local_relpath = ?2
-       OR IS_STRICT_DESCENDANT_OF(def_local_relpath, ?2))
-
--- STMT_UPDATE_EXTERNAL_FILEINFO
-UPDATE externals SET recorded_size = ?3, recorded_mod_time = ?4
-WHERE wc_id = ?1 AND local_relpath = ?2
+/* ### The Sqlite optimizer needs help here ###
+ * WHERE wc_id = ?1
+ *   AND (def_local_relpath = ?2
+ *        OR IS_STRICT_DESCENDANT_OF(def_local_relpath, ?2)) */
+WHERE (wc_id = ?1 AND def_local_relpath = ?2)
+   OR (wc_id = ?1 AND IS_STRICT_DESCENDANT_OF(def_local_relpath, ?2))
 
 -- STMT_DELETE_EXTERNAL
 DELETE FROM externals
 WHERE wc_id = ?1 AND local_relpath = ?2
 
 -- STMT_SELECT_EXTERNAL_PROPERTIES
+/* ### It would be nice if Sqlite would handle
+ * SELECT IFNULL((SELECT properties FROM actual_node a
+ *                WHERE a.wc_id = ?1 AND A.local_relpath = n.local_relpath),
+ *               properties),
+ *        local_relpath, depth
+ * FROM nodes_current n
+ * WHERE wc_id = ?1
+ *   AND (local_relpath = ?2
+ *        OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
+ *   AND kind = 'dir' AND presence IN ('normal', 'incomplete')
+ * ### But it would take a double table scan execution plan for it.
+ * ### Maybe there is something else going on? */
 SELECT IFNULL((SELECT properties FROM actual_node a
                WHERE a.wc_id = ?1 AND A.local_relpath = n.local_relpath),
               properties),
        local_relpath, depth
-FROM nodes n
-WHERE wc_id = ?1
-  AND (?2 = ''
-       OR local_relpath = ?2
-       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
-  AND kind = 'dir' AND presence='normal'
-  AND op_depth=(SELECT MAX(op_depth) FROM nodes o
-                WHERE o.wc_id = ?1 AND o.local_relpath = n.local_relpath)
+FROM nodes_current n
+WHERE wc_id = ?1 AND local_relpath = ?2
+  AND kind = 'dir' AND presence IN ('normal', 'incomplete')
+UNION ALL
+SELECT IFNULL((SELECT properties FROM actual_node a
+               WHERE a.wc_id = ?1 AND A.local_relpath = n.local_relpath),
+              properties),
+       local_relpath, depth
+FROM nodes_current n
+WHERE wc_id = ?1 AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2)
+  AND kind = 'dir' AND presence IN ('normal', 'incomplete')
+
+-- STMT_SELECT_CURRENT_PROPS_RECURSIVE
+/* ### Ugly OR to make sqlite use the proper optimizations */
+SELECT IFNULL((SELECT properties FROM actual_node a
+               WHERE a.wc_id = ?1 AND A.local_relpath = n.local_relpath),
+              properties),
+       local_relpath
+FROM nodes_current n
+WHERE (wc_id = ?1 AND local_relpath = ?2)
+   OR (wc_id = ?1 AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
 
 /* ------------------------------------------------------------------------- */
 
@@ -1064,16 +1085,8 @@ INSERT INTO actual_node (
   wc_id, local_relpath, conflict_data, parent_relpath)
 VALUES (?1, ?2, ?3, ?4)
 
--- STMT_SELECT_OLD_TREE_CONFLICT
-SELECT wc_id, local_relpath, tree_conflict_data
-FROM actual_node
-WHERE tree_conflict_data IS NOT NULL
-
--- STMT_ERASE_OLD_CONFLICTS
-UPDATE actual_node SET tree_conflict_data = NULL
-
 -- STMT_SELECT_ALL_FILES
-SELECT DISTINCT local_relpath FROM nodes
+SELECT local_relpath FROM nodes_current
 WHERE wc_id = ?1 AND parent_relpath = ?2 AND kind = 'file'
 
 -- STMT_UPDATE_NODE_PROPS
@@ -1084,71 +1097,61 @@ WHERE wc_id = ?1 AND local_relpath = ?2 
 SELECT 1 FROM nodes WHERE op_depth > 0
 LIMIT 1
 
--- STMT_HAS_ACTUAL_NODES_CONFLICTS
-SELECT 1 FROM actual_node
-WHERE NOT ((prop_reject IS NULL) AND (conflict_old IS NULL)
-           AND (conflict_new IS NULL) AND (conflict_working IS NULL)
-           AND (tree_conflict_data IS NULL))
-LIMIT 1
-
-/* ------------------------------------------------------------------------- */
-/* PROOF OF CONCEPT: Complex queries for callback walks, caching results
-                     in a temporary table. */
+/* --------------------------------------------------------------------------
+ * Complex queries for callback walks, caching results in a temporary table.
+ *
+ * These target table are then used for joins against NODES, or for reporting
+ */
 
--- STMT_CREATE_NODE_PROPS_CACHE
-DROP TABLE IF EXISTS temp__node_props_cache;
-CREATE TEMPORARY TABLE temp__node_props_cache (
-  local_Relpath TEXT NOT NULL,
+-- STMT_CREATE_TARGET_PROP_CACHE
+DROP TABLE IF EXISTS target_prop_cache;
+CREATE TEMPORARY TABLE target_prop_cache (
+  local_relpath TEXT NOT NULL PRIMARY KEY,
   kind TEXT NOT NULL,
   properties BLOB
-  );
+);
 /* ###  Need index?
 CREATE UNIQUE INDEX temp__node_props_cache_unique
   ON temp__node_props_cache (local_relpath) */
 
--- STMT_CACHE_NODE_PROPS
-INSERT INTO temp__node_props_cache(local_relpath, kind, properties)
- SELECT local_relpath, kind, properties FROM nodes_current
-  WHERE wc_id = ?1
-    AND local_relpath IN (SELECT local_relpath FROM targets_list)
-    AND presence IN ('normal', 'incomplete')
-
--- STMT_CACHE_ACTUAL_PROPS
-UPDATE temp__node_props_cache 
-   SET properties=
-        IFNULL((SELECT properties FROM actual_node a
-                 WHERE a.wc_id = ?1
-                   AND a.local_relpath = temp__node_props_cache.local_relpath),
-               properties)
-
--- STMT_CACHE_NODE_BASE_PROPS
-INSERT INTO temp__node_props_cache (local_relpath, kind, properties)
-  SELECT local_relpath, kind, properties FROM nodes_base
-  WHERE wc_id = ?1
-    AND local_relpath IN (SELECT local_relpath FROM targets_list)
-    AND presence IN ('normal', 'incomplete')
+-- STMT_CACHE_TARGET_PROPS
+INSERT INTO target_prop_cache(local_relpath, kind, properties)
+ SELECT n.local_relpath, n.kind,
+        IFNULL((SELECT properties FROM actual_node AS a
+                 WHERE a.wc_id = n.wc_id
+                   AND a.local_relpath = n.local_relpath),
+               n.properties)
+   FROM targets_list AS t
+   JOIN nodes_current AS n ON t.wc_id= n.wc_id
+                          AND t.local_relpath = n.local_relpath
+  WHERE t.wc_id = ?1
+    AND (presence='normal' OR presence='incomplete')
+
+-- STMT_CACHE_TARGET_PRISTINE_PROPS
+INSERT INTO target_prop_cache(local_relpath, kind, properties)
+ SELECT n.local_relpath, n.kind,
+        CASE n.presence
+          WHEN 'base-deleted'
+          THEN (SELECT properties FROM nodes AS p
+                 WHERE p.wc_id = n.wc_id
+                   AND p.local_relpath = n.local_relpath
+                   AND p.op_depth < n.op_depth
+                 ORDER BY p.op_depth DESC /* LIMIT 1 */)
+          ELSE properties END
+  FROM targets_list AS t
+  JOIN nodes_current AS n ON t.wc_id= n.wc_id
+                          AND t.local_relpath = n.local_relpath
+  WHERE t.wc_id = ?1
+    AND (presence = 'normal'
+         OR presence = 'incomplete'
+         OR presence = 'base-deleted')
 
--- STMT_CACHE_NODE_PRISTINE_PROPS
-INSERT INTO temp__node_props_cache(local_relpath, kind, properties)
- SELECT local_relpath, kind, 
-        IFNULL((SELECT properties FROM nodes nn
-                 WHERE n.presence = 'base-deleted'
-                   AND nn.wc_id = n.wc_id
-                   AND nn.local_relpath = n.local_relpath
-                   AND nn.op_depth < n.op_depth
-                 ORDER BY op_depth DESC),
-               properties)
-  FROM nodes_current n
-  WHERE wc_id = ?1
-    AND local_relpath IN (SELECT local_relpath FROM targets_list)
-    AND presence IN ('normal', 'incomplete', 'base-deleted')
-
--- STMT_SELECT_RELEVANT_PROPS_FROM_CACHE
-SELECT local_relpath, properties FROM temp__node_props_cache
+-- STMT_SELECT_ALL_TARGET_PROP_CACHE
+SELECT local_relpath, properties FROM target_prop_cache
 ORDER BY local_relpath
 
--- STMT_DROP_NODE_PROPS_CACHE
-DROP TABLE IF EXISTS temp__node_props_cache;
+-- STMT_DROP_TARGET_PROP_CACHE
+DROP TABLE IF EXISTS target_prop_cache;
 
 
 -- STMT_CREATE_REVERT_LIST
@@ -1219,7 +1222,7 @@ ORDER BY actual DESC
 -- STMT_SELECT_REVERT_LIST_COPIED_CHILDREN
 SELECT local_relpath, kind
 FROM revert_list
-WHERE local_relpath LIKE ?1 ESCAPE '#'
+WHERE IS_STRICT_DESCENDANT_OF(local_relpath, ?1)
   AND op_depth >= ?2
   AND repos_id IS NOT NULL
 ORDER BY local_relpath
@@ -1230,13 +1233,15 @@ DELETE FROM revert_list WHERE local_relp
 -- STMT_SELECT_REVERT_LIST_RECURSIVE
 SELECT DISTINCT local_relpath
 FROM revert_list
-WHERE (local_relpath = ?1 OR local_relpath LIKE ?2 ESCAPE '#')
+WHERE (local_relpath = ?1
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?1))
   AND (notify OR actual = 0)
 ORDER BY local_relpath
 
 -- STMT_DELETE_REVERT_LIST_RECURSIVE
 DELETE FROM revert_list
-WHERE local_relpath = ?1 OR local_relpath LIKE ?2 ESCAPE '#'
+WHERE (local_relpath = ?1
+       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?1))
 
 -- STMT_DROP_REVERT_LIST
 DROP TABLE IF EXISTS revert_list
@@ -1249,14 +1254,18 @@ CREATE TEMPORARY TABLE delete_list (
    local_relpath TEXT PRIMARY KEY NOT NULL UNIQUE
    )
 
-/* This matches the selection in STMT_INSERT_DELETE_FROM_NODE_RECURSIVE */
+/* This matches the selection in STMT_INSERT_DELETE_FROM_NODE_RECURSIVE.
+   A subquery is used instead of nodes_current to avoid a table scan */
 -- STMT_INSERT_DELETE_LIST
 INSERT INTO delete_list(local_relpath)
-SELECT local_relpath FROM nodes_current
+SELECT local_relpath FROM nodes AS n
 WHERE wc_id = ?1
   AND (local_relpath = ?2
        OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND op_depth >= ?3
+  AND op_depth = (SELECT MAX(s.op_depth) FROM nodes AS s
+                  WHERE s.wc_id = ?1
+                    AND s.local_relpath = n.local_relpath)
   AND presence NOT IN ('base-deleted', 'not-present', 'excluded', 'absent')
 
 -- STMT_SELECT_DELETE_LIST
@@ -1275,9 +1284,8 @@ DROP TABLE IF EXISTS delete_list
 SELECT MIN(revision), MAX(revision),
        MIN(changed_revision), MAX(changed_revision) FROM nodes
   WHERE wc_id = ?1
-    AND (?2 = ''
-       OR local_relpath = ?2
-       OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
+    AND (local_relpath = ?2
+         OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
     AND presence IN ('normal', 'incomplete')
     AND file_external IS NULL
     AND op_depth = 0
@@ -1285,8 +1293,7 @@ SELECT MIN(revision), MAX(revision),
 -- STMT_HAS_SPARSE_NODES
 SELECT 1 FROM nodes
 WHERE wc_id = ?1
-  AND (?2 = ''
-       OR local_relpath = ?2
+  AND (local_relpath = ?2
        OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND op_depth = 0
   AND (presence IN ('absent', 'excluded')
@@ -1297,8 +1304,7 @@ LIMIT 1
 -- STMT_SUBTREE_HAS_TREE_MODIFICATIONS
 SELECT 1 FROM nodes
 WHERE wc_id = ?1
-  AND (?2 = ''
-       OR local_relpath = ?2
+  AND (local_relpath = ?2
        OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND op_depth > 0
 LIMIT 1
@@ -1306,8 +1312,7 @@ LIMIT 1
 -- STMT_SUBTREE_HAS_PROP_MODIFICATIONS
 SELECT 1 FROM actual_node
 WHERE wc_id = ?1
-  AND (?2 = ''
-       OR local_relpath = ?2
+  AND (local_relpath = ?2
        OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND properties IS NOT NULL
 LIMIT 1
@@ -1384,8 +1389,7 @@ LIMIT 1
 -- STMT_SELECT_BASE_FILES_RECURSIVE
 SELECT local_relpath, translated_size, last_mod_time FROM nodes AS n
 WHERE wc_id = ?1
-  AND (?2 = ''
-       OR local_relpath = ?2
+  AND (local_relpath = ?2
        OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2))
   AND op_depth = 0
   AND kind='file'