Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/wc-checks.sql URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/wc-checks.sql?rev=1661492&r1=1661491&r2=1661492&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/libsvn_wc/wc-checks.sql (original) +++ subversion/branches/move-tracking-2/subversion/libsvn_wc/wc-checks.sql Sun Feb 22 16:52:05 2015 @@ -75,3 +75,217 @@ BEGIN SELECT RAISE(FAIL, 'WC DB validity check 04 failed'); END; +-- STMT_STATIC_VERIFY +SELECT local_relpath, op_depth, 1, 'Invalid parent relpath set in NODES' +FROM nodes n WHERE local_relpath != '' + AND (parent_relpath IS NULL + OR NOT IS_STRICT_DESCENDANT_OF(local_relpath, parent_relpath) + OR relpath_depth(local_relpath) != relpath_depth(parent_relpath)+1) + +UNION ALL + +SELECT local_relpath, -1, 2, 'Invalid parent relpath set in ACTUAL' +FROM actual_node a WHERE local_relpath != '' + AND (parent_relpath IS NULL + OR NOT IS_STRICT_DESCENDANT_OF(local_relpath, parent_relpath) + OR relpath_depth(local_relpath) != relpath_depth(parent_relpath)+1) + +UNION ALL + +/* All ACTUAL nodes must have an equivalent NODE in NODES + or be only one level deep (delete-delete tc) */ +SELECT local_relpath, -1, 10, 'No ancestor in ACTUAL' +FROM actual_node a WHERE local_relpath != '' + AND NOT EXISTS(SELECT 1 from nodes i + WHERE i.wc_id=a.wc_id + AND i.local_relpath=a.parent_relpath) + AND NOT EXISTS(SELECT 1 from nodes i + WHERE i.wc_id=a.wc_id + AND i.local_relpath=a.local_relpath) + +UNION ALL +/* Verify if the ACTUAL data makes sense for the related node. + Only conflict data is valid if there is none */ +SELECT a.local_relpath, -1, 11, 'Bad or Unneeded actual data' +FROM actual_node a +LEFT JOIN nodes n on n.wc_id = a.wc_id AND n.local_relpath = a.local_relpath + AND n.op_depth = (SELECT MAX(op_depth) from nodes i + WHERE i.wc_id=a.wc_id AND i.local_relpath=a.local_relpath) +WHERE (a.properties IS NOT NULL + AND (n.presence IS NULL + OR n.presence NOT IN (MAP_NORMAL, MAP_INCOMPLETE))) + OR (a.changelist IS NOT NULL AND (n.kind IS NOT NULL AND n.kind != MAP_FILE)) + OR (a.conflict_data IS NULL AND a.properties IS NULL AND a.changelist IS NULL) + AND NOT EXISTS(SELECT 1 from nodes i + WHERE i.wc_id=a.wc_id + AND i.local_relpath=a.parent_relpath) + +UNION ALL + +/* A parent node must exist for every normal node except the root. + That node must exist at a lower or equal op-depth */ +SELECT local_relpath, op_depth, 20, 'No ancestor in NODES' +FROM nodes n WHERE local_relpath != '' + AND file_external IS NULL + AND NOT EXISTS(SELECT 1 from nodes i + WHERE i.wc_id=n.wc_id + AND i.local_relpath=n.parent_relpath + AND i.op_depth <= n.op_depth) + +UNION ALL +/* If a node is not present in the working copy (normal, add, copy) it doesn't + have revision details stored on this record */ +SELECT local_relpath, op_depth, 21, 'Unneeded node data' +FROM nodes +WHERE presence NOT IN (MAP_NORMAL, MAP_INCOMPLETE) +AND (properties IS NOT NULL + OR checksum IS NOT NULL + OR depth IS NOT NULL + OR symlink_target IS NOT NULL + OR changed_revision IS NOT NULL + OR (changed_date IS NOT NULL AND changed_date != 0) + OR changed_author IS NOT NULL + OR translated_size IS NOT NULL + OR last_mod_time IS NOT NULL + OR dav_cache IS NOT NULL + OR file_external IS NOT NULL + OR inherited_props IS NOT NULL) + +UNION ALL +/* base-deleted nodes don't have a repository location. They are just + shadowing without a replacement */ +SELECT local_relpath, op_depth, 22, 'Unneeded base-deleted node data' +FROM nodes +WHERE presence IN (MAP_BASE_DELETED) +AND (repos_id IS NOT NULL + OR repos_path IS NOT NULL + OR revision IS NOT NULL) + +UNION ALL +/* Verify if type specific data is set (or not set for wrong type) */ +SELECT local_relpath, op_depth, 23, 'Kind specific data invalid on normal' +FROM nodes +WHERE presence IN (MAP_NORMAL, MAP_INCOMPLETE) +AND (kind IS NULL + OR (repos_path IS NULL + AND (properties IS NOT NULL + OR changed_revision IS NOT NULL + OR changed_author IS NOT NULL + OR (changed_date IS NOT NULL AND changed_date != 0))) + OR (CASE WHEN kind = MAP_FILE AND repos_path IS NOT NULL + THEN checksum IS NULL + ELSE checksum IS NOT NULL END) + OR (CASE WHEN kind = MAP_DIR THEN depth IS NULL + ELSE depth IS NOT NULL END) + OR (CASE WHEN kind = MAP_SYMLINK THEN symlink_target IS NULL + ELSE symlink_target IS NOT NULL END)) + +UNION ALL +/* Local-adds are always their own operation (read: they don't have + op-depth descendants, nor are op-depth descendants */ +SELECT local_relpath, op_depth, 24, 'Invalid op-depth for local add' +FROM nodes +WHERE presence IN (MAP_NORMAL, MAP_INCOMPLETE) + AND repos_path IS NULL + AND op_depth != relpath_depth(local_relpath) + +UNION ALL +/* op-depth descendants are only valid if they have a direct parent + node at the same op-depth. Only certain types allow further + descendants */ +SELECT local_relpath, op_depth, 25, 'Node missing op-depth ancestor' +FROM nodes n +WHERE op_depth < relpath_depth(local_relpath) + AND file_external IS NULL + AND NOT EXISTS(SELECT 1 FROM nodes p + WHERE p.wc_id=n.wc_id AND p.local_relpath=n.parent_relpath + AND p.op_depth=n.op_depth + AND (p.presence IN (MAP_NORMAL, MAP_INCOMPLETE) + OR (p.presence IN (MAP_BASE_DELETED, MAP_NOT_PRESENT) + AND n.presence = MAP_BASE_DELETED))) + +UNION ALL +/* Present op-depth descendants have the repository location implied by their + ancestor */ +SELECT n.local_relpath, n.op_depth, 26, 'Copied descendant mismatch' +FROM nodes n +JOIN nodes p + ON p.wc_id=n.wc_id AND p.local_relpath=n.parent_relpath + AND n.op_depth=p.op_depth +WHERE n.op_depth > 0 AND n.presence IN (MAP_NORMAL, MAP_INCOMPLETE) + AND (n.repos_id != p.repos_id + OR n.repos_path != + RELPATH_SKIP_JOIN(n.parent_relpath, p.repos_path, n.local_relpath) + OR n.revision != p.revision + OR p.kind != MAP_DIR + OR n.moved_here IS NOT p.moved_here) + +UNION ALL +/* Only certain presence values are valid as op-root. + Note that the wc-root always has presence normal or incomplete */ +SELECT n.local_relpath, n.op_depth, 27, 'Invalid op-root presence' +FROM nodes n +WHERE n.op_depth = relpath_depth(local_relpath) + AND presence NOT IN (MAP_NORMAL, MAP_INCOMPLETE, MAP_BASE_DELETED) + +UNION ALL +/* If a node is shadowed, all its present op-depth descendants + must be shadowed at the same op-depth as well */ +SELECT n.local_relpath, s.op_depth, 28, 'Incomplete shadowing' +FROM nodes n +JOIN nodes s ON s.wc_id=n.wc_id AND s.local_relpath=n.local_relpath + AND s.op_depth = relpath_depth(s.local_relpath) + AND s.op_depth = (SELECT MIN(op_depth) FROM nodes d + WHERE d.wc_id=s.wc_id AND d.local_relpath=s.local_relpath + AND d.op_depth > n.op_depth) +WHERE n.presence IN (MAP_NORMAL, MAP_INCOMPLETE) + AND EXISTS(SELECT 1 + FROM nodes dn + WHERE dn.wc_id=n.wc_id AND dn.op_depth=n.op_depth + AND dn.presence IN (MAP_NORMAL, MAP_INCOMPLETE) + AND IS_STRICT_DESCENDANT_OF(dn.local_relpath, n.local_relpath) + AND dn.file_external IS NULL + AND NOT EXISTS(SELECT 1 + FROM nodes ds + WHERE ds.wc_id=n.wc_id AND ds.op_depth=s.op_depth + AND ds.local_relpath=dn.local_relpath)) + +UNION ALL +/* A base-delete is only valid if it directly deletes a present node */ +SELECT s.local_relpath, s.op_depth, 29, 'Invalid base-delete' +FROM nodes s +LEFT JOIN nodes n ON n.wc_id=s.wc_id AND n.local_relpath=s.local_relpath + AND n.op_depth = (SELECT MAX(op_depth) FROM nodes d + WHERE d.wc_id=s.wc_id AND d.local_relpath=s.local_relpath + AND d.op_depth < s.op_depth) +WHERE s.presence = MAP_BASE_DELETED + AND (n.presence IS NULL + OR n.presence NOT IN (MAP_NORMAL, MAP_INCOMPLETE) + /*OR n.kind != s.kind*/) + +UNION ALL +/* Moves are stored in the working layers, not in BASE */ +SELECT n.local_relpath, n.op_depth, 30, 'Invalid data for BASE' +FROM nodes n +WHERE n.op_depth = 0 + AND (n.moved_to IS NOT NULL + OR n.moved_here IS NOT NULL) + +UNION ALL +/* If moved_here is set on an op-root, there must be a proper moved_to */ +SELECT d.local_relpath, d.op_depth, 60, 'Moved here without origin' +FROM nodes d +WHERE d.op_depth = relpath_depth(d.local_relpath) + AND d.moved_here IS NOT NULL + AND NOT EXISTS(SELECT 1 FROM nodes s + WHERE s.wc_id = d.wc_id AND s.moved_to = d.local_relpath) + +UNION ALL +/* If moved_to is set there should be an moved op root at the target */ +SELECT s.local_relpath, s.op_depth, 61, 'Moved to without target' +FROM nodes s +WHERE s.moved_to IS NOT NULL + AND NOT EXISTS(SELECT 1 FROM nodes d + WHERE d.wc_id = s.wc_id AND d.local_relpath = s.moved_to + AND d.op_depth = relpath_depth(d.local_relpath) + AND d.moved_here =1 AND d.repos_path IS NOT NULL)
Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/wc-queries.sql URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/wc-queries.sql?rev=1661492&r1=1661491&r2=1661492&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/libsvn_wc/wc-queries.sql (original) +++ subversion/branches/move-tracking-2/subversion/libsvn_wc/wc-queries.sql Sun Feb 22 16:52:05 2015 @@ -233,6 +233,16 @@ WHERE wc_id = ?1 AND IS_STRICT_DESCENDAN -- STMT_DELETE_WORKING_BASE_DELETE DELETE FROM nodes +WHERE wc_id = ?1 AND local_relpath = ?2 + AND presence = MAP_BASE_DELETED + AND op_depth > ?3 + AND op_depth = (SELECT MIN(op_depth) FROM nodes n + WHERE n.wc_id = ?1 + AND n.local_relpath = nodes.local_relpath + AND op_depth > ?3) + +-- STMT_DELETE_WORKING_BASE_DELETE_RECURSIVE +DELETE FROM nodes WHERE wc_id = ?1 AND IS_STRICT_DESCENDANT_OF(local_relpath, ?2) AND presence = MAP_BASE_DELETED AND op_depth > ?3 @@ -378,6 +388,7 @@ UPDATE NODES SET op_depth = 0, revision = ?6, dav_cache = NULL, moved_here = NULL, + moved_to = NULL, presence = CASE presence WHEN MAP_NORMAL THEN MAP_NORMAL WHEN MAP_EXCLUDED THEN MAP_EXCLUDED @@ -390,22 +401,30 @@ WHERE wc_id = ?1 -- STMT_SELECT_NODE_CHILDREN /* Return all paths that are children of the directory (?1, ?2) in any op-depth, including children of any underlying, replaced directories. */ -SELECT local_relpath FROM nodes +SELECT DISTINCT local_relpath FROM nodes WHERE wc_id = ?1 AND parent_relpath = ?2 +ORDER BY local_relpath -- STMT_SELECT_WORKING_CHILDREN /* Return all paths that are children of the working version of the directory (?1, ?2). A given path is not included just because it is a child of an underlying (replaced) directory, it has to be in the working version of the directory. */ -SELECT local_relpath FROM nodes +SELECT DISTINCT local_relpath FROM nodes WHERE wc_id = ?1 AND parent_relpath = ?2 AND (op_depth > (SELECT MAX(op_depth) FROM nodes WHERE wc_id = ?1 AND local_relpath = ?2) OR (op_depth = (SELECT MAX(op_depth) FROM nodes WHERE wc_id = ?1 AND local_relpath = ?2) - AND presence != MAP_BASE_DELETED)) + AND presence IN (MAP_NORMAL, MAP_INCOMPLETE))) +ORDER BY local_relpath + +-- STMT_SELECT_BASE_NOT_PRESENT_CHILDREN +SELECT local_relpath FROM nodes +WHERE wc_id = ?1 AND parent_relpath = ?2 AND op_depth = 0 + AND presence = MAP_NOT_PRESENT +ORDER BY local_relpath -- STMT_SELECT_NODE_PROPS SELECT properties, presence FROM nodes @@ -452,25 +471,13 @@ 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. moved.moved_to IS NOT NULL works when there is - only one move but we need something else when there are several. */ -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 +SELECT b.presence, w.presence, w.op_depth, w.moved_to +FROM nodes w +LEFT JOIN nodes b ON b.wc_id = ?1 AND b.local_relpath = ?2 AND b.op_depth = 0 +WHERE w.wc_id = ?1 AND w.local_relpath = ?2 + AND w.op_depth = (SELECT MAX(op_depth) FROM nodes d + WHERE d.wc_id = ?1 AND d.local_relpath = ?2 + AND d.op_depth > 0) LIMIT 1 -- STMT_SELECT_MOVED_TO_NODE @@ -722,6 +729,13 @@ INSERT OR IGNORE INTO actual_node ( SELECT wc_id, local_relpath, parent_relpath FROM targets_list +-- STMT_INSERT_ACTUAL_EMPTIES_FILES +INSERT OR IGNORE INTO actual_node ( + wc_id, local_relpath, parent_relpath) +SELECT wc_id, local_relpath, parent_relpath +FROM targets_list +WHERE kind=MAP_FILE + -- STMT_DELETE_ACTUAL_EMPTY DELETE FROM actual_node WHERE wc_id = ?1 AND local_relpath = ?2 @@ -736,7 +750,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 (local_relpath = ?2 OR IS_STRICT_DESCENDANT_OF(local_relpath, ?2)) AND properties IS NULL AND conflict_data IS NULL AND changelist IS NULL @@ -815,6 +829,17 @@ SET properties = NULL, right_checksum = NULL WHERE wc_id = ?1 AND local_relpath = ?2 +-- STMT_CLEAR_ACTUAL_NODE_LEAVING_CONFLICT +UPDATE actual_node +SET properties = NULL, + text_mod = NULL, + tree_conflict_data = NULL, + older_checksum = NULL, + left_checksum = NULL, + right_checksum = NULL, + changelist = NULL +WHERE wc_id = ?1 AND local_relpath = ?2 + -- STMT_CLEAR_ACTUAL_NODE_LEAVING_CHANGELIST_RECURSIVE UPDATE actual_node SET properties = NULL, @@ -1005,15 +1030,17 @@ WHERE wc_id = ?1 ORDER BY local_relpath -- STMT_INSERT_WORKING_NODE_FROM_BASE_COPY -INSERT INTO nodes ( +INSERT OR REPLACE INTO nodes ( wc_id, local_relpath, op_depth, parent_relpath, repos_id, repos_path, revision, presence, depth, kind, changed_revision, changed_date, changed_author, checksum, properties, translated_size, last_mod_time, - symlink_target ) + symlink_target, moved_to ) SELECT wc_id, local_relpath, ?3 /*op_depth*/, parent_relpath, repos_id, repos_path, revision, presence, depth, kind, changed_revision, changed_date, changed_author, checksum, properties, translated_size, - last_mod_time, symlink_target + last_mod_time, symlink_target, + (SELECT moved_to FROM nodes + WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = ?3) moved_to FROM nodes WHERE wc_id = ?1 AND local_relpath = ?2 AND op_depth = 0 Modified: subversion/branches/move-tracking-2/subversion/libsvn_wc/wc.h URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/libsvn_wc/wc.h?rev=1661492&r1=1661491&r2=1661492&view=diff ============================================================================== --- subversion/branches/move-tracking-2/subversion/libsvn_wc/wc.h (original) +++ subversion/branches/move-tracking-2/subversion/libsvn_wc/wc.h Sun Feb 22 16:52:05 2015 @@ -577,17 +577,6 @@ svn_wc__internal_get_origin(svn_boolean_ apr_pool_t *result_pool, apr_pool_t *scratch_pool); -/* Internal version of svn_wc__node_get_repos_info() */ -svn_error_t * -svn_wc__internal_get_repos_info(svn_revnum_t *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); - /* Upgrade the wc sqlite database given in SDB for the wc located at WCROOT_ABSPATH. It's current/starting format is given by START_FORMAT. After the upgrade is complete (to as far as the automatic upgrade will
