Merge branch 'master' into f20

Conflicts:
	subversion.spec
This commit is contained in:
Joe Orton 2014-02-28 19:27:22 +00:00
commit f35e3f08ff
7 changed files with 35 additions and 452 deletions

1
.gitignore vendored
View File

@ -27,3 +27,4 @@ subversion-1.6.12.tar.bz2
/subversion-1.8.3.tar.bz2
/subversion-1.8.4.tar.bz2
/subversion-1.8.5.tar.bz2
/subversion-1.8.8.tar.bz2

View File

@ -1 +1 @@
77349caf0ef5a612c9718c53516a9934 subversion-1.8.5.tar.bz2
db04a587c68e38da6d0e342e6508f514 subversion-1.8.8.tar.bz2

View File

@ -1,15 +0,0 @@
https://svn.apache.org/viewvc?view=revision&revision=1543145
--- subversion-1.8.4/subversion/svn/status-cmd.c
+++ subversion-1.8.4/subversion/svn/status-cmd.c
@@ -358,7 +358,8 @@
NULL, opt_state->quiet,
/* not versioned: */
SVN_ERR_WC_NOT_WORKING_COPY,
- SVN_ERR_WC_PATH_NOT_FOUND));
+ SVN_ERR_WC_PATH_NOT_FOUND,
+ SVN_NO_ERROR));
if (opt_state->xml)
SVN_ERR(print_finish_target_xml(repos_rev, iterpool));

View File

@ -1,352 +0,0 @@
# ./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
--- 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,
+ STMT_INSTALL_SCHEMA_STATISTICS,
/* Memory tables */
STMT_CREATE_TARGETS_LIST,
STMT_CREATE_CHANGELIST_LIST,
@@ -95,8 +96,8 @@ static const int slow_statements[] =
/* Operate on the entire WC */
STMT_SELECT_ALL_NODES, /* schema validation code */
- /* Is there a record? ### Can we somehow check for LIMIT 1? */
- STMT_LOOK_FOR_WORK,
+ /* Updates all records for a repository (designed slow) */
+ STMT_UPDATE_LOCK_REPOS_ID,
/* Full temporary table read */
STMT_INSERT_ACTUAL_EMPTIES,
@@ -114,6 +115,19 @@ static const int slow_statements[] =
-1 /* final marker */
};
+/* Statements that just read the first record from a table,
+ using the primary key. Specialized as different sqlite
+ versions produce different results */
+static const int primary_key_statements[] =
+{
+ /* Is there a record? ### Can we somehow check for LIMIT 1,
+ and primary key instead of adding a list? */
+ STMT_LOOK_FOR_WORK,
+ STMT_SELECT_WORK_ITEM,
+
+ -1 /* final marker */
+};
+
/* Helper function to determine if a statement is in a list */
static svn_boolean_t
in_list(const int list[], int stmt_idx)
@@ -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
+ || apr_strnatcasecmp(table_name, "lock") == 0
|| apr_strnatcasecmp(table_name, "wc_lock") == 0
|| FALSE);
}
@@ -651,14 +666,24 @@ test_query_expectations(apr_pool_t *scra
|| (item->expression_vars < 1))
&& !is_result_table(item->table))
{
- warned = TRUE;
- if (!is_slow_statement(i))
- warnings = svn_error_createf(SVN_ERR_TEST_FAILED, warnings,
+ if (in_list(primary_key_statements, i))
+ {
+ /* Reported as primary key index usage in Sqlite 3.7,
+ as table scan in 3.8+, while the execution plan is
+ identical: read first record from table */
+ }
+ else if (!is_slow_statement(i))
+ {
+ warned = TRUE;
+ warnings = svn_error_createf(SVN_ERR_TEST_FAILED, warnings,
"%s: "
"Uses %s with only %d index component: (%s)\n%s",
wc_query_info[i][0], item->table,
item->expression_vars, item->expressions,
wc_queries[i]);
+ }
+ else
+ warned = TRUE;
}
else if (item->search && !item->index)
{
@@ -718,6 +743,144 @@ test_query_expectations(apr_pool_t *scra
return warnings;
}
+/* Helper to verify a bit of data in the sqlite3 statistics */
+static int
+parse_stat_data(const char *stat)
+{
+ int n = 0;
+ apr_int64_t last = APR_INT64_MAX;
+ while (*stat)
+ {
+ apr_int64_t v;
+ char *next;
+
+ if (*stat < '0' || *stat > '9')
+ return -2;
+
+ errno = 0;
+ v = apr_strtoi64(stat, &next, 10);
+
+ /* All numbers specify the average number of rows
+ with the same values in all columns left of it,
+ so the value must be >= 1 and lower than or equal
+ to all previous seen numbers */
+ if (v <= 0 || (v > last) || (errno != 0))
+ return -1;
+
+ last = v;
+
+ n++;
+ stat = next;
+
+ if (*stat == ' ')
+ stat++;
+ }
+
+ return n;
+}
+
+static svn_error_t *
+test_schema_statistics(apr_pool_t *scratch_pool)
+{
+ sqlite3 *sdb;
+ sqlite3_stmt *stmt;
+
+ SVN_ERR(create_memory_db(&sdb, scratch_pool));
+
+ SQLITE_ERR(
+ sqlite3_exec(sdb,
+ "CREATE TABLE shadow_stat1(tbl TEXT, idx TEXT, stat TEXT)",
+ NULL, NULL, NULL));
+
+ SQLITE_ERR(
+ sqlite3_exec(sdb,
+ "INSERT INTO shadow_stat1 (tbl, idx, stat) "
+ "SELECT tbl, idx, stat FROM sqlite_stat1",
+ NULL, NULL, NULL));
+
+ SQLITE_ERR(
+ sqlite3_exec(sdb,
+ "DROP TABLE sqlite_stat1",
+ NULL, NULL, NULL));
+
+ /* Insert statement to give index at least 1 record */
+ SQLITE_ERR(
+ sqlite3_exec(sdb,
+ "INSERT INTO nodes (wc_id, local_relpath, op_depth,"
+ " presence, kind) "
+ "VALUES (1, '', 0, 'normal', 'dir')",
+ NULL, NULL, NULL));
+
+ SQLITE_ERR(
+ sqlite3_exec(sdb,
+ "INSERT INTO actual_node (wc_id, local_relpath) "
+ "VALUES (1, '')",
+ NULL, NULL, NULL));
+
+ SQLITE_ERR(
+ sqlite3_exec(sdb,
+ "INSERT INTO lock (repos_id, repos_relpath, lock_token) "
+ "VALUES (1, '', '')",
+ NULL, NULL, NULL));
+
+ /* These are currently not necessary for query optimization, but it's better
+ to tell Sqlite how we intend to use this table anyway */
+ SQLITE_ERR(
+ sqlite3_exec(sdb,
+ "INSERT INTO wc_lock (wc_id, local_dir_relpath) "
+ "VALUES (1, '')",
+ NULL, NULL, NULL));
+
+ SQLITE_ERR(
+ sqlite3_exec(sdb,
+ "INSERT INTO WORK_QUEUE (work) "
+ "VALUES ('')",
+ NULL, NULL, NULL));
+
+ SQLITE_ERR(
+ sqlite3_exec(sdb,
+ "ANALYZE",
+ NULL, NULL, NULL));
+
+ SQLITE_ERR(
+ sqlite3_prepare(sdb, "SELECT s.tbl, s.idx, s.stat, r.stat "
+ "FROM shadow_stat1 s "
+ "LEFT JOIN sqlite_stat1 r ON "
+ "s.tbl=r.tbl and s.idx=r.idx",
+ -1, &stmt, NULL));
+
+ while (sqlite3_step(stmt) == SQLITE_ROW)
+ {
+ const char *wc_stat = (const char*)sqlite3_column_text(stmt, 2);
+ const char *sqlite_stat = (const char*)sqlite3_column_text(stmt, 3);
+
+ if (! sqlite_stat)
+ {
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "Schema statistic failure:"
+ " Refering to unknown index '%s' on '%s'",
+ sqlite3_column_text(stmt, 1),
+ sqlite3_column_text(stmt, 0));
+ }
+
+ if (parse_stat_data(wc_stat) != parse_stat_data(sqlite_stat))
+ {
+ return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
+ "Schema statistic failure:"
+ " Column mismatch for '%s' on '%s'",
+ sqlite3_column_text(stmt, 1),
+ sqlite3_column_text(stmt, 0));
+ }
+ }
+
+ SQLITE_ERR(sqlite3_reset(stmt));
+ SQLITE_ERR(sqlite3_finalize(stmt));
+
+ SQLITE_ERR(sqlite3_close(sdb)); /* Close the DB if ok; otherwise leaked */
+
+ return SVN_NO_ERROR;
+}
+
struct svn_test_descriptor_t test_funcs[] =
{
SVN_TEST_NULL,
@@ -727,5 +890,7 @@ struct svn_test_descriptor_t test_funcs[
"queries are parsable"),
SVN_TEST_PASS2(test_query_expectations,
"test query expectations"),
+ SVN_TEST_PASS2(test_schema_statistics,
+ "test schema statistics"),
SVN_TEST_NULL
};

View File

@ -1,74 +0,0 @@
http://svn.apache.org/viewvc?view=revision&revision=1542774
(H/T Andreas Stieger)
--- 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
@@ -95,8 +95,8 @@ static const int slow_statements[] =
/* Operate on the entire WC */
STMT_SELECT_ALL_NODES, /* schema validation code */
- /* Is there a record? ### Can we somehow check for LIMIT 1? */
- STMT_LOOK_FOR_WORK,
+ /* Updates all records for a repository (designed slow) */
+ STMT_UPDATE_LOCK_REPOS_ID,
/* Full temporary table read */
STMT_INSERT_ACTUAL_EMPTIES,
@@ -114,6 +114,19 @@ static const int slow_statements[] =
-1 /* final marker */
};
+/* Statements that just read the first record from a table,
+ using the primary key. Specialized as different sqlite
+ versions produce different results */
+static const int primary_key_statements[] =
+{
+ /* Is there a record? ### Can we somehow check for LIMIT 1,
+ and primary key instead of adding a list? */
+ STMT_LOOK_FOR_WORK,
+ STMT_SELECT_WORK_ITEM,
+
+ -1 /* final marker */
+};
+
/* Helper function to determine if a statement is in a list */
static svn_boolean_t
in_list(const int list[], int stmt_idx)
@@ -529,6 +542,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
+ || apr_strnatcasecmp(table_name, "lock") == 0
|| apr_strnatcasecmp(table_name, "wc_lock") == 0
|| FALSE);
}
@@ -651,14 +665,24 @@ test_query_expectations(apr_pool_t *scra
|| (item->expression_vars < 1))
&& !is_result_table(item->table))
{
- warned = TRUE;
- if (!is_slow_statement(i))
- warnings = svn_error_createf(SVN_ERR_TEST_FAILED, warnings,
+ if (in_list(primary_key_statements, i))
+ {
+ /* Reported as primary key index usage in Sqlite 3.7,
+ as table scan in 3.8+, while the execution plan is
+ identical: read first record from table */
+ }
+ else if (!is_slow_statement(i))
+ {
+ warned = TRUE;
+ warnings = svn_error_createf(SVN_ERR_TEST_FAILED, warnings,
"%s: "
"Uses %s with only %d index component: (%s)\n%s",
wc_query_info[i][0], item->table,
item->expression_vars, item->expressions,
wc_queries[i]);
+ }
+ else
+ warned = TRUE;
}
else if (item->search && !item->index)
{

View File

@ -0,0 +1,16 @@
Don't drop -Wall in the swig Perl bindings, otherwise building with
e.g. -Wformat-security might break.
https://bugzilla.redhat.com/show_bug.cgi?id=1037341
--- subversion-1.8.5/subversion/bindings/swig/perl/native/Makefile.PL.in.swigplWall
+++ subversion-1.8.5/subversion/bindings/swig/perl/native/Makefile.PL.in
@@ -54,7 +54,6 @@ my $includes = ' -I/usr/include/apr-1
# SWIG is using C++ style comments in an extern "C" code.
$cflags =~ s/-ansi\s+//g;
$cflags =~ s/-std=c89\s+//g;
-$cflags =~ s/-Wall//g;
$cflags =~ s/-Wunused//g;
$cflags =~ s/-Wshadow//g;
$cflags =~ s/-Wstrict-prototypes//g;

View File

@ -20,15 +20,15 @@
%{!?python_sitearch: %define python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")}
%{!?_httpd_apxs: %{expand: %%global _httpd_apxs %%{_sbindir}/apxs}}
%{!?_httpd_mmn: %{expand: %%global _httpd_mmn %%(cat %{_includedir}/httpd/.mmn 2>/dev/null || echo missing-httpd-devel)}}
%{!?_httpd_mmn: %{expand: %%global _httpd_mmn %%(cat %{_includedir}/httpd/.mmn 2>/dev/null || echo 0-0)}}
%{!?_httpd_confdir: %{expand: %%global _httpd_confdir %%{_sysconfdir}/httpd/conf.d}}
# /etc/httpd/conf.d with httpd < 2.4 and defined as /etc/httpd/conf.modules.d with httpd >= 2.4
%{!?_httpd_modconfdir: %{expand: %%global _httpd_modconfdir %%{_sysconfdir}/httpd/conf.d}}
Summary: A Modern Concurrent Version Control System
Name: subversion
Version: 1.8.5
Release: 2%{?dist}
Version: 1.8.8
Release: 1%{?dist}
License: ASL 2.0
Group: Development/Tools
URL: http://subversion.apache.org/
@ -45,8 +45,7 @@ Patch2: subversion-1.8.0-pie.patch
Patch3: subversion-1.8.0-kwallet.patch
Patch4: subversion-1.8.0-rubybind.patch
Patch5: subversion-1.8.0-aarch64.patch
Patch6: subversion-1.8.4-r1543145.patch
Patch7: subversion-1.8.5-r1542774+.patch
Patch8: subversion-1.8.5-swigplWall.patch
BuildRequires: autoconf, libtool, python, python-devel, texinfo, which
BuildRequires: %{dbdevel} >= 4.1.25, swig >= 1.3.24, gettext
BuildRequires: apr-devel >= 1.3.0, apr-util-devel >= 1.3.0
@ -185,8 +184,7 @@ This package includes supplementary tools for use with Subversion.
%patch3 -p1 -b .kwallet
%patch4 -p1 -b .rubybind
%patch5 -p1 -b .aarch64
%patch6 -p1 -b .r1543145
%patch7 -p1 -b .r1542774+
%patch8 -p1 -b .swigplWall
%build
# Regenerate the buildsystem, so that:
@ -409,7 +407,7 @@ rm -rf ${RPM_BUILD_ROOT}
%dir %{_sysconfdir}/subversion
%exclude %{_mandir}/man*/*::*
%{_unitdir}/*.service
%dir /run/svnserve
%attr(0700,root,root) %dir /run/svnserve
%{_prefix}/lib/tmpfiles.d/svnserve.conf
%files tools -f tools.files
@ -479,8 +477,17 @@ rm -rf ${RPM_BUILD_ROOT}
%endif
%changelog
* Mon Dec 2 2013 Joe Orton <jorton@redhat.com> - 1.8.5-2
- disable override of sqlite minimum version
* Fri Feb 28 2014 Joe Orton <jorton@redhat.com> - 1.8.8-1
- update to 1.8.8
* Thu Jan 23 2014 Joe Orton <jorton@redhat.com> - 1.8.5-4
- fix _httpd_mmn expansion in absence of httpd-devel
* Mon Jan 6 2014 Joe Orton <jorton@redhat.com> - 1.8.5-3
- fix permissions of /run/svnserve (#1048422)
* Tue Dec 10 2013 Joe Orton <jorton@redhat.com> - 1.8.5-2
- don't drop -Wall when building swig Perl bindings (#1037341)
* Tue Nov 26 2013 Joe Orton <jorton@redhat.com> - 1.8.5-1
- update to 1.8.5 (#1034130)