diff --git a/subversion-1.8.5-r1542774+.patch b/subversion-1.8.5-r1542774+.patch index ecdde53..3105098 100644 --- a/subversion-1.8.5-r1542774+.patch +++ b/subversion-1.8.5-r1542774+.patch @@ -1,12 +1,128 @@ -# ./pullrev.sh 1542774 1542767 1542765 +# ./pullrev.sh 1542774 1542765 1542767 http://svn.apache.org/viewvc?view=revision&revision=1542774 http://svn.apache.org/viewvc?view=revision&revision=1542767 http://svn.apache.org/viewvc?view=revision&revision=1542765 ---- httpd-1.8.5/subversion/tests/libsvn_wc/wc-queries-test.c -+++ httpd-1.8.5/subversion/tests/libsvn_wc/wc-queries-test.c -@@ -73,6 +73,7 @@ +--- subversion-1.8.5/subversion/libsvn_wc/upgrade.c.r1542774+ ++++ subversion-1.8.5/subversion/libsvn_wc/upgrade.c +@@ -1958,6 +1958,10 @@ svn_wc__upgrade_sdb(int *result_format, + case SVN_WC__VERSION: + /* already upgraded */ + *result_format = SVN_WC__VERSION; ++ ++ SVN_SQLITE__WITH_LOCK( ++ svn_wc__db_install_schema_statistics(sdb, scratch_pool), ++ sdb); + } + + #ifdef SVN_DEBUG +--- subversion-1.8.5/subversion/libsvn_wc/wc_db.c.r1542774+ ++++ subversion-1.8.5/subversion/libsvn_wc/wc_db.c +@@ -1390,6 +1390,15 @@ does_node_exist(svn_boolean_t *exists, + return svn_error_trace(svn_sqlite__reset(stmt)); + } + ++svn_error_t * ++svn_wc__db_install_schema_statistics(svn_sqlite__db_t *sdb, ++ apr_pool_t *scratch_pool) ++{ ++ SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_INSTALL_SCHEMA_STATISTICS)); ++ ++ return SVN_NO_ERROR; ++} ++ + /* Helper for create_db(). Initializes our wc.db schema. + */ + static svn_error_t * +@@ -1417,6 +1426,8 @@ init_db(/* output values */ + SVN_ERR(create_repos_id(repos_id, repos_root_url, repos_uuid, + db, scratch_pool)); + ++ SVN_ERR(svn_wc__db_install_schema_statistics(db, scratch_pool)); ++ + /* Insert the wcroot. */ + /* ### Right now, this just assumes wc metadata is being stored locally. */ + SVN_ERR(svn_sqlite__get_statement(&stmt, db, STMT_INSERT_WCROOT)); +--- subversion-1.8.5/subversion/libsvn_wc/wc_db.h.r1542774+ ++++ subversion-1.8.5/subversion/libsvn_wc/wc_db.h +@@ -2831,6 +2831,16 @@ svn_wc__db_scan_deletion(const char **ba + @{ + */ + ++/* Installs or updates Sqlite schema statistics for the current (aka latest) ++ working copy schema. ++ ++ This function should be called once on initializing the database and after ++ an schema update completes */ ++svn_error_t * ++svn_wc__db_install_schema_statistics(svn_sqlite__db_t *sdb, ++ apr_pool_t *scratch_pool); ++ ++ + /* Create a new wc.db file for LOCAL_DIR_ABSPATH, which is going to be a + working copy for the repository REPOS_ROOT_URL with uuid REPOS_UUID. + Return the raw sqlite handle, repository id and working copy id +--- subversion-1.8.5/subversion/libsvn_wc/wc-metadata.sql.r1542774+ ++++ subversion-1.8.5/subversion/libsvn_wc/wc-metadata.sql +@@ -573,6 +573,54 @@ CREATE UNIQUE INDEX I_EXTERNALS_DEFINED + local_relpath); + + /* ------------------------------------------------------------------------- */ ++/* This statement provides SQLite with the necessary information about our ++ indexes to make better decisions in the query planner. ++ ++ For every interesting index this contains a number of rows where the ++ statistics ar calculated for and then for every column in the index the ++ average number of rows with the same value in all columns left of this ++ column including the column itself. ++ ++ See http://www.sqlite.org/fileformat2.html#stat1tab for more details. ++ ++ The important thing here is that this tells Sqlite that the wc_id column ++ of the NODES and ACTUAL_NODE table is usually a single value, so queries ++ should use more than one column for index usage. ++ ++ The current hints describe NODES+ACTUAL_NODE as a working copy with ++ 8000 nodes in 1 a single working copy(=wc_id), 10 nodes per directory ++ and an average of 2 op-depth layers per node. ++ ++ The number of integers must be number of index columns + 1, which is ++ verified via the test_schema_statistics() test. ++ */ ++-- STMT_INSTALL_SCHEMA_STATISTICS ++ANALYZE sqlite_master; /* Creates empty sqlite_stat1 if necessary */ ++ ++INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES ++ ('NODES', 'sqlite_autoindex_NODES_1', '8000 8000 2 1'); ++INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES ++ ('NODES', 'I_NODES_PARENT', '8000 8000 10 2 1'); ++/* Tell a lie: We ignore that 99.9% of all moved_to values are NULL */ ++INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES ++ ('NODES', 'I_NODES_MOVED', '8000 8000 1 1'); ++ ++INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES ++ ('ACTUAL_NODE', 'sqlite_autoindex_ACTUAL_NODE_1', '8000 8000 1'); ++INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES ++ ('ACTUAL_NODE', 'I_ACTUAL_PARENT', '8000 8000 10 1'); ++ ++INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES ++ ('LOCK', 'sqlite_autoindex_LOCK_1', '100 100 1'); ++ ++INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES ++ ('WC_LOCK', 'sqlite_autoindex_WC_LOCK_1', '100 100 1'); ++ ++/* sqlite_autoindex_WORK_QUEUE_1 doesn't exist because WORK_QUEUE is ++ a INTEGER PRIMARY KEY AUTOINCREMENT table */ ++ ++ANALYZE sqlite_master; /* Loads sqlite_stat1 data for query optimizer */ ++/* ------------------------------------------------------------------------- */ + + /* Format 20 introduces NODES and removes BASE_NODE and WORKING_NODE */ + +--- subversion-1.8.5/subversion/tests/libsvn_wc/wc-queries-test.c.r1542774+ ++++ subversion-1.8.5/subversion/tests/libsvn_wc/wc-queries-test.c +@@ -77,6 +77,7 @@ static const int schema_statements[] = STMT_CREATE_NODES, STMT_CREATE_NODES_TRIGGERS, STMT_CREATE_EXTERNALS, @@ -14,7 +130,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1542765 /* Memory tables */ STMT_CREATE_TARGETS_LIST, STMT_CREATE_CHANGELIST_LIST, -@@ -92,8 +93,8 @@ +@@ -95,8 +96,8 @@ static const int slow_statements[] = /* Operate on the entire WC */ STMT_SELECT_ALL_NODES, /* schema validation code */ @@ -25,7 +141,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1542765 /* Full temporary table read */ STMT_INSERT_ACTUAL_EMPTIES, -@@ -111,6 +112,19 @@ +@@ -114,6 +115,19 @@ static const int slow_statements[] = -1 /* final marker */ }; @@ -45,7 +161,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1542765 /* Helper function to determine if a statement is in a list */ static svn_boolean_t in_list(const int list[], int stmt_idx) -@@ -526,6 +540,7 @@ +@@ -529,6 +543,7 @@ is_node_table(const char *table_name) return (apr_strnatcasecmp(table_name, "nodes") == 0 || apr_strnatcasecmp(table_name, "actual_node") == 0 || apr_strnatcasecmp(table_name, "externals") == 0 @@ -53,7 +169,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1542765 || apr_strnatcasecmp(table_name, "wc_lock") == 0 || FALSE); } -@@ -648,14 +663,24 @@ +@@ -651,14 +666,24 @@ test_query_expectations(apr_pool_t *scra || (item->expression_vars < 1)) && !is_result_table(item->table)) { @@ -81,7 +197,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1542765 } else if (item->search && !item->index) { -@@ -789,6 +814,147 @@ +@@ -718,6 +743,144 @@ test_query_expectations(apr_pool_t *scra return warnings; } @@ -125,9 +241,6 @@ http://svn.apache.org/viewvc?view=revision&revision=1542765 +test_schema_statistics(apr_pool_t *scratch_pool) +{ + sqlite3 *sdb; -+ int r; -+ apr_pool_t *iterpool = svn_pool_create(scratch_pool); -+ svn_error_t *warnings = NULL; + sqlite3_stmt *stmt; + + SVN_ERR(create_memory_db(&sdb, scratch_pool)); @@ -229,137 +342,9 @@ http://svn.apache.org/viewvc?view=revision&revision=1542765 struct svn_test_descriptor_t test_funcs[] = { SVN_TEST_NULL, -@@ -801,4 +967,6 @@ - SVN_TEST_PASS2(test_query_duplicates, - "test query duplicates"), -+ SVN_TEST_PASS2(test_schema_statistics, -+ "test schema statistics"), +@@ -729,3 +892,5 @@ struct svn_test_descriptor_t test_funcs[ + "test query expectations"), SVN_TEST_NULL }; -@@ -830,9 +998,6 @@ - test_schema_statistics(apr_pool_t *scratch_pool) - { - sqlite3 *sdb; -- int r; -- apr_pool_t *iterpool = svn_pool_create(scratch_pool); -- svn_error_t *warnings = NULL; - sqlite3_stmt *stmt; - - SVN_ERR(create_memory_db(&sdb, scratch_pool)); ---- httpd-1.8.5/subversion/libsvn_wc/wc-metadata.sql -+++ httpd-1.8.5/subversion/libsvn_wc/wc-metadata.sql -@@ -573,7 +573,55 @@ - local_relpath); - - /* ------------------------------------------------------------------------- */ -+/* This statement provides SQLite with the necessary information about our -+ indexes to make better decisions in the query planner. - -+ For every interesting index this contains a number of rows where the -+ statistics ar calculated for and then for every column in the index the -+ average number of rows with the same value in all columns left of this -+ column including the column itself. -+ -+ See http://www.sqlite.org/fileformat2.html#stat1tab for more details. -+ -+ The important thing here is that this tells Sqlite that the wc_id column -+ of the NODES and ACTUAL_NODE table is usually a single value, so queries -+ should use more than one column for index usage. -+ -+ The current hints describe NODES+ACTUAL_NODE as a working copy with -+ 8000 nodes in 1 a single working copy(=wc_id), 10 nodes per directory -+ and an average of 2 op-depth layers per node. -+ -+ The number of integers must be number of index columns + 1, which is -+ verified via the test_schema_statistics() test. -+ */ -+-- STMT_INSTALL_SCHEMA_STATISTICS -+ANALYZE sqlite_master; /* Creates empty sqlite_stat1 if necessary */ -+ -+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES -+ ('NODES', 'sqlite_autoindex_NODES_1', '8000 8000 2 1'); -+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES -+ ('NODES', 'I_NODES_PARENT', '8000 8000 10 2 1'); -+/* Tell a lie: We ignore that 99.9% of all moved_to values are NULL */ -+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES -+ ('NODES', 'I_NODES_MOVED', '8000 8000 1 1'); -+ -+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES -+ ('ACTUAL_NODE', 'sqlite_autoindex_ACTUAL_NODE_1', '8000 8000 1'); -+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES -+ ('ACTUAL_NODE', 'I_ACTUAL_PARENT', '8000 8000 10 1'); -+ -+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES -+ ('LOCK', 'sqlite_autoindex_LOCK_1', '100 100 1'); -+ -+INSERT OR REPLACE INTO sqlite_stat1(tbl, idx, stat) VALUES -+ ('WC_LOCK', 'sqlite_autoindex_WC_LOCK_1', '100 100 1'); -+ -+/* sqlite_autoindex_WORK_QUEUE_1 doesn't exist because WORK_QUEUE is -+ a INTEGER PRIMARY KEY AUTOINCREMENT table */ -+ -+ANALYZE sqlite_master; /* Loads sqlite_stat1 data for query optimizer */ -+/* ------------------------------------------------------------------------- */ -+ - /* Format 20 introduces NODES and removes BASE_NODE and WORKING_NODE */ - - -- STMT_UPGRADE_TO_20 ---- httpd-1.8.5/subversion/libsvn_wc/wc_db.c -+++ httpd-1.8.5/subversion/libsvn_wc/wc_db.c -@@ -1440,6 +1440,15 @@ - return svn_error_trace(svn_sqlite__reset(stmt)); - } - -+svn_error_t * -+svn_wc__db_install_schema_statistics(svn_sqlite__db_t *sdb, -+ apr_pool_t *scratch_pool) -+{ -+ SVN_ERR(svn_sqlite__exec_statements(sdb, STMT_INSTALL_SCHEMA_STATISTICS)); -+ -+ return SVN_NO_ERROR; -+} -+ - /* Helper for create_db(). Initializes our wc.db schema. - */ - static svn_error_t * -@@ -1467,6 +1476,8 @@ - SVN_ERR(create_repos_id(repos_id, repos_root_url, repos_uuid, - db, scratch_pool)); - -+ SVN_ERR(svn_wc__db_install_schema_statistics(db, scratch_pool)); -+ - /* Insert the wcroot. */ - /* ### Right now, this just assumes wc metadata is being stored locally. */ - SVN_ERR(svn_sqlite__get_statement(&stmt, db, STMT_INSERT_WCROOT)); ---- httpd-1.8.5/subversion/libsvn_wc/wc_db.h -+++ httpd-1.8.5/subversion/libsvn_wc/wc_db.h -@@ -2831,6 +2831,16 @@ - @{ - */ - -+/* Installs or updates Sqlite schema statistics for the current (aka latest) -+ working copy schema. -+ -+ This function should be called once on initializing the database and after -+ an schema update completes */ -+svn_error_t * -+svn_wc__db_install_schema_statistics(svn_sqlite__db_t *sdb, -+ apr_pool_t *scratch_pool); -+ -+ - /* Create a new wc.db file for LOCAL_DIR_ABSPATH, which is going to be a - working copy for the repository REPOS_ROOT_URL with uuid REPOS_UUID. - Return the raw sqlite handle, repository id and working copy id ---- httpd-1.8.5/subversion/libsvn_wc/upgrade.c -+++ httpd-1.8.5/subversion/libsvn_wc/upgrade.c -@@ -1959,6 +1959,10 @@ - case SVN_WC__VERSION: - /* already upgraded */ - *result_format = SVN_WC__VERSION; -+ -+ SVN_SQLITE__WITH_LOCK( -+ svn_wc__db_install_schema_statistics(sdb, scratch_pool), -+ sdb); - } - - #ifdef SVN_DEBUG ++ SVN_TEST_PASS2(test_schema_statistics, ++ "test schema statistics"),