Merge branch 'cassandra-3.9' into trunk

* cassandra-3.9:
  AssertionError with MVs on updating a row that isn't indexed due to a null value
This commit is contained in:
Sylvain Lebresne 2016-07-27 11:29:56 +02:00
commit 472a7c55bc
3 changed files with 32 additions and 2 deletions

View File

@ -21,6 +21,7 @@
* cqlsh: Fix handling of $$-escaped strings (CASSANDRA-12189) * cqlsh: Fix handling of $$-escaped strings (CASSANDRA-12189)
* Fix SSL JMX requiring truststore containing server cert (CASSANDRA-12109) * Fix SSL JMX requiring truststore containing server cert (CASSANDRA-12109)
Merged from 3.0: Merged from 3.0:
* AssertionError with MVs on updating a row that isn't indexed due to a null value (CASSANDRA-12247)
* Disable RR and speculative retry with EACH_QUORUM reads (CASSANDRA-11980) * Disable RR and speculative retry with EACH_QUORUM reads (CASSANDRA-11980)
* Add option to override compaction space check (CASSANDRA-12180) * Add option to override compaction space check (CASSANDRA-12180)
* Faster startup by only scanning each directory for temporary files once (CASSANDRA-12114) * Faster startup by only scanning each directory for temporary files once (CASSANDRA-12114)

View File

@ -190,7 +190,7 @@ public class ViewUpdateGenerator
// If the update didn't modified this column, the cells will be the same object so it's worth checking // If the update didn't modified this column, the cells will be the same object so it's worth checking
if (before == after) if (before == after)
return before == null ? UpdateAction.NONE : UpdateAction.UPDATE_EXISTING; return isLive(before) ? UpdateAction.UPDATE_EXISTING : UpdateAction.NONE;
if (!isLive(before)) if (!isLive(before))
return isLive(after) ? UpdateAction.NEW_ENTRY : UpdateAction.NONE; return isLive(after) ? UpdateAction.NEW_ENTRY : UpdateAction.NONE;
@ -451,7 +451,7 @@ public class ViewUpdateGenerator
ColumnDefinition baseColumn = view.baseNonPKColumnsInViewPK.get(0); ColumnDefinition baseColumn = view.baseNonPKColumnsInViewPK.get(0);
Cell cell = baseRow.getCell(baseColumn); Cell cell = baseRow.getCell(baseColumn);
assert isLive(cell) : "We shouldn't have got there is the base row had no associated entry"; assert isLive(cell) : "We shouldn't have got there if the base row had no associated entry";
long timestamp = Math.max(baseLiveness.timestamp(), cell.timestamp()); long timestamp = Math.max(baseLiveness.timestamp(), cell.timestamp());
return LivenessInfo.withExpirationTime(timestamp, cell.ttl(), cell.localDeletionTime()); return LivenessInfo.withExpirationTime(timestamp, cell.ttl(), cell.localDeletionTime());

View File

@ -1108,4 +1108,33 @@ public class ViewTest extends CQLTester
} }
} }
@Test
public void testNullInClusteringColumns() throws Throwable
{
createTable("CREATE TABLE %s (id1 int, id2 int, v1 text, v2 text, PRIMARY KEY (id1, id2))");
executeNet(protocolVersion, "USE " + keyspace());
createView("mv",
"CREATE MATERIALIZED VIEW %s AS" +
" SELECT id1, v1, id2, v2" +
" FROM %%s" +
" WHERE id1 IS NOT NULL AND v1 IS NOT NULL AND id2 IS NOT NULL" +
" PRIMARY KEY (id1, v1, id2)" +
" WITH CLUSTERING ORDER BY (v1 DESC, id2 ASC)");
execute("INSERT INTO %s (id1, id2, v1, v2) VALUES (?, ?, ?, ?)", 0, 1, "foo", "bar");
assertRowsNet(protocolVersion, executeNet(protocolVersion, "SELECT * FROM %s"), row(0, 1, "foo", "bar"));
assertRowsNet(protocolVersion, executeNet(protocolVersion, "SELECT * FROM mv"), row(0, "foo", 1, "bar"));
executeNet(protocolVersion, "UPDATE %s SET v1=? WHERE id1=? AND id2=?", null, 0, 1);
assertRowsNet(protocolVersion, executeNet(protocolVersion, "SELECT * FROM %s"), row(0, 1, null, "bar"));
assertRowsNet(protocolVersion, executeNet(protocolVersion, "SELECT * FROM mv"));
executeNet(protocolVersion, "UPDATE %s SET v2=? WHERE id1=? AND id2=?", "rab", 0, 1);
assertRowsNet(protocolVersion, executeNet(protocolVersion, "SELECT * FROM %s"), row(0, 1, null, "rab"));
assertRowsNet(protocolVersion, executeNet(protocolVersion, "SELECT * FROM mv"));
}
} }