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 <[email protected]> Authored: Wed Apr 13 20:12:29 2016 +0200 Committer: Robert Stupp <[email protected]> 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)
