This is an automated email from the ASF dual-hosted git repository.

dcapwell pushed a commit to branch cep-15-accord
in repository https://gitbox.apache.org/repos/asf/cassandra.git


The following commit(s) were added to refs/heads/cep-15-accord by this push:
     new 662facce68 txns that update a static row when the desired row doesn't 
exist leads to an error
662facce68 is described below

commit 662facce68057177086f1a09bec5712348633344
Author: David Capwell <[email protected]>
AuthorDate: Thu Aug 29 13:34:45 2024 -0700

    txns that update a static row when the desired row doesn't exist leads to 
an error
    
    patch by David Capwell; reviewed by Caleb Rackliffe for CASSANDRA-19855
---
 CHANGES.txt                                        |  1 +
 .../cassandra/service/accord/txn/TxnWrite.java     |  2 +-
 .../distributed/test/accord/AccordCQLTestBase.java | 22 ++++++++++++++++++++++
 .../distributed/test/accord/AccordTestBase.java    |  6 ++++--
 4 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index 2bb66212c4..ba389b50cc 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 5.1
+ * txns that update a static row when the desired row doesn't exist leads to 
an error (CASSANDRA-19855)
  * CommandsForRanges does not support slice which cause over returned data 
being sent (CASSANDRA-19857)
  * Prohibit counter column access in Accord transactions (CASSANDRA-18987)
  * Add Accord configuration stub (CASSANDRA-18221)
diff --git a/src/java/org/apache/cassandra/service/accord/txn/TxnWrite.java 
b/src/java/org/apache/cassandra/service/accord/txn/TxnWrite.java
index 7d6e67ad84..f7081927eb 100644
--- a/src/java/org/apache/cassandra/service/accord/txn/TxnWrite.java
+++ b/src/java/org/apache/cassandra/service/accord/txn/TxnWrite.java
@@ -263,7 +263,7 @@ public class TxnWrite extends 
AbstractKeySorted<TxnWrite.Update> implements Writ
             if (!staticRow.isEmpty())
                 updateBuilder.add(staticRow);
 
-            Row existing = !baseUpdate.isEmpty() ? 
Iterables.getOnlyElement(baseUpdate) : null;
+            Row existing = baseUpdate.hasRows() ? 
Iterables.getOnlyElement(baseUpdate) : null;
             Row row = applyUpdates(existing, referenceOps.regulars, key, 
referenceOps.clustering, up, data);
             if (row != null)
                 updateBuilder.add(row);
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 eebe6ac000..f094f43ba9 100644
--- 
a/test/distributed/org/apache/cassandra/distributed/test/accord/AccordCQLTestBase.java
+++ 
b/test/distributed/org/apache/cassandra/distributed/test/accord/AccordCQLTestBase.java
@@ -59,6 +59,7 @@ import org.apache.cassandra.service.accord.AccordService;
 import org.apache.cassandra.service.accord.AccordTestUtils;
 import org.apache.cassandra.service.consensus.TransactionalMode;
 import org.apache.cassandra.utils.ByteBufferUtil;
+import org.apache.cassandra.utils.FailingConsumer;
 import org.assertj.core.api.Assertions;
 
 import static java.util.Collections.singletonList;
@@ -91,6 +92,27 @@ public abstract class AccordCQLTestBase extends 
AccordTestBase
         SHARED_CLUSTER.schemaChange("CREATE TYPE " + KEYSPACE + ".person 
(height int, age int)");
     }
 
+    @Override
+    protected void test(FailingConsumer<Cluster> fn) throws Exception
+    {
+        test("CREATE TABLE " + qualifiedAccordTableName + " (k int, c int, v 
int, primary key (k, c)) WITH " + transactionalMode.asCqlParam(), fn);
+    }
+
+    @Test
+    public void testNonExistingKeyWithStaticUpdate() throws Exception
+    {
+        test("CREATE TABLE " + qualifiedAccordTableName + " (k int, c int, s 
int static, v int, primary key (k, c)) WITH " + transactionalMode.asCqlParam(), 
cluster -> {
+            for (int i = 0; i < 10; i++)
+                cluster.coordinator(1).execute(wrapInTxn("UPDATE " + 
qualifiedAccordTableName + " SET v += ?, s=? WHERE k=? AND c=?"), 
ConsistencyLevel.ANY, 1, i, 0, i);
+
+            SimpleQueryResult result = 
cluster.coordinator(1).executeWithResult(wrapInTxn("SELECT * FROM " + 
qualifiedAccordTableName + " WHERE k=? LIMIT 1"), ConsistencyLevel.ANY, 0);
+            AssertUtils.assertRows(result, QueryResults.builder()
+                                                       .columns("k", "c", "s", 
"v")
+                                                       .row(0, null, 9, null)
+                                                       .build());
+        });
+    }
+
     @Test
     public void testMultiPartitionReturn() throws Exception
     {
diff --git 
a/test/distributed/org/apache/cassandra/distributed/test/accord/AccordTestBase.java
 
b/test/distributed/org/apache/cassandra/distributed/test/accord/AccordTestBase.java
index cfec7f44e9..f30ef762cc 100644
--- 
a/test/distributed/org/apache/cassandra/distributed/test/accord/AccordTestBase.java
+++ 
b/test/distributed/org/apache/cassandra/distributed/test/accord/AccordTestBase.java
@@ -439,12 +439,14 @@ public abstract class AccordTestBase extends TestBaseImpl
         });
     }
 
-    private static String wrapInTxn(String statement)
+    protected static String wrapInTxn(String statement)
     {
         if (!statement.trim().toUpperCase().startsWith("BEGIN TRANSACTION"))
         {
             statement = statement.trim();
-            statement = 
Arrays.stream(statement.split("\\n")).collect(Collectors.joining("\n  ", "BEGIN 
TRANSACTION\n  ", "\nCOMMIT TRANSACTION"));
+            statement = Arrays.stream(statement.split("\\n"))
+                              .map(line -> line.trim().endsWith(";") ? line : 
line + ';')
+                              .collect(Collectors.joining("\n  ", "BEGIN 
TRANSACTION\n  ", "\nCOMMIT TRANSACTION"));
         }
         return statement;
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to