cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sn...@apache.org
Subject [04/17] cassandra git commit: Merge branch 'cassandra-2.2' into cassandra-3.0
Date Fri, 09 Dec 2016 10:49:05 GMT
http://git-wip-us.apache.org/repos/asf/cassandra/blob/3aefe356/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java
----------------------------------------------------------------------
diff --cc test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java
index c52e178,d4d2a10..8a743ea
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java
@@@ -17,44 -17,37 +17,29 @@@
   */
  package org.apache.cassandra.cql3.validation.entities;
  
 +import java.nio.ByteBuffer;
  import java.util.ArrayList;
--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 java.security.AccessControlException;
  
  import org.junit.Assert;
 -import org.junit.BeforeClass;
  import org.junit.Test;
  
- import com.datastax.driver.core.*;
 -import com.datastax.driver.core.Row;
  import com.datastax.driver.core.exceptions.InvalidQueryException;
--import org.apache.cassandra.config.DatabaseDescriptor;
 +import org.apache.cassandra.config.Schema;
- import org.apache.cassandra.cql3.CQL3Type;
  import org.apache.cassandra.cql3.CQLTester;
  import org.apache.cassandra.cql3.QueryProcessor;
  import org.apache.cassandra.cql3.UntypedResultSet;
- import org.apache.cassandra.config.Config;
  import org.apache.cassandra.cql3.functions.FunctionName;
 -import org.apache.cassandra.cql3.functions.Functions;
  import org.apache.cassandra.cql3.functions.UDFunction;
- import org.apache.cassandra.cql3.functions.UDHelper;
  import org.apache.cassandra.db.marshal.CollectionType;
- import org.apache.cassandra.exceptions.FunctionExecutionException;
 -import org.apache.cassandra.dht.ByteOrderedPartitioner;
  import org.apache.cassandra.exceptions.InvalidRequestException;
 +import org.apache.cassandra.schema.KeyspaceMetadata;
  import org.apache.cassandra.service.ClientState;
- import org.apache.cassandra.service.ClientWarn;
  import org.apache.cassandra.transport.Event;
  import org.apache.cassandra.transport.Server;
  import org.apache.cassandra.transport.messages.ResultMessage;
 -import org.apache.cassandra.utils.UUIDGen;
 +import org.apache.cassandra.utils.ByteBufferUtil;
- import org.apache.cassandra.utils.UUIDGen;
  
  public class UFTest extends CQLTester
  {
@@@ -1017,320 -724,115 +710,6 @@@
      }
  
      @Test
--    public void testComplexNullValues() throws Throwable
--    {
--        String type = KEYSPACE + '.' + createType("CREATE TYPE %s (txt text, i int)");
--
--        createTable("CREATE TABLE %s (key int primary key, lst list<double>, st set<text>, mp map<int, boolean>," +
--                    "tup frozen<tuple<double, text, int, boolean>>, udt frozen<" + type + ">)");
--
--        String fList = createFunction(KEYSPACE, "list<double>",
--                                      "CREATE FUNCTION %s( coll list<double> ) " +
--                                      "CALLED ON NULL INPUT " +
--                                      "RETURNS list<double> " +
--                                      "LANGUAGE java\n" +
--                                      "AS $$return coll;$$;");
--        String fSet = createFunction(KEYSPACE, "set<text>",
--                                     "CREATE FUNCTION %s( coll set<text> ) " +
--                                     "CALLED ON NULL INPUT " +
--                                     "RETURNS set<text> " +
--                                     "LANGUAGE java\n" +
--                                     "AS $$return coll;$$;");
--        String fMap = createFunction(KEYSPACE, "map<int, boolean>",
--                                     "CREATE FUNCTION %s( coll map<int, boolean> ) " +
--                                     "CALLED ON NULL INPUT " +
--                                     "RETURNS map<int, boolean> " +
--                                     "LANGUAGE java\n" +
--                                     "AS $$return coll;$$;");
--        String fTup = createFunction(KEYSPACE, "tuple<double, text, int, boolean>",
--                                     "CREATE FUNCTION %s( val tuple<double, text, int, boolean> ) " +
--                                     "CALLED ON NULL INPUT " +
--                                     "RETURNS tuple<double, text, int, boolean> " +
--                                     "LANGUAGE java\n" +
--                                     "AS $$return val;$$;");
--        String fUdt = createFunction(KEYSPACE, type,
--                                     "CREATE FUNCTION %s( val " + type + " ) " +
--                                     "CALLED ON NULL INPUT " +
--                                     "RETURNS " + type + " " +
--                                     "LANGUAGE java\n" +
--                                     "AS $$return val;$$;");
--        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, "one", 42, false);
--
--        execute("INSERT INTO %s (key, lst, st, mp, tup, udt) VALUES (1, ?, ?, ?, ?, {txt: 'one', i:1})", list, set, map, t);
--        execute("INSERT INTO %s (key, lst, st, mp, tup, udt) VALUES (2, ?, ?, ?, ?, null)", null, null, null, null);
--
--        execute("SELECT " +
--                fList + "(lst), " +
--                fSet + "(st), " +
--                fMap + "(mp), " +
--                fTup + "(tup), " +
--                fUdt + "(udt) FROM %s WHERE key = 1");
--        UntypedResultSet.Row row = execute("SELECT " +
--                                           fList + "(lst) as l, " +
--                                           fSet + "(st) as s, " +
--                                           fMap + "(mp) as m, " +
--                                           fTup + "(tup) as t, " +
--                                           fUdt + "(udt) as u " +
--                                           "FROM %s WHERE key = 1").one();
--        Assert.assertNotNull(row.getBytes("l"));
--        Assert.assertNotNull(row.getBytes("s"));
--        Assert.assertNotNull(row.getBytes("m"));
--        Assert.assertNotNull(row.getBytes("t"));
--        Assert.assertNotNull(row.getBytes("u"));
--        row = execute("SELECT " +
--                      fList + "(lst) as l, " +
--                      fSet + "(st) as s, " +
--                      fMap + "(mp) as m, " +
--                      fTup + "(tup) as t, " +
--                      fUdt + "(udt) as u " +
--                      "FROM %s WHERE key = 2").one();
--        Assert.assertNull(row.getBytes("l"));
--        Assert.assertNull(row.getBytes("s"));
--        Assert.assertNull(row.getBytes("m"));
--        Assert.assertNull(row.getBytes("t"));
--        Assert.assertNull(row.getBytes("u"));
--
-         for (int version : PROTOCOL_VERSIONS)
 -        for (int version = Server.VERSION_2; version <= maxProtocolVersion; version++)
--        {
--            Row r = executeNet(version, "SELECT " +
--                                        fList + "(lst) as l, " +
--                                        fSet + "(st) as s, " +
--                                        fMap + "(mp) as m, " +
--                                        fTup + "(tup) as t, " +
--                                        fUdt + "(udt) as u " +
--                                        "FROM %s WHERE key = 1").one();
--            Assert.assertNotNull(r.getBytesUnsafe("l"));
--            Assert.assertNotNull(r.getBytesUnsafe("s"));
--            Assert.assertNotNull(r.getBytesUnsafe("m"));
--            Assert.assertNotNull(r.getBytesUnsafe("t"));
--            Assert.assertNotNull(r.getBytesUnsafe("u"));
--            r = executeNet(version, "SELECT " +
--                                    fList + "(lst) as l, " +
--                                    fSet + "(st) as s, " +
--                                    fMap + "(mp) as m, " +
--                                    fTup + "(tup) as t, " +
--                                    fUdt + "(udt) as u " +
--                                    "FROM %s WHERE key = 2").one();
--            Assert.assertNull(r.getBytesUnsafe("l"));
--            Assert.assertNull(r.getBytesUnsafe("s"));
--            Assert.assertNull(r.getBytesUnsafe("m"));
--            Assert.assertNull(r.getBytesUnsafe("t"));
--            Assert.assertNull(r.getBytesUnsafe("u"));
-         }
-     }
- 
-     @Test
-     public void testJavaTupleType() throws Throwable
-     {
-         createTable("CREATE TABLE %s (key int primary key, tup frozen<tuple<double, text, int, boolean>>)");
- 
-         String fName = createFunction(KEYSPACE, "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 java\n" +
-                                      "AS $$return 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 testJavaTupleTypeCollection() 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 fTup0 = createFunction(KEYSPACE_PER_TEST, tupleTypeDef,
-                 "CREATE FUNCTION %s( tup " + tupleTypeDef + " ) " +
-                 "CALLED ON NULL INPUT " +
-                 "RETURNS " + tupleTypeDef + ' ' +
-                 "LANGUAGE java\n" +
-                 "AS $$return " +
-                 "       tup;$$;");
-         String fTup1 = createFunction(KEYSPACE_PER_TEST, tupleTypeDef,
-                 "CREATE FUNCTION %s( tup " + tupleTypeDef + " ) " +
-                 "CALLED ON NULL INPUT " +
-                 "RETURNS double " +
-                 "LANGUAGE java\n" +
-                 "AS $$return " +
-                 "       Double.valueOf(tup.getDouble(0));$$;");
-         String fTup2 = createFunction(KEYSPACE_PER_TEST, tupleTypeDef,
-                                       "CREATE FUNCTION %s( tup " + tupleTypeDef + " ) " +
-                                       "RETURNS NULL ON NULL INPUT " +
-                                       "RETURNS list<double> " +
-                                       "LANGUAGE java\n" +
-                                       "AS $$return " +
-                                       "       tup.getList(1, Double.class);$$;");
-         String fTup3 = createFunction(KEYSPACE_PER_TEST, tupleTypeDef,
-                 "CREATE FUNCTION %s( tup " + tupleTypeDef + " ) " +
-                 "RETURNS NULL ON NULL INPUT " +
-                 "RETURNS set<text> " +
-                 "LANGUAGE java\n" +
-                 "AS $$return " +
-                 "       tup.getSet(2, String.class);$$;");
-         String fTup4 = createFunction(KEYSPACE_PER_TEST, tupleTypeDef,
-                 "CREATE FUNCTION %s( tup " + tupleTypeDef + " ) " +
-                 "RETURNS NULL ON NULL INPUT " +
-                 "RETURNS map<int, boolean> " +
-                 "LANGUAGE java\n" +
-                 "AS $$return " +
-                 "       tup.getMap(3, Integer.class, 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 " + fTup0 + "(tup) FROM %s WHERE key = 1"),
-                    row(t));
-         assertRows(execute("SELECT " + fTup1 + "(tup) FROM %s WHERE key = 1"),
-                    row(1d));
-         assertRows(execute("SELECT " + fTup2 + "(tup) FROM %s WHERE key = 1"),
-                    row(list));
-         assertRows(execute("SELECT " + fTup3 + "(tup) FROM %s WHERE key = 1"),
-                    row(set));
-         assertRows(execute("SELECT " + fTup4 + "(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(Server.VERSION_3,
-                                       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 (int version : PROTOCOL_VERSIONS)
-         {
-             assertRowsNet(version,
-                           executeNet(version, "SELECT " + fTup0 + "(tup) FROM %s WHERE key = 1"),
-                           row(tup));
-             assertRowsNet(version,
-                           executeNet(version, "SELECT " + fTup1 + "(tup) FROM %s WHERE key = 1"),
-                           row(1d));
-             assertRowsNet(version,
-                           executeNet(version, "SELECT " + fTup2 + "(tup) FROM %s WHERE key = 1"),
-                           row(list));
-             assertRowsNet(version,
-                           executeNet(version, "SELECT " + fTup3 + "(tup) FROM %s WHERE key = 1"),
-                           row(set));
-             assertRowsNet(version,
-                           executeNet(version, "SELECT " + fTup4 + "(tup) FROM %s WHERE key = 1"),
-                           row(map));
-         }
-     }
- 
-     @Test
-     public void testJavaUserTypeWithUse() throws Throwable
-     {
-         String type = createType("CREATE TYPE %s (txt text, i int)");
-         createTable("CREATE TABLE %s (key int primary key, udt frozen<" + KEYSPACE + '.' + type + ">)");
-         execute("INSERT INTO %s (key, udt) VALUES (1, {txt: 'one', i:1})");
- 
-         for (int version : PROTOCOL_VERSIONS)
-         {
-             executeNet(version, "USE " + KEYSPACE);
- 
-             executeNet(version,
-                        "CREATE FUNCTION f_use1( udt " + type + " ) " +
-                        "RETURNS NULL ON NULL INPUT " +
-                        "RETURNS " + type + " " +
-                        "LANGUAGE java " +
-                        "AS $$return " +
-                        "     udt;$$;");
-             try
-             {
-                 List<Row> rowsNet = executeNet(version, "SELECT f_use1(udt) FROM %s WHERE key = 1").all();
-                 Assert.assertEquals(1, rowsNet.size());
-                 UDTValue udtVal = rowsNet.get(0).getUDTValue(0);
-                 Assert.assertEquals("one", udtVal.getString("txt"));
-                 Assert.assertEquals(1, udtVal.getInt("i"));
-             }
-             finally
-             {
-                 executeNet(version, "DROP FUNCTION f_use1");
-             }
-         }
-     }
- 
-     @Test
-     public void testJavaUserType() throws Throwable
-     {
-         String type = KEYSPACE + '.' + createType("CREATE TYPE %s (txt text, i int)");
- 
-         createTable("CREATE TABLE %s (key int primary key, udt frozen<" + type + ">)");
- 
-         String fUdt0 = createFunction(KEYSPACE, type,
-                                       "CREATE FUNCTION %s( udt " + type + " ) " +
-                                       "RETURNS NULL ON NULL INPUT " +
-                                       "RETURNS " + type + " " +
-                                       "LANGUAGE java " +
-                                       "AS $$return " +
-                                       "     udt;$$;");
-         String fUdt1 = createFunction(KEYSPACE, type,
-                                       "CREATE FUNCTION %s( udt " + type + ") " +
-                                       "RETURNS NULL ON NULL INPUT " +
-                                       "RETURNS text " +
-                                       "LANGUAGE java " +
-                                       "AS $$return " +
-                                       "     udt.getString(\"txt\");$$;");
-         String fUdt2 = createFunction(KEYSPACE, type,
-                                       "CREATE FUNCTION %s( udt " + type + ") " +
-                                       "CALLED ON NULL INPUT " +
-                                       "RETURNS int " +
-                                       "LANGUAGE java " +
-                                       "AS $$return " +
-                                       "     Integer.valueOf(udt.getInt(\"i\"));$$;");
- 
-         execute("INSERT INTO %s (key, udt) VALUES (1, {txt: 'one', i:1})");
- 
-         UntypedResultSet rows = execute("SELECT " + fUdt0 + "(udt) FROM %s WHERE key = 1");
-         Assert.assertEquals(1, rows.size());
-         assertRows(execute("SELECT " + fUdt1 + "(udt) FROM %s WHERE key = 1"),
-                    row("one"));
-         assertRows(execute("SELECT " + fUdt2 + "(udt) FROM %s WHERE key = 1"),
-                    row(1));
- 
-         for (int version : PROTOCOL_VERSIONS)
-         {
-             List<Row> rowsNet = executeNet(version, "SELECT " + fUdt0 + "(udt) FROM %s WHERE key = 1").all();
-             Assert.assertEquals(1, rowsNet.size());
-             UDTValue udtVal = rowsNet.get(0).getUDTValue(0);
-             Assert.assertEquals("one", udtVal.getString("txt"));
-             Assert.assertEquals(1, udtVal.getInt("i"));
-             assertRowsNet(version,
-                           executeNet(version, "SELECT " + fUdt1 + "(udt) FROM %s WHERE key = 1"),
-                           row("one"));
-             assertRowsNet(version,
-                           executeNet(version, "SELECT " + fUdt2 + "(udt) FROM %s WHERE key = 1"),
-                           row(1));
--        }
--    }
--
--    @Test
      public void testUserTypeDrop() throws Throwable
      {
          String type = KEYSPACE + '.' + createType("CREATE TYPE %s (txt text, i int)");
@@@ -1593,162 -880,140 +757,7 @@@
                               "AS '\"foo bar\";';");
      }
  
 -    private static class TypesTestDef
 -    {
 -        final String udfType;
 -        final String tableType;
 -        final String columnName;
 -        final Object referenceValue;
 -
 -        String fCheckArgAndReturn;
 -
 -        String fCalledOnNull;
 -        String fReturnsNullOnNull;
 -
 -        TypesTestDef(String udfType, String tableType, String columnName, Object referenceValue)
 -        {
 -            this.udfType = udfType;
 -            this.tableType = tableType;
 -            this.columnName = columnName;
 -            this.referenceValue = referenceValue;
 -        }
 -    }
 -
 -    @Test
 -    public void testTypesWithAndWithoutNulls() throws Throwable
 -    {
 -        // test various combinations of types against UDFs with CALLED ON NULL or RETURNS NULL ON NULL
 -
 -        String type = createType("CREATE TYPE %s (txt text, i int)");
 -
 -        TypesTestDef[] typeDefs =
 -        {
 -        //                udf type,            table type,                 column, reference value
 -        new TypesTestDef("timestamp", "timestamp", "ts", new Date()),
 -        new TypesTestDef("date", "date", "dt", 12345),
 -        new TypesTestDef("time", "time", "tim", 12345L),
 -        new TypesTestDef("uuid", "uuid", "uu", UUID.randomUUID()),
 -        new TypesTestDef("timeuuid", "timeuuid", "tu", UUIDGen.getTimeUUID()),
 -        new TypesTestDef("tinyint", "tinyint", "ti", (byte) 42),
 -        new TypesTestDef("smallint", "smallint", "si", (short) 43),
 -        new TypesTestDef("int", "int", "i", 44),
 -        new TypesTestDef("bigint", "bigint", "b", 45L),
 -        new TypesTestDef("float", "float", "f", 46f),
 -        new TypesTestDef("double", "double", "d", 47d),
 -        new TypesTestDef("boolean", "boolean", "x", true),
 -        new TypesTestDef("ascii", "ascii", "a", "tqbfjutld"),
 -        new TypesTestDef("text", "text", "t", "k\u00f6lsche jung"),
 -        //new TypesTestDef(type,                 "frozen<" + type + '>',     "u",    null),
 -        new TypesTestDef("tuple<int, text>", "frozen<tuple<int, text>>", "tup", tuple(1, "foo"))
 -        };
 -
 -        String createTableDDL = "CREATE TABLE %s (key int PRIMARY KEY";
 -        String insertDML = "INSERT INTO %s (key";
 -        List<Object> values = new ArrayList<>();
 -        for (TypesTestDef typeDef : typeDefs)
 -        {
 -            createTableDDL += ", " + typeDef.columnName + ' ' + typeDef.tableType;
 -            insertDML += ", " + typeDef.columnName;
 -            String typeName = typeDef.udfType;
 -            typeDef.fCheckArgAndReturn = createFunction(KEYSPACE,
 -                                                        typeName,
 -                                                        "CREATE OR REPLACE FUNCTION %s(val " + typeName + ") " +
 -                                                        "CALLED ON NULL INPUT " +
 -                                                        "RETURNS " + typeName + ' ' +
 -                                                        "LANGUAGE java\n" +
 -                                                        "AS 'return val;';");
 -            typeDef.fCalledOnNull = createFunction(KEYSPACE,
 -                                                   typeName,
 -                                                   "CREATE OR REPLACE FUNCTION %s(val " + typeName + ") " +
 -                                                   "CALLED ON NULL INPUT " +
 -                                                   "RETURNS text " +
 -                                                   "LANGUAGE java\n" +
 -                                                   "AS 'return \"called\";';");
 -            typeDef.fReturnsNullOnNull = createFunction(KEYSPACE,
 -                                                        typeName,
 -                                                        "CREATE OR REPLACE FUNCTION %s(val " + typeName + ") " +
 -                                                        "RETURNS NULL ON NULL INPUT " +
 -                                                        "RETURNS text " +
 -                                                        "LANGUAGE java\n" +
 -                                                        "AS 'return \"called\";';");
 -            values.add(typeDef.referenceValue);
 -        }
 -
 -        createTableDDL += ')';
 -        createTable(createTableDDL);
 -
 -        insertDML += ") VALUES (1";
 -        for (TypesTestDef ignored : typeDefs)
 -            insertDML += ", ?";
 -        insertDML += ')';
 -
 -        execute(insertDML, values.toArray());
 -
 -        // second row with null values
 -        for (int i = 0; i < values.size(); i++)
 -            values.set(i, null);
 -        execute(insertDML.replace('1', '2'), values.toArray());
 -
 -        // check argument input + return
 -        for (TypesTestDef typeDef : typeDefs)
 -        {
 -            assertRows(execute("SELECT " + typeDef.fCheckArgAndReturn + '(' + typeDef.columnName + ") FROM %s WHERE key = 1"),
 -                       row(new Object[]{ typeDef.referenceValue }));
 -        }
 -
 -        // check for CALLED ON NULL INPUT with non-null arguments
 -        for (TypesTestDef typeDef : typeDefs)
 -        {
 -            assertRows(execute("SELECT " + typeDef.fCalledOnNull + '(' + typeDef.columnName + ") FROM %s WHERE key = 1"),
 -                       row(new Object[]{ "called" }));
 -        }
 -
 -        // check for CALLED ON NULL INPUT with null arguments
 -        for (TypesTestDef typeDef : typeDefs)
 -        {
 -            assertRows(execute("SELECT " + typeDef.fCalledOnNull + '(' + typeDef.columnName + ") FROM %s WHERE key = 2"),
 -                       row(new Object[]{ "called" }));
 -        }
 -
 -        // check for RETURNS NULL ON NULL INPUT with non-null arguments
 -        for (TypesTestDef typeDef : typeDefs)
 -        {
 -            assertRows(execute("SELECT " + typeDef.fReturnsNullOnNull + '(' + typeDef.columnName + ") FROM %s WHERE key = 1"),
 -                       row(new Object[]{ "called" }));
 -        }
 -
 -        // check for RETURNS NULL ON NULL INPUT with null arguments
 -        for (TypesTestDef typeDef : typeDefs)
 -        {
 -            assertRows(execute("SELECT " + typeDef.fReturnsNullOnNull + '(' + typeDef.columnName + ") FROM %s WHERE key = 2"),
 -                       row(new Object[]{ null }));
 -        }
 -
 -    }
 -
      @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?';");
-     }
- 
-     static class TypesTestDef
-     {
-         final String udfType;
-         final String tableType;
-         final String columnName;
-         final Object referenceValue;
- 
-         String fCheckArgAndReturn;
- 
-         String fCalledOnNull;
-         String fReturnsNullOnNull;
- 
-         TypesTestDef(String udfType, String tableType, String columnName, Object referenceValue)
-         {
-             this.udfType = udfType;
-             this.tableType = tableType;
-             this.columnName = columnName;
-             this.referenceValue = referenceValue;
-         }
-     }
- 
-     @Test
-     public void testTypesWithAndWithoutNulls() throws Throwable
-     {
-         // test various combinations of types against UDFs with CALLED ON NULL or RETURNS NULL ON NULL
- 
-         String type = createType("CREATE TYPE %s (txt text, i int)");
- 
-         TypesTestDef[] typeDefs =
-         {
-         //                udf type,            table type,                 column, reference value
-         new TypesTestDef("timestamp", "timestamp", "ts", new Date()),
-         new TypesTestDef("date", "date", "dt", 12345),
-         new TypesTestDef("time", "time", "tim", 12345L),
-         new TypesTestDef("uuid", "uuid", "uu", UUID.randomUUID()),
-         new TypesTestDef("timeuuid", "timeuuid", "tu", UUIDGen.getTimeUUID()),
-         new TypesTestDef("tinyint", "tinyint", "ti", (byte) 42),
-         new TypesTestDef("smallint", "smallint", "si", (short) 43),
-         new TypesTestDef("int", "int", "i", 44),
-         new TypesTestDef("bigint", "bigint", "b", 45L),
-         new TypesTestDef("float", "float", "f", 46f),
-         new TypesTestDef("double", "double", "d", 47d),
-         new TypesTestDef("boolean", "boolean", "x", true),
-         new TypesTestDef("ascii", "ascii", "a", "tqbfjutld"),
-         new TypesTestDef("text", "text", "t", "k\u00f6lsche jung"),
-         //new TypesTestDef(type,                 "frozen<" + type + '>',     "u",    null),
-         new TypesTestDef("tuple<int, text>", "frozen<tuple<int, text>>", "tup", tuple(1, "foo"))
-         };
- 
-         String createTableDDL = "CREATE TABLE %s (key int PRIMARY KEY";
-         String insertDML = "INSERT INTO %s (key";
-         List<Object> values = new ArrayList<>();
-         for (TypesTestDef typeDef : typeDefs)
-         {
-             createTableDDL += ", " + typeDef.columnName + ' ' + typeDef.tableType;
-             insertDML += ", " + typeDef.columnName;
-             String typeName = typeDef.udfType;
-             typeDef.fCheckArgAndReturn = createFunction(KEYSPACE,
-                                                         typeName,
-                                                         "CREATE OR REPLACE FUNCTION %s(val " + typeName + ") " +
-                                                         "CALLED ON NULL INPUT " +
-                                                         "RETURNS " + typeName + ' ' +
-                                                         "LANGUAGE java\n" +
-                                                         "AS 'return val;';");
-             typeDef.fCalledOnNull = createFunction(KEYSPACE,
-                                                    typeName,
-                                                    "CREATE OR REPLACE FUNCTION %s(val " + typeName + ") " +
-                                                    "CALLED ON NULL INPUT " +
-                                                    "RETURNS text " +
-                                                    "LANGUAGE java\n" +
-                                                    "AS 'return \"called\";';");
-             typeDef.fReturnsNullOnNull = createFunction(KEYSPACE,
-                                                         typeName,
-                                                         "CREATE OR REPLACE FUNCTION %s(val " + typeName + ") " +
-                                                         "RETURNS NULL ON NULL INPUT " +
-                                                         "RETURNS text " +
-                                                         "LANGUAGE java\n" +
-                                                         "AS 'return \"called\";';");
-             values.add(typeDef.referenceValue);
-         }
- 
-         createTableDDL += ')';
-         createTable(createTableDDL);
- 
-         insertDML += ") VALUES (1";
-         for (TypesTestDef ignored : typeDefs)
-             insertDML += ", ?";
-         insertDML += ')';
- 
-         execute(insertDML, values.toArray());
- 
-         // second row with null values
-         for (int i = 0; i < values.size(); i++)
-             values.set(i, null);
-         execute(insertDML.replace('1', '2'), values.toArray());
- 
-         // check argument input + return
-         for (TypesTestDef typeDef : typeDefs)
-         {
-             assertRows(execute("SELECT " + typeDef.fCheckArgAndReturn + '(' + typeDef.columnName + ") FROM %s WHERE key = 1"),
-                        row(new Object[]{ typeDef.referenceValue }));
-         }
- 
-         // check for CALLED ON NULL INPUT with non-null arguments
-         for (TypesTestDef typeDef : typeDefs)
-         {
-             assertRows(execute("SELECT " + typeDef.fCalledOnNull + '(' + typeDef.columnName + ") FROM %s WHERE key = 1"),
-                        row(new Object[]{ "called" }));
-         }
- 
-         // check for CALLED ON NULL INPUT with null arguments
-         for (TypesTestDef typeDef : typeDefs)
-         {
-             assertRows(execute("SELECT " + typeDef.fCalledOnNull + '(' + typeDef.columnName + ") FROM %s WHERE key = 2"),
-                        row(new Object[]{ "called" }));
-         }
- 
-         // check for RETURNS NULL ON NULL INPUT with non-null arguments
-         for (TypesTestDef typeDef : typeDefs)
-         {
-             assertRows(execute("SELECT " + typeDef.fReturnsNullOnNull + '(' + typeDef.columnName + ") FROM %s WHERE key = 1"),
-                        row(new Object[]{ "called" }));
-         }
- 
-         // check for RETURNS NULL ON NULL INPUT with null arguments
-         for (TypesTestDef typeDef : typeDefs)
-         {
-             assertRows(execute("SELECT " + typeDef.fReturnsNullOnNull + '(' + typeDef.columnName + ") FROM %s WHERE key = 2"),
-                        row(new Object[]{ null }));
-         }
- 
-     }
- 
-     @Test
      public void testReplaceAllowNulls() throws Throwable
      {
          String fNulls = createFunction(KEYSPACE,
@@@ -1851,638 -1108,4 +860,112 @@@
              }
          }
      }
-     @Test
-     public void testFunctionWithFrozenSetType() throws Throwable
-     {
-         createTable("CREATE TABLE %s (a int PRIMARY KEY, b frozen<set<int>>)");
-         createIndex("CREATE INDEX ON %s (FULL(b))");
- 
-         execute("INSERT INTO %s (a, b) VALUES (?, ?)", 0, set());
-         execute("INSERT INTO %s (a, b) VALUES (?, ?)", 1, set(1, 2, 3));
-         execute("INSERT INTO %s (a, b) VALUES (?, ?)", 2, set(4, 5, 6));
-         execute("INSERT INTO %s (a, b) VALUES (?, ?)", 3, set(7, 8, 9));
- 
-         assertInvalidMessage("The function arguments should not be frozen",
-                              "CREATE OR REPLACE FUNCTION " + KEYSPACE + ".frozenSetArg(values frozen<set<int>>) " +
-                              "CALLED ON NULL INPUT " +
-                              "RETURNS int " +
-                              "LANGUAGE java\n" +
-                              "AS 'int sum = 0; for (Object value : values) {sum += value;} return sum;';");
- 
-         assertInvalidMessage("The function return type should not be frozen",
-                              "CREATE OR REPLACE FUNCTION " + KEYSPACE + ".frozenReturnType(values set<int>) " +
-                              "CALLED ON NULL INPUT " +
-                              "RETURNS frozen<set<int>> " +
-                              "LANGUAGE java\n" +
-                              "AS 'return values;';");
- 
-         String functionName = createFunction(KEYSPACE,
-                                              "set<int>",
-                                              "CREATE FUNCTION %s (values set<int>) " +
-                                              "CALLED ON NULL INPUT " +
-                                              "RETURNS int " +
-                                              "LANGUAGE java\n" +
-                                              "AS 'int sum = 0; for (Object value : values) {sum += ((Integer) value);} return sum;';");
- 
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 0"), row(0, 0));
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 1"), row(1, 6));
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 2"), row(2, 15));
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 3"), row(3, 24));
- 
-         functionName = createFunction(KEYSPACE,
-                                       "set<int>",
-                                              "CREATE FUNCTION %s (values set<int>) " +
-                                              "CALLED ON NULL INPUT " +
-                                              "RETURNS set<int> " +
-                                              "LANGUAGE java\n" +
-                                              "AS 'return values;';");
- 
-         assertRows(execute("SELECT a FROM %s WHERE b = " + functionName + "(?)", set(1, 2, 3)),
-                    row(1));
- 
-         assertInvalidMessage("The function arguments should not be frozen",
-                              "DROP FUNCTION " + functionName + "(frozen<set<int>>);");
-     }
- 
-     @Test
-     public void testFunctionWithFrozenListType() throws Throwable
-     {
-         createTable("CREATE TABLE %s (a int PRIMARY KEY, b frozen<list<int>>)");
-         createIndex("CREATE INDEX ON %s (FULL(b))");
- 
-         execute("INSERT INTO %s (a, b) VALUES (?, ?)", 0, list());
-         execute("INSERT INTO %s (a, b) VALUES (?, ?)", 1, list(1, 2, 3));
-         execute("INSERT INTO %s (a, b) VALUES (?, ?)", 2, list(4, 5, 6));
-         execute("INSERT INTO %s (a, b) VALUES (?, ?)", 3, list(7, 8, 9));
- 
-         assertInvalidMessage("The function arguments should not be frozen",
-                              "CREATE OR REPLACE FUNCTION " + KEYSPACE + ".withFrozenArg(values frozen<list<int>>) " +
-                              "CALLED ON NULL INPUT " +
-                              "RETURNS int " +
-                              "LANGUAGE java\n" +
-                              "AS 'int sum = 0; for (Object value : values) {sum += value;} return sum;';");
- 
-         assertInvalidMessage("The function return type should not be frozen",
-                              "CREATE OR REPLACE FUNCTION " + KEYSPACE + ".frozenReturnType(values list<int>) " +
-                              "CALLED ON NULL INPUT " +
-                              "RETURNS frozen<list<int>> " +
-                              "LANGUAGE java\n" +
-                              "AS 'return values;';");
- 
-         String functionName = createFunction(KEYSPACE,
-                                              "list<int>",
-                                              "CREATE FUNCTION %s (values list<int>) " +
-                                              "CALLED ON NULL INPUT " +
-                                              "RETURNS int " +
-                                              "LANGUAGE java\n" +
-                                              "AS 'int sum = 0; for (Object value : values) {sum += ((Integer) value);} return sum;';");
- 
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 0"), row(0, 0));
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 1"), row(1, 6));
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 2"), row(2, 15));
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 3"), row(3, 24));
- 
-         functionName = createFunction(KEYSPACE,
-                                       "list<int>",
-                                       "CREATE FUNCTION %s (values list<int>) " +
-                                       "CALLED ON NULL INPUT " +
-                                       "RETURNS list<int> " +
-                                       "LANGUAGE java\n" +
-                                       "AS 'return values;';");
- 
-         assertRows(execute("SELECT a FROM %s WHERE b = " + functionName + "(?)", set(1, 2, 3)),
-                    row(1));
- 
-         assertInvalidMessage("The function arguments should not be frozen",
-                              "DROP FUNCTION " + functionName + "(frozen<list<int>>);");
-     }
- 
-     @Test
-     public void testFunctionWithFrozenMapType() throws Throwable
-     {
-         createTable("CREATE TABLE %s (a int PRIMARY KEY, b frozen<map<int, int>>)");
-         createIndex("CREATE INDEX ON %s (FULL(b))");
- 
-         execute("INSERT INTO %s (a, b) VALUES (?, ?)", 0, map());
-         execute("INSERT INTO %s (a, b) VALUES (?, ?)", 1, map(1, 1, 2, 2, 3, 3));
-         execute("INSERT INTO %s (a, b) VALUES (?, ?)", 2, map(4, 4, 5, 5, 6, 6));
-         execute("INSERT INTO %s (a, b) VALUES (?, ?)", 3, map(7, 7, 8, 8, 9, 9));
- 
-         assertInvalidMessage("The function arguments should not be frozen",
-                              "CREATE OR REPLACE FUNCTION " + KEYSPACE + ".withFrozenArg(values frozen<map<int, int>>) " +
-                              "CALLED ON NULL INPUT " +
-                              "RETURNS int " +
-                              "LANGUAGE java\n" +
-                              "AS 'int sum = 0; for (Object value : values.values()) {sum += value;} return sum;';");
- 
-         assertInvalidMessage("The function return type should not be frozen",
-                              "CREATE OR REPLACE FUNCTION " + KEYSPACE + ".frozenReturnType(values map<int, int>) " +
-                              "CALLED ON NULL INPUT " +
-                              "RETURNS frozen<map<int, int>> " +
-                              "LANGUAGE java\n" +
-                              "AS 'return values;';");
- 
-         String functionName = createFunction(KEYSPACE,
-                                              "map<int, int>",
-                                              "CREATE FUNCTION %s (values map<int, int>) " +
-                                              "CALLED ON NULL INPUT " +
-                                              "RETURNS int " +
-                                              "LANGUAGE java\n" +
-                                              "AS 'int sum = 0; for (Object value : values.values()) {sum += ((Integer) value);} return sum;';");
- 
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 0"), row(0, 0));
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 1"), row(1, 6));
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 2"), row(2, 15));
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 3"), row(3, 24));
- 
-         functionName = createFunction(KEYSPACE,
-                                       "map<int, int>",
-                                       "CREATE FUNCTION %s (values map<int, int>) " +
-                                       "CALLED ON NULL INPUT " +
-                                       "RETURNS map<int, int> " +
-                                       "LANGUAGE java\n" +
-                                       "AS 'return values;';");
- 
-         assertRows(execute("SELECT a FROM %s WHERE b = " + functionName + "(?)", map(1, 1, 2, 2, 3, 3)),
-                    row(1));
- 
-         assertInvalidMessage("The function arguments should not be frozen",
-                              "DROP FUNCTION " + functionName + "(frozen<map<int, int>>);");
-     }
- 
-     @Test
-     public void testFunctionWithFrozenTupleType() throws Throwable
-     {
-         createTable("CREATE TABLE %s (a int PRIMARY KEY, b frozen<tuple<int, int>>)");
-         createIndex("CREATE INDEX ON %s (b)");
- 
-         execute("INSERT INTO %s (a, b) VALUES (?, ?)", 0, tuple());
-         execute("INSERT INTO %s (a, b) VALUES (?, ?)", 1, tuple(1, 2));
-         execute("INSERT INTO %s (a, b) VALUES (?, ?)", 2, tuple(4, 5));
-         execute("INSERT INTO %s (a, b) VALUES (?, ?)", 3, tuple(7, 8));
- 
-         assertInvalidMessage("The function arguments should not be frozen",
-                              "CREATE OR REPLACE FUNCTION " + KEYSPACE + ".withFrozenArg(values frozen<tuple<int, int>>) " +
-                              "CALLED ON NULL INPUT " +
-                              "RETURNS text " +
-                              "LANGUAGE java\n" +
-                              "AS 'return values.toString();';");
- 
-         assertInvalidMessage("The function return type should not be frozen",
-                              "CREATE OR REPLACE FUNCTION " + KEYSPACE + ".frozenReturnType(values tuple<int, int>) " +
-                              "CALLED ON NULL INPUT " +
-                              "RETURNS frozen<tuple<int, int>> " +
-                              "LANGUAGE java\n" +
-                              "AS 'return values;';");
- 
-         String functionName = createFunction(KEYSPACE,
-                                              "tuple<int, int>",
-                                              "CREATE FUNCTION %s (values tuple<int, int>) " +
-                                              "CALLED ON NULL INPUT " +
-                                              "RETURNS text " +
-                                              "LANGUAGE java\n" +
-                                              "AS 'return values.toString();';");
- 
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 0"), row(0, "(NULL,NULL)"));
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 1"), row(1, "(1,2)"));
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 2"), row(2, "(4,5)"));
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 3"), row(3, "(7,8)"));
- 
-         functionName = createFunction(KEYSPACE,
-                                       "tuple<int, int>",
-                                       "CREATE FUNCTION %s (values tuple<int, int>) " +
-                                       "CALLED ON NULL INPUT " +
-                                       "RETURNS tuple<int, int> " +
-                                       "LANGUAGE java\n" +
-                                       "AS 'return values;';");
- 
-         assertRows(execute("SELECT a FROM %s WHERE b = " + functionName + "(?)", tuple(1, 2)),
-                    row(1));
- 
-         assertInvalidMessage("The function arguments should not be frozen",
-                              "DROP FUNCTION " + functionName + "(frozen<tuple<int, int>>);");
-     }
- 
-     @Test
-     public void testFunctionWithFrozenUDType() throws Throwable
-     {
-         String myType = createType("CREATE TYPE %s (f int)");
-         createTable("CREATE TABLE %s (a int PRIMARY KEY, b frozen<" + myType + ">)");
-         createIndex("CREATE INDEX ON %s (b)");
- 
-         execute("INSERT INTO %s (a, b) VALUES (?, {f : ?})", 0, 0);
-         execute("INSERT INTO %s (a, b) VALUES (?, {f : ?})", 1, 1);
-         execute("INSERT INTO %s (a, b) VALUES (?, {f : ?})", 2, 4);
-         execute("INSERT INTO %s (a, b) VALUES (?, {f : ?})", 3, 7);
- 
-         assertInvalidMessage("The function arguments should not be frozen",
-                              "CREATE OR REPLACE FUNCTION " + KEYSPACE + ".withFrozenArg(values frozen<" + myType + ">) " +
-                              "CALLED ON NULL INPUT " +
-                              "RETURNS text " +
-                              "LANGUAGE java\n" +
-                              "AS 'return values.toString();';");
- 
-         assertInvalidMessage("The function return type should not be frozen",
-                              "CREATE OR REPLACE FUNCTION " + KEYSPACE + ".frozenReturnType(values " + myType + ") " +
-                              "CALLED ON NULL INPUT " +
-                              "RETURNS frozen<" + myType + "> " +
-                              "LANGUAGE java\n" +
-                              "AS 'return values;';");
- 
-         String functionName = createFunction(KEYSPACE,
-                                              myType,
-                                              "CREATE FUNCTION %s (values " + myType + ") " +
-                                              "CALLED ON NULL INPUT " +
-                                              "RETURNS text " +
-                                              "LANGUAGE java\n" +
-                                              "AS 'return values.toString();';");
- 
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 0"), row(0, "{f:0}"));
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 1"), row(1, "{f:1}"));
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 2"), row(2, "{f:4}"));
-         assertRows(execute("SELECT a, " + functionName + "(b) FROM %s WHERE a = 3"), row(3, "{f:7}"));
- 
-         functionName = createFunction(KEYSPACE,
-                                       myType,
-                                       "CREATE FUNCTION %s (values " + myType + ") " +
-                                       "CALLED ON NULL INPUT " +
-                                       "RETURNS " + myType + " " +
-                                       "LANGUAGE java\n" +
-                                       "AS 'return values;';");
- 
-         assertRows(execute("SELECT a FROM %s WHERE b = " + functionName + "({f: ?})", 1),
-                    row(1));
- 
-         assertInvalidMessage("The function arguments should not be frozen",
-                              "DROP FUNCTION " + functionName + "(frozen<" + myType + ">);");
-     }
 +
 +    @Test
 +    public void testEmptyString() throws Throwable
 +    {
 +        createTable("CREATE TABLE %s (key int primary key, sval text, aval ascii, bval blob, empty_int int)");
 +        execute("INSERT INTO %s (key, sval, aval, bval, empty_int) VALUES (?, ?, ?, ?, blobAsInt(0x))", 1, "", "", ByteBuffer.allocate(0));
 +
 +        String fNameSRC = createFunction(KEYSPACE_PER_TEST, "text",
 +                                         "CREATE OR REPLACE FUNCTION %s(val text) " +
 +                                         "CALLED ON NULL INPUT " +
 +                                         "RETURNS text " +
 +                                         "LANGUAGE JAVA\n" +
 +                                         "AS 'return val;'");
 +
 +        String fNameSCC = createFunction(KEYSPACE_PER_TEST, "text",
 +                                         "CREATE OR REPLACE FUNCTION %s(val text) " +
 +                                         "CALLED ON NULL INPUT " +
 +                                         "RETURNS text " +
 +                                         "LANGUAGE JAVA\n" +
 +                                         "AS 'return \"\";'");
 +
 +        String fNameSRN = createFunction(KEYSPACE_PER_TEST, "text",
 +                                         "CREATE OR REPLACE FUNCTION %s(val text) " +
 +                                         "RETURNS NULL ON NULL INPUT " +
 +                                         "RETURNS text " +
 +                                         "LANGUAGE JAVA\n" +
 +                                         "AS 'return val;'");
 +
 +        String fNameSCN = createFunction(KEYSPACE_PER_TEST, "text",
 +                                         "CREATE OR REPLACE FUNCTION %s(val text) " +
 +                                         "RETURNS NULL ON NULL INPUT " +
 +                                         "RETURNS text " +
 +                                         "LANGUAGE JAVA\n" +
 +                                         "AS 'return \"\";'");
 +
 +        String fNameBRC = createFunction(KEYSPACE_PER_TEST, "blob",
 +                                         "CREATE OR REPLACE FUNCTION %s(val blob) " +
 +                                         "CALLED ON NULL INPUT " +
 +                                         "RETURNS blob " +
 +                                         "LANGUAGE JAVA\n" +
 +                                         "AS 'return val;'");
 +
 +        String fNameBCC = createFunction(KEYSPACE_PER_TEST, "blob",
 +                                         "CREATE OR REPLACE FUNCTION %s(val blob) " +
 +                                         "CALLED ON NULL INPUT " +
 +                                         "RETURNS blob " +
 +                                         "LANGUAGE JAVA\n" +
 +                                         "AS 'return ByteBuffer.allocate(0);'");
 +
 +        String fNameBRN = createFunction(KEYSPACE_PER_TEST, "blob",
 +                                         "CREATE OR REPLACE FUNCTION %s(val blob) " +
 +                                         "RETURNS NULL ON NULL INPUT " +
 +                                         "RETURNS blob " +
 +                                         "LANGUAGE JAVA\n" +
 +                                         "AS 'return val;'");
 +
 +        String fNameBCN = createFunction(KEYSPACE_PER_TEST, "blob",
 +                                         "CREATE OR REPLACE FUNCTION %s(val blob) " +
 +                                         "RETURNS NULL ON NULL INPUT " +
 +                                         "RETURNS blob " +
 +                                         "LANGUAGE JAVA\n" +
 +                                         "AS 'return ByteBuffer.allocate(0);'");
 +
 +        String fNameIRC = createFunction(KEYSPACE_PER_TEST, "int",
 +                                         "CREATE OR REPLACE FUNCTION %s(val int) " +
 +                                         "CALLED ON NULL INPUT " +
 +                                         "RETURNS int " +
 +                                         "LANGUAGE JAVA\n" +
 +                                         "AS 'return val;'");
 +
 +        String fNameICC = createFunction(KEYSPACE_PER_TEST, "int",
 +                                         "CREATE OR REPLACE FUNCTION %s(val int) " +
 +                                         "CALLED ON NULL INPUT " +
 +                                         "RETURNS int " +
 +                                         "LANGUAGE JAVA\n" +
 +                                         "AS 'return 0;'");
 +
 +        String fNameIRN = createFunction(KEYSPACE_PER_TEST, "int",
 +                                         "CREATE OR REPLACE FUNCTION %s(val int) " +
 +                                         "RETURNS NULL ON NULL INPUT " +
 +                                         "RETURNS int " +
 +                                         "LANGUAGE JAVA\n" +
 +                                         "AS 'return val;'");
 +
 +        String fNameICN = createFunction(KEYSPACE_PER_TEST, "int",
 +                                         "CREATE OR REPLACE FUNCTION %s(val int) " +
 +                                         "RETURNS NULL ON NULL INPUT " +
 +                                         "RETURNS int " +
 +                                         "LANGUAGE JAVA\n" +
 +                                         "AS 'return 0;'");
 +
 +        assertRows(execute("SELECT " + fNameSRC + "(sval) FROM %s"), row(""));
 +        assertRows(execute("SELECT " + fNameSRN + "(sval) FROM %s"), row(""));
 +        assertRows(execute("SELECT " + fNameSCC + "(sval) FROM %s"), row(""));
 +        assertRows(execute("SELECT " + fNameSCN + "(sval) FROM %s"), row(""));
 +        assertRows(execute("SELECT " + fNameSRC + "(aval) FROM %s"), row(""));
 +        assertRows(execute("SELECT " + fNameSRN + "(aval) FROM %s"), row(""));
 +        assertRows(execute("SELECT " + fNameSCC + "(aval) FROM %s"), row(""));
 +        assertRows(execute("SELECT " + fNameSCN + "(aval) FROM %s"), row(""));
 +        assertRows(execute("SELECT " + fNameBRC + "(bval) FROM %s"), row(ByteBufferUtil.EMPTY_BYTE_BUFFER));
 +        assertRows(execute("SELECT " + fNameBRN + "(bval) FROM %s"), row(ByteBufferUtil.EMPTY_BYTE_BUFFER));
 +        assertRows(execute("SELECT " + fNameBCC + "(bval) FROM %s"), row(ByteBufferUtil.EMPTY_BYTE_BUFFER));
 +        assertRows(execute("SELECT " + fNameBCN + "(bval) FROM %s"), row(ByteBufferUtil.EMPTY_BYTE_BUFFER));
 +        assertRows(execute("SELECT " + fNameIRC + "(empty_int) FROM %s"), row(new Object[]{ null }));
 +        assertRows(execute("SELECT " + fNameIRN + "(empty_int) FROM %s"), row(new Object[]{ null }));
 +        assertRows(execute("SELECT " + fNameICC + "(empty_int) FROM %s"), row(0));
 +        assertRows(execute("SELECT " + fNameICN + "(empty_int) FROM %s"), row(new Object[]{ null }));
 +    }
- 
-     @Test
-     public void testAllNativeTypes() throws Throwable
-     {
-         StringBuilder sig = new StringBuilder();
-         StringBuilder args = new StringBuilder();
-         for (CQL3Type.Native type : CQL3Type.Native.values())
-         {
-             if (type == CQL3Type.Native.EMPTY)
-                 continue;
- 
-             if (sig.length() > 0)
-                 sig.append(',');
-             sig.append(type.toString());
- 
-             if (args.length() > 0)
-                 args.append(',');
-             args.append("arg").append(type.toString()).append(' ').append(type.toString());
-         }
-         createFunction(KEYSPACE, sig.toString(),
-                        "CREATE OR REPLACE FUNCTION %s(" + args + ") " +
-                        "RETURNS NULL ON NULL INPUT " +
-                        "RETURNS int " +
-                        "LANGUAGE JAVA\n" +
-                        "AS 'return 0;'");
- 
-         for (CQL3Type.Native type : CQL3Type.Native.values())
-         {
-             if (type == CQL3Type.Native.EMPTY)
-                 continue;
- 
-             createFunction(KEYSPACE_PER_TEST, type.toString(),
-                            "CREATE OR REPLACE FUNCTION %s(val " + type.toString() + ") " +
-                            "RETURNS NULL ON NULL INPUT " +
-                            "RETURNS int " +
-                            "LANGUAGE JAVA\n" +
-                            "AS 'return 0;'");
-         }
-     }
- 
-     @Test
-     public void testSecurityPermissions() throws Throwable
-     {
-         createTable("CREATE TABLE %s (key int primary key, dval double)");
-         execute("INSERT INTO %s (key, dval) VALUES (?, ?)", 1, 1d);
- 
-         // Java UDFs
- 
-         try
-         {
-             String fName = createFunction(KEYSPACE_PER_TEST, "double",
-                                           "CREATE OR REPLACE FUNCTION %s(val double) " +
-                                           "RETURNS NULL ON NULL INPUT " +
-                                           "RETURNS double " +
-                                           "LANGUAGE JAVA\n" +
-                                           "AS 'System.getProperty(\"foo.bar.baz\"); return 0d;';");
-             execute("SELECT " + fName + "(dval) FROM %s WHERE key=1");
-             Assert.fail();
-         }
-         catch (FunctionExecutionException e)
-         {
-             assertAccessControlException("System.getProperty(\"foo.bar.baz\"); return 0d;", e);
-         }
- 
-         String[][] typesAndSources =
-         {
-         {"",                        "try { Class.forName(\"" + UDHelper.class.getName() + "\"); } catch (Exception e) { throw new RuntimeException(e); } return 0d;"},
-         {"sun.misc.Unsafe",         "sun.misc.Unsafe.getUnsafe(); return 0d;"},
-         {"",                        "try { Class.forName(\"sun.misc.Unsafe\"); } catch (Exception e) { throw new RuntimeException(e); } return 0d;"},
-         {"java.nio.file.FileSystems", "try {" +
-                                     "     java.nio.file.FileSystems.getDefault(); return 0d;" +
-                                     "} catch (Exception t) {" +
-                                     "     throw new RuntimeException(t);" +
-                                     '}'},
-         {"java.nio.channels.FileChannel", "try {" +
-                                     "     java.nio.channels.FileChannel.open(java.nio.file.FileSystems.getDefault().getPath(\"/etc/passwd\")).close(); return 0d;" +
-                                     "} catch (Exception t) {" +
-                                     "     throw new RuntimeException(t);" +
-                                     '}'},
-         {"java.nio.channels.SocketChannel", "try {" +
-                                     "     java.nio.channels.SocketChannel.open().close(); return 0d;" +
-                                     "} catch (Exception t) {" +
-                                     "     throw new RuntimeException(t);" +
-                                     '}'},
-         {"java.io.FileInputStream", "try {" +
-                                     "     new java.io.FileInputStream(\"./foobar\").close(); return 0d;" +
-                                     "} catch (Exception t) {" +
-                                     "     throw new RuntimeException(t);" +
-                                     '}'},
-         {"java.lang.Runtime",       "try {" +
-                                     "     java.lang.Runtime.getRuntime(); return 0d;" +
-                                     "} catch (Exception t) {" +
-                                     "     throw new RuntimeException(t);" +
-                                     '}'},
-         {"org.apache.cassandra.service.StorageService",
-                                     "try {" +
-                                     "     org.apache.cassandra.service.StorageService v = org.apache.cassandra.service.StorageService.instance; v.isShutdown(); return 0d;" +
-                                     "} catch (Exception t) {" +
-                                     "     throw new RuntimeException(t);" +
-                                     '}'},
-         {"java.net.ServerSocket",   "try {" +
-                                     "     new java.net.ServerSocket().bind(); return 0d;" +
-                                     "} catch (Exception t) {" +
-                                     "     throw new RuntimeException(t);" +
-                                     '}'},
-         {"java.io.FileOutputStream","try {" +
-                                     "     new java.io.FileOutputStream(\".foo\"); return 0d;" +
-                                     "} catch (Exception t) {" +
-                                     "     throw new RuntimeException(t);" +
-                                     '}'},
-         {"java.lang.Runtime",       "try {" +
-                                     "     java.lang.Runtime.getRuntime().exec(\"/tmp/foo\"); return 0d;" +
-                                     "} catch (Exception t) {" +
-                                     "     throw new RuntimeException(t);" +
-                                     '}'}
-         };
- 
-         for (String[] typeAndSource : typesAndSources)
-         {
-             assertInvalidMessage(typeAndSource[0] + " cannot be resolved",
-                                  "CREATE OR REPLACE FUNCTION " + KEYSPACE + ".invalid_class_access(val double) " +
-                                  "RETURNS NULL ON NULL INPUT " +
-                                  "RETURNS double " +
-                                  "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.Class.forName(\"java.lang.System\"); 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);
-             }
-         }
-     }
- 
-     private static void assertAccessControlException(String script, FunctionExecutionException e)
-     {
-         for (Throwable t = e; t != null && t != t.getCause(); t = t.getCause())
-             if (t instanceof AccessControlException)
-                 return;
-         Assert.fail("no AccessControlException for " + script + " (got " + e + ')');
-     }
- 
-     @Test
-     public void testAmokUDF() throws Throwable
-     {
-         createTable("CREATE TABLE %s (key int primary key, dval double)");
-         execute("INSERT INTO %s (key, dval) VALUES (?, ?)", 1, 1d);
- 
-         long udfWarnTimeout = DatabaseDescriptor.getUserDefinedFunctionWarnTimeout();
-         long udfFailTimeout = DatabaseDescriptor.getUserDefinedFunctionFailTimeout();
-         int maxTries = 5;
-         for (int i = 1; i <= maxTries; i++)
-         {
-             try
-             {
-                 // short timeout
-                 DatabaseDescriptor.setUserDefinedFunctionWarnTimeout(10);
-                 DatabaseDescriptor.setUserDefinedFunctionFailTimeout(250);
-                 // don't kill the unit test... - default policy is "die"
-                 DatabaseDescriptor.setUserFunctionTimeoutPolicy(Config.UserFunctionTimeoutPolicy.ignore);
- 
-                 ClientWarn.instance.captureWarnings();
-                 String fName = createFunction(KEYSPACE_PER_TEST, "double",
-                                               "CREATE OR REPLACE FUNCTION %s(val double) " +
-                                               "RETURNS NULL ON NULL INPUT " +
-                                               "RETURNS double " +
-                                               "LANGUAGE JAVA\n" +
-                                               "AS 'long t=System.currentTimeMillis()+110; while (t>System.currentTimeMillis()) { }; return 0d;'");
-                 execute("SELECT " + fName + "(dval) FROM %s WHERE key=1");
-                 List<String> warnings = ClientWarn.instance.getWarnings();
-                 Assert.assertNotNull(warnings);
-                 Assert.assertFalse(warnings.isEmpty());
-                 ClientWarn.instance.resetWarnings();
- 
-                 // Java UDF
- 
-                 fName = createFunction(KEYSPACE_PER_TEST, "double",
-                                        "CREATE OR REPLACE FUNCTION %s(val double) " +
-                                        "RETURNS NULL ON NULL INPUT " +
-                                        "RETURNS double " +
-                                        "LANGUAGE JAVA\n" +
-                                        "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)
-             {
-                 if (i == maxTries)
-                     throw e;
-             }
-             finally
-             {
-                 // reset to defaults
-                 DatabaseDescriptor.setUserDefinedFunctionWarnTimeout(udfWarnTimeout);
-                 DatabaseDescriptor.setUserDefinedFunctionFailTimeout(udfFailTimeout);
-             }
-         }
-     }
  }


Mime
View raw message