Repository: cassandra Updated Branches: refs/heads/cassandra-3.0 6e20325fe -> dc61fa6cf
When more than one table exists, be sure the MV base table matches query table patch by jjirsa; reviewed by carlyeks for CASSANDRA-10503 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/dc61fa6c Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/dc61fa6c Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/dc61fa6c Branch: refs/heads/cassandra-3.0 Commit: dc61fa6cff1234ea2179191211b08c5200b235b4 Parents: 6e20325 Author: Jeff Jirsa <[email protected]> Authored: Sun Oct 11 13:31:18 2015 -0700 Committer: Sylvain Lebresne <[email protected]> Committed: Tue Oct 13 11:00:16 2015 +0200 ---------------------------------------------------------------------- CHANGES.txt | 3 +- src/java/org/apache/cassandra/db/view/View.java | 6 +++- .../apache/cassandra/db/view/ViewManager.java | 22 ++++++------ .../org/apache/cassandra/cql3/ViewTest.java | 35 ++++++++++++++++++++ 4 files changed, 54 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/dc61fa6c/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 0d80a8d..3b63714 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ -3.0 +3.0-rc2 + * Fix NPE in MVs on update (CASSANDRA-10503) * Only include modified cell data in indexing deltas (CASSANDRA-10438) * Do not load keyspace when creating sstable writer (CASSANDRA-10443) * If node is not yet gossiping write all MV updates to batchlog only (CASSANDRA-10413) http://git-wip-us.apache.org/repos/asf/cassandra/blob/dc61fa6c/src/java/org/apache/cassandra/db/view/View.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/view/View.java b/src/java/org/apache/cassandra/db/view/View.java index 87ea2ec..9d5f472 100644 --- a/src/java/org/apache/cassandra/db/view/View.java +++ b/src/java/org/apache/cassandra/db/view/View.java @@ -192,6 +192,10 @@ public class View public boolean updateAffectsView(AbstractBTreePartition partition) { ReadQuery selectQuery = getReadQuery(); + + if (!partition.metadata().cfId.equals(definition.baseTableId)) + return false; + if (!selectQuery.selectsKey(partition.partitionKey())) return false; @@ -582,7 +586,7 @@ public class View public TemporalRow.Set getTemporalRowSet(AbstractBTreePartition partition, TemporalRow.Set existing, boolean isBuilding) { if (!updateAffectsView(partition)) - return null; + return existing; Set<ColumnIdentifier> columns = new HashSet<>(this.columns.primaryKeyDefs.size()); for (ColumnDefinition def : this.columns.primaryKeyDefs) http://git-wip-us.apache.org/repos/asf/cassandra/blob/dc61fa6c/src/java/org/apache/cassandra/db/view/ViewManager.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/db/view/ViewManager.java b/src/java/org/apache/cassandra/db/view/ViewManager.java index efadd72..c11e641 100644 --- a/src/java/org/apache/cassandra/db/view/ViewManager.java +++ b/src/java/org/apache/cassandra/db/view/ViewManager.java @@ -125,14 +125,19 @@ public class ViewManager TemporalRow.Set temporalRows = null; for (Map.Entry<String, View> view : viewsByName.entrySet()) { - temporalRows = view.getValue().getTemporalRowSet(update, temporalRows, false); - - Collection<Mutation> viewMutations = view.getValue().createMutations(update, temporalRows, false); - if (viewMutations != null && !viewMutations.isEmpty()) + // Make sure that we only get mutations from views which are affected since the set includes all views for a + // keyspace. This will prevent calling getTemporalRowSet for the wrong base table. + if (view.getValue().updateAffectsView(update)) { - if (mutations == null) - mutations = Lists.newLinkedList(); - mutations.addAll(viewMutations); + temporalRows = view.getValue().getTemporalRowSet(update, temporalRows, false); + + Collection<Mutation> viewMutations = view.getValue().createMutations(update, temporalRows, false); + if (viewMutations != null && !viewMutations.isEmpty()) + { + if (mutations == null) + mutations = Lists.newLinkedList(); + mutations.addAll(viewMutations); + } } } @@ -156,9 +161,6 @@ public class ViewManager for (View view : allViews()) { - if (!cf.metadata().cfId.equals(view.getDefinition().baseTableId)) - continue; - if (view.updateAffectsView(cf)) return true; } http://git-wip-us.apache.org/repos/asf/cassandra/blob/dc61fa6c/test/unit/org/apache/cassandra/cql3/ViewTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/cql3/ViewTest.java b/test/unit/org/apache/cassandra/cql3/ViewTest.java index 55e7e1f..2353167 100644 --- a/test/unit/org/apache/cassandra/cql3/ViewTest.java +++ b/test/unit/org/apache/cassandra/cql3/ViewTest.java @@ -811,6 +811,41 @@ public class ViewTest extends CQLTester } @Test + public void testTwoTablesOneView() throws Throwable + { + execute("USE " + keyspace()); + executeNet(protocolVersion, "USE " + keyspace()); + + createTable("CREATE TABLE " + keyspace() + ".dummy_table (" + + "j int, " + + "intval int, " + + "PRIMARY KEY (j))"); + + createTable("CREATE TABLE " + keyspace() + ".real_base (" + + "k int, " + + "intval int, " + + "PRIMARY KEY (k))"); + + createView("mv", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM " + keyspace() + ".real_base WHERE k IS NOT NULL AND intval IS NOT NULL PRIMARY KEY (intval, k)"); + createView("mv2", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM " + keyspace() + ".dummy_table WHERE j IS NOT NULL AND intval IS NOT NULL PRIMARY KEY (intval, j)"); + + updateView("INSERT INTO " + keyspace() + ".real_base (k, intval) VALUES (?, ?)", 0, 0); + assertRows(execute("SELECT k, intval FROM " + keyspace() + ".real_base WHERE k = ?", 0), row(0, 0)); + assertRows(execute("SELECT k, intval from mv WHERE intval = ?", 0), row(0, 0)); + + updateView("INSERT INTO " + keyspace() + ".real_base (k, intval) VALUES (?, ?)", 0, 1); + assertRows(execute("SELECT k, intval FROM " + keyspace() + ".real_base WHERE k = ?", 0), row(0, 1)); + assertRows(execute("SELECT k, intval from mv WHERE intval = ?", 1), row(0, 1)); + + assertRows(execute("SELECT k, intval FROM " + keyspace() + ".real_base WHERE k = ?", 0), row(0, 1)); + assertRows(execute("SELECT k, intval from mv WHERE intval = ?", 1), row(0, 1)); + + updateView("INSERT INTO " + keyspace() +".dummy_table (j, intval) VALUES(?, ?)", 0, 1); + assertRows(execute("SELECT j, intval FROM " + keyspace() + ".dummy_table WHERE j = ?", 0), row(0, 1)); + assertRows(execute("SELECT k, intval from mv WHERE intval = ?", 1), row(0, 1)); + } + + @Test public void testDecimalUpdate() throws Throwable { createTable("CREATE TABLE %s (" +
