Author: julianfoad
Date: Fri Feb 11 14:24:47 2022
New Revision: 1897977

URL: http://svn.apache.org/viewvc?rev=1897977&view=rev
Log:
On the 'pristines-on-demand-on-mwf' branch: be compatible with older WCs.

This makes the behaviour conditional on the WC format alone, with no further
configuration option:

  - pristines-on-demand when WC format is 32;
  - all pristines assumed present when WC format is 31.

This is incomplete.

  - With 'make check WC_FORMAT_VERSION=1.15': test suite still passes.
  - With 'make check [WC_FORMAT_VERSION=1.8]': some tests FAIL or XPASS:

    XPASS: authz_tests.py 31: remove a subdir with authz file
    XPASS: basic_tests.py 8: basic corruption detection on commit
           [[Relies on wc.text_base_path()]]
    XPASS: revert_tests.py 2: revert reexpands manually contracted keyword
    XPASS: trans_tests.py 1: commit new files with keywords active from birth
           [[Relies on wc.text_base_path()]]
    XPASS: trans_tests.py 3: committing eol-style change forces text send
           [[Relies on wc.text_base_path()]]
    XPASS: update_tests.py 83: missing tmp update caused segfault
           [[The error message has changed]]
    XPASS: upgrade_tests.py 16: upgrade with base and working replaced files
           [[Can't fetch pristines: the working copy points to 
file:///tmp/repo]]
    XPASS: upgrade_tests.py 34: automatic SQLite ANALYZE
    FAIL:  wc-queries-test 3: test query expectations

* subversion/libsvn_wc/textbase.c
  (svn_wc__textbase_sync): Skip the sync when WC format is too low.

* subversion/libsvn_wc/upgrade.c
  (migrate_text_bases): Use schema format 31, as further upgrade is handled
    elsewhere.

* subversion/libsvn_wc/wc.h
  (SVN_WC__PRISTINES_ON_DEMAND_VERSION): New constant.

* subversion/libsvn_wc/wc_db.h,
  subversion/libsvn_wc/wc_db_pristine.c
  (svn_wc__db_pristine_prepare_install): Never omit prisine in old schema.
  (stmt_select_pristine): New function, factored out from four call sites.
    Use old or new schema as appropriate.
  (maybe_transfer_one_pristine,
   pristine_transfer_txn): Use old or new schema as appropriate.

* subversion/libsvn_wc/wc_db.h,
  subversion/libsvn_wc/wc_db_wcroot.c
  (svn_wc__db_pristines_mode): New.

* subversion/libsvn_wc/wc_db_private.h,
  subversion/libsvn_wc/wc_db_wcroot.c
  (svn_wc__db_wcroot_t): Add a 'pristines_mode' field, ...
  (svn_wc__db_pdh_create_wcroot): ... and set it based on the WC format.

* subversion/libsvn_wc/wc-queries.sql
  (STMT_INSERT_OR_IGNORE_PRISTINE,
   STMT_UPSERT_PRISTINE,
   STMT_SELECT_PRISTINE,
   STMT_SELECT_COPY_PRISTINES): Split each query into a '*_F31' version to
    match the old schema and a '*_F32' version to match the new schema.

* subversion/tests/libsvn_wc/db-test.c,
  subversion/tests/libsvn_wc/entries-compat.c
  (TESTING_DATA): Split into a '*_F31' version to
    match the old schema and a '*_F32' version to match the new schema.
  (testing_wc_format_32): New.
  (create_open, create_fake_wc): Use old or new schema as appropriate.

* subversion/tests/libsvn_wc/op-depth-test.c
  (stmt_for_f31_or_f32): New.
  (insert_actual): Use old or new schema as appropriate.

* subversion/tests/libsvn_wc/pristine-store-test.c
  (testing_wc_format_32): New.
  (pristine_install_dehydrated): Adjust expectations according to WC format.
  (pristine_dehydrate): Skip if testing against the old WC format.

* subversion/tests/libsvn_wc/wc-queries-test.c
  (stmt_matches_wc_format): New.
  (test_parsable,
   test_query_expectations): Skip statements that do not match the WC format
    under test.

* subversion/tests/libsvn_wc/wc-test-queries.sql
  (STMT_ENSURE_EMPTY_PRISTINE): Split into a '*_F31' version to
    match the old schema and a '*_F32' version to match the new schema.

Modified:
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/textbase.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/upgrade.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc-queries.sql
    subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc.h
    subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db.h
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_pristine.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_private.h
    
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_wcroot.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/db-test.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/entries-compat.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/op-depth-test.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/pristine-store-test.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-queries-test.c
    
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-test-queries.sql

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/textbase.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/textbase.c?rev=1897977&r1=1897976&r2=1897977&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/textbase.c 
(original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/textbase.c 
Fri Feb 11 14:24:47 2022
@@ -527,10 +527,16 @@ svn_wc__textbase_sync(svn_wc_context_t *
                       void *cancel_baton,
                       apr_pool_t *scratch_pool)
 {
+  const char *mode;
   textbase_sync_baton_t baton = {0};
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath));
 
+  SVN_ERR(svn_wc__db_pristines_mode(&mode, wc_ctx->db, local_abspath,
+                                    scratch_pool));
+  if (strcmp(mode, "local-only") == 0)
+    return SVN_NO_ERROR;
+
   baton.db = wc_ctx->db;
   baton.hydrate_callback = hydrate_callback;
   baton.hydrate_baton = hydrate_baton;

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/upgrade.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/upgrade.c?rev=1897977&r1=1897976&r2=1897977&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/upgrade.c 
(original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/upgrade.c 
Fri Feb 11 14:24:47 2022
@@ -1074,11 +1074,10 @@ migrate_text_bases(apr_hash_t **text_bas
 
         /* Insert a row into the pristine table. */
         SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
-                                          STMT_INSERT_OR_IGNORE_PRISTINE));
+                                          STMT_INSERT_OR_IGNORE_PRISTINE_F31));
         SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, iterpool));
         SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, md5_checksum, iterpool));
         SVN_ERR(svn_sqlite__bind_int64(stmt, 3, finfo.size));
-        SVN_ERR(svn_sqlite__bind_int(stmt, 4, TRUE));
         SVN_ERR(svn_sqlite__insert(NULL, stmt));
 
         SVN_ERR(svn_wc__db_pristine_get_future_path(&pristine_path,

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc-queries.sql
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc-queries.sql?rev=1897977&r1=1897976&r2=1897977&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc-queries.sql
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc-queries.sql
 Fri Feb 11 14:24:47 2022
@@ -883,19 +883,33 @@ SELECT id, work FROM work_queue ORDER BY
 -- STMT_DELETE_WORK_ITEM
 DELETE FROM work_queue WHERE id = ?1
 
--- STMT_INSERT_OR_IGNORE_PRISTINE
+-- STMT_INSERT_OR_IGNORE_PRISTINE_F31
+INSERT OR IGNORE INTO pristine (checksum, md5_checksum, size, refcount)
+VALUES (?1, ?2, ?3, 0)
+
+-- STMT_INSERT_OR_IGNORE_PRISTINE_F32
 INSERT OR IGNORE INTO pristine (checksum, md5_checksum, size, refcount, 
hydrated)
 VALUES (?1, ?2, ?3, 0, ?4)
 
--- STMT_UPSERT_PRISTINE
+-- STMT_UPSERT_PRISTINE_F31
 /* ### Probably need to bump the minimum SQLite version for UPSERT support
    https://www.sqlite.org/lang_UPSERT.html
  */
+INSERT INTO pristine (checksum, md5_checksum, size, refcount)
+VALUES (?1, ?2, ?3, 0)
+ON CONFLICT(checksum) DO UPDATE SET size=?3
+
+-- STMT_UPSERT_PRISTINE_F32
 INSERT INTO pristine (checksum, md5_checksum, size, refcount, hydrated)
 VALUES (?1, ?2, ?3, 0, ?4)
 ON CONFLICT(checksum) DO UPDATE SET size=?3, hydrated=?4
 
--- STMT_SELECT_PRISTINE
+-- STMT_SELECT_PRISTINE_F31
+SELECT md5_checksum, size, 1
+FROM pristine
+WHERE checksum = ?1
+
+-- STMT_SELECT_PRISTINE_F32
 SELECT md5_checksum, size, hydrated
 FROM pristine
 WHERE checksum = ?1
@@ -914,7 +928,26 @@ WHERE refcount = 0
 DELETE FROM pristine
 WHERE checksum = ?1 AND refcount = 0
 
--- STMT_SELECT_COPY_PRISTINES
+-- STMT_SELECT_COPY_PRISTINES_F31
+/* For the root itself */
+SELECT n.checksum, md5_checksum, size, 1
+FROM nodes_current n
+LEFT JOIN pristine p ON n.checksum = p.checksum
+WHERE wc_id = ?1
+  AND n.local_relpath = ?2
+  AND n.checksum IS NOT NULL
+UNION ALL
+/* And all descendants */
+SELECT n.checksum, md5_checksum, size, 1
+FROM nodes n
+LEFT JOIN pristine p ON n.checksum = p.checksum
+WHERE wc_id = ?1
+  AND IS_STRICT_DESCENDANT_OF(n.local_relpath, ?2)
+  AND op_depth >=
+      (SELECT MAX(op_depth) FROM nodes WHERE wc_id = ?1 AND local_relpath = ?2)
+  AND n.checksum IS NOT NULL
+
+-- STMT_SELECT_COPY_PRISTINES_F32
 /* For the root itself */
 SELECT n.checksum, md5_checksum, size, p.hydrated
 FROM nodes_current n

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc.h?rev=1897977&r1=1897976&r2=1897977&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc.h 
(original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc.h 
Fri Feb 11 14:24:47 2022
@@ -206,6 +206,10 @@ extern "C" {
    sqlite_stat1 table on opening */
 #define SVN_WC__ENSURE_STAT1_TABLE 31
 
+/* Starting from this version, pristines can be missing and fetched on
+ * demand.  */
+#define SVN_WC__PRISTINES_ON_DEMAND_VERSION 32
+
 /* Return a string indicating the released version (or versions) of
  * Subversion that used WC format number WC_FORMAT, or some other
  * suitable string if no released version used WC_FORMAT.

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db.h?rev=1897977&r1=1897976&r2=1897977&view=diff
==============================================================================
--- subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db.h 
(original)
+++ subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db.h 
Fri Feb 11 14:24:47 2022
@@ -971,7 +971,8 @@ typedef struct svn_wc__db_install_data_t
    set to the MD-5 and SHA-1 checksums respectively of that file.
    MD5_CHECKSUM and/or SHA1_CHECKSUM may be NULL if not wanted.
 
-   If HYDRATED is true, the contents of the pristine will be saved to disk.
+   The contents of the pristine will be saved to disk if HYDRATED is true or
+   if the WC version or configuration doesn't allow dehydrated pristines.
 
    Allocate the new stream, path and checksums in RESULT_POOL.
  */
@@ -1085,6 +1086,14 @@ svn_wc__db_pristine_dehydrate(svn_wc__db
                               const svn_checksum_t *sha1_checksum,
                               apr_pool_t *scratch_pool);
 
+/* Return the *PRISTINES_MODE for the WC at (DB, LOCAL_ABSPATH).
+ */
+svn_error_t *
+svn_wc__db_pristines_mode(const char **pristines_mode,
+                          svn_wc__db_t *db,
+                          const char *local_abspath,
+                          apr_pool_t *scratch_pool);
+
 /* @defgroup svn_wc__db_external  External management
    @{ */
 

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_pristine.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_pristine.c?rev=1897977&r1=1897976&r2=1897977&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_pristine.c
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_pristine.c
 Fri Feb 11 14:24:47 2022
@@ -106,6 +106,52 @@ svn_wc__db_pristine_get_future_path(cons
   return SVN_NO_ERROR;
 }
 
+/* Read *HAVE_ROW, *MD5_CHECKSUM, *SIZE, *HYDRATED for WCROOT:SHA1_CHECKSUM.
+ * If it returns with *HAVE_ROW=FALSE, other outputs are null/zero/false.
+ */
+static svn_error_t *
+stmt_select_pristine(svn_boolean_t *have_row,
+                     const svn_checksum_t **md5_checksum,
+                     svn_filesize_t *size,
+                     svn_boolean_t *hydrated,
+                     svn_wc__db_wcroot_t *wcroot,
+                     const svn_checksum_t *sha1_checksum,
+                     apr_pool_t *result_pool,
+                     apr_pool_t *scratch_pool)
+{
+  int stmt_num;
+  svn_sqlite__stmt_t *stmt;
+
+  /* Check that this pristine text is present in the store.  (The presence
+   * of the file is not sufficient.) */
+  stmt_num = (wcroot->format >= SVN_WC__PRISTINES_ON_DEMAND_VERSION
+              ? STMT_SELECT_PRISTINE_F32
+              : STMT_SELECT_PRISTINE_F31);
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, stmt_num));
+  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool));
+  SVN_ERR(svn_sqlite__step(have_row, stmt));
+  if (!*have_row)
+    {
+      if (md5_checksum)
+        *md5_checksum = NULL;
+      if (size)
+        *size = 0;
+      if (hydrated)
+        *hydrated = FALSE;
+      return svn_sqlite__reset(stmt);
+    }
+
+  if (md5_checksum)
+    SVN_ERR(svn_sqlite__column_checksum(md5_checksum, stmt, 0, result_pool));
+  if (size)
+    *size = svn_sqlite__column_int64(stmt, 1);
+  if (hydrated)
+    *hydrated = svn_sqlite__column_boolean(stmt, 2);
+
+  SVN_ERR(svn_sqlite__reset(stmt));
+  return SVN_NO_ERROR;
+}
+
 /* Set *CONTENTS to a readable stream from which the pristine text
  * identified by SHA1_CHECKSUM and PRISTINE_ABSPATH can be read from the
  * pristine store of WCROOT.  If the pristine contents are currently not
@@ -131,22 +177,14 @@ pristine_read_txn(svn_stream_t **content
                   apr_pool_t *result_pool,
                   apr_pool_t *scratch_pool)
 {
-  svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
   svn_boolean_t hydrated;
 
   /* Check that this pristine text is present in the store.  (The presence
    * of the file is not sufficient.) */
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_SELECT_PRISTINE));
-  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-
-  if (size)
-    *size = svn_sqlite__column_int64(stmt, 1);
-
-  hydrated = svn_sqlite__column_boolean(stmt, 2);
-
-  SVN_ERR(svn_sqlite__reset(stmt));
+  SVN_ERR(stmt_select_pristine(&have_row, NULL, size, &hydrated,
+                               wcroot, sha1_checksum,
+                               result_pool, scratch_pool));
   if (! have_row)
     {
       return svn_error_createf(SVN_ERR_WC_PATH_NOT_FOUND, NULL,
@@ -291,7 +329,7 @@ pristine_get_tempdir(svn_wc__db_wcroot_t
  * Implements 'notes/wc-ng/pristine-store' section A-3(a).
  */
 static svn_error_t *
-pristine_install_txn(svn_sqlite__db_t *sdb,
+pristine_install_txn(svn_wc__db_wcroot_t *wcroot,
                      svn_wc__db_install_data_t *install_data,
                      /* The target path for the file (within the pristine 
store). */
                      const char *pristine_abspath,
@@ -302,20 +340,14 @@ pristine_install_txn(svn_sqlite__db_t *s
                      apr_pool_t *scratch_pool)
 {
   svn_stream_t *install_stream = install_data->inner_stream;
+  int stmt_num;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
   svn_boolean_t hydrated;
 
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_SELECT_PRISTINE));
-  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-
-  if (have_row)
-    hydrated = svn_sqlite__column_boolean(stmt, 2);
-  else
-    hydrated = FALSE;
-
-  SVN_ERR(svn_sqlite__reset(stmt));
+  SVN_ERR(stmt_select_pristine(&have_row, NULL, NULL, &hydrated,
+                               wcroot, sha1_checksum,
+                               scratch_pool, scratch_pool));
 
   if (have_row && hydrated)
     {
@@ -345,11 +377,14 @@ pristine_install_txn(svn_sqlite__db_t *s
       SVN_ERR(svn_io_remove_file2(pristine_abspath, TRUE, scratch_pool));
     }
 
-  SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_UPSERT_PRISTINE));
+  stmt_num = (wcroot->format >= SVN_WC__PRISTINES_ON_DEMAND_VERSION
+              ? STMT_UPSERT_PRISTINE_F32 : STMT_UPSERT_PRISTINE_F31);
+  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, stmt_num));
   SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool));
   SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, md5_checksum, scratch_pool));
   SVN_ERR(svn_sqlite__bind_int64(stmt, 3, install_data->size));
-  SVN_ERR(svn_sqlite__bind_int(stmt, 4, install_stream != NULL));
+  if (wcroot->format >= SVN_WC__PRISTINES_ON_DEMAND_VERSION)
+    SVN_ERR(svn_sqlite__bind_int(stmt, 4, install_stream != NULL));
   SVN_ERR(svn_sqlite__insert(NULL, stmt));
 
   return SVN_NO_ERROR;
@@ -383,7 +418,7 @@ svn_wc__db_pristine_prepare_install(svn_
   install_data = apr_pcalloc(result_pool, sizeof(*install_data));
   install_data->wcroot = wcroot;
 
-  if (hydrated)
+  if (hydrated || strcmp(wcroot->pristines_mode, "local-only") == 0)
     {
       SVN_ERR_W(svn_stream__create_for_install(&install_data->inner_stream,
                                                temp_dir_abspath,
@@ -436,7 +471,7 @@ svn_wc__db_pristine_install(svn_wc__db_i
   /* Ensure the SQL txn has at least a 'RESERVED' lock before we start looking
    * at the disk, to ensure no concurrent pristine install/delete txn. */
   SVN_SQLITE__WITH_IMMEDIATE_TXN(
-    pristine_install_txn(wcroot->sdb,
+    pristine_install_txn(wcroot,
                          install_data, pristine_abspath,
                          sha1_checksum, md5_checksum,
                          scratch_pool),
@@ -468,7 +503,6 @@ svn_wc__db_pristine_get_md5(const svn_ch
 {
   svn_wc__db_wcroot_t *wcroot;
   const char *local_relpath;
-  svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(wri_abspath));
@@ -479,20 +513,19 @@ svn_wc__db_pristine_get_md5(const svn_ch
                               wri_abspath, scratch_pool, scratch_pool));
   VERIFY_USABLE_WCROOT(wcroot);
 
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_SELECT_PRISTINE));
-  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
+  SVN_ERR(stmt_select_pristine(&have_row, md5_checksum, NULL, NULL,
+                               wcroot, sha1_checksum,
+                               result_pool, scratch_pool));
   if (!have_row)
-    return svn_error_createf(SVN_ERR_WC_DB_ERROR, svn_sqlite__reset(stmt),
+    return svn_error_createf(SVN_ERR_WC_DB_ERROR, NULL,
                              _("The pristine text with checksum '%s' was "
                                "not found"),
                              svn_checksum_to_cstring_display(sha1_checksum,
                                                              scratch_pool));
 
-  SVN_ERR(svn_sqlite__column_checksum(md5_checksum, stmt, 0, result_pool));
   SVN_ERR_ASSERT((*md5_checksum)->kind == svn_checksum_md5);
 
-  return svn_error_trace(svn_sqlite__reset(stmt));
+  return SVN_NO_ERROR;
 }
 
 
@@ -548,15 +581,19 @@ maybe_transfer_one_pristine(svn_wc__db_w
                             void *cancel_baton,
                             apr_pool_t *scratch_pool)
 {
+  int stmt_num;
   svn_sqlite__stmt_t *stmt;
   int affected_rows;
 
-  SVN_ERR(svn_sqlite__get_statement(&stmt, dst_wcroot->sdb,
-                                    STMT_INSERT_OR_IGNORE_PRISTINE));
+  stmt_num = (dst_wcroot->format >= SVN_WC__PRISTINES_ON_DEMAND_VERSION
+              ? STMT_INSERT_OR_IGNORE_PRISTINE_F32
+              : STMT_INSERT_OR_IGNORE_PRISTINE_F31);
+  SVN_ERR(svn_sqlite__get_statement(&stmt, dst_wcroot->sdb, stmt_num));
   SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, checksum, scratch_pool));
   SVN_ERR(svn_sqlite__bind_checksum(stmt, 2, md5_checksum, scratch_pool));
   SVN_ERR(svn_sqlite__bind_int64(stmt, 3, size));
-  SVN_ERR(svn_sqlite__bind_int(stmt, 4, hydrated));
+  if (dst_wcroot->format >= SVN_WC__PRISTINES_ON_DEMAND_VERSION)
+    SVN_ERR(svn_sqlite__bind_int(stmt, 4, hydrated));
 
   SVN_ERR(svn_sqlite__update(&affected_rows, stmt));
 
@@ -635,12 +672,15 @@ pristine_transfer_txn(svn_wc__db_wcroot_
                        void *cancel_baton,
                        apr_pool_t *scratch_pool)
 {
+  int stmt_num;
   svn_sqlite__stmt_t *stmt;
   svn_boolean_t got_row;
   apr_pool_t *iterpool = svn_pool_create(scratch_pool);
 
-  SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb,
-                                    STMT_SELECT_COPY_PRISTINES));
+  stmt_num = (dst_wcroot->format >= SVN_WC__PRISTINES_ON_DEMAND_VERSION
+              ? STMT_SELECT_COPY_PRISTINES_F32
+              : STMT_SELECT_COPY_PRISTINES_F31);
+  SVN_ERR(svn_sqlite__get_statement(&stmt, src_wcroot->sdb, stmt_num));
   SVN_ERR(svn_sqlite__bindf(stmt, "is", src_wcroot->wc_id, src_relpath));
 
   /* This obtains an sqlite read lock on src_wcroot */
@@ -912,7 +952,6 @@ svn_wc__db_pristine_check(svn_boolean_t
 {
   svn_wc__db_wcroot_t *wcroot;
   const char *local_relpath;
-  svn_sqlite__stmt_t *stmt;
   svn_boolean_t have_row;
 
   SVN_ERR_ASSERT(svn_dirent_is_absolute(wri_abspath));
@@ -932,15 +971,9 @@ svn_wc__db_pristine_check(svn_boolean_t
   VERIFY_USABLE_WCROOT(wcroot);
 
   /* Check that there is an entry in the PRISTINE table. */
-  SVN_ERR(svn_sqlite__get_statement(&stmt, wcroot->sdb, STMT_SELECT_PRISTINE));
-  SVN_ERR(svn_sqlite__bind_checksum(stmt, 1, sha1_checksum, scratch_pool));
-  SVN_ERR(svn_sqlite__step(&have_row, stmt));
-
-  if (hydrated)
-    *hydrated = svn_sqlite__column_boolean(stmt, 2);
-
-  SVN_ERR(svn_sqlite__reset(stmt));
-
+  SVN_ERR(stmt_select_pristine(&have_row, NULL, NULL, hydrated,
+                               wcroot, sha1_checksum,
+                               scratch_pool, scratch_pool));
   *present = have_row;
   return SVN_NO_ERROR;
 }

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_private.h
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_private.h?rev=1897977&r1=1897976&r2=1897977&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_private.h
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_private.h
 Fri Feb 11 14:24:47 2022
@@ -107,6 +107,9 @@ typedef struct svn_wc__db_wcroot_t {
      const char *local_abspath -> svn_wc_adm_access_t *adm_access */
   apr_hash_t *access_cache;
 
+  /* How to manage the pristines ("local-only" or "on-demand") */
+  const char *pristines_mode;
+
 } svn_wc__db_wcroot_t;
 
 

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_wcroot.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_wcroot.c?rev=1897977&r1=1897976&r2=1897977&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_wcroot.c
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/libsvn_wc/wc_db_wcroot.c
 Fri Feb 11 14:24:47 2022
@@ -390,6 +390,12 @@ svn_wc__db_pdh_create_wcroot(svn_wc__db_
   (*wcroot)->owned_locks = apr_array_make(result_pool, 8,
                                           sizeof(svn_wc__db_wclock_t));
   (*wcroot)->access_cache = apr_hash_make(result_pool);
+  /* Determine the pristines-mode for this WC. */
+  /* ### TODO: read this from per-WC storage instead of locked to wc format */
+  if (format < SVN_WC__PRISTINES_ON_DEMAND_VERSION)
+    (*wcroot)->pristines_mode = "local-only";
+  else
+    (*wcroot)->pristines_mode = "on-demand";
 
   /* SDB will be NULL for pre-NG working copies. We only need to run a
      cleanup when the SDB is present.  */
@@ -1112,3 +1118,21 @@ svn_wc__format_from_context(int *format,
     return SVN_NO_ERROR;
   }
 }
+
+svn_error_t *
+svn_wc__db_pristines_mode(const char **pristines_mode,
+                          svn_wc__db_t *db,
+                          const char *local_abspath,
+                          apr_pool_t *scratch_pool)
+{
+  svn_wc__db_wcroot_t *wcroot;
+  const char *local_relpath;
+
+  SVN_ERR(svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath, db,
+                                                local_abspath, scratch_pool,
+                                                scratch_pool));
+  VERIFY_USABLE_WCROOT(wcroot);
+
+  *pristines_mode = wcroot->pristines_mode;
+  return SVN_NO_ERROR;
+}

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/db-test.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/db-test.c?rev=1897977&r1=1897976&r2=1897977&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/db-test.c
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/db-test.c
 Fri Feb 11 14:24:47 2022
@@ -36,6 +36,7 @@
 
 #include "svn_dirent_uri.h"
 #include "svn_pools.h"
+#include "svn_version.h"
 
 #include "private/svn_sqlite.h"
 
@@ -77,7 +78,20 @@
 #define F_TC_DATA "(conflict F file update edited deleted (version 22 " 
ROOT_ONE " 1 2 branch1/ft/F none) (version 22 " ROOT_ONE " 1 3 branch1/ft/F 
file))"
 #define G_TC_DATA "(conflict G file update edited deleted (version 22 " 
ROOT_ONE " 1 2 branch1/ft/F none) (version 22 " ROOT_ONE " 1 3 branch1/ft/F 
file))"
 
-static const char * const TESTING_DATA = (
+static const char * const TESTING_DATA_F31 = (
+   /* Load our test data.
+
+      Note: do not use named-column insertions. This allows us to test
+      the column count in the schema matches our expectation here. */
+
+   "insert into repository values (1, '" ROOT_ONE "', '" UUID_ONE "'); "
+   "insert into repository values (2, '" ROOT_TWO "', '" UUID_TWO "'); "
+   "insert into wcroot values (1, null); "
+
+   "insert into pristine values ('$sha1$" SHA1_1 "', NULL, 15, 1, '$md5 $" 
MD5_1 "'); "
+   );
+
+static const char * const TESTING_DATA_F32 = (
    /* Load our test data.
 
       Note: do not use named-column insertions. This allows us to test
@@ -88,7 +102,7 @@ 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 "', 1); "
-);
+   );
 
 #define NOT_MOVED FALSE, NULL
 #define NO_COPY_FROM 0, NULL, SVN_INVALID_REVNUM
@@ -288,6 +302,13 @@ static const svn_test__actual_data_t act
   { 0 }
 };
 
+/* Are we testing WC format 32+? */
+static svn_boolean_t
+testing_wc_format_32(const svn_test_opts_t *opts)
+{
+  return opts->wc_format_version->minor >= 15;
+}
+
 static svn_error_t *
 create_open(svn_wc__db_t **db,
             const char **local_abspath,
@@ -304,7 +325,9 @@ 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,
+  SVN_ERR(svn_test__create_fake_wc(*local_abspath,
+                                   testing_wc_format_32(opts)
+                                     ? TESTING_DATA_F32 : TESTING_DATA_F31,
                                    nodes_init_data, actual_init_data,
                                    opts->wc_format_version, pool));
 

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/entries-compat.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/entries-compat.c?rev=1897977&r1=1897976&r2=1897977&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/entries-compat.c
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/entries-compat.c
 Fri Feb 11 14:24:47 2022
@@ -37,6 +37,7 @@
 #include "svn_dirent_uri.h"
 #include "svn_pools.h"
 #include "svn_wc.h"
+#include "svn_version.h"
 
 #include "../../libsvn_wc/wc.h"
 #include "../../libsvn_wc/wc_db.h"
@@ -76,7 +77,20 @@
 #define F_TC_DATA "(conflict F file update edited deleted (version 22 " 
ROOT_ONE " 1 2 branch1/ft/F none) (version 22 " ROOT_ONE " 1 3 branch1/ft/F 
file))"
 #define G_TC_DATA "(conflict G file update edited deleted (version 22 " 
ROOT_ONE " 1 2 branch1/ft/F none) (version 22 " ROOT_ONE " 1 3 branch1/ft/F 
file))"
 
-static const char * const TESTING_DATA = (
+static const char * const TESTING_DATA_F31 = (
+   /* Load our test data.
+
+      Note: do not use named-column insertions. This allows us to test
+      the column count in the schema matches our expectation here. */
+
+   "insert into repository values (1, '" ROOT_ONE "', '" UUID_ONE "'); "
+   "insert into repository values (2, '" ROOT_TWO "', '" UUID_TWO "'); "
+   "insert into wcroot values (1, null); "
+
+   "insert into pristine values ('$sha1$" SHA1_1 "', NULL, 15, 1, '$md5 $" 
MD5_1 "'); "
+   );
+
+static const char * const TESTING_DATA_F32 = (
    /* Load our test data.
 
       Note: do not use named-column insertions. This allows us to test
@@ -286,6 +300,13 @@ static const char * const M_TESTING_DATA
    );
 
 
+/* Are we testing WC format 32+? */
+static svn_boolean_t
+testing_wc_format_32(const svn_test_opts_t *opts)
+{
+  return opts->wc_format_version->minor >= 15;
+}
+
 static svn_error_t *
 create_fake_wc(const char *subdir,
                const svn_test_opts_t *opts,
@@ -299,7 +320,10 @@ create_fake_wc(const char *subdir,
   SVN_ERR(svn_io_remove_dir2(root, TRUE, NULL, NULL, pool));
 
   SVN_ERR(svn_dirent_get_absolute(&wc_abspath, root, pool));
-  SVN_ERR(svn_test__create_fake_wc(wc_abspath, TESTING_DATA, nodes, actuals,
+  SVN_ERR(svn_test__create_fake_wc(wc_abspath,
+                                   testing_wc_format_32(opts)
+                                     ? TESTING_DATA_F32 : TESTING_DATA_F31,
+                                   nodes, actuals,
                                    opts->wc_format_version, pool));
 
   return SVN_NO_ERROR;

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/op-depth-test.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/op-depth-test.c?rev=1897977&r1=1897976&r2=1897977&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/op-depth-test.c
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/op-depth-test.c
 Fri Feb 11 14:24:47 2022
@@ -2063,6 +2063,31 @@ typedef struct actual_row_t {
   const char *changelist;
 } actual_row_t;
 
+/* Return STMT_FOR_F31 or STMT_FOR_F32 according to the format (31 or 32)
+ * of the WC in sandbox B. On error, return -1 to trigger a SQLite API error.
+ */
+static int
+stmt_for_f31_or_f32(svn_test__sandbox_t *b,
+                    int stmt_for_f31,
+                    int stmt_for_f32)
+{
+  svn_error_t *err;
+  svn_wc__db_wcroot_t *wcroot;
+  const char *local_relpath;
+
+  err = svn_wc__db_wcroot_parse_local_abspath(&wcroot, &local_relpath,
+                                              b->wc_ctx->db, b->wc_abspath,
+                                              b->pool, b->pool);
+  if (err)
+    {
+      svn_error_clear(err);
+      return -1;
+    }
+
+  return (wcroot->format >= SVN_WC__PRISTINES_ON_DEMAND_VERSION
+          ? stmt_for_f31 : stmt_for_f32);
+}
+
 static svn_error_t *
 insert_actual(svn_test__sandbox_t *b,
               actual_row_t *actual)
@@ -2092,7 +2117,10 @@ insert_actual(svn_test__sandbox_t *b,
       if (actual->changelist)
         {
           SVN_ERR(svn_sqlite__get_statement(&stmt, sdb,
-                                            STMT_ENSURE_EMPTY_PRISTINE));
+                                            stmt_for_f31_or_f32(
+                                              b,
+                                              STMT_ENSURE_EMPTY_PRISTINE_F32,
+                                              
STMT_ENSURE_EMPTY_PRISTINE_F31)));
           SVN_ERR(svn_sqlite__step_done(stmt));
           SVN_ERR(svn_sqlite__get_statement(&stmt, sdb, STMT_NODES_SET_FILE));
           SVN_ERR(svn_sqlite__bindf(stmt, "s", actual->local_relpath));

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/pristine-store-test.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/pristine-store-test.c?rev=1897977&r1=1897976&r2=1897977&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/pristine-store-test.c
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/pristine-store-test.c
 Fri Feb 11 14:24:47 2022
@@ -39,6 +39,7 @@
 #include "svn_repos.h"
 #include "svn_wc.h"
 #include "svn_client.h"
+#include "svn_version.h"
 
 #include "utils.h"
 
@@ -52,6 +53,13 @@
 #include "../svn_test.h"
 
 
+/* Are we testing WC format 32+? */
+static svn_boolean_t
+testing_wc_format_32(const svn_test_opts_t *opts)
+{
+  return opts->wc_format_version->minor >= 15;
+}
+
 /* Create repos and WC, set *WC_ABSPATH to the WC path, and set *DB to a new
  * DB context. */
 static svn_error_t *
@@ -366,7 +374,7 @@ pristine_install_dehydrated(const svn_te
     SVN_ERR(svn_wc__db_pristine_check(&present, &hydrated, db, wc_abspath,
                                       data_sha1, pool));
     SVN_TEST_ASSERT(present);
-    SVN_TEST_ASSERT(! hydrated);
+    SVN_TEST_ASSERT(hydrated == !testing_wc_format_32(opts));
   }
 
   /* Look up its MD-5 from its SHA-1, and check it's the same MD-5. */
@@ -386,7 +394,10 @@ pristine_install_dehydrated(const svn_te
 
     SVN_ERR(svn_wc__db_pristine_read(&actual_contents, &actual_size,
                                      db, wc_abspath, data_sha1, pool, pool));
-    SVN_TEST_ASSERT(actual_contents == NULL);
+    if (testing_wc_format_32(opts))
+      SVN_TEST_ASSERT(actual_contents == NULL);
+    else
+      SVN_TEST_ASSERT(actual_contents != NULL);
     SVN_TEST_INT_ASSERT(actual_size, sz);
   }
 
@@ -431,6 +442,10 @@ pristine_dehydrate(const svn_test_opts_t
   svn_string_t *data_string = svn_string_create(data, pool);
   svn_checksum_t *data_sha1, *data_md5;
 
+  if (!testing_wc_format_32(opts))
+    return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL,
+                            "dehydrate not available in WC format under test");
+
   SVN_ERR(create_repos_and_wc(&wc_abspath, &db,
                               "pristine_dehydrate", opts, pool));
 

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-queries-test.c
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-queries-test.c?rev=1897977&r1=1897976&r2=1897977&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-queries-test.c
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-queries-test.c
 Fri Feb 11 14:24:47 2022
@@ -24,6 +24,7 @@
 #include "svn_pools.h"
 #include "svn_hash.h"
 #include "svn_ctype.h"
+#include "svn_version.h"
 #include "private/svn_dep_compat.h"
 #include "private/svn_wc_private.h"
 #include "../../libsvn_wc/wc.h"
@@ -216,6 +217,38 @@ test_sqlite_version(apr_pool_t *scratch_
 #endif
 }
 
+/* Return TRUE iff statement STMT_NUM is valid in the schema for
+ * WC format FORMAT. */
+static svn_boolean_t
+stmt_matches_wc_format(int stmt_num,
+                       const svn_test_opts_t *opts,
+                       apr_pool_t *pool)
+{
+  int wc_format = -1;
+
+  svn_error_clear(svn_wc__format_from_version(
+                    &wc_format, opts->wc_format_version, pool));
+  switch (stmt_num)
+    {
+    case STMT_INSERT_OR_IGNORE_PRISTINE_F31:
+    case STMT_UPSERT_PRISTINE_F31:
+    case STMT_SELECT_PRISTINE_F31:
+    case STMT_SELECT_COPY_PRISTINES_F31:
+      return (wc_format <= 31);
+    case STMT_INSERT_OR_IGNORE_PRISTINE_F32:
+    case STMT_UPSERT_PRISTINE_F32:
+    case STMT_SELECT_PRISTINE_F32:
+    case STMT_SELECT_COPY_PRISTINES_F32:
+    case STMT_UPDATE_PRISTINE_HYDRATED:
+    case STMT_TEXTBASE_ADD_REF:
+    case STMT_TEXTBASE_REMOVE_REF:
+    case STMT_TEXTBASE_WALK:
+    case STMT_TEXTBASE_SYNC:
+      return (wc_format >= 32);
+    }
+  return TRUE;
+}
+
 /* Parse all normal queries */
 static svn_error_t *
 test_parsable(const svn_test_opts_t *opts,
@@ -234,6 +267,9 @@ test_parsable(const svn_test_opts_t *opt
       if (is_schema_statement(i))
         continue;
 
+      if (!stmt_matches_wc_format(i, opts, scratch_pool))
+        continue;
+
       /* Some of our statement texts contain multiple queries. We prepare
          them all. */
       while (*text != '\0')
@@ -674,6 +710,9 @@ test_query_expectations(const svn_test_o
       if (is_schema_statement(i))
         continue;
 
+      if (!stmt_matches_wc_format(i, opts, scratch_pool))
+        continue;
+
       /* Prepare statement to find if it is a single statement. */
       r = sqlite3_prepare_v2(sdb, wc_queries[i], -1, &stmt, &tail);
 

Modified: 
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-test-queries.sql
URL: 
http://svn.apache.org/viewvc/subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-test-queries.sql?rev=1897977&r1=1897976&r2=1897977&view=diff
==============================================================================
--- 
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-test-queries.sql
 (original)
+++ 
subversion/branches/pristines-on-demand-on-mwf/subversion/tests/libsvn_wc/wc-test-queries.sql
 Fri Feb 11 14:24:47 2022
@@ -60,7 +60,13 @@ DELETE FROM actual_node;
 INSERT INTO actual_node (local_relpath, parent_relpath, changelist, wc_id)
                 VALUES (?1, ?2, ?3, 1)
 
--- STMT_ENSURE_EMPTY_PRISTINE
+-- STMT_ENSURE_EMPTY_PRISTINE_F31
+INSERT OR IGNORE INTO pristine (checksum, md5_checksum, size, refcount)
+  VALUES ('$sha1$da39a3ee5e6b4b0d3255bfef95601890afd80709',
+          '$md5 $d41d8cd98f00b204e9800998ecf8427e',
+          0, 0)
+
+-- STMT_ENSURE_EMPTY_PRISTINE_F32
 INSERT OR IGNORE INTO pristine (checksum, md5_checksum, size, refcount, 
hydrated)
   VALUES ('$sha1$da39a3ee5e6b4b0d3255bfef95601890afd80709',
           '$md5 $d41d8cd98f00b204e9800998ecf8427e',


Reply via email to