Author: rhuijben
Date: Tue Feb 24 11:56:52 2015
New Revision: 1661899

URL: http://svn.apache.org/r1661899
Log:
Create '1.9.x-db-verify' branch as a starting point for backporting
several db stability fixes.

* build/transform_sql.py (Partial of r1660742)
  Make IS_STRICT_DESCENDANT_OF() usable between db columns

* build.conf (r1660874)
  (svn-wc-db-tester): New tool.
  (__MORE__): Add svn-wc-db-tester and x509-parser.
  (x509-parser): Add description.

* subversion/include/private/svn_sqlite.h (r1660659)
  (svn_sqlite__func_t): Update prototype.

* subversion/libsvn_subr/sqlite.c (r1660610, r1660641, r1660659, r1661890)
  (function_wrapper_baton_t): Remove pool.
  (wrapped_func): Update caller. (Different argument type)
  (svn_sqlite__create_scalar_function): Avoid init of state pool.
  (svn_sqlite__value_type,
   svn_sqlite__value_text): Handle different argument type.

* subversion/libsvn_wc/wc-checks.sql (many)
  (STMT_STATIC_VERIFY): Bring up to date with trunk.

* subversion/libsvn_wc/wc-queries.sql (1660758)
  (STMT_SELECT_DELETION_INFO): Use join make query more similar to other cases.
  (STMT_SELECT_DELETION_INFO_SCAN): Remove query that searched for moved
    information in multiple (including wrong) locations.

* subversion/libsvn_wc/wc_db.c
  (scan_deletion_txn): Update statement usage. Only search for moved_to in the
    intended layer. (r1660758)

  (svn_wc__db_verify_db_full_internal,
   svn_wc__db_verify_db_full): New functions. (r1660874)

* subversion/libsvn_wc/wc_db.h (r1660874)
  (svn_wc__db_verify_cb_t): New prototype.
  (svn_wc__db_verify_db_full): New function.

* subversion/libsvn_wc/wc_db_private.h (r1660874)
  (svn_wc__db_verify_db_full_internal): New function.

* subversion/libsvn_wc/wc_db_util.c (r1661890)
  (relpath_depth_sqlite): Update prototype.

* subversion/libsvn_wc/wc_db_wcroot.c (r1660874)
  (verify_sqlite): Rename to...
  (verify_db_cb): ... this. Implement svn_wc__db_verify_cb_t.
  (close_wcroot): Update caller.

* subversion/tests/libsvn_subr/sqlite-test.c
  (error_second): Update argument (r1660659).

* subversion/tests/libsvn_wc/db-test.c
  (r1658602,1660529,1660587,1660633,1660687,1660758,1660928)
  (TESTING_DATA): Convert sqlite statements to...
  (nodes_init_data,
   actual_init_data): New variables.
  (create_open): Update caller.
  (validate_abspath): Return svn_error_t * to provide details.
  (*): Minor expectation fixes.

* subversion/tests/libsvn_wc/entries-compat.c (r1660928,1660955,1660961)
  (TESTING_DATA): Convert sqlite statements to...
  (nodes,
   actuals): New variables.
  (create_fake_wc): Update callers.
  (test_entries_alloc): Assume a few more nodes, to make db valid.

* subversion/tests/libsvn_wc/op-depth-test.c (r1660587)
  (insert_actual): Ensure that pristine data exists before turning a directory
    in a file.

* subversion/tests/libsvn_wc/utils.c (r1660928)
  (includes): Add token-map.h.
  (svn_test__create_fake_wc): Add support for creating nodes from C structs.

* subversion/tests/libsvn_wc/utils.h (r1660928)
  (svn_test__nodes_data_t,
   svn_test__actual_data_t): New structs.
  (svn_test__create_fake_wc): Add arguments.

* subversion/tests/libsvn_wc/wc-queries-test.c (r1660587,1660610)
  (relpath_depth_sqlite,
   test_verify_parsable): New functions, to verify that the verify code is
     accepted by sqlite.
  (test_funcs): Add test_verify_parsable.

* subversion/tests/libsvn_wc/wc-test-queries.sql (r1660587)
  (STMT_ENSURE_EMPTY_PRISTINE): New statement.
  (STMT_NODES_SET_FILE): Really turn a directory into a file.


Added:
    subversion/branches/1.9.x-db-verify/   (props changed)
      - copied from r1661884, subversion/branches/1.9.x/
    subversion/branches/1.9.x-db-verify/tools/dev/wc-ng/svn-wc-db-tester.c
      - copied unchanged from r1660874, 
subversion/trunk/tools/dev/wc-ng/svn-wc-db-tester.c
Modified:
    subversion/branches/1.9.x-db-verify/build.conf
    subversion/branches/1.9.x-db-verify/build/transform_sql.py
    subversion/branches/1.9.x-db-verify/subversion/include/private/svn_sqlite.h
    subversion/branches/1.9.x-db-verify/subversion/libsvn_subr/sqlite.c
    subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc-checks.sql
    subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db.c
    subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db.h
    subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db_private.h
    subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db_util.c
    subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db_wcroot.c
    
subversion/branches/1.9.x-db-verify/subversion/tests/libsvn_subr/sqlite-test.c
    subversion/branches/1.9.x-db-verify/subversion/tests/libsvn_wc/db-test.c
    
subversion/branches/1.9.x-db-verify/subversion/tests/libsvn_wc/entries-compat.c
    
subversion/branches/1.9.x-db-verify/subversion/tests/libsvn_wc/op-depth-test.c
    subversion/branches/1.9.x-db-verify/subversion/tests/libsvn_wc/utils.c
    subversion/branches/1.9.x-db-verify/subversion/tests/libsvn_wc/utils.h
    
subversion/branches/1.9.x-db-verify/subversion/tests/libsvn_wc/wc-queries-test.c
    
subversion/branches/1.9.x-db-verify/subversion/tests/libsvn_wc/wc-test-queries.sql

Propchange: subversion/branches/1.9.x-db-verify/
------------------------------------------------------------------------------
--- bugtraq:logregex (added)
+++ bugtraq:logregex Tue Feb 24 11:56:52 2015
@@ -0,0 +1,2 @@
+[Ii]ssues?:?(\s*(,|and)?\s*#\d+)+
+(\d+)

Propchange: subversion/branches/1.9.x-db-verify/
------------------------------------------------------------------------------
    bugtraq:url = http://subversion.tigris.org/issues/show_bug.cgi?id=%BUGID%

Propchange: subversion/branches/1.9.x-db-verify/
------------------------------------------------------------------------------
--- svn:auto-props (added)
+++ svn:auto-props Tue Feb 24 11:56:52 2015
@@ -0,0 +1,13 @@
+*.c = svn:eol-style=native
+*.cpp = svn:eol-style=native
+*.h = svn:eol-style=native
+*.hpp = svn:eol-style=native
+*.java = svn:eol-style=native
+*.py = svn:eol-style=native
+*.pl = svn:eol-style=native
+*.rb = svn:eol-style=native
+*.sql = svn:eol-style=native
+*.txt = svn:eol-style=native
+README = svn:eol-style=native
+BRANCH-README = svn:eol-style=native
+STATUS = svn:eol-style=native

Propchange: subversion/branches/1.9.x-db-verify/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Tue Feb 24 11:56:52 2015
@@ -0,0 +1,57 @@
+ChangeLog*
+Makefile
+config.cache
+config.log
+config.nice
+config.status
+configure
+libtool
+.gdb_history
+.swig_checked
+*.orig
+*.rej
+TAGS
+tags
+neon
+build-outputs.mk
+autogen-standalone.mk
+autom4te.cache
+gen-make.opts
+tests.log*
+fails.log*
+db4-win32
+db
+*.o
+*~
+.*~
+apr
+apr-util
+apr-iconv
+Release
+Debug
+ipch
+subversion_msvc.dsw
+subversion_msvc.ncb
+subversion_msvc.opt
+subversion_msvc.plg
+subversion_vcnet.sln
+subversion_vcnet.ncb
+subversion_vcnet.suo
+subversion_vcnet.v11.suo
+subversion_vcnet.sdf
+subversion_vcnet.opensdf
+mkmf.log
+.project
+.classpath
+.cdtproject
+.settings
+.cproject
+zlib
+sqlite-amalgamation
+serf
+gmock-fused
+.git
+.gitignore
+compile_commands.json
+.kdev4
+*.kdev4

Propchange: subversion/branches/1.9.x-db-verify/
------------------------------------------------------------------------------
--- svn:mergeinfo (added)
+++ svn:mergeinfo Tue Feb 24 11:56:52 2015
@@ -0,0 +1,92 @@
+/subversion/branches/1.5.x-r30215:870312
+/subversion/branches/1.7.x-fs-verify:1146708,1161180
+/subversion/branches/10Gb:1388102,1388163-1388190,1388195,1388202,1388205,1388211,1388276,1388362,1388375,1388394,1388636,1388639-1388640,1388643-1388644,1388654,1388720,1388789,1388795,1388801,1388805,1388807,1388810,1388816,1389044,1389276,1389289,1389662,1389867,1390017,1390209,1390216,1390407,1390409,1390414,1390419,1390955
+/subversion/branches/atomic-revprop:965046-1000689
+/subversion/branches/authzperf:1615360
+/subversion/branches/auto-props-sdc:1384106-1401643
+/subversion/branches/bdb-reverse-deltas:872050-872529
+/subversion/branches/cache-server:1458643-1476567
+/subversion/branches/diff-callbacks3:870059-870761
+/subversion/branches/diff-optimizations:1031270-1037352
+/subversion/branches/diff-optimizations-bytes:1037353-1067789
+/subversion/branches/dont-save-plaintext-passwords-by-default:870728-871118
+/subversion/branches/double-delete:870511-872970
+/subversion/branches/dump-load-cross-check:1654853-1657295
+/subversion/branches/ev2-export:1325914,1332738,1413107
+/subversion/branches/explore-wc:875486,875493,875497,875507,875511,875514,875559,875580-875581,875584,875587,875611,875627,875647,875667-875668,875711-875712,875733-875734,875736,875744-875748,875751,875758,875782,875795-875796,875830,875836,875838,875842,875852,875855,875864,875870,875873,875880,875885-875888,875890,875897-875898,875905,875907-875909,875935,875943-875944,875946,875979,875982-875983,875985-875986,875990,875997
+/subversion/branches/file-externals:871779-873302
+/subversion/branches/fs-rep-sharing:869036-873803
+/subversion/branches/fsfs-format7:1426304,1430673,1433848,1438408,1438982,1441129,1442051,1442068,1442504,1442910,1443171,1443803,1444690,1444693,1444695,1445040,1445080,1446103,1451129,1453590,1454307,1460579,1461851,1461865,1462837,1462904,1463120,1467362,1467382,1469487,1471208,1477166,1478055,1481447,1489817,1489949,1490673-1490674,1491784,1493042,1498029,1498103,1498155,1500054,1507729-1507731,1507735-1507736
+/subversion/branches/fsfs-improvements:1499981-1547039
+/subversion/branches/fsfs-lock-many:1571740-1577217
+/subversion/branches/fsfs-pack:873717-874575
+/subversion/branches/fsx:1507845-1509914
+/subversion/branches/fsx-id:1645603-1649011
+/subversion/branches/gnome-keyring:870558-871410
+/subversion/branches/gpg-agent-password-store:1005036-1150766
+/subversion/branches/gtest_addition:1452117-1502138
+/subversion/branches/http-protocol-v2:874395-876041
+/subversion/branches/in-memory-cache:869829-871452
+/subversion/branches/in-repo-authz:1414342-1424779
+/subversion/branches/inheritable-props:1297080-1395089
+/subversion/branches/integrate-cache-item-serialization:1068724-1068739
+/subversion/branches/integrate-cache-membuffer:998649-998852
+/subversion/branches/integrate-compression-level:1068651-1072287
+/subversion/branches/integrate-io-improvements:1068684-1072297
+/subversion/branches/integrate-is-cachable:1072568-1074082
+/subversion/branches/integrate-partial-getter:1072558-1076552
+/subversion/branches/integrate-readline-speedup:1072553-1072555
+/subversion/branches/integrate-stream-api-extensions:1068695-1072516
+/subversion/branches/integrate-string-improvements:1068251-1190617
+/subversion/branches/integrate-txdelta-caching:1072541-1078213
+/subversion/branches/issue-2779-dev:965496-984198
+/subversion/branches/issue-2843-dev:871432-874179
+/subversion/branches/issue-3000:871713,871716-871719,871721-871726,871728,871734
+/subversion/branches/issue-3067-deleted-subtrees:873375-874084
+/subversion/branches/issue-3148-dev:875193-875204
+/subversion/branches/issue-3220-dev:872210-872226
+/subversion/branches/issue-3242-dev:879653-896436
+/subversion/branches/issue-3334-dirs:875156-875867
+/subversion/branches/issue-3975:1152931-1160746
+/subversion/branches/issue-4116-dev:1424719-1425040
+/subversion/branches/issue-4194-dev:1410507-1414880
+/subversion/branches/javahl-ra:991978-1494640
+/subversion/branches/kwallet:870785-871314
+/subversion/branches/log-addressing:1509279-1546844
+/subversion/branches/log-g-performance:870941-871032
+/subversion/branches/merge-skips-obstructions:874525-874615
+/subversion/branches/move-tracking-2:1607334
+/subversion/branches/multi-layer-moves:1239019-1300930
+/subversion/branches/nfc-nfd-aware-client:870276,870376
+/subversion/branches/node_pool:1304828-1305388
+/subversion/branches/performance:979193,980118,981087,981090,981189,981194,981287,981684,981827,982043,982355,983398,983406,983430,983474,983488,983490,983760,983764,983766,983770,984927,984973,984984,985014,985037,985046,985472,985477,985482,985487-985488,985493,985497,985500,985514,985601,985603,985606,985669,985673,985695,985697,986453,986465,986485,986491-986492,986517,986521,986605,986608,986817,986832,987865,987868-987869,987872,987886-987888,987893,988319,988898,990330,990533,990535-990537,990541,990568,990572,990574-990575,990600,990759,992899,992904,992911,993127,993141,994956,995478,995507,995603,998012,998858,999098,1001413,1001417,1004291,1022668,1022670,1022676,1022715,1022719,1025660,1025672,1027193,1027203,1027206,1027214,1027227,1028077,1028092,1028094,1028104,1028107,1028111,1028354,1029038,1029042-1029043,1029054-1029055,1029062-1029063,1029078,1029080,1029090,1029092-1029093,1029111,1029151,1029158,1029229-1029230,1029232,1029335-1029336,1029339-1029340,1029342,10
 
29344,1030763,1030827,1031203,1031235,1032285,1032333,1033040,1033057,1033294,1035869,1035882,1039511,1043705,1053735,1056015,1066452,1067683,1067697-1078365
+/subversion/branches/pin-externals:1643757-1659392
+/subversion/branches/py-tests-as-modules:956579-1033052
+/subversion/branches/ra_serf-digest-authn:875693-876404
+/subversion/branches/reintegrate-improvements:873853-874164
+/subversion/branches/remote-only-status:1581845-1586090
+/subversion/branches/revprop-cache:1298521-1326293
+/subversion/branches/revprop-caching-ng:1620597,1620599
+/subversion/branches/revprop-packing:1143907,1143971,1143997,1144017,1144499,1144568,1146145
+/subversion/branches/subtree-mergeinfo:876734-878766
+/subversion/branches/svn-auth-x509:1603509-1655900
+/subversion/branches/svn-info-detail:1660035-1660413
+/subversion/branches/svn-mergeinfo-enhancements:870119-870195,870197-870288
+/subversion/branches/svn-patch-improvements:918519-934609
+/subversion/branches/svn_mutex:1141683-1182099
+/subversion/branches/svnpatch-diff:865738-876477
+/subversion/branches/svnraisetc:874709-875149
+/subversion/branches/svnserve-logging:869828-870893
+/subversion/branches/tc-issue-3334:874697-874773
+/subversion/branches/tc-merge-notify:874017-874062
+/subversion/branches/tc-resolve:874191-874239
+/subversion/branches/tc_url_rev:874351-874483
+/subversion/branches/tree-conflicts:868291-873154
+/subversion/branches/tree-conflicts-notify:873926-874008
+/subversion/branches/tristate-chunked-request:1502394-1502681
+/subversion/branches/tweak-build-take-two:1424288-1425049,1425051-1425613
+/subversion/branches/uris-as-urls:1060426-1064427
+/subversion/branches/verify-at-commit:1462039-1462408
+/subversion/branches/verify-keep-going:1439280-1546110
+/subversion/branches/wc-collate-path:1402685-1480384
+/subversion/trunk:1660587,1660610,1660633,1660641,1660659,1660671,1660687,1660758,1660874,1660928,1660955,1660961,1661890

Propchange: subversion/branches/1.9.x-db-verify/
------------------------------------------------------------------------------
    tsvn:logwidthmarker = 78

Propchange: subversion/branches/1.9.x-db-verify/
------------------------------------------------------------------------------
    webviewer:revision = http://svn.apache.org/r%REVISION%

Modified: subversion/branches/1.9.x-db-verify/build.conf
URL: 
http://svn.apache.org/viewvc/subversion/branches/1.9.x-db-verify/build.conf?rev=1661899&r1=1661884&r2=1661899&view=diff
==============================================================================
--- subversion/branches/1.9.x-db-verify/build.conf (original)
+++ subversion/branches/1.9.x-db-verify/build.conf Tue Feb 24 11:56:52 2015
@@ -1354,6 +1354,15 @@ libs = libsvn_wc libsvn_subr apriconv ap
 msvc-force-static = yes
 testing = skip
 
+[svn-wc-db-tester]
+type = exe
+path = tools/dev/wc-ng
+sources = svn-wc-db-tester.c
+install = test
+libs = libsvn_wc libsvn_subr apr
+msvc-force-static = yes
+testing = skip
+
 # ----------------------------------------------------------------------------
 #
 # EXTERNAL TARGETS (NO BUILD NEEDED)
@@ -1513,7 +1522,7 @@ type = project
 path = build/win32
 libs = __ALL_TESTS__
        diff diff3 diff4 fsfs-access-map svnauth 
-       svn-populate-node-origins-index
+       svn-populate-node-origins-index x509-parser svn-wc-db-tester
 
 [__LIBS__]
 type = project
@@ -1628,6 +1637,7 @@ libs = libsvn_wc libsvn_subr apriconv ap
 install = tools
 
 [x509-parser]
+description = Tool to verify x509 certificates
 type = exe
 path = tools/dev
 sources = x509-parser.c

Modified: subversion/branches/1.9.x-db-verify/build/transform_sql.py
URL: 
http://svn.apache.org/viewvc/subversion/branches/1.9.x-db-verify/build/transform_sql.py?rev=1661899&r1=1661884&r2=1661899&view=diff
==============================================================================
--- subversion/branches/1.9.x-db-verify/build/transform_sql.py (original)
+++ subversion/branches/1.9.x-db-verify/build/transform_sql.py Tue Feb 24 
11:56:52 2015
@@ -140,7 +140,7 @@ class Processor(object):
 
       # '/'+1 == '0'
       line = re.sub(
-            r'IS_STRICT_DESCENDANT_OF[(]([A-Za-z_.]+), ([?][0-9]+)[)]',
+            r'IS_STRICT_DESCENDANT_OF[(]([?]?[A-Za-z0-9_.]+), 
([?]?[A-Za-z0-9_.]+)[)]',
             r"(((\1) > (CASE (\2) WHEN '' THEN '' ELSE (\2) || '/' END))" +
             r" AND ((\1) < CASE (\2) WHEN '' THEN X'FFFF' ELSE (\2) || '0' 
END))",
             line)

Modified: 
subversion/branches/1.9.x-db-verify/subversion/include/private/svn_sqlite.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/1.9.x-db-verify/subversion/include/private/svn_sqlite.h?rev=1661899&r1=1661884&r2=1661899&view=diff
==============================================================================
--- subversion/branches/1.9.x-db-verify/subversion/include/private/svn_sqlite.h 
(original)
+++ subversion/branches/1.9.x-db-verify/subversion/include/private/svn_sqlite.h 
Tue Feb 24 11:56:52 2015
@@ -63,7 +63,7 @@ typedef enum svn_sqlite__mode_e {
 typedef svn_error_t *(*svn_sqlite__func_t)(svn_sqlite__context_t *sctx,
                                            int argc,
                                            svn_sqlite__value_t *values[],
-                                           apr_pool_t *scatch_pool);
+                                           void *baton);
 
 
 /* Step the given statement; if it returns SQLITE_DONE, reset the statement.

Modified: subversion/branches/1.9.x-db-verify/subversion/libsvn_subr/sqlite.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/1.9.x-db-verify/subversion/libsvn_subr/sqlite.c?rev=1661899&r1=1661884&r2=1661899&view=diff
==============================================================================
--- subversion/branches/1.9.x-db-verify/subversion/libsvn_subr/sqlite.c 
(original)
+++ subversion/branches/1.9.x-db-verify/subversion/libsvn_subr/sqlite.c Tue Feb 
24 11:56:52 2015
@@ -1477,8 +1477,6 @@ struct function_wrapper_baton_t
 {
   svn_sqlite__func_t func;
   void *baton;
-
-  apr_pool_t *scratch_pool;
 };
 
 static void
@@ -1488,22 +1486,12 @@ wrapped_func(sqlite3_context *context,
 {
   struct function_wrapper_baton_t *fwb = sqlite3_user_data(context);
   svn_sqlite__context_t sctx;
-  svn_sqlite__value_t **local_vals =
-                            apr_palloc(fwb->scratch_pool,
-                                       sizeof(svn_sqlite__value_t *) * argc);
   svn_error_t *err;
-  int i;
+  void *void_values = values;
 
   sctx.context = context;
 
-  for (i = 0; i < argc; i++)
-    {
-      local_vals[i] = apr_palloc(fwb->scratch_pool, sizeof(*local_vals[i]));
-      local_vals[i]->value = values[i];
-    }
-
-  err = fwb->func(&sctx, argc, local_vals, fwb->scratch_pool);
-  svn_pool_clear(fwb->scratch_pool);
+  err = fwb->func(&sctx, argc, void_values, fwb->baton);
 
   if (err)
     {
@@ -1515,6 +1503,7 @@ wrapped_func(sqlite3_context *context,
     }
 }
 
+
 svn_error_t *
 svn_sqlite__create_scalar_function(svn_sqlite__db_t *db,
                                    const char *func_name,
@@ -1527,7 +1516,6 @@ svn_sqlite__create_scalar_function(svn_s
   struct function_wrapper_baton_t *fwb = apr_pcalloc(db->state_pool,
                                                      sizeof(*fwb));
 
-  fwb->scratch_pool = svn_pool_create(db->state_pool);
   fwb->func = func;
   fwb->baton = baton;
 
@@ -1545,13 +1533,15 @@ svn_sqlite__create_scalar_function(svn_s
 int
 svn_sqlite__value_type(svn_sqlite__value_t *val)
 {
-  return sqlite3_value_type(val->value);
+  void *v = val;
+  return sqlite3_value_type(v);
 }
 
 const char *
 svn_sqlite__value_text(svn_sqlite__value_t *val)
 {
-  return (const char *) sqlite3_value_text(val->value);
+  void *v = val;
+  return (const char *) sqlite3_value_text(v);
 }
 
 void

Modified: subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc-checks.sql
URL: 
http://svn.apache.org/viewvc/subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc-checks.sql?rev=1661899&r1=1661884&r2=1661899&view=diff
==============================================================================
--- subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc-checks.sql 
(original)
+++ subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc-checks.sql Tue 
Feb 24 11:56:52 2015
@@ -76,16 +76,25 @@ BEGIN
 END;
 
 -- STMT_STATIC_VERIFY
-SELECT local_relpath, op_depth, 'SV001: No ancestor in NODES'
+SELECT local_relpath, op_depth, 1, 'Invalid parent relpath set 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 (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
 
-SELECT local_relpath, -1, 'SV002: No ancestor in ACTUAL'
+/* 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
@@ -95,14 +104,16 @@ FROM actual_node a WHERE local_relpath !
                   AND i.local_relpath=a.local_relpath)
 
 UNION ALL
-
-SELECT a.local_relpath, -1, 'SV003: Bad or Unneeded actual data'
+/* 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 NOT IN (MAP_NORMAL, MAP_INCOMPLETE))
+       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
@@ -111,7 +122,20 @@ WHERE (a.properties IS NOT NULL
 
 UNION ALL
 
-SELECT local_relpath, op_depth, 'SV004: Unneeded node data'
+/* 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
@@ -128,10 +152,140 @@ AND (properties IS NOT NULL
      OR inherited_props IS NOT NULL)
 
 UNION ALL
-
-SELECT local_relpath, op_depth, 'SV005: Unneeded base-deleted node data'
+/* 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)
\ No newline at end of file
+     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/1.9.x-db-verify/subversion/libsvn_wc/wc-queries.sql
URL: 
http://svn.apache.org/viewvc/subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc-queries.sql?rev=1661899&r1=1661884&r2=1661899&view=diff
==============================================================================
--- subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc-queries.sql 
(original)
+++ subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc-queries.sql Tue 
Feb 24 11:56:52 2015
@@ -452,25 +452,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

Modified: subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db.c?rev=1661899&r1=1661884&r2=1661899&view=diff
==============================================================================
--- subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db.c (original)
+++ subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db.c Tue Feb 24 
11:56:52 2015
@@ -4043,9 +4043,7 @@ scan_deletion_txn(const char **base_del_
   scan = (moved_to_op_root_relpath || moved_to_relpath);
 
   SVN_ERR(svn_sqlite__get_statement(
-                    &stmt, wcroot->sdb,
-                    scan ? STMT_SELECT_DELETION_INFO_SCAN
-                         : STMT_SELECT_DELETION_INFO));
+                    &stmt, wcroot->sdb, STMT_SELECT_DELETION_INFO));
 
   SVN_ERR(svn_sqlite__bindf(stmt, "is", wcroot->wc_id, current_relpath));
   SVN_ERR(svn_sqlite__step(&have_row, stmt));
@@ -15897,6 +15895,69 @@ svn_wc__db_verify(svn_wc__db_t *db,
   return SVN_NO_ERROR;
 }
 
+
+svn_error_t *
+svn_wc__db_verify_db_full_internal(svn_wc__db_wcroot_t *wcroot,
+                                   svn_wc__db_verify_cb_t callback,
+                                   void *baton,
+                                   apr_pool_t *scratch_pool)
+{
+  svn_sqlite__stmt_t *stmt;
+  svn_boolean_t have_row;
+  svn_error_t *err = NULL;
+  apr_pool_t *iterpool = svn_pool_create(scratch_pool);
+
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_STATIC_VERIFY));
+  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+
+  while (have_row)
+    {
+      const char *local_relpath;
+      int op_depth = svn_sqlite__column_int(stmt, 1);
+      int id = svn_sqlite__column_int(stmt, 2);
+      const char *msg;
+
+      svn_pool_clear(iterpool);
+
+      local_relpath =  svn_sqlite__column_text(stmt, 0, iterpool);
+      msg = svn_sqlite__column_text(stmt, 3, scratch_pool);
+
+      err = callback(baton, wcroot->abspath, local_relpath, op_depth,
+                     id, msg, iterpool);
+
+      if (err)
+        break;
+
+      SVN_ERR(svn_sqlite__step(&have_row, stmt));
+    }
+
+  svn_pool_destroy(iterpool);
+
+  return svn_error_trace(
+            svn_error_compose_create(err, svn_sqlite__reset(stmt)));
+}
+
+svn_error_t *
+svn_wc__db_verify_db_full(svn_wc__db_t *db,
+                          const char *wri_abspath,
+                          svn_wc__db_verify_cb_t callback,
+                          void *baton,
+                          apr_pool_t *scratch_pool)
+{
+  svn_wc__db_wcroot_t *wcroot;
+  const char *local_relpath;
+
+  SVN_ERR_ASSERT(svn_dirent_is_absolute(wri_abspath));
+
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
+                              wri_abspath, scratch_pool, scratch_pool));
+  VERIFY_USABLE_WCROOT(wcroot);
+
+  return svn_error_trace(
+            svn_wc__db_verify_db_full_internal(wcroot, callback, baton,
+                                               scratch_pool));
+}
+
 svn_error_t *
 svn_wc__db_bump_format(int *result_format,
                        svn_boolean_t *bumped_format,

Modified: subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db.h?rev=1661899&r1=1661884&r2=1661899&view=diff
==============================================================================
--- subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db.h (original)
+++ subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db.h Tue Feb 24 
11:56:52 2015
@@ -3526,6 +3526,28 @@ svn_wc__required_lock_for_resolve(const
                                   apr_pool_t *scratch_pool);
 /* @} */
 
+typedef svn_error_t * (*svn_wc__db_verify_cb_t)(void *baton,
+                                                const char *wc_abspath,
+                                                const char *local_relpath,
+                                                int op_depth,
+                                                int id,
+                                                const char *description,
+                                                apr_pool_t *scratch_pool);
+
+/* Checks the database for FULL-correctness according to the spec.
+
+   Note that typical 1.7-1.9 databases WILL PRODUCE warnings.
+
+   This is mainly useful for WC-NG developers, as there will be
+   warnings without the database being corrupt
+*/
+svn_error_t *
+svn_wc__db_verify_db_full(svn_wc__db_t *db,
+                          const char *wri_abspath,
+                          svn_wc__db_verify_cb_t callback,
+                          void *baton,
+                          apr_pool_t *scratch_pool);
+
 
 #ifdef __cplusplus
 }

Modified: 
subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db_private.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db_private.h?rev=1661899&r1=1661884&r2=1661899&view=diff
==============================================================================
--- subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db_private.h 
(original)
+++ subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db_private.h 
Tue Feb 24 11:56:52 2015
@@ -511,4 +511,10 @@ svn_wc__db_update_move_list_notify(svn_w
                                    void *notify_baton,
                                    apr_pool_t *scratch_pool);
 
+svn_error_t *
+svn_wc__db_verify_db_full_internal(svn_wc__db_wcroot_t *wcroot,
+                                   svn_wc__db_verify_cb_t callback,
+                                   void *baton,
+                                   apr_pool_t *scratch_pool);
+
 #endif /* WC_DB_PRIVATE_H */

Modified: subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db_util.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db_util.c?rev=1661899&r1=1661884&r2=1661899&view=diff
==============================================================================
--- subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db_util.c 
(original)
+++ subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db_util.c Tue 
Feb 24 11:56:52 2015
@@ -83,7 +83,7 @@ static svn_error_t *
 relpath_depth_sqlite(svn_sqlite__context_t *sctx,
                      int argc,
                      svn_sqlite__value_t *values[],
-                     apr_pool_t *scratch_pool)
+                     void *baton)
 {
   const char *path = NULL;
   apr_int64_t depth;

Modified: 
subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db_wcroot.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db_wcroot.c?rev=1661899&r1=1661884&r2=1661899&view=diff
==============================================================================
--- subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db_wcroot.c 
(original)
+++ subversion/branches/1.9.x-db-verify/subversion/libsvn_wc/wc_db_wcroot.c Tue 
Feb 24 11:56:52 2015
@@ -164,32 +164,23 @@ svn_wc__db_verify_no_work(svn_sqlite__db
 }
 
 #if defined(VERIFY_ON_CLOSE) && defined(SVN_DEBUG)
+/* Implements svn_wc__db_verify_cb_t */
 static svn_error_t *
-verify_sqlite(svn_sqlite__db_t *sdb,
-              const char *wc_abspath,
-              apr_pool_t *scratch_pool)
+verify_db_cb(void *baton,
+             const char *wc_abspath,
+             const char *local_relpath,
+             int op_depth,
+             int id,
+             const char *msg,
+             apr_pool_t *scratch_pool)
 {
-  svn_sqlite__stmt_t *stmt;
-  svn_boolean_t have_row;
+  if (op_depth >= 0)
+    SVN_DBG(("DB-VRFY: %s: %s (%d): SV%04d %s",
+              wc_abspath, local_relpath, op_depth, id, msg));
+  else
+    SVN_DBG(("DB-VRFY: %s: %s: SV%04d %s",
+              wc_abspath, local_relpath, id, msg));
 
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_STATIC_VERIFY));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-
-  while (have_row)
-    {
-      const char *item = svn_sqlite__column_text(stmt, 0, scratch_pool);
-      int op_depth = svn_sqlite__column_int(stmt, 1);
-      const char *msg = svn_sqlite__column_text(stmt, 2, scratch_pool);
-
-      if (op_depth >= 0)
-        SVN_DBG(("DB-VRFY: %s: %s:%d: %s", wc_abspath, item, op_depth, msg));
-      else
-        SVN_DBG(("DB-VRFY: %s: %s: %s", wc_abspath, item, msg));
-
-      SVN_ERR(svn_sqlite__step(&have_row, stmt));
-    }
-
-  SVN_ERR(svn_sqlite__reset(stmt));
   return SVN_NO_ERROR;
 }
 #endif
@@ -208,8 +199,8 @@ close_wcroot(void *data)
     {
       apr_pool_t *scratch_pool = svn_pool_create(NULL);
 
-      svn_error_clear(verify_sqlite(wcroot->sdb, wcroot->abspath,
-                                    scratch_pool));
+      svn_error_clear(svn_wc__db_verify_db_full_internal(
+                                    wcroot, verify_db_cb, NULL, scratch_pool));
 
       svn_pool_destroy(scratch_pool);
     }

Modified: 
subversion/branches/1.9.x-db-verify/subversion/tests/libsvn_subr/sqlite-test.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/1.9.x-db-verify/subversion/tests/libsvn_subr/sqlite-test.c?rev=1661899&r1=1661884&r2=1661899&view=diff
==============================================================================
--- 
subversion/branches/1.9.x-db-verify/subversion/tests/libsvn_subr/sqlite-test.c 
(original)
+++ 
subversion/branches/1.9.x-db-verify/subversion/tests/libsvn_subr/sqlite-test.c 
Tue Feb 24 11:56:52 2015
@@ -49,7 +49,7 @@ static svn_error_t *
 error_second(svn_sqlite__context_t *sctx,
              int argc,
              svn_sqlite__value_t *values[],
-             apr_pool_t *scratch_pool)
+             void *baton)
 {
   static int i = 0;
 

Modified: 
subversion/branches/1.9.x-db-verify/subversion/tests/libsvn_wc/db-test.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/1.9.x-db-verify/subversion/tests/libsvn_wc/db-test.c?rev=1661899&r1=1661884&r2=1661899&view=diff
==============================================================================
--- subversion/branches/1.9.x-db-verify/subversion/tests/libsvn_wc/db-test.c 
(original)
+++ subversion/branches/1.9.x-db-verify/subversion/tests/libsvn_wc/db-test.c 
Tue Feb 24 11:56:52 2015
@@ -88,256 +88,205 @@ static const char * const TESTING_DATA =
    "insert into wcroot values (1, null); "
 
    "insert into pristine values ('$sha1$" SHA1_1 "', NULL, 15, 1, '$md5 $" 
MD5_1 "'); "
+);
 
-   /* ### The file_externals column in NODES is temporary, and will be
-      ### removed.  However, to keep the tests passing, we need to add it
-      ### to the following insert statements.  *Be sure to remove it*. */
+#define NOT_MOVED FALSE, NULL
+#define NO_COPY_FROM 0, NULL, SVN_INVALID_REVNUM
 
+static const svn_test__nodes_data_t nodes_init_data[] = {
    /* load the base nodes into the nodes table */
-  "insert into nodes values ("
-  "  1, '', 0, null, 1, '', 1, 'normal',"
-  "  null, null, 'dir', '()', 'infinity', null, null, 1, " TIME_1s ", '" 
AUTHOR_1 "',"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'A', 0, '', 1, 'A', 1, 'normal',"
-  "  null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", 
'" AUTHOR_1 "',"
-  "  10, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'B', 0, '', 1, 'B', null, 'excluded',"
-  "  null, null, 'symlink', null, null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'C', 0, '', 1, 'C', null, 'server-excluded',"
-  "  null, null, 'unknown', null, null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'D', 0, '', 1, 'D', null, 'not-present',"
-  "  null, null, 'unknown', null, null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'E', 0, '', 1, 'E', null, 'incomplete',"
-  "  null, null, 'unknown', null, null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'F', 0, '', 1, 'F', 1, 'normal',"
-  "  null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", 
'" AUTHOR_1 "',"
-  "  15, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'G', 0, '', 2, 'G-alt', 1, 'normal',"
-  "  null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 2, " TIME_2s ", 
'" AUTHOR_2 "',"
-  "  15, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'H', 0, '', 1, 'H', 1, 'normal',"
-  "  null, null, 'symlink', '()', null, null, 'H-target', 1, " TIME_1s ", '" 
AUTHOR_1 "',"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'I', 0, '', 1, 'I', 1, 'normal',"
-  "  null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 
"',"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J', 0, '', 1, 'J', 1, 'normal',"
-  "  null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 
"',"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-e', 0, 'J', 1, 'J/J-e', 1, 'normal',"
-  "  null, 'other/place', 'dir', '()', null, null, null, 1, " TIME_1s ", '" 
AUTHOR_1 "',"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-e/J-e-a', 0, 'J/J-e', 1, 'J/J-e/J-e-a', 1, 'normal',"
-  "  null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", 
'" AUTHOR_1 "',"
-  "  15, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-e/J-e-b', 0, 'J/J-e', 1, 'J/J-e/J-e-b', 1, 'normal',"
-  "  null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 
"',"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-e/J-e-b/Jeba', 0, 'J/J-e/J-e-b', 1, 'J/J-e/J-e-b/Jeba', 1, 
'normal',"
-  "  null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", 
'" AUTHOR_1 "',"
-  "  15, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-f', 0, 'J', 1, 'J/J-f', 1, 'normal',"
-  "  null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 
"',"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-f/J-f-a', 0, 'J/J-f', 1, 'J/J-f/J-f-a', 1, 'normal',"
-  "  null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 
"',"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'K', 0, '', 1, 'K', 1, 'normal',"
-  "  null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 
"',"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'K/K-a', 0, 'K', 1, 'K/K-a', 1, 'normal',"
-  "  null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", 
'" AUTHOR_1 "',"
-  "  15, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'K/K-b', 0, 'K', 1, 'K/K-b', 1, 'normal',"
-  "  null, 'moved/away', 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " 
TIME_1s ", '" AUTHOR_1 "',"
-  "  15, null, null, null, null);"
-  ""
-   /* Load data into NODES table;
-      ### op_depths have not been calculated by me yet;
-      the value 1 is just 'good enough' to make the nodes WORKING nodes. */
-  "insert into nodes values ("
-  "  1, 'I', 1, '', 2, 'some/dir', 2, 'normal',"
-  "  null, null, 'dir', '()', 'immediates', null, null, 2, " TIME_2s ", '" 
AUTHOR_2 "',"
-  "  null, null, null, null, null);"
-
-   /* I'm not sure what the working J is supposed to represent.  It
-      replaces the base J, but is it a copy or not?  It has no
-      copyfrom, but nodes like J/J-e appear to be deleted which
-      implies they are children of a copied J. */
-  "insert into nodes values ("
-  "  1, 'J', 1, '', null, null, null, 'normal',"
-  "  null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-a', 1, 'J', null, null, null, 'normal',"
-  "  null, null, 'file', '()', null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-b', 2, 'J', 2, 'some/dir', 2, 'normal',"
-  "  null, null, 'dir', '()', 'infinity', null, null, 2, " TIME_2s ", '" 
AUTHOR_2 "',"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-b/J-b-a', 3, 'J/J-b', 2, 'another/dir', 2, 'normal',"
-  "  null, null, 'dir', '()', 'infinity', null, null, 2, " TIME_2s ", '" 
AUTHOR_2 "',"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-b/J-b-b', 2, 'J/J-b', null, null, 2, 'normal',"
-  "  null, null, 'file', '()', null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-c', 1, 'J', null, null, null, 'normal',"
-  "  null, null, 'dir', '()', null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-c/J-c-a', 1, 'J/J-c', null, null, null, 'normal',"
-  "  null, null, 'dir', '()', null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-c', 2, 'J', null, null, null, 'base-deleted',"
-  "  null, null, 'dir', null, null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-c/J-c-a', 2, 'J/J-c', null, null, null, 'base-deleted',"
-  "  null, null, 'dir', null, null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-d', 2, 'J', 2, 'moved/file', 2, 'normal',"
-  "  1, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 2, " TIME_2s ", '" 
AUTHOR_2 "',"
-  "  10, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'moved', 0, '', 2, 'moved', 2, 'normal',"
-  "  null, null, 'dir', '()', null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'moved/file', 0, 'moved', 2, 'moved/file', 2, 'normal',"
-  "  null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 2, " TIME_2s ", 
'" AUTHOR_2 "',"
-  "  10, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'moved/file', 2, 'moved', null, null, null, 'base-deleted',"
-  "  null, 'J/J-d', 'file', null, null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-e', 1, 'J', null, null, null, 'normal',"
-  "  null, null, 'dir', '()', null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-e/J-e-a', 1, 'J/J-e', null, null, null, 'normal',"
-  "  null, null, 'file', '()', null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-e/J-e-b', 1, 'J/J-e', null, null, null, 'normal',"
-  "  null, null, 'dir', '()', null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-e', 2, 'J', null, null, null, 'base-deleted',"
-  "  null, null, 'dir', null, null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-e/J-e-a', 2, 'J/J-e', null, null, null, 'base-deleted',"
-  "  null, null, 'file', null, null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-e/J-e-b', 2, 'J/J-e', null, null, null, 'base-deleted',"
-  "  null, null, 'dir', null, null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-e/J-e-b/Jeba', 1, 'J/J-e/J-e-b', null, null, null, 
'base-deleted',"
-  "  null, null, 'file', null, null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-f', 1, 'J', null, null, null, 'normal',"
-  "  null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'J/J-f/J-f-a', 1, 'J/J-f', null, null, null, 'base-deleted',"
-  "  null, null, 'dir', null, null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'K', 1, '', null, null, null, 'base-deleted',"
-  "  null, null, 'dir', null, null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'K/K-a', 1, 'K', null, null, null, 'base-deleted',"
-  "  null, null, 'file', null, null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'K/K-b', 1, 'K', null, null, null, 'base-deleted',"
-  "  null, null, 'file', null, null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'L', 1, '', null, null, null, 'normal',"
-  "  null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'L/L-a', 1, 'L', null, null, null, 'normal',"
-  "  null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'L/L-a/L-a-a', 1, 'L/L-a', null, null, null, 'normal',"
-  "  null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'L/L-a', 2, 'L', null, null, null, 'base-deleted',"
-  "  null, null, 'dir', null, null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'L/L-a/L-a-a', 2, 'L/L-a', null, null, null, 'base-deleted',"
-  "  null, null, 'dir', null, null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'other', 0, '', 2, 'other', 2, 'normal',"
-  "  null, null, 'dir', '()', null, null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'other/place', 2, 'other', null, null, null, 'normal',"
-  "  1, null, 'dir', '()', 'immediates', null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'other/place/J-e-a', 2, 'other/place', null, null, null, 'normal',"
-  "  null, null, 'dir', '()', 'immediates', null, null, null, null, null,"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'other/place/J-e-b', 2, 'other/place', null, null, null, 'normal',"
-  "  null, null, 'dir', '()', null, null, null, 1, " TIME_1s ", '" AUTHOR_1 
"',"
-  "  null, null, null, null, null);"
-  "insert into nodes values ("
-  "  1, 'other/place/J-e-b/Jeba', 0, 'other/place/J-e-b', null, null, null, 
'normal',"
-  "  null, null, 'file', '()', null, '$sha1$" SHA1_1 "', null, 1, " TIME_1s ", 
'" AUTHOR_1 "',"
-  "  15, null, null, null, null);"
-   "insert into actual_node values ("
-   "  1, 'A', '', null, null, null, null, null, 'changelist', null, "
-   "  null, null, null, null, null);"
-   "insert into actual_node values ("
-   "  1, 'F', '', null, null, null, null, null, null, null, "
-   "  '" F_TC_DATA "', null, null, null, null);"
-   "insert into actual_node values ("
-   "  1, 'G', '', null, null, null, null, null, null, null, "
-   "  '" G_TC_DATA "', null, null, null, null);"
-   );
+  { 0, "",            "normal",           1, "", 1,             NOT_MOVED,
+    svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
 
+  { 0, "A",           "normal",           1, "A", 1,            NOT_MOVED,
+    svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 1, TIME_1a, AUTHOR_1,
+    FALSE, NULL, 10, 10 },
+
+  { 0, "B",           "excluded",         1, "B", SVN_INVALID_REVNUM, 
NOT_MOVED,
+    svn_node_symlink},
+
+  { 0, "C",           "server-excluded",  1, "C", 0,            NOT_MOVED,
+    svn_node_unknown},
+
+  { 0, "D",           "not-present",      1, "D", 0,            NOT_MOVED,
+    svn_node_unknown},
+
+  { 0, "E",           "incomplete",       1, "E", 1,            NOT_MOVED,
+    svn_node_unknown},
+
+  { 0, "F",           "normal",           1, "F", 1,            NOT_MOVED,
+    svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2},
+
+  { 0, "G",           "normal",           2, "G-alt", 1,        NOT_MOVED,
+    svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 0, "H",           "normal",           1, "H", 1,            NOT_MOVED,
+    svn_node_symlink, "()", NULL, NULL, "H-target", 1, TIME_1a, AUTHOR_1 },
+
+  { 0, "I",           "normal",           1, "I", 1,            NOT_MOVED,
+    svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
+
+  { 0, "J",           "normal",           1, "J", 1,            NOT_MOVED,
+    svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
+
+  { 0, "J/J-e",       "normal",           1, "J/J-e", 1,        NOT_MOVED,
+    svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
+
+  { 0, "J/J-e/J-e-a", "normal",           1, "J/J-e/J-e-a", 1,  NOT_MOVED,
+    svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 1, TIME_1a, AUTHOR_1 },
+
+  { 0, "J/J-e/J-e-b", "normal",           1, "J/J-e/J-e-b", 1,  NOT_MOVED,
+    svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
+
+  { 0, "J/J-e/J-e-b/Jeba", "normal",      1, "J/J-e/J-e-b/Jeba", 1,  NOT_MOVED,
+    svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 1, TIME_1a, AUTHOR_1 },
+
+  { 0, "J/J-f",       "normal",           1, "J/J-f", 1,        NOT_MOVED,
+    svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
+
+  { 0, "J/J-f/J-f-a", "normal",           1, "J/J-f/J-f-a", 1,  NOT_MOVED,
+    svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
+
+  { 0, "J",           "normal",           1, "J", 1,            NOT_MOVED,
+    svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
+
+  { 0, "K",           "normal",           1, "K", 1,            NOT_MOVED,
+    svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
+
+  { 0, "K/K-a",       "normal",           2, "K/K-a", 1,        NOT_MOVED,
+    svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2,
+    FALSE, NULL, 15, 14},
+
+  { 0, "K/K-b",       "normal",           2, "K/K-b", 1,        NOT_MOVED,
+    svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2,
+    FALSE, NULL, 15, 14},
+
+   /* Load data into the working layers of NODES */
+
+  { 1, "I",           "normal",           2, "some/dir", 2,     NOT_MOVED,
+    svn_node_dir, "()", "immediates", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+   /* J was originally a local addition, but its descendants are replaced,
+      so let's turn J in a copy */
+  { 1, "J",           "normal",           2, "q", 2,            NOT_MOVED,
+    svn_node_dir, "()", "immediates", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 1, "J/J-a",       "normal",           2, "q/J-a", 2,        NOT_MOVED,
+    svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 1, "J/J-b",       "normal",           2, "q/J-b", 2,        NOT_MOVED,
+    svn_node_dir, "()", "infinity", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 3, "J/J-b/J-b-a", "normal",           2, "another/dir", 2,  NOT_MOVED,
+    svn_node_dir, "()", "infinity", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 1, "J/J-b/J-b-b", "normal",           2, "q/J-b/J-b-b", 2,  NOT_MOVED,
+    svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 1, "J/J-c",       "normal",           2, "q/J-c", 2,        NOT_MOVED,
+    svn_node_dir, "()", "infinity", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 1, "J/J-c/J-c-a", "normal",           2, "q/J-c/J-c-a", 2,  NOT_MOVED,
+    svn_node_dir, "()", "infinity", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 2, "J/J-c",       "base-deleted",     NO_COPY_FROM,         NOT_MOVED,
+    svn_node_dir},
+
+  { 2, "J/J-c/J-c-a", "base-deleted",     NO_COPY_FROM,         NOT_MOVED,
+    svn_node_dir},
+
+  { 2, "J/J-d",       "normal",           2, "moved/file", 2,   TRUE, NULL,
+    svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 0, "moved",       "normal",           2, "moved", 2,        NOT_MOVED,
+    svn_node_dir, "()", "infinity", NULL, NULL, 1, TIME_1a, AUTHOR_1 },
+
+  { 0, "moved/file",  "normal",           2, "moved/file", 2,   NOT_MOVED,
+    svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 2, "moved/file",  "base-deleted",     NO_COPY_FROM,         FALSE, "J/J-d",
+    svn_node_file},
+
+  { 1, "J/J-e",       "normal",           2, "q/J-e", 2,        NOT_MOVED,
+    svn_node_dir, "()", "infinity", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 1, "J/J-e/J-e-a", "normal",           2, "q/J-e/J-e-a", 2,  NOT_MOVED,
+    svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 1, "J/J-e/J-e-b", "normal",           2, "q/J-e/J-e-b", 2,  NOT_MOVED,
+    svn_node_dir, "()", "infinity", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 2, "J/J-e",       "base-deleted",     NO_COPY_FROM,         FALSE, 
"other/place",
+    svn_node_dir},
+
+  { 2, "J/J-e/J-e-a", "base-deleted",     NO_COPY_FROM,         NOT_MOVED,
+    svn_node_file},
+
+  { 2, "J/J-e/J-e-b", "base-deleted",     NO_COPY_FROM,         NOT_MOVED,
+    svn_node_dir},
+
+  { 1, "J/J-e/J-e-b/Jeba", "base-deleted", NO_COPY_FROM,        NOT_MOVED,
+    svn_node_file},
+
+  { 1, "J/J-f",       "normal",           2, "q/J-f", 2,        NOT_MOVED,
+    svn_node_dir, "()", "immediates", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 1, "J/J-f/J-f-a", "base-deleted",     NO_COPY_FROM,         NOT_MOVED,
+    svn_node_dir},
+
+  { 1, "K",           "base-deleted",     NO_COPY_FROM,         NOT_MOVED,
+    svn_node_dir},
+
+  { 1, "K/K-a",       "base-deleted",     NO_COPY_FROM,         NOT_MOVED,
+    svn_node_file},
+
+  { 1, "K/K-b",       "base-deleted",     NO_COPY_FROM,         FALSE, 
"moved/away",
+    svn_node_file},
+
+  { 1, "L",           "normal",           2, "from", 2,         NOT_MOVED,
+    svn_node_dir, "()", "immediates", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 1, "L/L-a",       "normal",           2, "from/L-a", 2,     NOT_MOVED,
+    svn_node_dir, "()", "immediates", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 1, "L/L-a/L-a-a", "normal",           2, "from/L-a/L-a-a", 2, NOT_MOVED,
+    svn_node_dir, "()", "immediates", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 2, "L/L-a",       "base-deleted",     NO_COPY_FROM,         NOT_MOVED,
+    svn_node_dir},
+
+  { 2, "L/L-a/L-a-a", "base-deleted",     NO_COPY_FROM,         NOT_MOVED,
+    svn_node_dir},
+
+  { 0, "other",       "normal",           2, "other", 2,        NOT_MOVED,
+    svn_node_dir, "()", "infinity", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 2, "other/place", "normal",           2, "q/J-e", 2,        TRUE, NULL,
+    svn_node_dir, "()", "immediates", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 2, "other/place/J-e-a", "normal",     2, "q/J-e/J-e-a", 2,  TRUE, NULL,
+    svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 2, "other/place/J-e-b", "normal",     2, "q/J-e/J-e-b", 2,  TRUE, NULL,
+    svn_node_dir, "()", "infinity", NULL, NULL, 2, TIME_2a, AUTHOR_2 },
+
+  { 2, "other/place/J-e-b/Jeba", "normal", 2, "q/J-e/J-e-b/Jeba", 2,  TRUE, 
NULL,
+    svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 1, TIME_1a, AUTHOR_1 },
+
+  /*** NEW ****/
+  { 2, "moved/away",  "normal",           2, "K/K-b", 1,        TRUE, NULL,
+    svn_node_file, "()", NULL, "$sha1$" SHA1_1, NULL, 2, TIME_2a, AUTHOR_2,
+    FALSE, NULL, 15, 14},
+  { 0 }
+};
+
+static const svn_test__actual_data_t actual_init_data[] = {
+  { "A", NULL, "changelist", NULL },
+  { "F", NULL, NULL, F_TC_DATA },
+  { "G", NULL, NULL, F_TC_DATA },
+
+  { 0 }
+};
 
 static svn_error_t *
 create_open(svn_wc__db_t **db,
@@ -354,7 +303,8 @@ create_open(svn_wc__db_t **db,
   SVN_ERR(svn_io_remove_dir2(*local_abspath, TRUE, NULL, NULL, pool));
 
   SVN_ERR(svn_wc__db_open(db, NULL, FALSE, TRUE, pool, pool));
-  SVN_ERR(svn_test__create_fake_wc(*local_abspath, TESTING_DATA, pool));
+  SVN_ERR(svn_test__create_fake_wc(*local_abspath, TESTING_DATA,
+                                   nodes_init_data, actual_init_data, pool));
 
   svn_test_add_dir_cleanup(*local_abspath);
 
@@ -374,18 +324,17 @@ set_prop(apr_hash_t *props, const char *
 }
 
 
-static svn_boolean_t
+static svn_error_t *
 validate_abspath(const char *wcroot_abspath,
                  const char *expected_relpath,
                  const char *actual_abspath,
                  apr_pool_t *scratch_pool)
 {
-  if (actual_abspath == NULL)
-    return FALSE;
-  return strcmp(svn_dirent_join(wcroot_abspath,
+  SVN_TEST_STRING_ASSERT(actual_abspath,
+                         svn_dirent_join(wcroot_abspath,
                                 expected_relpath,
-                                scratch_pool),
-                actual_abspath) == 0;
+                                scratch_pool));
+  return SVN_NO_ERROR;
 }
 
 
@@ -949,9 +898,16 @@ test_pdh(apr_pool_t *pool)
             NULL, NULL,
             pool));
 
+  SVN_ERR(svn_wc__db_base_add_directory(
+            db, svn_dirent_join(local_abspath, "sub2", pool),
+            local_abspath, "sub2", ROOT_ONE, UUID_ONE, 1,
+            apr_hash_make(pool), 1, 1, "me", NULL,
+            svn_depth_infinity, NULL, FALSE, NULL, NULL,
+            NULL, NULL, pool));
+
   SVN_ERR(svn_wc__db_base_add_excluded_node(
-            db, svn_dirent_join(local_abspath, "sub/A", pool),
-            "sub/A", ROOT_ONE, UUID_ONE, 1,
+            db, svn_dirent_join(local_abspath, "sub2/A", pool),
+            "sub2/A", ROOT_ONE, UUID_ONE, 1,
             svn_node_file, svn_wc__db_status_server_excluded,
             NULL, NULL,
             pool));
@@ -989,17 +945,17 @@ test_scan_addition(apr_pool_t *pool)
             &original_revision,
             db, svn_dirent_join(local_abspath, "J", pool),
             pool, pool));
-  SVN_TEST_ASSERT(status == svn_wc__db_status_added);
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J", op_root_abspath, pool));
+  SVN_TEST_ASSERT(status == svn_wc__db_status_copied);
+  SVN_ERR(validate_abspath(local_abspath, "J", op_root_abspath, pool));
   SVN_TEST_STRING_ASSERT(repos_relpath, "J");
   SVN_TEST_STRING_ASSERT(repos_root_url, ROOT_ONE);
   SVN_TEST_STRING_ASSERT(repos_uuid, UUID_ONE);
-  SVN_TEST_ASSERT(original_repos_relpath == NULL);
-  SVN_TEST_ASSERT(original_root_url == NULL);
-  SVN_TEST_ASSERT(original_uuid == NULL);
-  SVN_TEST_ASSERT(original_revision == SVN_INVALID_REVNUM);
+  SVN_TEST_STRING_ASSERT(original_repos_relpath, "q");
+  SVN_TEST_STRING_ASSERT(original_root_url, ROOT_TWO);
+  SVN_TEST_STRING_ASSERT(original_uuid, UUID_TWO);
+  SVN_TEST_ASSERT(original_revision == 2);
 
-  /* Simple addition of a file (affects how scan-up is started). */
+  /* Simple copy (affects how scan-up is started). */
   SVN_ERR(svn_wc__db_scan_addition(
             &status, &op_root_abspath,
             &repos_relpath, &repos_root_url, &repos_uuid,
@@ -1007,15 +963,15 @@ test_scan_addition(apr_pool_t *pool)
             &original_revision,
             db, svn_dirent_join(local_abspath, "J/J-a", pool),
             pool, pool));
-  SVN_TEST_ASSERT(status == svn_wc__db_status_added);
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J", op_root_abspath, pool));
+  SVN_TEST_ASSERT(status == svn_wc__db_status_copied);
+  SVN_ERR(validate_abspath(local_abspath, "J", op_root_abspath, pool));
   SVN_TEST_STRING_ASSERT(repos_relpath, "J/J-a");
   SVN_TEST_STRING_ASSERT(repos_root_url, ROOT_ONE);
   SVN_TEST_STRING_ASSERT(repos_uuid, UUID_ONE);
-  SVN_TEST_ASSERT(original_repos_relpath == NULL);
-  SVN_TEST_ASSERT(original_root_url == NULL);
-  SVN_TEST_ASSERT(original_uuid == NULL);
-  SVN_TEST_ASSERT(original_revision == SVN_INVALID_REVNUM);
+  SVN_TEST_STRING_ASSERT(original_repos_relpath, "q");
+  SVN_TEST_STRING_ASSERT(original_root_url, ROOT_TWO);
+  SVN_TEST_STRING_ASSERT(original_uuid, UUID_TWO);
+  SVN_TEST_ASSERT(original_revision == 2);
 
   /* Node was moved here. */
   SVN_ERR(svn_wc__db_scan_addition(
@@ -1033,15 +989,15 @@ test_scan_addition(apr_pool_t *pool)
             db, svn_dirent_join(local_abspath, "J/J-d", pool),
             pool, pool));
   SVN_TEST_ASSERT(status == svn_wc__db_status_moved_here);
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-d",
+  SVN_ERR(validate_abspath(local_abspath, "J/J-d",
                                    op_root_abspath, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "moved/file",
+  SVN_ERR(validate_abspath(local_abspath, "moved/file",
                                    moved_from_abspath, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-d",
+  SVN_ERR(validate_abspath(local_abspath, "J/J-d",
                                    move_op_root_abspath, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "moved/file",
+  SVN_ERR(validate_abspath(local_abspath, "moved/file",
                                    move_op_root_src, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "moved/file",
+  SVN_ERR(validate_abspath(local_abspath, "moved/file",
                                    delete_op_root_abspath, pool));
   SVN_TEST_STRING_ASSERT(repos_relpath, "J/J-d");
   SVN_TEST_STRING_ASSERT(repos_root_url, ROOT_ONE);
@@ -1060,12 +1016,12 @@ test_scan_addition(apr_pool_t *pool)
             db, svn_dirent_join(local_abspath, "J/J-b", pool),
             pool, pool));
   SVN_TEST_ASSERT(status == svn_wc__db_status_copied);
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-b",
+  SVN_ERR(validate_abspath(local_abspath, "J",
                                    op_root_abspath, pool));
   SVN_TEST_STRING_ASSERT(repos_relpath, "J/J-b");
   SVN_TEST_STRING_ASSERT(repos_root_url, ROOT_ONE);
   SVN_TEST_STRING_ASSERT(repos_uuid, UUID_ONE);
-  SVN_TEST_STRING_ASSERT(original_repos_relpath, "some/dir");
+  SVN_TEST_STRING_ASSERT(original_repos_relpath, "q");
   SVN_TEST_STRING_ASSERT(original_root_url, ROOT_TWO);
   SVN_TEST_STRING_ASSERT(original_uuid, UUID_TWO);
   SVN_TEST_ASSERT(original_revision == 2);
@@ -1079,7 +1035,7 @@ test_scan_addition(apr_pool_t *pool)
             db, svn_dirent_join(local_abspath, "J/J-b/J-b-a", pool),
             pool, pool));
   SVN_TEST_ASSERT(status == svn_wc__db_status_copied);
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-b/J-b-a",
+  SVN_ERR(validate_abspath(local_abspath, "J/J-b/J-b-a",
                                    op_root_abspath, pool));
   SVN_TEST_STRING_ASSERT(repos_relpath, "J/J-b/J-b-a");
   SVN_TEST_STRING_ASSERT(repos_root_url, ROOT_ONE);
@@ -1098,12 +1054,12 @@ test_scan_addition(apr_pool_t *pool)
             db, svn_dirent_join(local_abspath, "J/J-b/J-b-b", pool),
             pool, pool));
   SVN_TEST_ASSERT(status == svn_wc__db_status_copied);
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-b",
+  SVN_ERR(validate_abspath(local_abspath, "J",
                                    op_root_abspath, pool));
   SVN_TEST_STRING_ASSERT(repos_relpath, "J/J-b/J-b-b");
   SVN_TEST_STRING_ASSERT(repos_root_url, ROOT_ONE);
   SVN_TEST_STRING_ASSERT(repos_uuid, UUID_ONE);
-  SVN_TEST_STRING_ASSERT(original_repos_relpath, "some/dir");
+  SVN_TEST_STRING_ASSERT(original_repos_relpath, "q");
   SVN_TEST_STRING_ASSERT(original_root_url, ROOT_TWO);
   SVN_TEST_STRING_ASSERT(original_uuid, UUID_TWO);
   SVN_TEST_ASSERT(original_revision == 2);
@@ -1132,13 +1088,13 @@ test_scan_deletion(apr_pool_t *pool)
             &copy_op_root_abspath,
             db, svn_dirent_join(local_abspath, "J/J-e", pool),
             pool, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J",
+  SVN_ERR(validate_abspath(local_abspath, "J",
                                    base_del_abspath, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "other/place",
+  SVN_ERR(validate_abspath(local_abspath, "other/place",
                                    moved_to_abspath, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-e",
+  SVN_ERR(validate_abspath(local_abspath, "J/J-e",
                                    work_del_abspath, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "other/place",
+  SVN_ERR(validate_abspath(local_abspath, "other/place",
                                    copy_op_root_abspath, pool));
 
   /* Node was moved elsewhere (child of operation root). */
@@ -1149,13 +1105,13 @@ test_scan_deletion(apr_pool_t *pool)
             &copy_op_root_abspath,
             db, svn_dirent_join(local_abspath, "J/J-e/J-e-a", pool),
             pool, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J",
+  SVN_ERR(validate_abspath(local_abspath, "J",
                                    base_del_abspath, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "other/place/J-e-a",
+  SVN_ERR(validate_abspath(local_abspath, "other/place/J-e-a",
                                    moved_to_abspath, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-e",
+  SVN_ERR(validate_abspath(local_abspath, "J/J-e",
                                    work_del_abspath, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "other/place",
+  SVN_ERR(validate_abspath(local_abspath, "other/place",
                                    copy_op_root_abspath, pool));
 
   /* Root of delete. Parent is a WORKING node. */
@@ -1167,10 +1123,10 @@ test_scan_deletion(apr_pool_t *pool)
             db, svn_dirent_join(local_abspath, "J/J-c", pool),
             pool, pool));
   /* Implicit delete of "J" (via replacement).  */
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J",
+  SVN_ERR(validate_abspath(local_abspath, "J",
                                    base_del_abspath, pool));
   SVN_TEST_ASSERT(moved_to_abspath == NULL);
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-c",
+  SVN_ERR(validate_abspath(local_abspath, "J/J-c",
                                    work_del_abspath, pool));
 
   /* Child of a deleted root. */
@@ -1182,10 +1138,10 @@ test_scan_deletion(apr_pool_t *pool)
             db, svn_dirent_join(local_abspath, "J/J-c/J-c-a", pool),
             pool, pool));
   /* Implicit delete of "J" (via replacement).  */
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J",
+  SVN_ERR(validate_abspath(local_abspath, "J",
                                    base_del_abspath, pool));
   SVN_TEST_ASSERT(moved_to_abspath == NULL);
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J/J-c",
+  SVN_ERR(validate_abspath(local_abspath, "J/J-c",
                                    work_del_abspath, pool));
 
   /* Base-deleted tree extending past deleted WORKING subtree.  */
@@ -1199,11 +1155,11 @@ test_scan_deletion(apr_pool_t *pool)
   /* ### I don't understand this.  "J/J-e/J-e-b/Jeba" is a deleted
      base node that is not overlayed by the replacement rooted at "J".
      Why does base_del_abspath refer to "J-e"?  */
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J",
+  SVN_ERR(validate_abspath(local_abspath, "J",
                                    base_del_abspath, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "other/place/J-e-b/Jeba",
+  SVN_ERR(validate_abspath(local_abspath, "other/place/J-e-b/Jeba",
                                    moved_to_abspath, pool));
-  SVN_TEST_ASSERT(work_del_abspath == NULL);
+  SVN_TEST_STRING_ASSERT(work_del_abspath, NULL);
 
   /* Base-deleted tree extending past added WORKING tree.  */
   SVN_ERR(svn_wc__db_scan_deletion(
@@ -1214,10 +1170,10 @@ test_scan_deletion(apr_pool_t *pool)
             db, svn_dirent_join(local_abspath, "J/J-f/J-f-a", pool),
             pool, pool));
   /* Implicit delete of "J" (via replacement).  */
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "J",
+  SVN_ERR(validate_abspath(local_abspath, "J",
                                    base_del_abspath, pool));
-  SVN_TEST_ASSERT(moved_to_abspath == NULL);
-  SVN_TEST_ASSERT(work_del_abspath == NULL);
+  SVN_TEST_STRING_ASSERT(moved_to_abspath, NULL);
+  SVN_TEST_STRING_ASSERT(work_del_abspath, NULL);
 
   /* Root of delete. Parent is a BASE node. */
   SVN_ERR(svn_wc__db_scan_deletion(
@@ -1227,10 +1183,10 @@ test_scan_deletion(apr_pool_t *pool)
             NULL,
             db, svn_dirent_join(local_abspath, "K", pool),
             pool, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "K",
+  SVN_ERR(validate_abspath(local_abspath, "K",
                                    base_del_abspath, pool));
-  SVN_TEST_ASSERT(moved_to_abspath == NULL);
-  SVN_TEST_ASSERT(work_del_abspath == NULL);
+  SVN_TEST_STRING_ASSERT(moved_to_abspath, NULL);
+  SVN_TEST_STRING_ASSERT(work_del_abspath, NULL);
 
   /* Base-deleted tree. Start below root.  */
   SVN_ERR(svn_wc__db_scan_deletion(
@@ -1240,10 +1196,10 @@ test_scan_deletion(apr_pool_t *pool)
             NULL,
             db, svn_dirent_join(local_abspath, "K/K-a", pool),
             pool, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "K",
+  SVN_ERR(validate_abspath(local_abspath, "K",
                                    base_del_abspath, pool));
-  SVN_TEST_ASSERT(moved_to_abspath == NULL);
-  SVN_TEST_ASSERT(work_del_abspath == NULL);
+  SVN_TEST_STRING_ASSERT(moved_to_abspath, NULL);
+  SVN_TEST_STRING_ASSERT(work_del_abspath, NULL);
 
   /* Base-deleted tree via move.  */
   SVN_ERR(svn_wc__db_scan_deletion(
@@ -1253,13 +1209,13 @@ test_scan_deletion(apr_pool_t *pool)
             &copy_op_root_abspath,
             db, svn_dirent_join(local_abspath, "K/K-b", pool),
             pool, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "K",
+  SVN_ERR(validate_abspath(local_abspath, "K",
                                    base_del_abspath, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "moved/away",
+  SVN_ERR(validate_abspath(local_abspath, "moved/away",
                                    moved_to_abspath, pool));
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "moved/away",
+  SVN_ERR(validate_abspath(local_abspath, "moved/away",
                                    copy_op_root_abspath, pool));
-  SVN_TEST_ASSERT(work_del_abspath == NULL);
+  SVN_TEST_STRING_ASSERT(work_del_abspath, NULL);
 
   /* Subtree deletion of added tree. Start at child.  */
   SVN_ERR(svn_wc__db_scan_deletion(
@@ -1269,9 +1225,9 @@ test_scan_deletion(apr_pool_t *pool)
             NULL,
             db, svn_dirent_join(local_abspath, "L/L-a/L-a-a", pool),
             pool, pool));
-  SVN_TEST_ASSERT(base_del_abspath == NULL);
-  SVN_TEST_ASSERT(moved_to_abspath == NULL);
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "L/L-a",
+  SVN_TEST_STRING_ASSERT(base_del_abspath, NULL);
+  SVN_TEST_STRING_ASSERT(moved_to_abspath, NULL);
+  SVN_ERR(validate_abspath(local_abspath, "L/L-a",
                                    work_del_abspath, pool));
 
   /* Subtree deletion of added tree. Start at root.  */
@@ -1282,9 +1238,9 @@ test_scan_deletion(apr_pool_t *pool)
             NULL,
             db, svn_dirent_join(local_abspath, "L/L-a", pool),
             pool, pool));
-  SVN_TEST_ASSERT(base_del_abspath == NULL);
-  SVN_TEST_ASSERT(moved_to_abspath == NULL);
-  SVN_TEST_ASSERT(validate_abspath(local_abspath, "L/L-a",
+  SVN_TEST_STRING_ASSERT(base_del_abspath, NULL);
+  SVN_TEST_STRING_ASSERT(moved_to_abspath, NULL);
+  SVN_ERR(validate_abspath(local_abspath, "L/L-a",
                                    work_del_abspath, pool));
 
   return SVN_NO_ERROR;


Reply via email to