You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sl...@apache.org on 2015/09/18 12:13:15 UTC
cassandra git commit: Issues with MVs caused by updateAffectsView and
createForDeletionInfo
Repository: cassandra
Updated Branches:
refs/heads/cassandra-3.0 df3972e94 -> 9f335fe48
Issues with MVs caused by updateAffectsView and createForDeletionInfo
patch by carlyeks; reviewed by slebresne for CASSANDRA-10362
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/9f335fe4
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/9f335fe4
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/9f335fe4
Branch: refs/heads/cassandra-3.0
Commit: 9f335fe482d49e84af8c5380df56d3e768a60be9
Parents: df3972e
Author: Carl Yeksigian <ca...@apache.org>
Authored: Thu Sep 17 12:20:20 2015 -0400
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Fri Sep 18 12:13:07 2015 +0200
----------------------------------------------------------------------
CHANGES.txt | 1 +
src/java/org/apache/cassandra/db/view/View.java | 17 +++--
.../org/apache/cassandra/cql3/ViewTest.java | 76 +++++++++++++++++++-
3 files changed, 85 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/9f335fe4/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index afe7dcb..d6554e9 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
3.0.0-rc1
+ * Fix minor bugs in MV handling (CASSANDRA-10362)
* Allow custom indexes with 0,1 or multiple target columns (CASSANDRA-10124)
* Improve MV schema representation (CASSANDRA-9921)
* Add flag to enable/disable coordinator batchlog for MV writes (CASSANDRA-10230)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/9f335fe4/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 7bcb592..fb34ca9 100644
--- a/src/java/org/apache/cassandra/db/view/View.java
+++ b/src/java/org/apache/cassandra/db/view/View.java
@@ -36,6 +36,7 @@ import org.apache.cassandra.config.ColumnDefinition;
import org.apache.cassandra.config.ViewDefinition;
import org.apache.cassandra.config.Schema;
import org.apache.cassandra.cql3.ColumnIdentifier;
+import org.apache.cassandra.db.AbstractReadCommandBuilder;
import org.apache.cassandra.db.AbstractReadCommandBuilder.SinglePartitionSliceBuilder;
import org.apache.cassandra.db.CBuilder;
import org.apache.cassandra.db.Clustering;
@@ -62,6 +63,7 @@ import org.apache.cassandra.db.rows.Row;
import org.apache.cassandra.db.rows.RowIterator;
import org.apache.cassandra.schema.KeyspaceMetadata;
import org.apache.cassandra.service.pager.QueryPager;
+import org.apache.cassandra.utils.FBUtilities;
/**
* A View copies data from a base table into a view table which can be queried independently from the
@@ -214,11 +216,12 @@ public class View
// Check each row for deletion or update
for (Row row : partition)
{
- if (row.hasComplexDeletion())
- return true;
if (!row.deletion().isLive())
return true;
+ if (row.primaryKeyLivenessInfo().isLive(FBUtilities.nowInSeconds()))
+ return true;
+
for (ColumnData data : row)
{
if (definition.metadata.getColumnDefinition(data.column().name) != null)
@@ -434,7 +437,11 @@ public class View
// entire partition of data which is not distributed on a single partition node.
DecoratedKey dk = rowSet.dk;
- if (deletionInfo.hasRanges())
+ if (!deletionInfo.getPartitionDeletion().isLive())
+ {
+ command = SinglePartitionReadCommand.fullPartitionRead(baseCfs.metadata, rowSet.nowInSec, dk);
+ }
+ else
{
SinglePartitionSliceBuilder builder = new SinglePartitionSliceBuilder(baseCfs, dk);
Iterator<RangeTombstone> tombstones = deletionInfo.rangeIterator(false);
@@ -447,10 +454,6 @@ public class View
command = builder.build();
}
- else
- {
- command = SinglePartitionReadCommand.fullPartitionRead(baseCfs.metadata, rowSet.nowInSec, dk);
- }
}
if (command == null)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/9f335fe4/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 95662e5..43f7747 100644
--- a/test/unit/org/apache/cassandra/cql3/ViewTest.java
+++ b/test/unit/org/apache/cassandra/cql3/ViewTest.java
@@ -186,6 +186,9 @@ public class ViewTest extends CQLTester
"bigintval bigint, " +
"PRIMARY KEY((k, asciival)))");
+ execute("USE " + keyspace());
+ executeNet(protocolVersion, "USE " + keyspace());
+
// Must include "IS NOT NULL" for primary keys
try
{
@@ -1335,8 +1338,8 @@ public class ViewTest extends CQLTester
createView("mv3", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE b IS NOT NULL AND c IS NOT NULL PRIMARY KEY (a, b, c)");
createView("mv4", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE b IS NOT NULL AND c IS NOT NULL PRIMARY KEY (a, c, b) WITH CLUSTERING ORDER BY (c DESC)");
- updateView("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?) USING TIMESTAMP 1", 1, 1, 1, 1);
- updateView("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?) USING TIMESTAMP 1", 1, 2, 2, 2);
+ updateView("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 1, 1, 1, 1);
+ updateView("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 1, 2, 2, 2);
ResultSet mvRows = executeNet(protocolVersion, "SELECT b FROM mv1");
assertRowsNet(protocolVersion, mvRows,
@@ -1384,4 +1387,73 @@ public class ViewTest extends CQLTester
Assert.assertEquals("Cannot use DROP TABLE on Materialized View", e.getMessage());
}
}
+
+ @Test
+ public void testMultipleDeletes() throws Throwable
+ {
+ createTable("CREATE TABLE %s (" +
+ "a int," +
+ "b int," +
+ "PRIMARY KEY (a, b))");
+
+ executeNet(protocolVersion, "USE " + keyspace());
+
+ createView("mv1", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE b IS NOT NULL PRIMARY KEY (b, a)");
+
+ updateView("INSERT INTO %s (a, b) VALUES (?, ?)", 1, 1);
+ updateView("INSERT INTO %s (a, b) VALUES (?, ?)", 1, 2);
+ updateView("INSERT INTO %s (a, b) VALUES (?, ?)", 1, 3);
+
+ ResultSet mvRows = executeNet(protocolVersion, "SELECT a, b FROM mv1");
+ assertRowsNet(protocolVersion, mvRows,
+ row(1, 1),
+ row(1, 2),
+ row(1, 3));
+
+ updateView(String.format("BEGIN UNLOGGED BATCH " +
+ "DELETE FROM %s WHERE a = 1 AND b > 1 AND b < 3;" +
+ "DELETE FROM %s WHERE a = 1;" +
+ "APPLY BATCH", currentTable(), currentTable()));
+
+ mvRows = executeNet(protocolVersion, "SELECT a, b FROM mv1");
+ assertRowsNet(protocolVersion, mvRows);
+ }
+
+ @Test
+ public void testPrimaryKeyOnlyTable() throws Throwable
+ {
+ createTable("CREATE TABLE %s (" +
+ "a int," +
+ "b int," +
+ "PRIMARY KEY (a, b))");
+
+ executeNet(protocolVersion, "USE " + keyspace());
+
+ // Cannot use SELECT *, as those are always handled by the includeAll shortcut in View.updateAffectsView
+ createView("mv1", "CREATE MATERIALIZED VIEW %s AS SELECT a, b FROM %%s WHERE b IS NOT NULL PRIMARY KEY (b, a)");
+
+ updateView("INSERT INTO %s (a, b) VALUES (?, ?)", 1, 1);
+
+ ResultSet mvRows = executeNet(protocolVersion, "SELECT a, b FROM mv1");
+ assertRowsNet(protocolVersion, mvRows, row(1, 1));
+ }
+
+ @Test
+ public void testPartitionKeyOnlyTable() throws Throwable
+ {
+ createTable("CREATE TABLE %s (" +
+ "a int," +
+ "b int," +
+ "PRIMARY KEY ((a, b)))");
+
+ executeNet(protocolVersion, "USE " + keyspace());
+
+ // Cannot use SELECT *, as those are always handled by the includeAll shortcut in View.updateAffectsView
+ createView("mv1", "CREATE MATERIALIZED VIEW %s AS SELECT a, b FROM %%s WHERE a IS NOT NULL AND b IS NOT NULL PRIMARY KEY (b, a)");
+
+ updateView("INSERT INTO %s (a, b) VALUES (?, ?)", 1, 1);
+
+ ResultSet mvRows = executeNet(protocolVersion, "SELECT a, b FROM mv1");
+ assertRowsNet(protocolVersion, mvRows, row(1, 1));
+ }
}