This is an automated email from the ASF dual-hosted git repository.
dcapwell pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git
The following commit(s) were added to refs/heads/trunk by this push:
new 8c9627076b When using BEGIN TRANSACTION if a complex mutation exists
in the same statement as one that uses a reference, then the complex delete is
dropped
8c9627076b is described below
commit 8c9627076b0bb7956d1303e7a7454ac0c30e5074
Author: David Capwell <[email protected]>
AuthorDate: Tue Jul 29 11:07:30 2025 -0700
When using BEGIN TRANSACTION if a complex mutation exists in the same
statement as one that uses a reference, then the complex delete is dropped
patch by David Capwell; reviewed by Caleb Rackliffe for CASSANDRA-20788
---
CHANGES.txt | 1 +
.../apache/cassandra/cql3/UpdateParameters.java | 18 +++++++++-
.../distributed/test/accord/AccordCQLTestBase.java | 39 ++++++++++++++++++++++
3 files changed, 57 insertions(+), 1 deletion(-)
diff --git a/CHANGES.txt b/CHANGES.txt
index d34add029e..a53677d2fb 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
5.1
+ * When using BEGIN TRANSACTION if a complex mutation exists in the same
statement as one that uses a reference, then the complex delete is dropped
(CASSANDRA-20788)
* Migrate all nodetool commands from airline to picocli (CASSANDRA-17445)
* Journal.TopologyUpdate should not store the local topology as it can be
inferred from the global on (CASSANDRA-20785)
* Accord: Topology serializer has a lot of repeated data, can dedup to shrink
the cost (CASSANDRA-20715)
diff --git a/src/java/org/apache/cassandra/cql3/UpdateParameters.java
b/src/java/org/apache/cassandra/cql3/UpdateParameters.java
index 6ef6c7bb6c..e6ad075974 100644
--- a/src/java/org/apache/cassandra/cql3/UpdateParameters.java
+++ b/src/java/org/apache/cassandra/cql3/UpdateParameters.java
@@ -35,6 +35,7 @@ import org.apache.cassandra.db.rows.BTreeRow;
import org.apache.cassandra.db.rows.BufferCell;
import org.apache.cassandra.db.rows.Cell;
import org.apache.cassandra.db.rows.CellPath;
+import org.apache.cassandra.db.rows.ComplexColumnData;
import org.apache.cassandra.db.rows.Row;
import org.apache.cassandra.db.rows.Rows;
import org.apache.cassandra.exceptions.InvalidRequestException;
@@ -202,7 +203,22 @@ public class UpdateParameters
newRow(row.clustering());
addRowDeletion(row.deletion());
addPrimaryKeyLivenessInfo(row.primaryKeyLivenessInfo());
- row.cells().forEach(builder::addCell);
+ row.iterator().forEachRemaining(cd -> {
+ if (cd instanceof Cell<?>)
+ {
+ builder.addCell((Cell<?>) cd);
+ }
+ else if (cd instanceof ComplexColumnData)
+ {
+ ComplexColumnData ccd = (ComplexColumnData) cd;
+ builder.addComplexDeletion(ccd.column(),
ccd.complexDeletion());
+ ccd.iterator().forEachRemaining(builder::addCell);
+ }
+ else
+ {
+ throw new AssertionError("Unexpected type: " + cd.getClass() +
"; " + cd);
+ }
+ });
}
private void validateColumnSize(ColumnMetadata column, ByteBuffer value)
diff --git
a/test/distributed/org/apache/cassandra/distributed/test/accord/AccordCQLTestBase.java
b/test/distributed/org/apache/cassandra/distributed/test/accord/AccordCQLTestBase.java
index caa2f6da69..27a07343f3 100644
---
a/test/distributed/org/apache/cassandra/distributed/test/accord/AccordCQLTestBase.java
+++
b/test/distributed/org/apache/cassandra/distributed/test/accord/AccordCQLTestBase.java
@@ -22,6 +22,7 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -37,6 +38,7 @@ import java.util.stream.Collectors;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
@@ -47,8 +49,10 @@ import accord.primitives.Unseekables;
import accord.topology.Topologies;
import org.apache.cassandra.config.Config.PaxosVariant;
import org.apache.cassandra.cql3.CQLTester;
+import org.apache.cassandra.cql3.ast.Symbol;
import org.apache.cassandra.cql3.functions.types.utils.Bytes;
import org.apache.cassandra.cql3.statements.TransactionStatement;
+import org.apache.cassandra.distributed.util.QueryResultUtil;
import org.apache.cassandra.db.marshal.Int32Type;
import org.apache.cassandra.db.marshal.ListType;
import org.apache.cassandra.db.marshal.MapType;
@@ -3221,4 +3225,39 @@ public abstract class AccordCQLTestBase extends
AccordTestBase
}
);
}
+
+ @Test
+ public void setComplexWithReferenceOnAnotherColumn() throws Exception
+ {
+ // we add a row first
+ // then do a mutation that references the row
+ Symbol v0 = new Symbol("v0", SetType.getInstance(Int32Type.instance,
true));
+ Symbol v1 = new Symbol("v1", Int32Type.instance);
+ Symbol row = Symbol.unknownType("row");
+ test("CREATE TABLE " + qualifiedAccordTableName + "(k int, c int, v0
set<int>, v1 int, primary key(k, c)) WITH transactional_mode='" +
transactionalMode + "'",
+ cluster -> {
+ ICoordinator coordinator = cluster.coordinator(1);
+ coordinator.execute("INSERT INTO " + qualifiedAccordTableName
+ "(k, c, v0, v1) VALUES (0, 0, {0}, 1)", QUORUM);
+
+ String cql = "BEGIN TRANSACTION\n" +
+ " LET row = (SELECT *\n" +
+ " FROM " + qualifiedAccordTableName
+ '\n' +
+ " WHERE k = ? AND c = ?);\n" +
+ " UPDATE " + qualifiedAccordTableName + '\n' +
+ " SET\n" +
+ " v0={1},\n" +
+ " v1 += row.v1\n" +
+ " WHERE \n" +
+ " k = ? AND \n" +
+ " c = ?;\n" +
+ "COMMIT TRANSACTION";
+ coordinator.execute(cql, QUORUM, 0, 0, 0, 0);
+
+ // is the data correct?
+ var result = coordinator.executeWithResult("SELECT * FROM " +
qualifiedAccordTableName, QUORUM);
+
QueryResultUtil.assertThat(result).isEqualTo(QueryResults.builder()
+ .row(0, 0, Collections.singleton(1), 2)
+ .build());
+ });
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]