Change behaviour for LWTs on static columns will null and non-existing values.
Patch by Alex Petrov; reviewed by TBD for CASSANDRA-12060. Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/94e1d56c Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/94e1d56c Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/94e1d56c Branch: refs/heads/12060-3.0-v2 Commit: 94e1d56c0a478f23d8626951a82e7a1a43a43bbb Parents: 8b5b185 Author: Alex Petrov <[email protected]> Authored: Wed Aug 10 13:15:30 2016 +0200 Committer: Alex Petrov <[email protected]> Committed: Wed Aug 17 15:30:21 2016 +0200 ---------------------------------------------------------------------- .../cassandra/cql3/statements/CQL3CasRequest.java | 12 ++++++++++-- .../cql3/statements/ModificationStatement.java | 5 ++++- src/java/org/apache/cassandra/service/StorageProxy.java | 2 +- 3 files changed, 15 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/94e1d56c/src/java/org/apache/cassandra/cql3/statements/CQL3CasRequest.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/CQL3CasRequest.java b/src/java/org/apache/cassandra/cql3/statements/CQL3CasRequest.java index 9564005..5362e8f 100644 --- a/src/java/org/apache/cassandra/cql3/statements/CQL3CasRequest.java +++ b/src/java/org/apache/cassandra/cql3/statements/CQL3CasRequest.java @@ -28,6 +28,8 @@ import org.apache.cassandra.cql3.*; import org.apache.cassandra.db.*; import org.apache.cassandra.db.filter.ClusteringIndexSliceFilter; import org.apache.cassandra.db.filter.ColumnFilter; +import org.apache.cassandra.db.filter.DataLimits; +import org.apache.cassandra.db.filter.RowFilter; import org.apache.cassandra.db.partitions.FilteredPartition; import org.apache.cassandra.db.partitions.Partition; import org.apache.cassandra.db.partitions.PartitionUpdate; @@ -123,7 +125,9 @@ public class CQL3CasRequest implements CASRequest // if an insert only static columns, then the existence condition applies only to the // static columns themselves, and so we don't want to include regular columns in that // case. - if (hasExists) + // If static row is updated, in order to maintain backward compatibility with 2.x + // we have to read at least one row to return failure result with filled clustering. + if (hasExists || updatesStaticRow) { PartitionColumns allColumns = cfm.partitionColumns(); Columns statics = updatesStaticRow ? allColumns.statics : Columns.NONE; @@ -144,10 +148,14 @@ public class CQL3CasRequest implements CASRequest { if (clustering != Clustering.STATIC_CLUSTERING) builder.add(Slice.make(clustering)); + // In order to make distinction between non-existing partition and partition without statics on static condition, + // we have to read at least one row (see #12060). + else if (conditions.size() == 1) + builder.add(Slice.ALL); } ClusteringIndexSliceFilter filter = new ClusteringIndexSliceFilter(builder.build(), false); - return SinglePartitionReadCommand.create(cfm, nowInSec, key, ColumnFilter.selection(columnsToRead()), filter); + return SinglePartitionReadCommand.create(false, cfm, nowInSec, ColumnFilter.selection(columnsToRead()), RowFilter.NONE, DataLimits.cqlLimits(conditions.size()), key, filter); } public boolean appliesTo(FilteredPartition current) throws InvalidRequestException http://git-wip-us.apache.org/repos/asf/cassandra/blob/94e1d56c/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java index 01c2ad1..7094853 100644 --- a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java @@ -587,8 +587,11 @@ public abstract class ModificationStatement implements CQLStatement current = FilteredPartition.create(PartitionIterators.getOnlyElement(iter, readCommand)); } - if (!request.appliesTo(current)) + // If partition is effectively empty (no rows, no statics, not live), we pass null to indicate it does not exist + if (!request.appliesTo(current.isEmpty() ? null : current)) + { return current.rowIterator(); + } PartitionUpdate updates = request.makeUpdates(current); updates = TriggerExecutor.instance.execute(updates); http://git-wip-us.apache.org/repos/asf/cassandra/blob/94e1d56c/src/java/org/apache/cassandra/service/StorageProxy.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/service/StorageProxy.java b/src/java/org/apache/cassandra/service/StorageProxy.java index 8a151f2..1550bb0 100644 --- a/src/java/org/apache/cassandra/service/StorageProxy.java +++ b/src/java/org/apache/cassandra/service/StorageProxy.java @@ -251,7 +251,7 @@ public class StorageProxy implements StorageProxyMBean current = FilteredPartition.create(rowIter); } - if (!request.appliesTo(current)) + if (!request.appliesTo(current.isEmpty() ? null : current)) { Tracing.trace("CAS precondition does not match current values {}", current); casWriteMetrics.conditionNotMet.inc();
