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 <jeff@jeffjirsa.net>
Authored: Sun Oct 11 13:31:18 2015 -0700
Committer: Sylvain Lebresne <sylvain@datastax.com>
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 (" +
|