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]

Reply via email to