You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by be...@apache.org on 2021/09/10 07:37:00 UTC

[cassandra] branch cassandra-4.0 updated: Cassandra fails to process OperationExecutionException which causes ClassCastException

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

bereng pushed a commit to branch cassandra-4.0
in repository https://gitbox.apache.org/repos/asf/cassandra.git


The following commit(s) were added to refs/heads/cassandra-4.0 by this push:
     new 8b0b22e  Cassandra fails to process OperationExecutionException which causes ClassCastException
8b0b22e is described below

commit 8b0b22e166e2845a7c61af21cf13d8e0ff19efd6
Author: Bereng <be...@gmail.com>
AuthorDate: Mon Sep 6 09:27:32 2021 +0200

    Cassandra fails to process OperationExecutionException which causes ClassCastException
    
    patch by Benjamin Lerer, Berenguer Blasi; reviewed by Benjamin Lerer, Berenguer Blasi for CASSANDRA-15269
---
 .../org/apache/cassandra/cql3/functions/FromJsonFct.java |  2 +-
 .../cassandra/exceptions/FunctionExecutionException.java | 12 +++++++++---
 .../exceptions/OperationExecutionException.java          | 16 ++++++++--------
 .../cassandra/transport/messages/ErrorMessage.java       |  2 +-
 .../cassandra/cql3/functions/OperationFctsTest.java      | 15 +++++++++++++++
 5 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/src/java/org/apache/cassandra/cql3/functions/FromJsonFct.java b/src/java/org/apache/cassandra/cql3/functions/FromJsonFct.java
index 8f07b38..01a6e20 100644
--- a/src/java/org/apache/cassandra/cql3/functions/FromJsonFct.java
+++ b/src/java/org/apache/cassandra/cql3/functions/FromJsonFct.java
@@ -69,7 +69,7 @@ public class FromJsonFct extends NativeScalarFunction
         }
         catch (IOException exc)
         {
-            throw new FunctionExecutionException(NAME, Collections.singletonList("text"), String.format("Could not decode JSON string '%s': %s", jsonArg, exc.toString()));
+            throw FunctionExecutionException.create(NAME, Collections.singletonList("text"), String.format("Could not decode JSON string '%s': %s", jsonArg, exc.toString()));
         }
         catch (MarshalException exc)
         {
diff --git a/src/java/org/apache/cassandra/exceptions/FunctionExecutionException.java b/src/java/org/apache/cassandra/exceptions/FunctionExecutionException.java
index e743fde..a9a99f6 100644
--- a/src/java/org/apache/cassandra/exceptions/FunctionExecutionException.java
+++ b/src/java/org/apache/cassandra/exceptions/FunctionExecutionException.java
@@ -37,11 +37,17 @@ public class FunctionExecutionException extends RequestExecutionException
         return fee;
     }
 
-    public FunctionExecutionException(FunctionName functionName, List<String> argTypes, String detail)
+    public static FunctionExecutionException create(FunctionName functionName, List<String> argTypes, String detail)
     {
-        super(ExceptionCode.FUNCTION_FAILURE, "execution of '" + functionName + argTypes + "' failed: " + detail);
+        String msg = "execution of '" + functionName + argTypes + "' failed: " + detail;
+        return new FunctionExecutionException(functionName, argTypes, msg);
+    }
+
+    public FunctionExecutionException(FunctionName functionName, List<String> argTypes, String msg)
+    {
+        super(ExceptionCode.FUNCTION_FAILURE, msg);
         this.functionName = functionName;
         this.argTypes = argTypes;
-        this.detail = detail;
+        this.detail = msg;
     }
 }
diff --git a/src/java/org/apache/cassandra/exceptions/OperationExecutionException.java b/src/java/org/apache/cassandra/exceptions/OperationExecutionException.java
index 4f9ffa4..f86969e 100644
--- a/src/java/org/apache/cassandra/exceptions/OperationExecutionException.java
+++ b/src/java/org/apache/cassandra/exceptions/OperationExecutionException.java
@@ -19,12 +19,13 @@ package org.apache.cassandra.exceptions;
 
 import java.util.List;
 
+import org.apache.cassandra.cql3.functions.OperationFcts;
 import org.apache.cassandra.db.marshal.AbstractType;
 
 /**
  * Thrown when an operation problem has occured (e.g. division by zero with integer).
  */
-public final class OperationExecutionException extends RequestExecutionException
+public final class OperationExecutionException extends FunctionExecutionException
 {
 
     /**
@@ -38,20 +39,19 @@ public final class OperationExecutionException extends RequestExecutionException
     public static OperationExecutionException create(char operator, List<AbstractType<?>> argTypes, Exception e)
     {
         List<String> cqlTypes = AbstractType.asCQLTypeStringList(argTypes);
-        return new OperationExecutionException(String.format("the operation '%s %s %s' failed: %s",
-                                                             cqlTypes.get(0),
-                                                             operator,
-                                                             cqlTypes.get(1),
-                                                             e.getMessage()));
+        String msg = String.format("the operation '%s %s %s' failed: %s", cqlTypes.get(0), operator, cqlTypes.get(1), e.getMessage());
+        return new OperationExecutionException(operator, cqlTypes, msg);
     }
 
     /**
      * Creates an <code>OperationExecutionException</code> with the specified message.
+     * @param operator the operator
+     * @param argTypes the argument types
      * @param msg the error message
      */
-    public OperationExecutionException(String msg)
+    public OperationExecutionException(char operator, List<String> argTypes, String msg)
     {
-        super(ExceptionCode.FUNCTION_FAILURE, msg);
+        super(OperationFcts.getFunctionNameFromOperator(operator), argTypes, msg);
     }
 
 }
diff --git a/src/java/org/apache/cassandra/transport/messages/ErrorMessage.java b/src/java/org/apache/cassandra/transport/messages/ErrorMessage.java
index 14b4ac4..6890584 100644
--- a/src/java/org/apache/cassandra/transport/messages/ErrorMessage.java
+++ b/src/java/org/apache/cassandra/transport/messages/ErrorMessage.java
@@ -149,7 +149,7 @@ public class ErrorMessage extends Message.Response
                     String fKeyspace = CBUtil.readString(body);
                     String fName = CBUtil.readString(body);
                     List<String> argTypes = CBUtil.readStringList(body);
-                    te = new FunctionExecutionException(new FunctionName(fKeyspace, fName), argTypes, msg);
+                    te = FunctionExecutionException.create(new FunctionName(fKeyspace, fName), argTypes, msg);
                     break;
                 case UNPREPARED:
                     {
diff --git a/test/unit/org/apache/cassandra/cql3/functions/OperationFctsTest.java b/test/unit/org/apache/cassandra/cql3/functions/OperationFctsTest.java
index c8ee935..053283d 100644
--- a/test/unit/org/apache/cassandra/cql3/functions/OperationFctsTest.java
+++ b/test/unit/org/apache/cassandra/cql3/functions/OperationFctsTest.java
@@ -20,6 +20,7 @@ package org.apache.cassandra.cql3.functions;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.Date;
+import java.util.Optional;
 
 import org.junit.Test;
 
@@ -28,6 +29,7 @@ import org.apache.cassandra.cql3.UntypedResultSet;
 import org.apache.cassandra.exceptions.OperationExecutionException;
 import org.apache.cassandra.serializers.SimpleDateSerializer;
 import org.apache.cassandra.serializers.TimestampSerializer;
+import org.apache.cassandra.transport.ProtocolVersion;
 
 public class OperationFctsTest extends CQLTester
 {
@@ -861,4 +863,17 @@ public class OperationFctsTest extends CQLTester
     {
         return SimpleDateSerializer.dateStringToDays(dateAsString);
     }
+
+    @Test
+    public void testFunctionException() throws Throwable
+    {
+        createTable("CREATE TABLE %s (pk int, c1 int, c2 int, v text, PRIMARY KEY(pk, c1, c2))");
+        execute("INSERT INTO %s (pk, c1, c2, v) VALUES (1, 0, 2, 'test')");
+
+        assertInvalidThrowMessage(Optional.of(ProtocolVersion.CURRENT),
+                                  "the operation 'int / int' failed: / by zero",
+                                  com.datastax.driver.core.exceptions.FunctionExecutionException.class,
+                                  "SELECT c2 / c1 FROM %s WHERE pk = 1");
+    }
+
 }

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org