cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sn...@apache.org
Subject cassandra git commit: Allow instantiation of UDTs and tuples in UDFs
Date Wed, 13 Apr 2016 18:13:17 GMT
Repository: cassandra
Updated Branches:
  refs/heads/trunk ea0a97263 -> 5288d434b


Allow instantiation of UDTs and tuples in UDFs

patch by Robert Stupp; reviewed by Tyler Hobbs for CASSANDRA-10818


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/5288d434
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/5288d434
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/5288d434

Branch: refs/heads/trunk
Commit: 5288d434b3b559c7006fa001a2dc56f4f4b2e2c3
Parents: ea0a972
Author: Robert Stupp <snazy@snazy.de>
Authored: Wed Apr 13 20:12:29 2016 +0200
Committer: Robert Stupp <snazy@snazy.de>
Committed: Wed Apr 13 20:12:29 2016 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 doc/cql3/CQL.textile                            |  49 ++++++-
 .../cql3/functions/JavaBasedUDFunction.java     |   9 +-
 .../cassandra/cql3/functions/JavaUDF.java       |   5 +-
 .../cql3/functions/ScriptBasedUDFunction.java   |  74 ++++++++++
 .../cql3/functions/UDFByteCodeVerifier.java     |   2 +-
 .../cassandra/cql3/functions/UDFContext.java    | 105 +++++++++++++
 .../cql3/functions/UDFContextImpl.java          | 146 +++++++++++++++++++
 .../cassandra/cql3/functions/UDFunction.java    |   6 +
 .../cassandra/cql3/functions/UDHelper.java      |  10 +-
 .../cassandra/cql3/functions/JavaSourceUDF.txt  |   7 +-
 .../cql3/validation/entities/UFTest.java        | 144 +++++++++++++++++-
 .../entities/udfverify/CallClone.java           |   5 +-
 .../entities/udfverify/CallComDatastax.java     |   5 +-
 .../entities/udfverify/CallFinalize.java        |   5 +-
 .../entities/udfverify/CallOrgApache.java       |   5 +-
 .../entities/udfverify/ClassWithField.java      |   5 +-
 .../udfverify/ClassWithInitializer.java         |   5 +-
 .../udfverify/ClassWithInitializer2.java        |   5 +-
 .../udfverify/ClassWithInitializer3.java        |   5 +-
 .../udfverify/ClassWithStaticInitializer.java   |   5 +-
 .../entities/udfverify/GoodClass.java           |   5 +-
 .../entities/udfverify/UseOfSynchronized.java   |   5 +-
 .../udfverify/UseOfSynchronizedWithNotify.java  |   5 +-
 .../UseOfSynchronizedWithNotifyAll.java         |   5 +-
 .../udfverify/UseOfSynchronizedWithWait.java    |   5 +-
 .../udfverify/UseOfSynchronizedWithWaitL.java   |   5 +-
 .../udfverify/UseOfSynchronizedWithWaitLI.java  |   5 +-
 28 files changed, 587 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 8067962..3b5f1b7 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 3.6
+ * Allow instantiation of UDTs and tuples in UDFs (CASSANDRA-10818)
  * Support UDT in CQLSSTableWriter (CASSANDRA-10624)
  * Support for non-frozen user-defined types, updating
    individual fields of user-defined types (CASSANDRA-7423)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/doc/cql3/CQL.textile
----------------------------------------------------------------------
diff --git a/doc/cql3/CQL.textile b/doc/cql3/CQL.textile
index b0173a6..9fd5f85 100644
--- a/doc/cql3/CQL.textile
+++ b/doc/cql3/CQL.textile
@@ -2059,6 +2059,49 @@ CREATE FUNCTION fct_using_udt ( udtarg frozen<custom_type> )
 
 User-defined functions can be used in "@SELECT@":#selectStmt, "@INSERT@":#insertStmt and "@UPDATE@":#updateStmt statements.
 
+The implicitly available @udfContext@ field (or binding for script UDFs) provides the neccessary functionality to create new UDT and tuple values.
+
+bc(sample). 
+CREATE TYPE custom_type (txt text, i int);
+CREATE FUNCTION fct_using_udt ( somearg int )
+  RETURNS NULL ON NULL INPUT
+  RETURNS custom_type
+  LANGUAGE java
+  AS $$
+    UDTValue udt = udfContext.newReturnUDTValue();
+    udt.setString("txt", "some string");
+    udt.setInt("i", 42);
+    return udt;
+  $$;
+
+The definition of the @UDFContext@ interface can be found in the Apache Cassandra source code for @org.apache.cassandra.cql3.functions.UDFContext@.
+
+bc(sample). 
+public interface UDFContext
+{
+    UDTValue newArgUDTValue(String argName);
+    UDTValue newArgUDTValue(int argNum);
+    UDTValue newReturnUDTValue();
+    UDTValue newUDTValue(String udtName);
+    TupleValue newArgTupleValue(String argName);
+    TupleValue newArgTupleValue(int argNum);
+    TupleValue newReturnTupleValue();
+    TupleValue newTupleValue(String cqlDefinition);
+}
+
+Java UDFs already have some imports for common interfaces and classes defined. These imports are:
+Please note, that these convenience imports are not available for script UDFs.
+
+bc(sample). 
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.cassandra.cql3.functions.UDFContext;
+import com.datastax.driver.core.TypeCodec;
+import com.datastax.driver.core.TupleValue;
+import com.datastax.driver.core.UDTValue;
+
 See "@CREATE FUNCTION@":#createFunctionStmt and "@DROP FUNCTION@":#dropFunctionStmt.
 
 h2(#udas). User-Defined Aggregates
@@ -2328,10 +2371,8 @@ h3. 3.4.2
 * "@INSERT/UPDATE options@":#updateOptions for tables having a default_time_to_live specifying a TTL of 0 will remove the TTL from the inserted or updated values
 * "@ALTER TABLE@":#alterTableStmt @ADD@ and @DROP@ now allow mutiple columns to be added/removed
 * New "@PER PARTITION LIMIT@":#selectLimit option (see "CASSANDRA-7017":https://issues.apache.org/jira/browse/CASSANDRA-7017).
-
-h3. 3.4.2
-
-* User-defined types may now be stored in a non-frozen form, allowing individual fields to be updated and deleted in "@UPDATE@ statements":#updateStmt and "@DELETE@ statements":#deleteStmt, respectively.  (CASSANDRA-7423)
+* "User-defined functions":#udfs can now instantiate @UDTValue@ and @TupleValue@ instances via the new @UDFContext@ interface (see "CASSANDRA-10818":https://issues.apache.org/jira/browse/CASSANDRA-10818).
+* "User-defined types"#createTypeStmt may now be stored in a non-frozen form, allowing individual fields to be updated and deleted in "@UPDATE@ statements":#updateStmt and "@DELETE@ statements":#deleteStmt, respectively. ("CASSANDRA-7423":https://issues.apache.org/jira/browse/CASSANDRA-7423)
 
 h3. 3.4.1
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/src/java/org/apache/cassandra/cql3/functions/JavaBasedUDFunction.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/functions/JavaBasedUDFunction.java b/src/java/org/apache/cassandra/cql3/functions/JavaBasedUDFunction.java
index ae30adc..15103be 100644
--- a/src/java/org/apache/cassandra/cql3/functions/JavaBasedUDFunction.java
+++ b/src/java/org/apache/cassandra/cql3/functions/JavaBasedUDFunction.java
@@ -296,15 +296,12 @@ public final class JavaBasedUDFunction extends UDFunction
             // Verify the UDF bytecode against use of probably dangerous code
             Set<String> errors = udfByteCodeVerifier.verify(targetClassLoader.classData(targetClassName));
             String validDeclare = "not allowed method declared: " + executeInternalName + '(';
-            String validCall = "call to " + targetClassName.replace('.', '/') + '.' + executeInternalName + "()";
             for (Iterator<String> i = errors.iterator(); i.hasNext();)
             {
                 String error = i.next();
                 // we generate a random name of the private, internal execute method, which is detected by the byte-code verifier
-                if (error.startsWith(validDeclare) || error.equals(validCall))
-                {
+                if (error.startsWith(validDeclare))
                     i.remove();
-                }
             }
             if (!errors.isEmpty())
                 throw new InvalidRequestException("Java UDF validation failed: " + errors);
@@ -332,9 +329,9 @@ public final class JavaBasedUDFunction extends UDFunction
                 if (nonSyntheticMethodCount != 2 || cls.getDeclaredConstructors().length != 1)
                     throw new InvalidRequestException("Check your source to not define additional Java methods or constructors");
                 MethodType methodType = MethodType.methodType(void.class)
-                                                  .appendParameterTypes(TypeCodec.class, TypeCodec[].class);
+                                                  .appendParameterTypes(TypeCodec.class, TypeCodec[].class, UDFContext.class);
                 MethodHandle ctor = MethodHandles.lookup().findConstructor(cls, methodType);
-                this.javaUDF = (JavaUDF) ctor.invokeWithArguments(returnCodec, argCodecs);
+                this.javaUDF = (JavaUDF) ctor.invokeWithArguments(returnCodec, argCodecs, udfContext);
             }
             finally
             {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/src/java/org/apache/cassandra/cql3/functions/JavaUDF.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/functions/JavaUDF.java b/src/java/org/apache/cassandra/cql3/functions/JavaUDF.java
index fcfd21c..7410f1f 100644
--- a/src/java/org/apache/cassandra/cql3/functions/JavaUDF.java
+++ b/src/java/org/apache/cassandra/cql3/functions/JavaUDF.java
@@ -34,10 +34,13 @@ public abstract class JavaUDF
     private final TypeCodec<Object> returnCodec;
     private final TypeCodec<Object>[] argCodecs;
 
-    protected JavaUDF(TypeCodec<Object> returnCodec, TypeCodec<Object>[] argCodecs)
+    protected final UDFContext udfContext;
+
+    protected JavaUDF(TypeCodec<Object> returnCodec, TypeCodec<Object>[] argCodecs, UDFContext udfContext)
     {
         this.returnCodec = returnCodec;
         this.argCodecs = argCodecs;
+        this.udfContext = udfContext;
     }
 
     protected abstract ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/src/java/org/apache/cassandra/cql3/functions/ScriptBasedUDFunction.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/functions/ScriptBasedUDFunction.java b/src/java/org/apache/cassandra/cql3/functions/ScriptBasedUDFunction.java
index 8743a20..b524163 100644
--- a/src/java/org/apache/cassandra/cql3/functions/ScriptBasedUDFunction.java
+++ b/src/java/org/apache/cassandra/cql3/functions/ScriptBasedUDFunction.java
@@ -27,6 +27,7 @@ import java.util.*;
 import java.util.concurrent.ExecutorService;
 import javax.script.*;
 
+import jdk.nashorn.api.scripting.AbstractJSObject;
 import org.apache.cassandra.concurrent.NamedThreadFactory;
 import org.apache.cassandra.cql3.ColumnIdentifier;
 import org.apache.cassandra.db.marshal.AbstractType;
@@ -127,6 +128,7 @@ final class ScriptBasedUDFunction extends UDFunction
     }
 
     private final CompiledScript script;
+    private final Object udfContextBinding;
 
     ScriptBasedUDFunction(FunctionName name,
                           List<ColumnIdentifier> argNames,
@@ -155,6 +157,13 @@ final class ScriptBasedUDFunction extends UDFunction
             throw new InvalidRequestException(
                                              String.format("Failed to compile function '%s' for language %s: %s", name, language, e));
         }
+
+        // It's not always possible to simply pass a plain Java object as a binding to Nashorn and
+        // let the script execute methods on it.
+        udfContextBinding =
+            ("Oracle Nashorn".equals(((ScriptEngine) scriptEngine).getFactory().getEngineName()))
+                ? new UDFContextWrapper()
+                : udfContext;
     }
 
     protected ExecutorService executor()
@@ -173,6 +182,7 @@ final class ScriptBasedUDFunction extends UDFunction
         Bindings bindings = scriptContext.getBindings(ScriptContext.ENGINE_SCOPE);
         for (int i = 0; i < params.length; i++)
             bindings.put(argNames.get(i).toString(), params[i]);
+        bindings.put("udfContext", udfContextBinding);
 
         Object result;
         try
@@ -243,4 +253,68 @@ final class ScriptBasedUDFunction extends UDFunction
 
         return decompose(protocolVersion, result);
     }
+
+    private final class UDFContextWrapper extends AbstractJSObject
+    {
+        private final AbstractJSObject fRetUDT;
+        private final AbstractJSObject fArgUDT;
+        private final AbstractJSObject fRetTup;
+        private final AbstractJSObject fArgTup;
+
+        UDFContextWrapper()
+        {
+            fRetUDT = new AbstractJSObject()
+            {
+                public Object call(Object thiz, Object... args)
+                {
+                    return udfContext.newReturnUDTValue();
+                }
+            };
+            fArgUDT = new AbstractJSObject()
+            {
+                public Object call(Object thiz, Object... args)
+                {
+                    if (args[0] instanceof String)
+                        return udfContext.newArgUDTValue((String) args[0]);
+                    if (args[0] instanceof Number)
+                        return udfContext.newArgUDTValue(((Number) args[0]).intValue());
+                    return super.call(thiz, args);
+                }
+            };
+            fRetTup = new AbstractJSObject()
+            {
+                public Object call(Object thiz, Object... args)
+                {
+                    return udfContext.newReturnTupleValue();
+                }
+            };
+            fArgTup = new AbstractJSObject()
+            {
+                public Object call(Object thiz, Object... args)
+                {
+                    if (args[0] instanceof String)
+                        return udfContext.newArgTupleValue((String) args[0]);
+                    if (args[0] instanceof Number)
+                        return udfContext.newArgTupleValue(((Number) args[0]).intValue());
+                    return super.call(thiz, args);
+                }
+            };
+        }
+
+        public Object getMember(String name)
+        {
+            switch(name)
+            {
+                case "newReturnUDTValue":
+                    return fRetUDT;
+                case "newArgUDTValue":
+                    return fArgUDT;
+                case "newReturnTupleValue":
+                    return fRetTup;
+                case "newArgTupleValue":
+                    return fArgTup;
+            }
+            return super.getMember(name);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/src/java/org/apache/cassandra/cql3/functions/UDFByteCodeVerifier.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/functions/UDFByteCodeVerifier.java b/src/java/org/apache/cassandra/cql3/functions/UDFByteCodeVerifier.java
index 1314af3..4bab883 100644
--- a/src/java/org/apache/cassandra/cql3/functions/UDFByteCodeVerifier.java
+++ b/src/java/org/apache/cassandra/cql3/functions/UDFByteCodeVerifier.java
@@ -47,7 +47,7 @@ public final class UDFByteCodeVerifier
 
     public static final String JAVA_UDF_NAME = JavaUDF.class.getName().replace('.', '/');
     public static final String OBJECT_NAME = Object.class.getName().replace('.', '/');
-    public static final String CTOR_SIG = "(Lcom/datastax/driver/core/TypeCodec;[Lcom/datastax/driver/core/TypeCodec;)V";
+    public static final String CTOR_SIG = "(Lcom/datastax/driver/core/TypeCodec;[Lcom/datastax/driver/core/TypeCodec;Lorg/apache/cassandra/cql3/functions/UDFContext;)V";
 
     private final Set<String> disallowedClasses = new HashSet<>();
     private final Multimap<String, String> disallowedMethodCalls = HashMultimap.create();

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/src/java/org/apache/cassandra/cql3/functions/UDFContext.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/functions/UDFContext.java b/src/java/org/apache/cassandra/cql3/functions/UDFContext.java
new file mode 100644
index 0000000..4465aec
--- /dev/null
+++ b/src/java/org/apache/cassandra/cql3/functions/UDFContext.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.cql3.functions;
+
+import com.datastax.driver.core.TupleValue;
+import com.datastax.driver.core.UDTValue;
+
+/**
+ * Provides context information for a particular user defined function.
+ * Java UDFs can access implementations of this interface using the
+ * {@code udfContext} field, scripted UDFs can get it using the {@code udfContext}
+ * binding.
+ */
+public interface UDFContext
+{
+    /**
+     * Creates a new {@code UDTValue} instance for an argument.
+     *
+     * @param argName name of the argument as declared in the {@code CREATE FUNCTION} statement
+     * @return a new {@code UDTValue} instance
+     * @throws IllegalArgumentException if no argument for the given name exists
+     * @throws IllegalStateException    if the argument is not a UDT
+     */
+    UDTValue newArgUDTValue(String argName);
+
+    /**
+     * Creates a new {@code UDTValue} instance for an argument.
+     *
+     * @param argNum zero-based index of the argument as declared in the {@code CREATE FUNCTION} statement
+     * @return a new {@code UDTValue} instance
+     * @throws ArrayIndexOutOfBoundsException if no argument for the given index exists
+     * @throws IllegalStateException          if the argument is not a UDT
+     */
+    UDTValue newArgUDTValue(int argNum);
+
+    /**
+     * Creates a new {@code UDTValue} instance for the return value.
+     *
+     * @return a new {@code UDTValue} instance
+     * @throws IllegalStateException          if the return type is not a UDT
+     */
+    UDTValue newReturnUDTValue();
+
+    /**
+     * Creates a new {@code UDTValue} instance by name in the same keyspace.
+     *
+     * @param udtName name of the user defined type in the same keyspace as the function
+     * @return a new {@code UDTValue} instance
+     * @throws IllegalArgumentException if no UDT for the given name exists
+     */
+    UDTValue newUDTValue(String udtName);
+
+    /**
+     * Creates a new {@code TupleValue} instance for an argument.
+     *
+     * @param argName name of the argument as declared in the {@code CREATE FUNCTION} statement
+     * @return a new {@code TupleValue} instance
+     * @throws IllegalArgumentException if no argument for the given name exists
+     * @throws IllegalStateException    if the argument is not a tuple
+     */
+    TupleValue newArgTupleValue(String argName);
+
+    /**
+     * Creates a new {@code TupleValue} instance for an argument.
+     *
+     * @param argNum zero-based index of the argument as declared in the {@code CREATE FUNCTION} statement
+     * @return a new {@code TupleValue} instance
+     * @throws ArrayIndexOutOfBoundsException if no argument for the given index exists
+     * @throws IllegalStateException          if the argument is not a tuple
+     */
+    TupleValue newArgTupleValue(int argNum);
+
+    /**
+     * Creates a new {@code TupleValue} instance for the return value.
+     *
+     * @return a new {@code TupleValue} instance
+     * @throws IllegalStateException          if the return type is not a tuple
+     */
+    TupleValue newReturnTupleValue();
+
+    /**
+     * Creates a new {@code TupleValue} instance for the CQL type definition.
+     *
+     * @param cqlDefinition CQL tuple type definition like {@code tuple<int, text, bigint>}
+     * @return a new {@code TupleValue} instance
+     * @throws IllegalStateException          if cqlDefinition type is not a tuple or an invalid type
+     */
+    TupleValue newTupleValue(String cqlDefinition);
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/src/java/org/apache/cassandra/cql3/functions/UDFContextImpl.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/functions/UDFContextImpl.java b/src/java/org/apache/cassandra/cql3/functions/UDFContextImpl.java
new file mode 100644
index 0000000..00625cd
--- /dev/null
+++ b/src/java/org/apache/cassandra/cql3/functions/UDFContextImpl.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.cassandra.cql3.functions;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import com.datastax.driver.core.DataType;
+import com.datastax.driver.core.TupleType;
+import com.datastax.driver.core.TupleValue;
+import com.datastax.driver.core.TypeCodec;
+import com.datastax.driver.core.UDTValue;
+import com.datastax.driver.core.UserType;
+import org.apache.cassandra.cql3.ColumnIdentifier;
+import org.apache.cassandra.db.marshal.AbstractType;
+import org.apache.cassandra.schema.CQLTypeParser;
+import org.apache.cassandra.schema.KeyspaceMetadata;
+import org.apache.cassandra.utils.ByteBufferUtil;
+
+/**
+ * Package private implementation of {@link UDFContext}
+ */
+public final class UDFContextImpl implements UDFContext
+{
+    private final KeyspaceMetadata keyspaceMetadata;
+    private final Map<String, TypeCodec<Object>> byName = new HashMap<>();
+    private final TypeCodec<Object>[] argCodecs;
+    private final TypeCodec<Object> returnCodec;
+
+    UDFContextImpl(List<ColumnIdentifier> argNames, TypeCodec<Object>[] argCodecs, TypeCodec<Object> returnCodec,
+                   KeyspaceMetadata keyspaceMetadata)
+    {
+        for (int i = 0; i < argNames.size(); i++)
+            byName.put(argNames.get(i).toString(), argCodecs[i]);
+        this.argCodecs = argCodecs;
+        this.returnCodec = returnCodec;
+        this.keyspaceMetadata = keyspaceMetadata;
+    }
+
+    public UDTValue newArgUDTValue(String argName)
+    {
+        return newUDTValue(codecFor(argName));
+    }
+
+    public UDTValue newArgUDTValue(int argNum)
+    {
+        return newUDTValue(codecFor(argNum));
+    }
+
+    public UDTValue newReturnUDTValue()
+    {
+        return newUDTValue(returnCodec);
+    }
+
+    public UDTValue newUDTValue(String udtName)
+    {
+        Optional<org.apache.cassandra.db.marshal.UserType> udtType = keyspaceMetadata.types.get(ByteBufferUtil.bytes(udtName));
+        DataType dataType = UDHelper.driverType(udtType.orElseThrow(
+                () -> new IllegalArgumentException("No UDT named " + udtName + " in keyspace " + keyspaceMetadata.name)
+            ));
+        return newUDTValue(dataType);
+    }
+
+    public TupleValue newArgTupleValue(String argName)
+    {
+        return newTupleValue(codecFor(argName));
+    }
+
+    public TupleValue newArgTupleValue(int argNum)
+    {
+        return newTupleValue(codecFor(argNum));
+    }
+
+    public TupleValue newReturnTupleValue()
+    {
+        return newTupleValue(returnCodec);
+    }
+
+    public TupleValue newTupleValue(String cqlDefinition)
+    {
+        AbstractType<?> abstractType = CQLTypeParser.parse(keyspaceMetadata.name, cqlDefinition, keyspaceMetadata.types);
+        DataType dataType = UDHelper.driverType(abstractType);
+        return newTupleValue(dataType);
+    }
+
+    private TypeCodec<Object> codecFor(int argNum)
+    {
+        if (argNum < 0 || argNum >= argCodecs.length)
+            throw new IllegalArgumentException("Function does not declare an argument with index " + argNum);
+        return argCodecs[argNum];
+    }
+
+    private TypeCodec<Object> codecFor(String argName)
+    {
+        TypeCodec<Object> codec = byName.get(argName);
+        if (codec == null)
+            throw new IllegalArgumentException("Function does not declare an argument named '" + argName + '\'');
+        return codec;
+    }
+
+    private static UDTValue newUDTValue(TypeCodec<Object> codec)
+    {
+        DataType dataType = codec.getCqlType();
+        return newUDTValue(dataType);
+    }
+
+    private static UDTValue newUDTValue(DataType dataType)
+    {
+        if (!(dataType instanceof UserType))
+            throw new IllegalStateException("Function argument is not a UDT but a " + dataType.getName());
+        UserType userType = (UserType) dataType;
+        return userType.newValue();
+    }
+
+    private static TupleValue newTupleValue(TypeCodec<Object> codec)
+    {
+        DataType dataType = codec.getCqlType();
+        return newTupleValue(dataType);
+    }
+
+    private static TupleValue newTupleValue(DataType dataType)
+    {
+        if (!(dataType instanceof TupleType))
+            throw new IllegalStateException("Function argument is not a tuple type but a " + dataType.getName());
+        TupleType tupleType = (TupleType) dataType;
+        return tupleType.newValue();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/src/java/org/apache/cassandra/cql3/functions/UDFunction.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/functions/UDFunction.java b/src/java/org/apache/cassandra/cql3/functions/UDFunction.java
index 7b69342..6e8d187 100644
--- a/src/java/org/apache/cassandra/cql3/functions/UDFunction.java
+++ b/src/java/org/apache/cassandra/cql3/functions/UDFunction.java
@@ -75,6 +75,8 @@ public abstract class UDFunction extends AbstractFunction implements ScalarFunct
     protected final TypeCodec<Object> returnCodec;
     protected final boolean calledOnNullInput;
 
+    protected final UDFContext udfContext;
+
     //
     // Access to classes is controlled via a whitelist and a blacklist.
     //
@@ -108,6 +110,7 @@ public abstract class UDFunction extends AbstractFunction implements ScalarFunct
     "java/time/",
     "java/util/",
     "org/apache/cassandra/cql3/functions/JavaUDF.class",
+    "org/apache/cassandra/cql3/functions/UDFContext.class",
     "org/apache/cassandra/exceptions/",
     };
     // Only need to blacklist a pattern, if it would otherwise be allowed via whitelistedPatterns
@@ -206,6 +209,9 @@ public abstract class UDFunction extends AbstractFunction implements ScalarFunct
         this.argCodecs = UDHelper.codecsFor(argDataTypes);
         this.returnCodec = UDHelper.codecFor(returnDataType);
         this.calledOnNullInput = calledOnNullInput;
+        KeyspaceMetadata keyspaceMetadata = Schema.instance.getKSMetaData(name.keyspace);
+        this.udfContext = new UDFContextImpl(argNames, argCodecs, returnCodec,
+                                             keyspaceMetadata);
     }
 
     public static UDFunction create(FunctionName name,

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/src/java/org/apache/cassandra/cql3/functions/UDHelper.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/functions/UDHelper.java b/src/java/org/apache/cassandra/cql3/functions/UDHelper.java
index d1c6157..9f322e5 100644
--- a/src/java/org/apache/cassandra/cql3/functions/UDHelper.java
+++ b/src/java/org/apache/cassandra/cql3/functions/UDHelper.java
@@ -130,9 +130,15 @@ public final class UDHelper
     public static DataType driverType(AbstractType abstractType)
     {
         CQL3Type cqlType = abstractType.asCQL3Type();
+        String abstractTypeDef = cqlType.getType().toString();
+        return driverTypeFromAbstractType(abstractTypeDef);
+    }
+
+    public static DataType driverTypeFromAbstractType(String abstractTypeDef)
+    {
         try
         {
-            return (DataType) methodParseOne.invoke(cqlType.getType().toString(),
+            return (DataType) methodParseOne.invoke(abstractTypeDef,
                                                     ProtocolVersion.fromInt(Server.CURRENT_VERSION),
                                                     codecRegistry);
         }
@@ -143,7 +149,7 @@ public final class UDHelper
         }
         catch (Throwable e)
         {
-            throw new RuntimeException("cannot parse driver type " + cqlType.getType().toString(), e);
+            throw new RuntimeException("cannot parse driver type " + abstractTypeDef, e);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/src/resources/org/apache/cassandra/cql3/functions/JavaSourceUDF.txt
----------------------------------------------------------------------
diff --git a/src/resources/org/apache/cassandra/cql3/functions/JavaSourceUDF.txt b/src/resources/org/apache/cassandra/cql3/functions/JavaSourceUDF.txt
index f0e9317..d736a5a 100644
--- a/src/resources/org/apache/cassandra/cql3/functions/JavaSourceUDF.txt
+++ b/src/resources/org/apache/cassandra/cql3/functions/JavaSourceUDF.txt
@@ -4,14 +4,17 @@ import java.nio.ByteBuffer;
 import java.util.*;
 
 import org.apache.cassandra.cql3.functions.JavaUDF;
+import org.apache.cassandra.cql3.functions.UDFContext;
 
 import com.datastax.driver.core.TypeCodec;
+import com.datastax.driver.core.TupleValue;
+import com.datastax.driver.core.UDTValue;
 
 public final class #class_name# extends JavaUDF
 {
-    public #class_name#(TypeCodec<Object> returnCodec, TypeCodec<Object>[] argCodecs)
+    public #class_name#(TypeCodec<Object> returnCodec, TypeCodec<Object>[] argCodecs, UDFContext udfContext)
     {
-        super(returnCodec, argCodecs);
+        super(returnCodec, argCodecs, udfContext);
     }
 
     protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java b/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java
index 90dedd4..1f1ed92 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java
@@ -2527,15 +2527,109 @@ public class UFTest extends CQLTester
                                   "     for (com.datastax.driver.core.UDTValue u : maptexttype.values()) {};" +
                                   "     return maplisttextsetint;" +
                                   "$$");
+    }
+
+    @Test
+    public void testArgAndReturnTypes() throws Throwable
+    {
+
+        String type = KEYSPACE + '.' + createType("CREATE TYPE %s (txt text, i int)");
+
+        createTable("CREATE TABLE %s (key int primary key, udt frozen<" + type + ">)");
+        execute("INSERT INTO %s (key, udt) VALUES (1, {txt: 'foo', i: 42})");
+
+        // Java UDFs
+
+        String f = createFunction(KEYSPACE, "int",
+                                  "CREATE OR REPLACE FUNCTION %s(val int) " +
+                                  "RETURNS NULL ON NULL INPUT " +
+                                  "RETURNS " + type + ' ' +
+                                  "LANGUAGE JAVA\n" +
+                                  "AS 'return udfContext.newReturnUDTValue();';");
+
+        assertRows(execute("SELECT " + f + "(key) FROM %s"),
+                   row(userType("txt", null, "i", null)));
+
+        f = createFunction(KEYSPACE, "int",
+                           "CREATE OR REPLACE FUNCTION %s(val " + type + ") " +
+                           "RETURNS NULL ON NULL INPUT " +
+                           "RETURNS " + type + ' ' +
+                           "LANGUAGE JAVA\n" +
+                           "AS $$" +
+                           "   com.datastax.driver.core.UDTValue udt = udfContext.newArgUDTValue(\"val\");" +
+                           "   udt.setString(\"txt\", \"baz\");" +
+                           "   udt.setInt(\"i\", 88);" +
+                           "   return udt;" +
+                           "$$;");
+
+        assertRows(execute("SELECT " + f + "(udt) FROM %s"),
+                   row(userType("txt", "baz", "i", 88)));
+
+        f = createFunction(KEYSPACE, "int",
+                           "CREATE OR REPLACE FUNCTION %s(val " + type + ") " +
+                           "RETURNS NULL ON NULL INPUT " +
+                           "RETURNS tuple<text, int>" +
+                           "LANGUAGE JAVA\n" +
+                           "AS $$" +
+                           "   com.datastax.driver.core.TupleValue tv = udfContext.newReturnTupleValue();" +
+                           "   tv.setString(0, \"baz\");" +
+                           "   tv.setInt(1, 88);" +
+                           "   return tv;" +
+                           "$$;");
 
+        assertRows(execute("SELECT " + f + "(udt) FROM %s"),
+                   row(tuple("baz", 88)));
+
+        // JavaScript UDFs
+
+        f = createFunction(KEYSPACE, "int",
+                           "CREATE OR REPLACE FUNCTION %s(val int) " +
+                           "RETURNS NULL ON NULL INPUT " +
+                           "RETURNS " + type + ' ' +
+                           "LANGUAGE JAVASCRIPT\n" +
+                           "AS $$" +
+                           "   udt = udfContext.newReturnUDTValue();" +
+                           "   udt;" +
+                           "$$;");
+
+        assertRows(execute("SELECT " + f + "(key) FROM %s"),
+                   row(userType("txt", null, "i", null)));
+
+        f = createFunction(KEYSPACE, "int",
+                           "CREATE OR REPLACE FUNCTION %s(val " + type + ") " +
+                           "RETURNS NULL ON NULL INPUT " +
+                           "RETURNS " + type + ' ' +
+                           "LANGUAGE JAVASCRIPT\n" +
+                           "AS $$" +
+                           "   udt = udfContext.newArgUDTValue(0);" +
+                           "   udt.setString(\"txt\", \"baz\");" +
+                           "   udt.setInt(\"i\", 88);" +
+                           "   udt;" +
+                           "$$;");
+
+        assertRows(execute("SELECT " + f + "(udt) FROM %s"),
+                   row(userType("txt", "baz", "i", 88)));
+
+        f = createFunction(KEYSPACE, "int",
+                           "CREATE OR REPLACE FUNCTION %s(val " + type + ") " +
+                           "RETURNS NULL ON NULL INPUT " +
+                           "RETURNS tuple<text, int>" +
+                           "LANGUAGE JAVASCRIPT\n" +
+                           "AS $$" +
+                           "   tv = udfContext.newReturnTupleValue();" +
+                           "   tv.setString(0, \"baz\");" +
+                           "   tv.setInt(1, 88);" +
+                           "   tv;" +
+                           "$$;");
+
+        assertRows(execute("SELECT " + f + "(udt) FROM %s"),
+                   row(tuple("baz", 88)));
     }
 
     @Test
     public void testImportJavaUtil() throws Throwable
     {
-        createTable("CREATE TABLE %s (key int primary key, sval text)");
-
-        String f = createFunction(KEYSPACE, "text",
+        createFunction(KEYSPACE, "list<text>",
                 "CREATE OR REPLACE FUNCTION %s(listText list<text>) "                                             +
                         "CALLED ON NULL INPUT "                          +
                         "RETURNS set<text> " +
@@ -2549,4 +2643,48 @@ public class UFTest extends CQLTester
                         "$$");
 
     }
+
+    @Test
+    public void testAnyUserTupleType() throws Throwable
+    {
+        createTable("CREATE TABLE %s (key int primary key, sval text)");
+        execute("INSERT INTO %s (key, sval) VALUES (1, 'foo')");
+
+        String udt = createType("CREATE TYPE %s (a int, b text, c bigint)");
+
+        String fUdt = createFunction(KEYSPACE, "text",
+                                     "CREATE OR REPLACE FUNCTION %s(arg text) " +
+                                     "CALLED ON NULL INPUT " +
+                                     "RETURNS " + udt + " " +
+                                     "LANGUAGE JAVA\n" +
+                                     "AS $$\n" +
+                                     "    UDTValue udt = udfContext.newUDTValue(\"" + udt + "\");" +
+                                     "    udt.setInt(\"a\", 42);" +
+                                     "    udt.setString(\"b\", \"42\");" +
+                                     "    udt.setLong(\"c\", 4242);" +
+                                     "    return udt;" +
+                                     "$$");
+
+        assertRows(execute("SELECT " + fUdt + "(sval) FROM %s"),
+                   row(userType("a", 42, "b", "42", "c", 4242L)));
+
+        String fTup = createFunction(KEYSPACE, "text",
+                                     "CREATE OR REPLACE FUNCTION %s(arg text) " +
+                                     "CALLED ON NULL INPUT " +
+                                     "RETURNS tuple<int, " + udt + "> " +
+                                     "LANGUAGE JAVA\n" +
+                                     "AS $$\n" +
+                                     "    UDTValue udt = udfContext.newUDTValue(\"" + udt + "\");" +
+                                     "    udt.setInt(\"a\", 42);" +
+                                     "    udt.setString(\"b\", \"42\");" +
+                                     "    udt.setLong(\"c\", 4242);" +
+                                     "    TupleValue tup = udfContext.newTupleValue(\"tuple<int," + udt + ">\");" +
+                                     "    tup.setInt(0, 88);" +
+                                     "    tup.setUDTValue(1, udt);" +
+                                     "    return tup;" +
+                                     "$$");
+
+        assertRows(execute("SELECT " + fTup + "(sval) FROM %s"),
+                   row(tuple(88, userType("a", 42, "b", "42", "c", 4242L))));
+    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallClone.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallClone.java b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallClone.java
index c01fbe6..e8bae70 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallClone.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallClone.java
@@ -23,15 +23,16 @@ import java.util.List;
 
 import com.datastax.driver.core.TypeCodec;
 import org.apache.cassandra.cql3.functions.JavaUDF;
+import org.apache.cassandra.cql3.functions.UDFContext;
 
 /**
  * Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
  */
 public final class CallClone extends JavaUDF
 {
-    public CallClone(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes)
+    public CallClone(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes, UDFContext udfContext)
     {
-        super(returnDataType, argDataTypes);
+        super(returnDataType, argDataTypes, udfContext);
     }
 
     protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallComDatastax.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallComDatastax.java b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallComDatastax.java
index 9cd799f..1af5b01 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallComDatastax.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallComDatastax.java
@@ -24,15 +24,16 @@ import java.util.List;
 import com.datastax.driver.core.DataType;
 import com.datastax.driver.core.TypeCodec;
 import org.apache.cassandra.cql3.functions.JavaUDF;
+import org.apache.cassandra.cql3.functions.UDFContext;
 
 /**
  * Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
  */
 public final class CallComDatastax extends JavaUDF
 {
-    public CallComDatastax(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes)
+    public CallComDatastax(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes, UDFContext udfContext)
     {
-        super(returnDataType, argDataTypes);
+        super(returnDataType, argDataTypes, udfContext);
     }
 
     protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallFinalize.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallFinalize.java b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallFinalize.java
index a16bd31..5208849 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallFinalize.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallFinalize.java
@@ -23,15 +23,16 @@ import java.util.List;
 
 import com.datastax.driver.core.TypeCodec;
 import org.apache.cassandra.cql3.functions.JavaUDF;
+import org.apache.cassandra.cql3.functions.UDFContext;
 
 /**
  * Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
  */
 public final class CallFinalize extends JavaUDF
 {
-    public CallFinalize(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes)
+    public CallFinalize(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes, UDFContext udfContext)
     {
-        super(returnDataType, argDataTypes);
+        super(returnDataType, argDataTypes, udfContext);
     }
 
     protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallOrgApache.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallOrgApache.java b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallOrgApache.java
index 4f511d7..758d0d0 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallOrgApache.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/CallOrgApache.java
@@ -24,15 +24,16 @@ import java.util.List;
 import com.datastax.driver.core.TypeCodec;
 import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.cql3.functions.JavaUDF;
+import org.apache.cassandra.cql3.functions.UDFContext;
 
 /**
  * Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
  */
 public final class CallOrgApache extends JavaUDF
 {
-    public CallOrgApache(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes)
+    public CallOrgApache(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes, UDFContext udfContext)
     {
-        super(returnDataType, argDataTypes);
+        super(returnDataType, argDataTypes, udfContext);
     }
 
     protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithField.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithField.java b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithField.java
index d981c18..256c2bd 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithField.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithField.java
@@ -23,15 +23,16 @@ import java.util.List;
 
 import com.datastax.driver.core.TypeCodec;
 import org.apache.cassandra.cql3.functions.JavaUDF;
+import org.apache.cassandra.cql3.functions.UDFContext;
 
 /**
  * Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
  */
 public final class ClassWithField extends JavaUDF
 {
-    public ClassWithField(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes)
+    public ClassWithField(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes, UDFContext udfContext)
     {
-        super(returnDataType, argDataTypes);
+        super(returnDataType, argDataTypes, udfContext);
     }
 
     protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithInitializer.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithInitializer.java b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithInitializer.java
index f53cc24..3366314 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithInitializer.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithInitializer.java
@@ -23,15 +23,16 @@ import java.util.List;
 
 import com.datastax.driver.core.TypeCodec;
 import org.apache.cassandra.cql3.functions.JavaUDF;
+import org.apache.cassandra.cql3.functions.UDFContext;
 
 /**
  * Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
  */
 public final class ClassWithInitializer extends JavaUDF
 {
-    public ClassWithInitializer(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes)
+    public ClassWithInitializer(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes, UDFContext udfContext)
     {
-        super(returnDataType, argDataTypes);
+        super(returnDataType, argDataTypes, udfContext);
     }
 
     protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithInitializer2.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithInitializer2.java b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithInitializer2.java
index 134f9f9..aaf3e7b 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithInitializer2.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithInitializer2.java
@@ -23,15 +23,16 @@ import java.util.List;
 
 import com.datastax.driver.core.TypeCodec;
 import org.apache.cassandra.cql3.functions.JavaUDF;
+import org.apache.cassandra.cql3.functions.UDFContext;
 
 /**
  * Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
  */
 public final class ClassWithInitializer2 extends JavaUDF
 {
-    public ClassWithInitializer2(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes)
+    public ClassWithInitializer2(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes, UDFContext udfContext)
     {
-        super(returnDataType, argDataTypes);
+        super(returnDataType, argDataTypes, udfContext);
     }
 
     protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithInitializer3.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithInitializer3.java b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithInitializer3.java
index 9cd04fb..4895aa0 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithInitializer3.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithInitializer3.java
@@ -23,15 +23,16 @@ import java.util.List;
 
 import com.datastax.driver.core.TypeCodec;
 import org.apache.cassandra.cql3.functions.JavaUDF;
+import org.apache.cassandra.cql3.functions.UDFContext;
 
 /**
  * Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
  */
 public final class ClassWithInitializer3 extends JavaUDF
 {
-    public ClassWithInitializer3(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes)
+    public ClassWithInitializer3(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes, UDFContext udfContext)
     {
-        super(returnDataType, argDataTypes);
+        super(returnDataType, argDataTypes, udfContext);
     }
 
     protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithStaticInitializer.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithStaticInitializer.java b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithStaticInitializer.java
index 64470ca..3c958e8 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithStaticInitializer.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/ClassWithStaticInitializer.java
@@ -23,15 +23,16 @@ import java.util.List;
 
 import com.datastax.driver.core.TypeCodec;
 import org.apache.cassandra.cql3.functions.JavaUDF;
+import org.apache.cassandra.cql3.functions.UDFContext;
 
 /**
  * Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
  */
 public final class ClassWithStaticInitializer extends JavaUDF
 {
-    public ClassWithStaticInitializer(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes)
+    public ClassWithStaticInitializer(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes, UDFContext udfContext)
     {
-        super(returnDataType, argDataTypes);
+        super(returnDataType, argDataTypes, udfContext);
     }
 
     protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/GoodClass.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/GoodClass.java b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/GoodClass.java
index e3bc1e2..eb25f72 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/GoodClass.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/GoodClass.java
@@ -23,15 +23,16 @@ import java.util.List;
 
 import com.datastax.driver.core.TypeCodec;
 import org.apache.cassandra.cql3.functions.JavaUDF;
+import org.apache.cassandra.cql3.functions.UDFContext;
 
 /**
  * Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
  */
 public final class GoodClass extends JavaUDF
 {
-    public GoodClass(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes)
+    public GoodClass(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes, UDFContext udfContext)
     {
-        super(returnDataType, argDataTypes);
+        super(returnDataType, argDataTypes, udfContext);
     }
 
     protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronized.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronized.java b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronized.java
index 2927b3e..bbbc823 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronized.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronized.java
@@ -23,15 +23,16 @@ import java.util.List;
 
 import com.datastax.driver.core.TypeCodec;
 import org.apache.cassandra.cql3.functions.JavaUDF;
+import org.apache.cassandra.cql3.functions.UDFContext;
 
 /**
  * Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
  */
 public final class UseOfSynchronized extends JavaUDF
 {
-    public UseOfSynchronized(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes)
+    public UseOfSynchronized(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes, UDFContext udfContext)
     {
-        super(returnDataType, argDataTypes);
+        super(returnDataType, argDataTypes, udfContext);
     }
 
     protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithNotify.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithNotify.java b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithNotify.java
index 7ef2e1c..07c70c7 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithNotify.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithNotify.java
@@ -23,15 +23,16 @@ import java.util.List;
 
 import com.datastax.driver.core.TypeCodec;
 import org.apache.cassandra.cql3.functions.JavaUDF;
+import org.apache.cassandra.cql3.functions.UDFContext;
 
 /**
  * Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
  */
 public final class UseOfSynchronizedWithNotify extends JavaUDF
 {
-    public UseOfSynchronizedWithNotify(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes)
+    public UseOfSynchronizedWithNotify(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes, UDFContext udfContext)
     {
-        super(returnDataType, argDataTypes);
+        super(returnDataType, argDataTypes, udfContext);
     }
 
     protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithNotifyAll.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithNotifyAll.java b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithNotifyAll.java
index 50a3da8..529c995 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithNotifyAll.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithNotifyAll.java
@@ -23,15 +23,16 @@ import java.util.List;
 
 import com.datastax.driver.core.TypeCodec;
 import org.apache.cassandra.cql3.functions.JavaUDF;
+import org.apache.cassandra.cql3.functions.UDFContext;
 
 /**
  * Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
  */
 public final class UseOfSynchronizedWithNotifyAll extends JavaUDF
 {
-    public UseOfSynchronizedWithNotifyAll(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes)
+    public UseOfSynchronizedWithNotifyAll(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes, UDFContext udfContext)
     {
-        super(returnDataType, argDataTypes);
+        super(returnDataType, argDataTypes, udfContext);
     }
 
     protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithWait.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithWait.java b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithWait.java
index 135c550..6e39813 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithWait.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithWait.java
@@ -23,15 +23,16 @@ import java.util.List;
 
 import com.datastax.driver.core.TypeCodec;
 import org.apache.cassandra.cql3.functions.JavaUDF;
+import org.apache.cassandra.cql3.functions.UDFContext;
 
 /**
  * Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
  */
 public final class UseOfSynchronizedWithWait extends JavaUDF
 {
-    public UseOfSynchronizedWithWait(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes)
+    public UseOfSynchronizedWithWait(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes, UDFContext udfContext)
     {
-        super(returnDataType, argDataTypes);
+        super(returnDataType, argDataTypes, udfContext);
     }
 
     protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithWaitL.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithWaitL.java b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithWaitL.java
index 4e49e5b..ac29211 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithWaitL.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithWaitL.java
@@ -23,15 +23,16 @@ import java.util.List;
 
 import com.datastax.driver.core.TypeCodec;
 import org.apache.cassandra.cql3.functions.JavaUDF;
+import org.apache.cassandra.cql3.functions.UDFContext;
 
 /**
  * Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
  */
 public final class UseOfSynchronizedWithWaitL extends JavaUDF
 {
-    public UseOfSynchronizedWithWaitL(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes)
+    public UseOfSynchronizedWithWaitL(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes, UDFContext udfContext)
     {
-        super(returnDataType, argDataTypes);
+        super(returnDataType, argDataTypes, udfContext);
     }
 
     protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5288d434/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithWaitLI.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithWaitLI.java b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithWaitLI.java
index 6770e7a..3b9ce8b 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithWaitLI.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/udfverify/UseOfSynchronizedWithWaitLI.java
@@ -23,15 +23,16 @@ import java.util.List;
 
 import com.datastax.driver.core.TypeCodec;
 import org.apache.cassandra.cql3.functions.JavaUDF;
+import org.apache.cassandra.cql3.functions.UDFContext;
 
 /**
  * Used by {@link org.apache.cassandra.cql3.validation.entities.UFVerifierTest}.
  */
 public final class UseOfSynchronizedWithWaitLI extends JavaUDF
 {
-    public UseOfSynchronizedWithWaitLI(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes)
+    public UseOfSynchronizedWithWaitLI(TypeCodec<Object> returnDataType, TypeCodec<Object>[] argDataTypes, UDFContext udfContext)
     {
-        super(returnDataType, argDataTypes);
+        super(returnDataType, argDataTypes, udfContext);
     }
 
     protected ByteBuffer executeImpl(int protocolVersion, List<ByteBuffer> params)


Mime
View raw message