| /* |
| * 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)); |
| } |
| } |
| } |