This is an automated email from the ASF dual-hosted git repository.
edimitrova pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git
The following commit(s) were added to refs/heads/trunk by this push:
new a0ec0ae303 Remove scripted UDFs, remove related tests or rewrite some
tests to create java UDFs instead, where it makes sense patch by Ekaterina
Dimitrova; reviewed by Michael Semb Wever for CASSANDRA-18252
a0ec0ae303 is described below
commit a0ec0ae303443b1d1cbfe845d94fccfb38123f8c
Author: Ekaterina Dimitrova <[email protected]>
AuthorDate: Thu Feb 9 15:00:05 2023 -0500
Remove scripted UDFs, remove related tests or rewrite some tests to create
java UDFs instead, where it makes sense
patch by Ekaterina Dimitrova; reviewed by Michael Semb Wever for
CASSANDRA-18252
---
CHANGES.txt | 1 +
conf/cassandra.yaml | 6 -
doc/modules/cassandra/pages/cql/functions.adoc | 7 +-
pylib/cassandra-cqlsh-tests.sh | 1 -
src/java/org/apache/cassandra/config/Config.java | 2 +
.../cassandra/config/DatabaseDescriptor.java | 8 +-
.../cql3/functions/ScriptBasedUDFunction.java | 346 -----------------
.../cassandra/cql3/functions/UDFunction.java | 18 +-
test/conf/cassandra-murmur.yaml | 2 +-
test/conf/cassandra-old.yaml | 2 +-
test/conf/cassandra-pem-jks-sslcontextfactory.yaml | 2 +-
...pem-sslcontextfactory-invalidconfiguration.yaml | 2 +-
test/conf/cassandra-pem-sslcontextfactory.yaml | 2 +-
test/conf/cassandra-seeds.yaml | 2 +-
...dra-sslcontextfactory-invalidconfiguration.yaml | 2 +-
test/conf/cassandra-sslcontextfactory.yaml | 2 +-
test/conf/cassandra.yaml | 2 +-
.../apache/cassandra/audit/AuditLoggerTest.java | 2 +-
.../LoadOldYAMLBackwardCompatibilityTest.java | 2 +-
.../cql3/selection/SelectionColumnMappingTest.java | 12 +-
.../entities/UFPureScriptTupleCollectionTest.java | 138 -------
.../cql3/validation/entities/UFScriptTest.java | 430 ---------------------
.../cql3/validation/entities/UFSecurityTest.java | 78 ----
.../cassandra/cql3/validation/entities/UFTest.java | 39 +-
.../validation/operations/AggregationTest.java | 107 +----
25 files changed, 65 insertions(+), 1150 deletions(-)
diff --git a/CHANGES.txt b/CHANGES.txt
index 7db90c01a9..793c1ab1fd 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
4.2
+ * Remove Scripted UDFs internals; hooks to be added later in CASSANDRA-17281
(CASSANDRA-18252)
* Update JNA to 5.13.0 (CASSANDRA-18050)
* Make virtual tables decide if they implicitly enable ALLOW FILTERING
(CASSANDRA-18238)
* Add row, tombstone, and sstable count to nodetool profileload
(CASSANDRA-18022)
diff --git a/conf/cassandra.yaml b/conf/cassandra.yaml
index 3bc759461a..5a5ddd28f9 100644
--- a/conf/cassandra.yaml
+++ b/conf/cassandra.yaml
@@ -1455,12 +1455,6 @@ trace_type_repair_ttl: 7d
# As of Cassandra 3.0 there is a sandbox in place that should prevent
execution of evil code.
user_defined_functions_enabled: false
-# Enables scripted UDFs (JavaScript UDFs).
-# Java UDFs are always enabled, if user_defined_functions_enabled is true.
-# Enable this option to be able to use UDFs with "language javascript" or any
custom JSR-223 provider.
-# This option has no effect, if user_defined_functions_enabled is false.
-scripted_user_defined_functions_enabled: false
-
# Enables encrypting data at-rest (on disk). Different key providers can be
plugged in, but the default reads from
# a JCE-style keystore. A single keystore can hold multiple keys, but the one
referenced by
# the "key_alias" is the only key that will be used for encrypt opertaions;
previously used keys
diff --git a/doc/modules/cassandra/pages/cql/functions.adoc
b/doc/modules/cassandra/pages/cql/functions.adoc
index a0c9d39f88..4a660e2f28 100644
--- a/doc/modules/cassandra/pages/cql/functions.adoc
+++ b/doc/modules/cassandra/pages/cql/functions.adoc
@@ -351,8 +351,7 @@ Examples:
==== User-defined functions
User-defined functions (UDFs) execute user-provided code in Cassandra.
-By default, Cassandra supports defining functions in _Java_ and _JavaScript_.
-Support for other JSR 223 compliant scripting languages, such as Python, Ruby,
and Scala, is possible by adding a JAR to the classpath.
+By default, Cassandra supports defining functions in _Java_.
UDFs are part of the Cassandra schema, and are automatically propagated to all
nodes in the cluster.
UDFs can be _overloaded_, so that multiple UDFs with different argument types
can have the same function name.
@@ -361,8 +360,8 @@ UDFs can be _overloaded_, so that multiple UDFs with
different argument types ca
[NOTE]
.Note
====
-_JavaScript_ user-defined functions have been deprecated. They are planned for
removal
-in the next major release.
+_JavaScript_ user-defined functions have been deprecated in Cassandra 4.1. In
preparation for Cassandra 5.0, their removal is
+already in progress. For more information - CASSANDRA-17281, CASSANDRA-18252.
====
For example:
diff --git a/pylib/cassandra-cqlsh-tests.sh b/pylib/cassandra-cqlsh-tests.sh
index ad6ae75368..4db07cf61b 100755
--- a/pylib/cassandra-cqlsh-tests.sh
+++ b/pylib/cassandra-cqlsh-tests.sh
@@ -97,7 +97,6 @@ fi
ccm remove test || true # in case an old ccm cluster is left behind
ccm create test -n 1 --install-dir=${CASSANDRA_DIR}
ccm updateconf "user_defined_functions_enabled: true"
-ccm updateconf "scripted_user_defined_functions_enabled: true"
version_from_build=$(ccm node1 versionfrombuild)
export pre_or_post_cdc=$(python -c """from distutils.version import
LooseVersion
diff --git a/src/java/org/apache/cassandra/config/Config.java
b/src/java/org/apache/cassandra/config/Config.java
index 3aff5fe956..4082d8eb41 100644
--- a/src/java/org/apache/cassandra/config/Config.java
+++ b/src/java/org/apache/cassandra/config/Config.java
@@ -564,6 +564,8 @@ public class Config
@Replaces(oldName = "enable_user_defined_functions", converter =
Converters.IDENTITY, deprecated = true)
public boolean user_defined_functions_enabled = false;
+
+ @Deprecated
@Replaces(oldName = "enable_scripted_user_defined_functions", converter =
Converters.IDENTITY, deprecated = true)
public boolean scripted_user_defined_functions_enabled = false;
diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
index 1cf36a064b..3e1630c561 100644
--- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
+++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
@@ -814,7 +814,8 @@ public class DatabaseDescriptor
logger.warn("Allowing java.lang.System.* access in UDFs is
dangerous and not recommended. Set allow_extra_insecure_udfs: false to
disable.");
if(conf.scripted_user_defined_functions_enabled)
- logger.warn("JavaScript user-defined functions have been
deprecated. You can still use them but the plan is to remove them in the next
major version. For more information - CASSANDRA-17280");
+ throw new ConfigurationException("JavaScript user-defined
functions were removed in CASSANDRA-18252. " +
+ "Hooks are planned to be
introduced as part of CASSANDRA-17280");
if (conf.commitlog_segment_size.toMebibytes() == 0)
throw new ConfigurationException("commitlog_segment_size must be
positive, but was "
@@ -3579,11 +3580,6 @@ public class DatabaseDescriptor
return conf.scripted_user_defined_functions_enabled;
}
- public static void enableScriptedUserDefinedFunctions(boolean
enableScriptedUserDefinedFunctions)
- {
- conf.scripted_user_defined_functions_enabled =
enableScriptedUserDefinedFunctions;
- }
-
public static boolean enableUserDefinedFunctionsThreads()
{
return conf.user_defined_functions_threads_enabled;
diff --git
a/src/java/org/apache/cassandra/cql3/functions/ScriptBasedUDFunction.java
b/src/java/org/apache/cassandra/cql3/functions/ScriptBasedUDFunction.java
deleted file mode 100644
index e42fbe9c42..0000000000
--- a/src/java/org/apache/cassandra/cql3/functions/ScriptBasedUDFunction.java
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * 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.math.BigDecimal;
-import java.math.BigInteger;
-import java.net.*;
-import java.nio.ByteBuffer;
-import java.security.*;
-import java.security.cert.Certificate;
-import java.util.*;
-import java.util.concurrent.ExecutorService;
-import javax.script.*;
-
-import jdk.nashorn.api.scripting.AbstractJSObject;
-import jdk.nashorn.api.scripting.ClassFilter;
-import jdk.nashorn.api.scripting.NashornScriptEngine;
-import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
-import org.apache.cassandra.concurrent.NamedThreadFactory;
-import org.apache.cassandra.cql3.ColumnIdentifier;
-import org.apache.cassandra.db.marshal.AbstractType;
-import org.apache.cassandra.exceptions.InvalidRequestException;
-import org.apache.cassandra.security.SecurityThreadGroup;
-import org.apache.cassandra.security.ThreadAwareSecurityManager;
-import org.apache.cassandra.transport.ProtocolVersion;
-
-final class ScriptBasedUDFunction extends UDFunction
-{
- private static final ProtectionDomain protectionDomain;
- private static final AccessControlContext accessControlContext;
-
- //
- // For scripted UDFs we have to rely on the security mechanisms of the
scripting engine and
- // SecurityManager - especially SecurityManager.checkPackageAccess().
Unlike Java-UDFs, strict checking
- // of class access via the UDF class loader is not possible, since e.g.
Nashorn builds its own class loader
- // (jdk.nashorn.internal.runtime.ScriptLoader /
jdk.nashorn.internal.runtime.NashornLoader) configured with
- // a system class loader.
- //
- private static final String[] allowedPackagesArray =
- {
- // following required by
jdk.nashorn.internal.objects.Global.initJavaAccess()
- "",
- "com",
- "edu",
- "java",
- "javax",
- "javafx",
- "org",
- // following required by Nashorn runtime
- "java.lang",
- "java.lang.invoke",
- "java.lang.reflect",
- "java.nio.charset",
- "java.util",
- "java.util.concurrent",
- "javax.script",
- "sun.reflect",
- "jdk.internal.org.objectweb.asm.commons",
- "jdk.nashorn.internal.runtime",
- "jdk.nashorn.internal.runtime.linker",
- // Nashorn / Java 11
- "java.lang.ref",
- "java.io",
- "java.util.function",
- "jdk.dynalink.linker",
- "jdk.internal.org.objectweb.asm",
- "jdk.internal.reflect",
- "jdk.nashorn.internal.scripts",
- // following required by Java Driver
- "java.math",
- "java.nio",
- "java.text",
- "com.google.common.base",
- "com.google.common.collect",
- "com.google.common.reflect",
- // following required by UDF
- "org.apache.cassandra.cql3.functions.types",
- "org.apache.cassandra.cql3.functions.types.exceptions",
- "org.apache.cassandra.cql3.functions.types.utils"
- };
-
- // use a JVM standard ExecutorService as ExecutorPlus references internal
- // classes, which triggers AccessControlException from the UDF sandbox
- private static final UDFExecutorService executor =
- new UDFExecutorService(new
NamedThreadFactory("UserDefinedScriptFunctions",
- Thread.MIN_PRIORITY,
- udfClassLoader,
- new
SecurityThreadGroup("UserDefinedScriptFunctions",
-
Collections.unmodifiableSet(new HashSet<>(Arrays.asList(allowedPackagesArray))),
-
UDFunction::initializeThread)),
- "userscripts");
-
- private static final ClassFilter classFilter = clsName ->
secureResource(clsName.replace('.', '/') + ".class");
-
- private static final NashornScriptEngine scriptEngine;
-
-
- static
- {
- ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
- ScriptEngine engine = scriptEngineManager.getEngineByName("nashorn");
- NashornScriptEngineFactory factory = engine != null ?
(NashornScriptEngineFactory) engine.getFactory() : null;
- scriptEngine = factory != null ? (NashornScriptEngine)
factory.getScriptEngine(new String[]{}, udfClassLoader, classFilter) : null;
-
- try
- {
- protectionDomain = new ProtectionDomain(new CodeSource(new
URL("udf", "localhost", 0, "/script", new URLStreamHandler()
- {
- protected URLConnection openConnection(URL u)
- {
- return null;
- }
- }), (Certificate[]) null),
ThreadAwareSecurityManager.noPermissions);
- }
- catch (MalformedURLException e)
- {
- throw new RuntimeException(e);
- }
- accessControlContext = new AccessControlContext(new
ProtectionDomain[]{ protectionDomain });
- }
-
- private final CompiledScript script;
- private final Object udfContextBinding;
-
- ScriptBasedUDFunction(FunctionName name,
- List<ColumnIdentifier> argNames,
- List<AbstractType<?>> argTypes,
- AbstractType<?> returnType,
- boolean calledOnNullInput,
- String language,
- String body)
- {
- super(name, argNames, argTypes, returnType, calledOnNullInput,
language, body);
-
- if (!"JavaScript".equalsIgnoreCase(language) || scriptEngine == null)
- throw new InvalidRequestException(String.format("Invalid language
'%s' for function '%s'", language, name));
-
- // execute compilation with no-permissions to prevent evil code e.g.
via "static code blocks" / "class initialization"
- try
- {
- this.script =
AccessController.doPrivileged((PrivilegedExceptionAction<CompiledScript>) () ->
scriptEngine.compile(body),
- accessControlContext);
- }
- catch (PrivilegedActionException x)
- {
- Throwable e = x.getCause();
- logger.info("Failed to compile function '{}' for language {}: ",
name, language, e);
- 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 = new UDFContextWrapper();
- }
-
- protected ExecutorService executor()
- {
- return executor;
- }
-
- public ByteBuffer executeUserDefined(ProtocolVersion protocolVersion,
List<ByteBuffer> parameters)
- {
- Object[] params = new Object[argTypes.size()];
- for (int i = 0; i < params.length; i++)
- params[i] = compose(protocolVersion, i, parameters.get(i));
-
- Object result = executeScriptInternal(params);
-
- return decompose(protocolVersion, result);
- }
-
- /**
- * Like {@link UDFunction#executeUserDefined(ProtocolVersion, List)} but
the first parameter is already in non-serialized form.
- * Remaining parameters (2nd paramters and all others) are in {@code
parameters}.
- * This is used to prevent superfluous (de)serialization of the state of
aggregates.
- * Means: scalar functions of aggregates are called using this variant.
- */
- protected Object executeAggregateUserDefined(ProtocolVersion
protocolVersion, Object firstParam, List<ByteBuffer> parameters)
- {
- Object[] params = new Object[argTypes.size()];
- params[0] = firstParam;
- for (int i = 1; i < params.length; i++)
- params[i] = compose(protocolVersion, i, parameters.get(i - 1));
-
- return executeScriptInternal(params);
- }
-
- private Object executeScriptInternal(Object[] params)
- {
- ScriptContext scriptContext = new SimpleScriptContext();
- scriptContext.setAttribute("javax.script.filename",
this.name.toString(), ScriptContext.ENGINE_SCOPE);
- 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
- {
- // How to prevent Class.forName() _without_ "help" from the script
engine ?
- // NOTE: Nashorn enforces a special permission to allow
class-loading, which is not granted - so it's fine.
-
- result = script.eval(scriptContext);
- }
- catch (ScriptException e)
- {
- throw new RuntimeException(e);
- }
- if (result == null)
- return null;
-
- Class<?> javaReturnType = UDHelper.asJavaClass(returnCodec);
- Class<?> resultType = result.getClass();
- if (!javaReturnType.isAssignableFrom(resultType))
- {
- if (result instanceof Number)
- {
- Number rNumber = (Number) result;
- if (javaReturnType == Integer.class)
- result = rNumber.intValue();
- else if (javaReturnType == Long.class)
- result = rNumber.longValue();
- else if (javaReturnType == Short.class)
- result = rNumber.shortValue();
- else if (javaReturnType == Byte.class)
- result = rNumber.byteValue();
- else if (javaReturnType == Float.class)
- result = rNumber.floatValue();
- else if (javaReturnType == Double.class)
- result = rNumber.doubleValue();
- else if (javaReturnType == BigInteger.class)
- {
- if (javaReturnType == Integer.class)
- result = rNumber.intValue();
- else if (javaReturnType == Short.class)
- result = rNumber.shortValue();
- else if (javaReturnType == Byte.class)
- result = rNumber.byteValue();
- else if (javaReturnType == Long.class)
- result = rNumber.longValue();
- else if (javaReturnType == Float.class)
- result = rNumber.floatValue();
- else if (javaReturnType == Double.class)
- result = rNumber.doubleValue();
- else if (javaReturnType == BigInteger.class)
- {
- if (rNumber instanceof BigDecimal)
- result = ((BigDecimal) rNumber).toBigInteger();
- else if (rNumber instanceof Double || rNumber
instanceof Float)
- result = new
BigDecimal(rNumber.toString()).toBigInteger();
- else
- result = BigInteger.valueOf(rNumber.longValue());
- }
- else if (javaReturnType == BigDecimal.class)
- // String c'tor of BigDecimal is more accurate than
valueOf(double)
- result = new BigDecimal(rNumber.toString());
- }
- else if (javaReturnType == BigDecimal.class)
- // String c'tor of BigDecimal is more accurate than
valueOf(double)
- result = new BigDecimal(rNumber.toString());
- }
- }
-
- return 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);
- }
- }
-}
diff --git a/src/java/org/apache/cassandra/cql3/functions/UDFunction.java
b/src/java/org/apache/cassandra/cql3/functions/UDFunction.java
index 52cd1fc187..58454a49ac 100644
--- a/src/java/org/apache/cassandra/cql3/functions/UDFunction.java
+++ b/src/java/org/apache/cassandra/cql3/functions/UDFunction.java
@@ -266,13 +266,7 @@ public abstract class UDFunction extends UserFunction
implements ScalarFunction
{
assertUdfsEnabled(language);
- switch (language)
- {
- case "java":
- return new JavaBasedUDFunction(name, argNames, argTypes,
returnType, calledOnNullInput, body);
- default:
- return new ScriptBasedUDFunction(name, argNames, argTypes,
returnType, calledOnNullInput, language, body);
- }
+ return new JavaBasedUDFunction(name, argNames, argTypes, returnType,
calledOnNullInput, body);
}
/**
@@ -448,8 +442,8 @@ public abstract class UDFunction extends UserFunction
implements ScalarFunction
{
if (!DatabaseDescriptor.enableUserDefinedFunctions())
throw new InvalidRequestException("User-defined functions are
disabled in cassandra.yaml - set user_defined_functions_enabled=true to
enable");
- if (!"java".equalsIgnoreCase(language) &&
!DatabaseDescriptor.enableScriptedUserDefinedFunctions())
- throw new InvalidRequestException("Scripted user-defined functions
are disabled in cassandra.yaml - set
scripted_user_defined_functions_enabled=true to enable if you are aware of the
security risks");
+ if (!"java".equalsIgnoreCase(language))
+ throw new InvalidRequestException("Currently only Java UDFs are
available in Cassandra. For more information - CASSANDRA-18252 and
CASSANDRA-17281");
}
static void initializeThread()
@@ -637,8 +631,7 @@ public abstract class UDFunction extends UserFunction
implements ScalarFunction
}
/**
- * Used by UDF implementations (both Java code generated by {@link
JavaBasedUDFunction}
- * and script executor {@link ScriptBasedUDFunction}) to convert the C*
+ * Used by UDF implementations (both Java code generated by {@link
JavaBasedUDFunction}) to convert the C*
* serialized representation to the Java object representation.
*
* @param protocolVersion the native protocol version used for
serialization
@@ -655,8 +648,7 @@ public abstract class UDFunction extends UserFunction
implements ScalarFunction
}
/**
- * Used by UDF implementations (both Java code generated by {@link
JavaBasedUDFunction}
- * and script executor {@link ScriptBasedUDFunction}) to convert the Java
+ * Used by UDF implementations (both Java code generated by {@link
JavaBasedUDFunction}) to convert the Java
* object representation for the return value to the C* serialized
representation.
*
* @param protocolVersion the native protocol version used for
serialization
diff --git a/test/conf/cassandra-murmur.yaml b/test/conf/cassandra-murmur.yaml
index c0c2ae71f6..385ed4632e 100644
--- a/test/conf/cassandra-murmur.yaml
+++ b/test/conf/cassandra-murmur.yaml
@@ -39,6 +39,6 @@ compaction_throughput: 0MiB/s
row_cache_class_name: org.apache.cassandra.cache.OHCProvider
row_cache_size: 16MiB
user_defined_functions_enabled: true
-scripted_user_defined_functions_enabled: true
+scripted_user_defined_functions_enabled: false
sasi_indexes_enabled: true
materialized_views_enabled: true
diff --git a/test/conf/cassandra-old.yaml b/test/conf/cassandra-old.yaml
index 86983acc9e..10981c22cb 100644
--- a/test/conf/cassandra-old.yaml
+++ b/test/conf/cassandra-old.yaml
@@ -43,7 +43,7 @@ compaction_throughput_mb_per_sec: 64
row_cache_class_name: org.apache.cassandra.cache.OHCProvider
row_cache_size_in_mb: 16
enable_user_defined_functions: true
-enable_scripted_user_defined_functions: true
+enable_scripted_user_defined_functions: false
prepared_statements_cache_size_mb:
corrupted_tombstone_strategy: exception
stream_entire_sstables: true
diff --git a/test/conf/cassandra-pem-jks-sslcontextfactory.yaml
b/test/conf/cassandra-pem-jks-sslcontextfactory.yaml
index 1f10e6c203..ad9d998551 100644
--- a/test/conf/cassandra-pem-jks-sslcontextfactory.yaml
+++ b/test/conf/cassandra-pem-jks-sslcontextfactory.yaml
@@ -140,7 +140,7 @@ compaction_throughput: 0MiB/s
row_cache_class_name: org.apache.cassandra.cache.OHCProvider
row_cache_size: 16MiB
user_defined_functions_enabled: true
-scripted_user_defined_functions_enabled: true
+scripted_user_defined_functions_enabled: false
prepared_statements_cache_size: 1MiB
corrupted_tombstone_strategy: exception
stream_entire_sstables: true
diff --git
a/test/conf/cassandra-pem-sslcontextfactory-invalidconfiguration.yaml
b/test/conf/cassandra-pem-sslcontextfactory-invalidconfiguration.yaml
index 8c7d910f49..15aaae0148 100644
--- a/test/conf/cassandra-pem-sslcontextfactory-invalidconfiguration.yaml
+++ b/test/conf/cassandra-pem-sslcontextfactory-invalidconfiguration.yaml
@@ -137,7 +137,7 @@ compaction_throughput: 0MiB/s
row_cache_class_name: org.apache.cassandra.cache.OHCProvider
row_cache_size: 16MiB
user_defined_functions_enabled: true
-scripted_user_defined_functions_enabled: true
+scripted_user_defined_functions_enabled: false
prepared_statements_cache_size: 1MiB
corrupted_tombstone_strategy: exception
stream_entire_sstables: true
diff --git a/test/conf/cassandra-pem-sslcontextfactory.yaml
b/test/conf/cassandra-pem-sslcontextfactory.yaml
index 26d0f1f998..36daecd117 100644
--- a/test/conf/cassandra-pem-sslcontextfactory.yaml
+++ b/test/conf/cassandra-pem-sslcontextfactory.yaml
@@ -141,7 +141,7 @@ compaction_throughput: 0MiB/s
row_cache_class_name: org.apache.cassandra.cache.OHCProvider
row_cache_size: 16MiB
user_defined_functions_enabled: true
-scripted_user_defined_functions_enabled: true
+scripted_user_defined_functions_enabled: false
prepared_statements_cache_size: 1MiB
corrupted_tombstone_strategy: exception
stream_entire_sstables: true
diff --git a/test/conf/cassandra-seeds.yaml b/test/conf/cassandra-seeds.yaml
index 1c38f8e1ad..2a206f11d7 100644
--- a/test/conf/cassandra-seeds.yaml
+++ b/test/conf/cassandra-seeds.yaml
@@ -40,4 +40,4 @@ compaction_throughput: 0MiB/s
row_cache_class_name: org.apache.cassandra.cache.OHCProvider
row_cache_size: 16MiB
user_defined_functions_enabled: true
-scripted_user_defined_functions_enabled: true
+scripted_user_defined_functions_enabled: false
diff --git a/test/conf/cassandra-sslcontextfactory-invalidconfiguration.yaml
b/test/conf/cassandra-sslcontextfactory-invalidconfiguration.yaml
index d3970cbf98..6e6b21f9b3 100644
--- a/test/conf/cassandra-sslcontextfactory-invalidconfiguration.yaml
+++ b/test/conf/cassandra-sslcontextfactory-invalidconfiguration.yaml
@@ -72,7 +72,7 @@ compaction_throughput: 0MiB/s
row_cache_class_name: org.apache.cassandra.cache.OHCProvider
row_cache_size: 16MiB
user_defined_functions_enabled: true
-scripted_user_defined_functions_enabled: true
+scripted_user_defined_functions_enabled: false
prepared_statements_cache_size: 1MiB
corrupted_tombstone_strategy: exception
stream_entire_sstables: true
diff --git a/test/conf/cassandra-sslcontextfactory.yaml
b/test/conf/cassandra-sslcontextfactory.yaml
index fde4bfdc6d..add166658a 100644
--- a/test/conf/cassandra-sslcontextfactory.yaml
+++ b/test/conf/cassandra-sslcontextfactory.yaml
@@ -75,7 +75,7 @@ compaction_throughput: 0MiB/s
row_cache_class_name: org.apache.cassandra.cache.OHCProvider
row_cache_size: 16MiB
user_defined_functions_enabled: true
-scripted_user_defined_functions_enabled: true
+scripted_user_defined_functions_enabled: false
prepared_statements_cache_size: 1MiB
corrupted_tombstone_strategy: exception
stream_entire_sstables: true
diff --git a/test/conf/cassandra.yaml b/test/conf/cassandra.yaml
index 3329ed9f36..f98207879c 100644
--- a/test/conf/cassandra.yaml
+++ b/test/conf/cassandra.yaml
@@ -43,7 +43,7 @@ compaction_throughput: 0MiB/s
row_cache_class_name: org.apache.cassandra.cache.OHCProvider
row_cache_size: 16MiB
user_defined_functions_enabled: true
-scripted_user_defined_functions_enabled: true
+scripted_user_defined_functions_enabled: false
prepared_statements_cache_size: 1MiB
corrupted_tombstone_strategy: exception
stream_entire_sstables: true
diff --git a/test/unit/org/apache/cassandra/audit/AuditLoggerTest.java
b/test/unit/org/apache/cassandra/audit/AuditLoggerTest.java
index b4ae02b6da..94bff48f5e 100644
--- a/test/unit/org/apache/cassandra/audit/AuditLoggerTest.java
+++ b/test/unit/org/apache/cassandra/audit/AuditLoggerTest.java
@@ -495,7 +495,7 @@ public class AuditLoggerTest extends CQLTester
{
String tblName = createTableName();
- String cql = "CREATE FUNCTION IF NOT EXISTS " + KEYSPACE + "." +
tblName + " (column TEXT,num int) RETURNS NULL ON NULL INPUT RETURNS text
LANGUAGE javascript AS $$ column.substring(0,num) $$";
+ String cql = "CREATE FUNCTION IF NOT EXISTS " + KEYSPACE + "." +
tblName + " (column TEXT,num int) RETURNS NULL ON NULL INPUT RETURNS text
LANGUAGE java AS $$ return column.substring(0,num); $$";
executeAndAssert(cql, AuditLogEntryType.CREATE_FUNCTION);
cql = "DROP FUNCTION " + KEYSPACE + "." + tblName;
diff --git
a/test/unit/org/apache/cassandra/config/LoadOldYAMLBackwardCompatibilityTest.java
b/test/unit/org/apache/cassandra/config/LoadOldYAMLBackwardCompatibilityTest.java
index 0e028cb161..e0ce161fed 100644
---
a/test/unit/org/apache/cassandra/config/LoadOldYAMLBackwardCompatibilityTest.java
+++
b/test/unit/org/apache/cassandra/config/LoadOldYAMLBackwardCompatibilityTest.java
@@ -105,7 +105,7 @@ public class LoadOldYAMLBackwardCompatibilityTest
assertEquals(new DurationSpec.IntSecondsBound(604800),
config.trace_type_repair_ttl);
assertNull(config.prepared_statements_cache_size);
assertTrue(config.user_defined_functions_enabled);
- assertTrue(config.scripted_user_defined_functions_enabled);
+ assertFalse(config.scripted_user_defined_functions_enabled);
assertTrue(config.materialized_views_enabled);
assertFalse(config.transient_replication_enabled);
assertTrue(config.sasi_indexes_enabled);
diff --git
a/test/unit/org/apache/cassandra/cql3/selection/SelectionColumnMappingTest.java
b/test/unit/org/apache/cassandra/cql3/selection/SelectionColumnMappingTest.java
index d6de5ffc2b..659f34a737 100644
---
a/test/unit/org/apache/cassandra/cql3/selection/SelectionColumnMappingTest.java
+++
b/test/unit/org/apache/cassandra/cql3/selection/SelectionColumnMappingTest.java
@@ -534,8 +534,8 @@ public class SelectionColumnMappingTest extends CQLTester
" CREATE FUNCTION %s
(a int, b int)" +
" RETURNS NULL ON NULL
INPUT" +
" RETURNS int" +
- " LANGUAGE javascript"
+
- " AS 'a + b'")).name;
+ " LANGUAGE java" +
+ " AS ' return a +
b;'")).name;
String aFunc = createAggregate(KEYSPACE, "int, int",
" CREATE AGGREGATE %s (int)" +
@@ -547,15 +547,15 @@ public class SelectionColumnMappingTest extends CQLTester
" CREATE FUNCTION %s (a int)" +
" RETURNS NULL ON NULL INPUT" +
" RETURNS int" +
- " LANGUAGE javascript" +
- " AS 'a+1'");
+ " LANGUAGE java" +
+ " AS ' return a + 1;'");
String sqFunc = createFunction(KEYSPACE, "int",
" CREATE FUNCTION %s (a int)" +
" RETURNS NULL ON NULL INPUT" +
" RETURNS int" +
- " LANGUAGE javascript" +
- " AS 'a*a'");
+ " LANGUAGE java" +
+ " AS ' return a * a;'");
ColumnMetadata v1 = columnDefinition("v1");
SelectionColumns expected = SelectionColumnMapping.newMapping()
diff --git
a/test/unit/org/apache/cassandra/cql3/validation/entities/UFPureScriptTupleCollectionTest.java
b/test/unit/org/apache/cassandra/cql3/validation/entities/UFPureScriptTupleCollectionTest.java
deleted file mode 100644
index a1801b3f5c..0000000000
---
a/test/unit/org/apache/cassandra/cql3/validation/entities/UFPureScriptTupleCollectionTest.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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.validation.entities;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-import org.junit.Test;
-
-import com.datastax.driver.core.DataType;
-import com.datastax.driver.core.TupleType;
-import com.datastax.driver.core.TupleValue;
-import org.apache.cassandra.cql3.CQLTester;
-import org.apache.cassandra.transport.ProtocolVersion;
-
-public class UFPureScriptTupleCollectionTest extends CQLTester
-{
- // Just JavaScript UDFs to check how UDF - especially
security/class-loading/sandboxing stuff -
- // behaves, if no Java UDF has been executed before.
-
- // Do not add any other test here!
- // See CASSANDRA-10141
-
- @Test
- public void testJavascriptTupleTypeCollection() throws Throwable
- {
- String tupleTypeDef = "tuple<double, list<double>, set<text>, map<int,
boolean>>";
- createTable("CREATE TABLE %s (key int primary key, tup frozen<" +
tupleTypeDef + ">)");
-
- String fTup1 = createFunction(KEYSPACE_PER_TEST, tupleTypeDef,
- "CREATE FUNCTION %s( tup " +
tupleTypeDef + " ) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS tuple<double, list<double>,
set<text>, map<int, boolean>> " +
- "LANGUAGE javascript\n" +
- "AS $$" +
- " tup;$$;");
- String fTup2 = createFunction(KEYSPACE_PER_TEST, tupleTypeDef,
- "CREATE FUNCTION %s( tup " +
tupleTypeDef + " ) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS double " +
- "LANGUAGE javascript\n" +
- "AS $$" +
- " tup.getDouble(0);$$;");
- String fTup3 = createFunction(KEYSPACE_PER_TEST, tupleTypeDef,
- "CREATE FUNCTION %s( tup " +
tupleTypeDef + " ) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS list<double> " +
- "LANGUAGE javascript\n" +
- "AS $$" +
- " tup.getList(1,
java.lang.Double.class);$$;");
- String fTup4 = createFunction(KEYSPACE_PER_TEST, tupleTypeDef,
- "CREATE FUNCTION %s( tup " +
tupleTypeDef + " ) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS set<text> " +
- "LANGUAGE javascript\n" +
- "AS $$" +
- " tup.getSet(2,
java.lang.String.class);$$;");
- String fTup5 = createFunction(KEYSPACE_PER_TEST, tupleTypeDef,
- "CREATE FUNCTION %s( tup " +
tupleTypeDef + " ) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS map<int, boolean> " +
- "LANGUAGE javascript\n" +
- "AS $$" +
- " tup.getMap(3,
java.lang.Integer.class, java.lang.Boolean.class);$$;");
-
- List<Double> list = Arrays.asList(1d, 2d, 3d);
- Set<String> set = new TreeSet<>(Arrays.asList("one", "three", "two"));
- Map<Integer, Boolean> map = new TreeMap<>();
- map.put(1, true);
- map.put(2, false);
- map.put(3, true);
-
- Object t = tuple(1d, list, set, map);
-
- execute("INSERT INTO %s (key, tup) VALUES (1, ?)", t);
-
- assertRows(execute("SELECT " + fTup1 + "(tup) FROM %s WHERE key = 1"),
- row(t));
- assertRows(execute("SELECT " + fTup2 + "(tup) FROM %s WHERE key = 1"),
- row(1d));
- assertRows(execute("SELECT " + fTup3 + "(tup) FROM %s WHERE key = 1"),
- row(list));
- assertRows(execute("SELECT " + fTup4 + "(tup) FROM %s WHERE key = 1"),
- row(set));
- assertRows(execute("SELECT " + fTup5 + "(tup) FROM %s WHERE key = 1"),
- row(map));
-
- // same test - but via native protocol
- // we use protocol V3 here to encode the expected version because the
server
- // always serializes Collections using V3 - see CollectionSerializer's
- // serialize and deserialize methods.
- TupleType tType = tupleTypeOf(ProtocolVersion.V3,
- DataType.cdouble(),
- DataType.list(DataType.cdouble()),
- DataType.set(DataType.text()),
- DataType.map(DataType.cint(),
- DataType.cboolean()));
- TupleValue tup = tType.newValue(1d, list, set, map);
- for (ProtocolVersion version : PROTOCOL_VERSIONS)
- {
- assertRowsNet(version,
- executeNet(version, "SELECT " + fTup1 + "(tup) FROM
%s WHERE key = 1"),
- row(tup));
- assertRowsNet(version,
- executeNet(version, "SELECT " + fTup2 + "(tup) FROM
%s WHERE key = 1"),
- row(1d));
- assertRowsNet(version,
- executeNet(version, "SELECT " + fTup3 + "(tup) FROM
%s WHERE key = 1"),
- row(list));
- assertRowsNet(version,
- executeNet(version, "SELECT " + fTup4 + "(tup) FROM
%s WHERE key = 1"),
- row(set));
- assertRowsNet(version,
- executeNet(version, "SELECT " + fTup5 + "(tup) FROM
%s WHERE key = 1"),
- row(map));
- }
- }
-}
diff --git
a/test/unit/org/apache/cassandra/cql3/validation/entities/UFScriptTest.java
b/test/unit/org/apache/cassandra/cql3/validation/entities/UFScriptTest.java
deleted file mode 100644
index fb33e6fabd..0000000000
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/UFScriptTest.java
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * 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.validation.entities;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.UUID;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import org.apache.cassandra.config.DatabaseDescriptor;
-import org.apache.cassandra.cql3.CQLTester;
-import org.apache.cassandra.cql3.UntypedResultSet;
-import org.apache.cassandra.cql3.functions.FunctionName;
-import org.apache.cassandra.exceptions.FunctionExecutionException;
-import org.apache.cassandra.transport.ProtocolVersion;
-import org.apache.cassandra.utils.TimeUUID;
-
-import static org.apache.cassandra.utils.TimeUUID.Generator.nextTimeUUID;
-
-public class UFScriptTest extends CQLTester
-{
- // Just JavaScript UDFs to check how UDF - especially
security/class-loading/sandboxing stuff -
- // behaves, if no Java UDF has been executed before.
-
- // Do not add any other test here - especially none using Java UDFs
-
- @Test
- public void testJavascriptSimpleCollections() throws Throwable
- {
- createTable("CREATE TABLE %s (key int primary key, lst list<double>,
st set<text>, mp map<int, boolean>)");
-
- String fName1 = createFunction(KEYSPACE_PER_TEST, "list<double>",
- "CREATE FUNCTION %s( lst list<double> )
" +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS list<double> " +
- "LANGUAGE javascript\n" +
- "AS 'lst;';");
- String fName2 = createFunction(KEYSPACE_PER_TEST, "set<text>",
- "CREATE FUNCTION %s( st set<text> ) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS set<text> " +
- "LANGUAGE javascript\n" +
- "AS 'st;';");
- String fName3 = createFunction(KEYSPACE_PER_TEST, "map<int, boolean>",
- "CREATE FUNCTION %s( mp map<int,
boolean> ) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS map<int, boolean> " +
- "LANGUAGE javascript\n" +
- "AS 'mp;';");
-
- List<Double> list = Arrays.asList(1d, 2d, 3d);
- Set<String> set = new TreeSet<>(Arrays.asList("one", "three", "two"));
- Map<Integer, Boolean> map = new TreeMap<>();
- map.put(1, true);
- map.put(2, false);
- map.put(3, true);
-
- execute("INSERT INTO %s (key, lst, st, mp) VALUES (1, ?, ?, ?)", list,
set, map);
-
- assertRows(execute("SELECT lst, st, mp FROM %s WHERE key = 1"),
- row(list, set, map));
-
- assertRows(execute("SELECT " + fName1 + "(lst), " + fName2 + "(st), "
+ fName3 + "(mp) FROM %s WHERE key = 1"),
- row(list, set, map));
-
- for (ProtocolVersion version : PROTOCOL_VERSIONS)
- assertRowsNet(version,
- executeNet(version, "SELECT " + fName1 + "(lst), " +
fName2 + "(st), " + fName3 + "(mp) FROM %s WHERE key = 1"),
- row(list, set, map));
- }
-
- @Test
- public void testJavascriptTupleType() throws Throwable
- {
- createTable("CREATE TABLE %s (key int primary key, tup
frozen<tuple<double, text, int, boolean>>)");
-
- String fName = createFunction(KEYSPACE_PER_TEST, "tuple<double, text,
int, boolean>",
- "CREATE FUNCTION %s( tup tuple<double,
text, int, boolean> ) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS tuple<double, text, int,
boolean> " +
- "LANGUAGE javascript\n" +
- "AS $$tup;$$;");
-
- Object t = tuple(1d, "foo", 2, true);
-
- execute("INSERT INTO %s (key, tup) VALUES (1, ?)", t);
-
- assertRows(execute("SELECT tup FROM %s WHERE key = 1"),
- row(t));
-
- assertRows(execute("SELECT " + fName + "(tup) FROM %s WHERE key = 1"),
- row(t));
- }
-
- @Test
- public void testJavascriptUserType() throws Throwable
- {
- String type = createType("CREATE TYPE %s (txt text, i int)");
-
- createTable("CREATE TABLE %s (key int primary key, udt frozen<" + type
+ ">)");
-
- String fUdt1 = createFunction(KEYSPACE, type,
- "CREATE FUNCTION %s( udt " + type + " )
" +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS " + type + ' ' +
- "LANGUAGE javascript\n" +
- "AS $$" +
- " udt;$$;");
- String fUdt2 = createFunction(KEYSPACE, type,
- "CREATE FUNCTION %s( udt " + type + " )
" +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS text " +
- "LANGUAGE javascript\n" +
- "AS $$" +
- " udt.getString(\"txt\");$$;");
- String fUdt3 = createFunction(KEYSPACE, type,
- "CREATE FUNCTION %s( udt " + type + " )
" +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS int " +
- "LANGUAGE javascript\n" +
- "AS $$" +
- " udt.getInt(\"i\");$$;");
-
- execute("INSERT INTO %s (key, udt) VALUES (1, {txt: 'one', i:1})");
-
- UntypedResultSet rows = execute("SELECT " + fUdt1 + "(udt) FROM %s
WHERE key = 1");
- Assert.assertEquals(1, rows.size());
- assertRows(execute("SELECT " + fUdt2 + "(udt) FROM %s WHERE key = 1"),
- row("one"));
- assertRows(execute("SELECT " + fUdt3 + "(udt) FROM %s WHERE key = 1"),
- row(1));
- }
-
- @Test
- public void testJavascriptUTCollections() throws Throwable
- {
- String type = createType("CREATE TYPE %s (txt text, i int)");
-
- createTable(String.format("CREATE TABLE %%s " +
- "(key int primary key, lst list<frozen<%s>>,
st set<frozen<%s>>, mp map<int, frozen<%s>>)",
- type, type, type));
-
- String fName = createFunction(KEYSPACE, "list<frozen<" + type + ">>",
- "CREATE FUNCTION %s( lst list<frozen<" +
type + ">> ) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS text " +
- "LANGUAGE javascript\n" +
- "AS $$" +
- "
lst.get(1).getString(\"txt\");$$;");
- createFunctionOverload(fName, "set<frozen<" + type + ">>",
- "CREATE FUNCTION %s( st set<frozen<" + type +
">> ) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS text " +
- "LANGUAGE javascript\n" +
- "AS $$" +
- "
st.iterator().next().getString(\"txt\");$$;");
- createFunctionOverload(fName, "map<int, frozen<" + type + ">>",
- "CREATE FUNCTION %s( mp map<int, frozen<" +
type + ">> ) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS text " +
- "LANGUAGE javascript\n" +
- "AS $$" +
- "
mp.get(java.lang.Integer.valueOf(3)).getString(\"txt\");$$;");
-
- execute("INSERT INTO %s (key, lst, st, mp) values (1, " +
- // list<frozen<UDT>>
- "[ {txt: 'one', i:1}, {txt: 'three', i:1}, {txt: 'one', i:1} ]
, " +
- // set<frozen<UDT>>
- "{ {txt: 'one', i:1}, {txt: 'three', i:3}, {txt: 'two', i:2}
}, " +
- // map<int, frozen<UDT>>
- "{ 1: {txt: 'one', i:1}, 2: {txt: 'one', i:3}, 3: {txt: 'two',
i:2} })");
-
- assertRows(execute("SELECT " + fName + "(lst) FROM %s WHERE key = 1"),
- row("three"));
- assertRows(execute("SELECT " + fName + "(st) FROM %s WHERE key = 1"),
- row("one"));
- assertRows(execute("SELECT " + fName + "(mp) FROM %s WHERE key = 1"),
- row("two"));
-
- String cqlSelect = "SELECT " + fName + "(lst), " + fName + "(st), " +
fName + "(mp) FROM %s WHERE key = 1";
- assertRows(execute(cqlSelect),
- row("three", "one", "two"));
-
- // same test - but via native protocol
- for (ProtocolVersion version : PROTOCOL_VERSIONS)
- assertRowsNet(version,
- executeNet(version, cqlSelect),
- row("three", "one", "two"));
- }
-
- @Test
- public void testJavascriptFunction() throws Throwable
- {
- createTable("CREATE TABLE %s (key int primary key, val double)");
-
- String functionBody = '\n' +
- " Math.sin(val);\n";
-
- String fName = createFunction(KEYSPACE, "double",
- "CREATE OR REPLACE FUNCTION %s(val
double) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS double " +
- "LANGUAGE javascript\n" +
- "AS '" + functionBody + "';");
-
- FunctionName fNameName = parseFunctionName(fName);
-
- assertRows(execute("SELECT language, body FROM system_schema.functions
WHERE keyspace_name=? AND function_name=?",
- fNameName.keyspace, fNameName.name),
- row("javascript", functionBody));
-
- execute("INSERT INTO %s (key, val) VALUES (?, ?)", 1, 1d);
- execute("INSERT INTO %s (key, val) VALUES (?, ?)", 2, 2d);
- execute("INSERT INTO %s (key, val) VALUES (?, ?)", 3, 3d);
- assertRows(execute("SELECT key, val, " + fName + "(val) FROM %s"),
- row(1, 1d, Math.sin(1d)),
- row(2, 2d, Math.sin(2d)),
- row(3, 3d, Math.sin(3d))
- );
- }
-
- @Test
- public void testJavascriptBadReturnType() throws Throwable
- {
- createTable("CREATE TABLE %s (key int primary key, val double)");
-
- String fName = createFunction(KEYSPACE, "double",
- "CREATE OR REPLACE FUNCTION %s(val
double) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS double " +
- "LANGUAGE javascript\n" +
- "AS '\"string\";';");
-
- execute("INSERT INTO %s (key, val) VALUES (?, ?)", 1, 1d);
- // throws IRE with ClassCastException
- assertInvalidMessage("Invalid value for CQL type double", "SELECT key,
val, " + fName + "(val) FROM %s");
- }
-
- @Test
- public void testJavascriptThrow() throws Throwable
- {
- createTable("CREATE TABLE %s (key int primary key, val double)");
-
- String fName = createFunction(KEYSPACE, "double",
- "CREATE OR REPLACE FUNCTION %s(val
double) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS double " +
- "LANGUAGE javascript\n" +
- "AS 'throw \"fool\";';");
-
- execute("INSERT INTO %s (key, val) VALUES (?, ?)", 1, 1d);
- // throws IRE with ScriptException
- assertInvalidThrowMessage("fool", FunctionExecutionException.class,
- "SELECT key, val, " + fName + "(val) FROM
%s");
- }
-
- @Test
- public void testScriptReturnTypeCasting() throws Throwable
- {
- createTable("CREATE TABLE %s (key int primary key, val double)");
- execute("INSERT INTO %s (key, val) VALUES (?, ?)", 1, 1d);
-
- Object[][] variations = {
- new Object[] { "true", "boolean", true },
- new Object[] { "false", "boolean", false },
- new Object[] { "100", "tinyint", (byte)100 },
- new Object[] { "100.", "tinyint", (byte)100 },
- new Object[] { "100", "smallint", (short)100 },
- new Object[] { "100.", "smallint", (short)100 },
- new Object[] { "100", "int", 100 },
- new Object[] { "100.", "int", 100 },
- new Object[] { "100", "double", 100d },
- new Object[] { "100.", "double", 100d },
- new Object[] { "100", "bigint", 100L },
- new Object[] { "100.", "bigint", 100L },
- new Object[] { "100", "varint", BigInteger.valueOf(100L) },
- new Object[] { "100.", "varint", BigInteger.valueOf(100L)
},
- new Object[] { "parseInt(\"100\");", "decimal",
BigDecimal.valueOf(100d) },
- new Object[] { "100.", "decimal", BigDecimal.valueOf(100d)
},
- };
-
- for (Object[] variation : variations)
- {
- Object functionBody = variation[0];
- Object returnType = variation[1];
- Object expectedResult = variation[2];
-
- String fName = createFunction(KEYSPACE, "double",
- "CREATE OR REPLACE FUNCTION %s(val
double) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS " +returnType + ' ' +
- "LANGUAGE javascript " +
- "AS '" + functionBody + ";';");
- assertRows(execute("SELECT key, val, " + fName + "(val) FROM %s"),
- row(1, 1d, expectedResult));
- }
- }
-
- @Test
- public void testScriptParamReturnTypes() throws Throwable
- {
- UUID ruuid = UUID.randomUUID();
- TimeUUID tuuid = nextTimeUUID();
-
- createTable("CREATE TABLE %s (key int primary key, " +
- "tival tinyint, sival smallint, ival int, lval bigint,
fval float, dval double, vval varint, ddval decimal, " +
- "timval time, dtval date, tsval timestamp, uval uuid,
tuval timeuuid)");
- execute("INSERT INTO %s (key, tival, sival, ival, lval, fval, dval,
vval, ddval, timval, dtval, tsval, uval, tuval) VALUES " +
- "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", 1,
- (byte)1, (short)1, 1, 1L, 1f, 1d, BigInteger.valueOf(1L),
BigDecimal.valueOf(1d), 1L, Integer.MAX_VALUE, new Date(1), ruuid, tuuid);
-
- Object[][] variations = {
- new Object[] { "tinyint", "tival", (byte)1,
(byte)2 },
- new Object[] { "smallint", "sival", (short)1,
(short)2 },
- new Object[] { "int", "ival", 1, 2 },
- new Object[] { "bigint", "lval", 1L, 2L },
- new Object[] { "float", "fval", 1f, 2f },
- new Object[] { "double", "dval", 1d, 2d },
- new Object[] { "varint", "vval", BigInteger.valueOf(1L),
BigInteger.valueOf(2L) },
- new Object[] { "decimal", "ddval", BigDecimal.valueOf(1d),
BigDecimal.valueOf(2d) },
- new Object[] { "time", "timval", 1L, 2L },
- };
-
- for (Object[] variation : variations)
- {
- Object type = variation[0];
- Object col = variation[1];
- Object expected1 = variation[2];
- Object expected2 = variation[3];
- String fName = createFunction(KEYSPACE, type.toString(),
- "CREATE OR REPLACE FUNCTION %s(val "
+ type + ") " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS " + type + ' ' +
- "LANGUAGE javascript " +
- "AS 'val+1;';");
- assertRows(execute("SELECT key, " + col + ", " + fName + '(' + col
+ ") FROM %s"),
- row(1, expected1, expected2));
- }
-
- variations = new Object[][] {
- new Object[] { "timestamp","tsval", new Date(1), new
Date(1) },
- new Object[] { "uuid", "uval", ruuid, ruuid
},
- new Object[] { "timeuuid", "tuval", tuuid, tuuid
},
- new Object[] { "date", "dtval", Integer.MAX_VALUE,
Integer.MAX_VALUE },
- };
-
- for (Object[] variation : variations)
- {
- Object type = variation[0];
- Object col = variation[1];
- Object expected1 = variation[2];
- Object expected2 = variation[3];
- String fName = createFunction(KEYSPACE, type.toString(),
- "CREATE OR REPLACE FUNCTION %s(val "
+ type + ") " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS " + type + ' ' +
- "LANGUAGE javascript " +
- "AS 'val;';");
- assertRows(execute("SELECT key, " + col + ", " + fName + '(' + col
+ ") FROM %s"),
- row(1, expected1, expected2));
- }
- }
-
- @Test
- public void testJavascriptDisabled() throws Throwable
- {
- createTable("CREATE TABLE %s (key int primary key, val double)");
-
- DatabaseDescriptor.enableScriptedUserDefinedFunctions(false);
- try
- {
- assertInvalid("CREATE OR REPLACE FUNCTION " + KEYSPACE +
".assertNotEnabled(val double) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS double " +
- "LANGUAGE javascript\n" +
- "AS 'Math.sin(val);';");
- }
- finally
- {
- DatabaseDescriptor.enableScriptedUserDefinedFunctions(true);
- }
- }
-
- @Test
- public void testJavascriptCompileFailure() throws Throwable
- {
- assertInvalidMessage("Failed to compile function
'cql_test_keyspace.scrinv'",
- "CREATE OR REPLACE FUNCTION " + KEYSPACE +
".scrinv(val double) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS double " +
- "LANGUAGE javascript\n" +
- "AS 'foo bar';");
- }
-
- @Test
- public void testScriptInvalidLanguage() throws Throwable
- {
- assertInvalidMessage("Invalid language 'artificial_intelligence' for
function 'cql_test_keyspace.scrinv'",
- "CREATE OR REPLACE FUNCTION " + KEYSPACE +
".scrinv(val double) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS double " +
- "LANGUAGE artificial_intelligence\n" +
- "AS 'question for 42?';");
- }
-}
diff --git
a/test/unit/org/apache/cassandra/cql3/validation/entities/UFSecurityTest.java
b/test/unit/org/apache/cassandra/cql3/validation/entities/UFSecurityTest.java
index 7422db4351..96a0cbc329 100644
---
a/test/unit/org/apache/cassandra/cql3/validation/entities/UFSecurityTest.java
+++
b/test/unit/org/apache/cassandra/cql3/validation/entities/UFSecurityTest.java
@@ -130,74 +130,6 @@ public class UFSecurityTest extends CQLTester
"LANGUAGE JAVA\n" +
"AS '" + typeAndSource[1] + "';");
}
-
- // JavaScript UDFs
-
- try
- {
- String fName = createFunction(KEYSPACE_PER_TEST, "double",
- "CREATE OR REPLACE FUNCTION %s(val
double) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS double " +
- "LANGUAGE javascript\n" +
- "AS
'org.apache.cassandra.service.StorageService.instance.isShutdown(); 0;';");
- execute("SELECT " + fName + "(dval) FROM %s WHERE key=1");
- Assert.fail("Javascript security check failed");
- }
- catch (FunctionExecutionException e)
- {
- assertAccessControlException("", e);
- }
-
- String[] javascript =
- {
- "java.lang.management.ManagmentFactory.getThreadMXBean(); 0;",
- "new java.io.FileInputStream(\"/tmp/foo\"); 0;",
- "new java.io.FileOutputStream(\"/tmp/foo\"); 0;",
-
"java.nio.file.FileSystems.getDefault().createFileExclusively(\"./foo_bar_baz\");
0;",
-
"java.nio.channels.FileChannel.open(java.nio.file.FileSystems.getDefault().getPath(\"/etc/passwd\"));
0;",
- "java.nio.channels.SocketChannel.open(); 0;",
- "new java.net.ServerSocket().bind(null); 0;",
- "var thread = new java.lang.Thread(); thread.start(); 0;",
- "java.lang.System.getProperty(\"foo.bar.baz\"); 0;",
- "java.lang.Runtime.getRuntime().exec(\"/tmp/foo\"); 0;",
- "java.lang.Runtime.getRuntime().loadLibrary(\"foobar\"); 0;",
- "java.lang.Runtime.getRuntime().loadLibrary(\"foobar\"); 0;",
- // TODO these (ugly) calls are still possible - these can consume CPU
(as one could do with an evil loop, too)
-// "java.lang.Runtime.getRuntime().traceMethodCalls(true); 0;",
-// "java.lang.Runtime.getRuntime().gc(); 0;",
-// "java.lang.Runtime.getRuntime(); 0;",
- };
-
- for (String script : javascript)
- {
- try
- {
- String fName = createFunction(KEYSPACE_PER_TEST, "double",
- "CREATE OR REPLACE FUNCTION
%s(val double) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS double " +
- "LANGUAGE javascript\n" +
- "AS '" + script + "';");
- execute("SELECT " + fName + "(dval) FROM %s WHERE key=1");
- Assert.fail("Javascript security check failed: " + script);
- }
- catch (FunctionExecutionException e)
- {
- assertAccessControlException(script, e);
- }
- }
-
- String script = "java.lang.Class.forName(\"java.lang.System\"); 0;";
- String fName = createFunction(KEYSPACE_PER_TEST, "double",
- "CREATE OR REPLACE FUNCTION %s(val
double) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS double " +
- "LANGUAGE javascript\n" +
- "AS '" + script + "';");
- assertInvalidThrowMessage("Java reflection not supported when class
filter is present",
- FunctionExecutionException.class,
- "SELECT " + fName + "(dval) FROM %s WHERE
key=1");
}
private static void assertAccessControlException(String script,
FunctionExecutionException e)
@@ -250,16 +182,6 @@ public class UFSecurityTest extends CQLTester
"AS 'long
t=System.currentTimeMillis()+500; while (t>System.currentTimeMillis()) { };
return 0d;';");
assertInvalidMessage("ran longer than 250ms", "SELECT " +
fName + "(dval) FROM %s WHERE key=1");
- // Javascript UDF
-
- fName = createFunction(KEYSPACE_PER_TEST, "double",
- "CREATE OR REPLACE FUNCTION %s(val
double) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS double " +
- "LANGUAGE JAVASCRIPT\n" +
- "AS 'var
t=java.lang.System.currentTimeMillis()+500; while
(t>java.lang.System.currentTimeMillis()) { }; 0;';");
- assertInvalidMessage("ran longer than 250ms", "SELECT " +
fName + "(dval) FROM %s WHERE key=1");
-
return;
}
catch (Error | RuntimeException e)
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 a092c04e97..bd1383eb11 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java
@@ -87,17 +87,17 @@ public class UFTest extends CQLTester
}
@Test
- public void testSchemaChange() throws Throwable
+ public void testSchemaChange()
{
String f = createFunctionName(KEYSPACE);
String functionName = shortFunctionName(f);
registerFunction(f, "double, double");
- assertSchemaChange("CREATE OR REPLACE FUNCTION " + f + "(state double,
val double) " +
- "RETURNS NULL ON NULL INPUT " +
+ assertSchemaChange("CREATE OR REPLACE FUNCTION " + f + "(state double,
val double)" +
+ "CALLED ON NULL INPUT " +
"RETURNS double " +
- "LANGUAGE javascript " +
- "AS '\"string\";';",
+ "LANGUAGE java " +
+ "AS ' return
Double.valueOf(Math.max(state.doubleValue(), val.doubleValue())); ';",
Change.CREATED,
Target.FUNCTION,
KEYSPACE, functionName,
@@ -108,22 +108,22 @@ public class UFTest extends CQLTester
assertSchemaChange("CREATE OR REPLACE FUNCTION " + f + "(state int,
val int) " +
"RETURNS NULL ON NULL INPUT " +
"RETURNS int " +
- "LANGUAGE javascript " +
- "AS '\"string\";';",
+ "LANGUAGE java " +
+ "AS ' return Integer.valueOf(Math.max(state,
val));';",
Change.CREATED,
Target.FUNCTION,
KEYSPACE, functionName,
"int", "int");
- assertSchemaChange("CREATE OR REPLACE FUNCTION " + f + "(state int,
val int) " +
+ /*assertSchemaChange("CREATE OR REPLACE FUNCTION " + f + "(state int,
val int) " +
"RETURNS NULL ON NULL INPUT " +
"RETURNS int " +
- "LANGUAGE javascript " +
- "AS '\"string1\";';",
+ "LANGUAGE java " +
+ "AS ' return Integer.valueOf(Math.max(state,
val));';",
Change.UPDATED,
Target.FUNCTION,
KEYSPACE, functionName,
- "int", "int");
+ "int", "int");*/
assertSchemaChange("DROP FUNCTION " + f + "(double, double)",
Change.DROPPED, Target.FUNCTION,
@@ -137,8 +137,8 @@ public class UFTest extends CQLTester
assertSchemaChange("CREATE OR REPLACE FUNCTION " + fl + "(state
list<tuple<int, int>>, val double) " +
"RETURNS NULL ON NULL INPUT " +
"RETURNS double " +
- "LANGUAGE javascript " +
- "AS '\"string\";';",
+ "LANGUAGE java " +
+ "AS ' return val;';",
Change.CREATED, Target.FUNCTION,
KEYSPACE, shortFunctionName(fl),
"list<tuple<int, int>>", "double");
@@ -333,8 +333,8 @@ public class UFTest extends CQLTester
"CREATE FUNCTION %s ( input double ) "
+
"CALLED ON NULL INPUT " +
"RETURNS double " +
- "LANGUAGE javascript " +
- "AS 'input'");
+ "LANGUAGE java " +
+ "AS 'return
Double.valueOf(Math.log(input.doubleValue()));'");
Assert.assertEquals(1,
Schema.instance.getUserFunctions(parseFunctionName(function)).size());
List<ResultMessage.Prepared> prepared = new ArrayList<>();
@@ -793,11 +793,10 @@ public class UFTest extends CQLTester
public void testDuplicateArgNames() throws Throwable
{
assertInvalidMessage("Duplicate argument names for given function",
- "CREATE OR REPLACE FUNCTION " + KEYSPACE +
".scrinv(val double, val text) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS text " +
- "LANGUAGE javascript\n" +
- "AS '\"foo bar\";';");
+ "CREATE OR REPLACE FUNCTION " + KEYSPACE +
".scrinv(input double, input int) " +
+ "CALLED ON NULL INPUT " +
+ "RETURNS double " +
+ "LANGUAGE java AS 'return Math.max(input,
input)';");
}
@Test
diff --git
a/test/unit/org/apache/cassandra/cql3/validation/operations/AggregationTest.java
b/test/unit/org/apache/cassandra/cql3/validation/operations/AggregationTest.java
index bfcf38e153..b078694dd6 100644
---
a/test/unit/org/apache/cassandra/cql3/validation/operations/AggregationTest.java
+++
b/test/unit/org/apache/cassandra/cql3/validation/operations/AggregationTest.java
@@ -512,16 +512,16 @@ public class AggregationTest extends CQLTester
"CREATE OR REPLACE FUNCTION %s(state double,
val double) " +
"RETURNS NULL ON NULL INPUT " +
"RETURNS double " +
- "LANGUAGE javascript " +
- "AS '\"string\";';");
+ "LANGUAGE java " +
+ "AS ' return state;';");
createFunctionOverload(f,
"double, double",
"CREATE OR REPLACE FUNCTION %s(state int, val
int) " +
"RETURNS NULL ON NULL INPUT " +
"RETURNS int " +
- "LANGUAGE javascript " +
- "AS '\"string\";';");
+ "LANGUAGE java " +
+ "AS 'return state;';");
String a = createAggregateName(KEYSPACE);
String aggregateName = shortFunctionName(a);
@@ -564,8 +564,8 @@ public class AggregationTest extends CQLTester
"CREATE OR REPLACE FUNCTION %s(state
double, val list<tuple<int, int>>) " +
"RETURNS NULL ON NULL INPUT " +
"RETURNS double " +
- "LANGUAGE javascript " +
- "AS '\"string\";';");
+ "LANGUAGE java " +
+ "AS ' return state;';");
String a1 = createAggregateName(KEYSPACE);
registerAggregate(a1, "list<tuple<int, int>>");
@@ -587,16 +587,16 @@ public class AggregationTest extends CQLTester
"CREATE OR REPLACE FUNCTION %s(state double,
val double) " +
"RETURNS NULL ON NULL INPUT " +
"RETURNS double " +
- "LANGUAGE javascript " +
- "AS '\"string\";';");
+ "LANGUAGE java " +
+ "AS 'return state;';");
createFunctionOverload(f,
"double, double",
"CREATE OR REPLACE FUNCTION %s(state int, val
int) " +
"RETURNS NULL ON NULL INPUT " +
"RETURNS int " +
- "LANGUAGE javascript " +
- "AS '\"string\";';");
+ "LANGUAGE java " +
+ "AS ' return state;';");
// DROP AGGREGATE must not succeed against a scalar
assertInvalidMessage("matches multiple function definitions", "DROP
AGGREGATE " + f);
@@ -639,8 +639,8 @@ public class AggregationTest extends CQLTester
"CREATE OR REPLACE FUNCTION %s(state double,
val double) " +
"RETURNS NULL ON NULL INPUT " +
"RETURNS double " +
- "LANGUAGE javascript " +
- "AS '\"string\";';");
+ "LANGUAGE java " +
+ "AS ' return state;';");
String a = createAggregate(KEYSPACE,
"double",
@@ -1138,81 +1138,6 @@ public class AggregationTest extends CQLTester
}
- @Test
- public void testJavascriptAggregate() throws Throwable
- {
- createTable("CREATE TABLE %s (a int primary key, b int)");
- execute("INSERT INTO %s (a, b) VALUES (1, 1)");
- execute("INSERT INTO %s (a, b) VALUES (2, 2)");
- execute("INSERT INTO %s (a, b) VALUES (3, 3)");
-
- String fState = createFunction(KEYSPACE,
- "int, int",
- "CREATE FUNCTION %s(a int, b int) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS int " +
- "LANGUAGE javascript " +
- "AS 'a + b;'");
-
- String fFinal = createFunction(KEYSPACE,
- "int",
- "CREATE FUNCTION %s(a int) " +
- "RETURNS NULL ON NULL INPUT " +
- "RETURNS text " +
- "LANGUAGE javascript " +
- "AS '\"\"+a'");
-
- String a = createFunction(KEYSPACE,
- "int",
- "CREATE AGGREGATE %s(int) " +
- "SFUNC " + shortFunctionName(fState) + " " +
- "STYPE int " +
- "FINALFUNC " + shortFunctionName(fFinal) + "
" +
- "INITCOND 42");
-
- // 42 + 1 + 2 + 3 = 48
- assertRows(execute("SELECT " + a + "(b) FROM %s"), row("48"));
-
- execute("DROP AGGREGATE " + a + "(int)");
-
- execute("DROP FUNCTION " + fFinal + "(int)");
- execute("DROP FUNCTION " + fState + "(int, int)");
-
- assertInvalidMessage("Unknown function", "SELECT " + a + "(b) FROM
%s");
- }
-
- @Test
- public void testJavascriptAggregateSimple() throws Throwable
- {
- createTable("CREATE TABLE %s (a int primary key, b int)");
- execute("INSERT INTO %s (a, b) VALUES (1, 1)");
- execute("INSERT INTO %s (a, b) VALUES (2, 2)");
- execute("INSERT INTO %s (a, b) VALUES (3, 3)");
-
- String fState = createFunction(KEYSPACE,
- "int, int",
- "CREATE FUNCTION %s(a int, b int) " +
- "CALLED ON NULL INPUT " +
- "RETURNS int " +
- "LANGUAGE javascript " +
- "AS 'a + b;'");
-
- String a = createAggregate(KEYSPACE,
- "int, int",
- "CREATE AGGREGATE %s(int) " +
- "SFUNC " + shortFunctionName(fState) + " " +
- "STYPE int ");
-
- // 1 + 2 + 3 = 6
- assertRows(execute("SELECT " + a + "(b) FROM %s"), row(6));
-
- execute("DROP AGGREGATE " + a + "(int)");
-
- execute("DROP FUNCTION " + fState + "(int, int)");
-
- assertInvalidMessage("Unknown function", "SELECT " + a + "(b) FROM
%s");
- }
-
@Test
public void testFunctionDropPreparedStatement() throws Throwable
{
@@ -1228,8 +1153,8 @@ public class AggregationTest extends CQLTester
"CREATE FUNCTION %s(a int, b int) "
+
"CALLED ON NULL INPUT " +
"RETURNS int " +
- "LANGUAGE javascript " +
- "AS 'a + b;'");
+ "LANGUAGE java " +
+ "AS ' return a + b;'");
String a = createAggregate(otherKS,
"int",
@@ -1271,8 +1196,8 @@ public class AggregationTest extends CQLTester
"CREATE FUNCTION %s(a int, b int) " +
"CALLED ON NULL INPUT " +
"RETURNS int " +
- "LANGUAGE javascript " +
- "AS 'a + b;'");
+ "LANGUAGE java " +
+ "AS ' return a + b;'");
String a = createAggregate(KEYSPACE,
"int",
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]