Author: rhuijben
Date: Wed Feb 18 12:24:05 2015
New Revision: 1660610

URL: http://svn.apache.org/r1660610
Log:
Make it possible to run sqlite queries that use user defined functions
when the child pools of the pool containing the sqlite database
are being cleaned up.

This is necessary to use op-depth calculations in verification queries.
(or to run queries at all when the verification triggers are used)

* subversion/libsvn_subr/sqlite.c
  (clear_sqlite_function): New function.
  (svn_sqlite__create_scalar_function): Document nasty problem.
    Create function pool in global pool.

* subversion/libsvn_wc/wc-checks.sql
  (STMT_STATIC_VERIFY): Extend verifications.

* subversion/tests/libsvn_wc/wc-queries-test.c
  (relpath_depth_sqlite): New function (stub).
  (test_verify_parsable): Define relpath_depth.

Modified:
    subversion/trunk/subversion/libsvn_subr/sqlite.c
    subversion/trunk/subversion/libsvn_wc/wc-checks.sql
    subversion/trunk/subversion/tests/libsvn_wc/wc-queries-test.c

Modified: subversion/trunk/subversion/libsvn_subr/sqlite.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/sqlite.c?rev=1660610&r1=1660609&r2=1660610&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_subr/sqlite.c (original)
+++ subversion/trunk/subversion/libsvn_subr/sqlite.c Wed Feb 18 12:24:05 2015
@@ -1515,6 +1515,16 @@ wrapped_func(sqlite3_context *context,
     }
 }
 
+/* pool cleanup function for function context */
+static apr_status_t
+clear_sqlite_function(void *baton)
+{
+  struct function_wrapper_baton_t *fwb = baton;
+
+  svn_pool_destroy(fwb->scratch_pool);
+  return APR_SUCCESS;
+}
+
 svn_error_t *
 svn_sqlite__create_scalar_function(svn_sqlite__db_t *db,
                                    const char *func_name,
@@ -1527,7 +1537,14 @@ 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);
+  /* If we create our scratch pool in db->state pool it is cleared
+     before the database is closed. This breaks using queries
+     before we close the database :(
+
+     We create a subpool in the global pool and only destroy it
+     when we want it to be destroyed */
+
+  fwb->scratch_pool = svn_pool_create(NULL);
   fwb->func = func;
   fwb->baton = baton;
 
@@ -1539,6 +1556,9 @@ svn_sqlite__create_scalar_function(svn_s
                                      fwb, wrapped_func, NULL, NULL),
              db);
 
+  apr_pool_cleanup_register(db->state_pool, fwb, clear_sqlite_function,
+                            apr_pool_cleanup_null);
+
   return SVN_NO_ERROR;
 }
 

Modified: subversion/trunk/subversion/libsvn_wc/wc-checks.sql
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_wc/wc-checks.sql?rev=1660610&r1=1660609&r2=1660610&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_wc/wc-checks.sql (original)
+++ subversion/trunk/subversion/libsvn_wc/wc-checks.sql Wed Feb 18 12:24:05 2015
@@ -155,3 +155,36 @@ AND (kind IS NULL
      OR (CASE WHEN kind = MAP_SYMLINK THEN symlink_target IS NULL
                                       ELSE symlink_target IS NOT NULL END))
 
+UNION ALL
+
+SELECT local_relpath, op_depth, 'SV007: 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
+
+SELECT local_relpath, op_depth, 'SV008: Node missing 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 = MAP_BASE_DELETED
+                            AND n.presence = MAP_BASE_DELETED)))
+
+UNION all
+
+SELECT n.local_relpath, n.op_depth, 'SV009: 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)

Modified: subversion/trunk/subversion/tests/libsvn_wc/wc-queries-test.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_wc/wc-queries-test.c?rev=1660610&r1=1660609&r2=1660610&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_wc/wc-queries-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_wc/wc-queries-test.c Wed Feb 18 
12:24:05 2015
@@ -984,6 +984,15 @@ test_schema_statistics(apr_pool_t *scrat
   return SVN_NO_ERROR;
 }
 
+/* An SQLite application defined function that allows SQL queries to
+   use "relpath_depth(local_relpath)".  */
+static void relpath_depth_sqlite(sqlite3_context* context,
+                                 int argc,
+                                 sqlite3_value* values[])
+{
+  SVN_ERR_MALFUNCTION_NO_RETURN(); /* STUB! */
+}
+
 /* Parse all verify/check queries */
 static svn_error_t *
 test_verify_parsable(apr_pool_t *scratch_pool)
@@ -993,6 +1002,9 @@ test_verify_parsable(apr_pool_t *scratch
 
   SVN_ERR(create_memory_db(&sdb, scratch_pool));
 
+  SQLITE_ERR(sqlite3_create_function(sdb, "relpath_depth", 1, SQLITE_ANY, NULL,
+                                     relpath_depth_sqlite, NULL, NULL));
+
   for (i=STMT_VERIFICATION_TRIGGERS; wc_queries[i]; i++)
     {
       sqlite3_stmt *stmt;


Reply via email to