mirror of https://github.com/apache/cassandra
Merge branch cassandra-3.0 into cassandra-3.11
This commit is contained in:
commit
ec5e242998
|
|
@ -144,8 +144,6 @@ public abstract class CQLTester
|
|||
}
|
||||
}
|
||||
|
||||
public static ResultMessage lastSchemaChangeResult;
|
||||
|
||||
private List<String> keyspaces = new ArrayList<>();
|
||||
private List<String> tables = new ArrayList<>();
|
||||
private List<String> types = new ArrayList<>();
|
||||
|
|
@ -590,24 +588,46 @@ public abstract class CQLTester
|
|||
return typeName;
|
||||
}
|
||||
|
||||
protected String createFunctionName(String keyspace)
|
||||
{
|
||||
return String.format("%s.function_%02d", keyspace, seqNumber.getAndIncrement());
|
||||
}
|
||||
|
||||
protected void registerFunction(String functionName, String argTypes)
|
||||
{
|
||||
functions.add(functionName + '(' + argTypes + ')');
|
||||
}
|
||||
|
||||
protected String createFunction(String keyspace, String argTypes, String query) throws Throwable
|
||||
{
|
||||
String functionName = keyspace + ".function_" + seqNumber.getAndIncrement();
|
||||
String functionName = createFunctionName(keyspace);
|
||||
|
||||
createFunctionOverload(functionName, argTypes, query);
|
||||
return functionName;
|
||||
}
|
||||
|
||||
protected void createFunctionOverload(String functionName, String argTypes, String query) throws Throwable
|
||||
{
|
||||
registerFunction(functionName, argTypes);
|
||||
String fullQuery = String.format(query, functionName);
|
||||
functions.add(functionName + '(' + argTypes + ')');
|
||||
logger.info(fullQuery);
|
||||
schemaChange(fullQuery);
|
||||
}
|
||||
|
||||
protected String createAggregateName(String keyspace)
|
||||
{
|
||||
return String.format("%s.aggregate_%02d", keyspace, seqNumber.getAndIncrement());
|
||||
}
|
||||
|
||||
protected void registerAggregate(String aggregateName, String argTypes)
|
||||
{
|
||||
aggregates.add(aggregateName + '(' + argTypes + ')');
|
||||
}
|
||||
|
||||
protected String createAggregate(String keyspace, String argTypes, String query) throws Throwable
|
||||
{
|
||||
String aggregateName = keyspace + "." + "aggregate_" + seqNumber.getAndIncrement();
|
||||
String aggregateName = createAggregateName(keyspace);
|
||||
|
||||
createAggregateOverload(aggregateName, argTypes, query);
|
||||
return aggregateName;
|
||||
}
|
||||
|
|
@ -615,7 +635,7 @@ public abstract class CQLTester
|
|||
protected void createAggregateOverload(String aggregateName, String argTypes, String query) throws Throwable
|
||||
{
|
||||
String fullQuery = String.format(query, aggregateName);
|
||||
aggregates.add(aggregateName + '(' + argTypes + ')');
|
||||
registerAggregate(aggregateName, argTypes);
|
||||
logger.info(fullQuery);
|
||||
schemaChange(fullQuery);
|
||||
}
|
||||
|
|
@ -745,20 +765,24 @@ public abstract class CQLTester
|
|||
schemaChange(fullQuery);
|
||||
}
|
||||
|
||||
protected void assertLastSchemaChange(Event.SchemaChange.Change change, Event.SchemaChange.Target target,
|
||||
String keyspace, String name,
|
||||
String... argTypes)
|
||||
protected static void assertSchemaChange(String query,
|
||||
Event.SchemaChange.Change expectedChange,
|
||||
Event.SchemaChange.Target expectedTarget,
|
||||
String expectedKeyspace,
|
||||
String expectedName,
|
||||
String... expectedArgTypes)
|
||||
{
|
||||
Assert.assertTrue(lastSchemaChangeResult instanceof ResultMessage.SchemaChange);
|
||||
ResultMessage.SchemaChange schemaChange = (ResultMessage.SchemaChange) lastSchemaChangeResult;
|
||||
Assert.assertSame(change, schemaChange.change.change);
|
||||
Assert.assertSame(target, schemaChange.change.target);
|
||||
Assert.assertEquals(keyspace, schemaChange.change.keyspace);
|
||||
Assert.assertEquals(name, schemaChange.change.name);
|
||||
Assert.assertEquals(argTypes != null ? Arrays.asList(argTypes) : null, schemaChange.change.argTypes);
|
||||
ResultMessage actual = schemaChange(query);
|
||||
Assert.assertTrue(actual instanceof ResultMessage.SchemaChange);
|
||||
Event.SchemaChange schemaChange = ((ResultMessage.SchemaChange) actual).change;
|
||||
Assert.assertSame(expectedChange, schemaChange.change);
|
||||
Assert.assertSame(expectedTarget, schemaChange.target);
|
||||
Assert.assertEquals(expectedKeyspace, schemaChange.keyspace);
|
||||
Assert.assertEquals(expectedName, schemaChange.name);
|
||||
Assert.assertEquals(expectedArgTypes != null ? Arrays.asList(expectedArgTypes) : null, schemaChange.argTypes);
|
||||
}
|
||||
|
||||
protected static void schemaChange(String query)
|
||||
protected static ResultMessage schemaChange(String query)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -771,7 +795,7 @@ public abstract class CQLTester
|
|||
|
||||
QueryOptions options = QueryOptions.forInternalCalls(Collections.<ByteBuffer>emptyList());
|
||||
|
||||
lastSchemaChangeResult = prepared.statement.executeInternal(queryState, options);
|
||||
return prepared.statement.executeInternal(queryState, options);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ import org.apache.cassandra.exceptions.InvalidRequestException;
|
|||
import org.apache.cassandra.exceptions.SyntaxException;
|
||||
import org.apache.cassandra.schema.KeyspaceMetadata;
|
||||
import org.apache.cassandra.service.ClientState;
|
||||
import org.apache.cassandra.transport.*;
|
||||
import org.apache.cassandra.transport.Event.SchemaChange.Change;
|
||||
import org.apache.cassandra.transport.Event.SchemaChange.Target;
|
||||
import org.apache.cassandra.transport.ProtocolVersion;
|
||||
import org.apache.cassandra.transport.messages.ResultMessage;
|
||||
|
||||
|
|
@ -71,58 +72,59 @@ public class UFTest extends CQLTester
|
|||
@Test
|
||||
public void testSchemaChange() throws Throwable
|
||||
{
|
||||
String f = createFunction(KEYSPACE,
|
||||
"double, double",
|
||||
"CREATE OR REPLACE FUNCTION %s(state double, val double) " +
|
||||
"RETURNS NULL ON NULL INPUT " +
|
||||
"RETURNS double " +
|
||||
"LANGUAGE javascript " +
|
||||
"AS '\"string\";';");
|
||||
String f = createFunctionName(KEYSPACE);
|
||||
String functionName = shortFunctionName(f);
|
||||
registerFunction(f, "double, double");
|
||||
|
||||
assertLastSchemaChange(Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.FUNCTION,
|
||||
KEYSPACE, parseFunctionName(f).name,
|
||||
"double", "double");
|
||||
assertSchemaChange("CREATE OR REPLACE FUNCTION " + f + "(state double, val double) " +
|
||||
"RETURNS NULL ON NULL INPUT " +
|
||||
"RETURNS double " +
|
||||
"LANGUAGE javascript " +
|
||||
"AS '\"string\";';",
|
||||
Change.CREATED,
|
||||
Target.FUNCTION,
|
||||
KEYSPACE, functionName,
|
||||
"double", "double");
|
||||
|
||||
createFunctionOverload(f,
|
||||
"double, double",
|
||||
"CREATE OR REPLACE FUNCTION %s(state int, val int) " +
|
||||
"RETURNS NULL ON NULL INPUT " +
|
||||
"RETURNS int " +
|
||||
"LANGUAGE javascript " +
|
||||
"AS '\"string\";';");
|
||||
registerFunction(f, "int, int");
|
||||
|
||||
assertLastSchemaChange(Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.FUNCTION,
|
||||
KEYSPACE, parseFunctionName(f).name,
|
||||
"int", "int");
|
||||
assertSchemaChange("CREATE OR REPLACE FUNCTION " + f + "(state int, val int) " +
|
||||
"RETURNS NULL ON NULL INPUT " +
|
||||
"RETURNS int " +
|
||||
"LANGUAGE javascript " +
|
||||
"AS '\"string\";';",
|
||||
Change.CREATED,
|
||||
Target.FUNCTION,
|
||||
KEYSPACE, functionName,
|
||||
"int", "int");
|
||||
|
||||
schemaChange("CREATE OR REPLACE FUNCTION " + f + "(state int, val int) " +
|
||||
"RETURNS NULL ON NULL INPUT " +
|
||||
"RETURNS int " +
|
||||
"LANGUAGE javascript " +
|
||||
"AS '\"string\";';");
|
||||
assertSchemaChange("CREATE OR REPLACE FUNCTION " + f + "(state int, val int) " +
|
||||
"RETURNS NULL ON NULL INPUT " +
|
||||
"RETURNS int " +
|
||||
"LANGUAGE javascript " +
|
||||
"AS '\"string1\";';",
|
||||
Change.UPDATED,
|
||||
Target.FUNCTION,
|
||||
KEYSPACE, functionName,
|
||||
"int", "int");
|
||||
|
||||
assertLastSchemaChange(Event.SchemaChange.Change.UPDATED, Event.SchemaChange.Target.FUNCTION,
|
||||
KEYSPACE, parseFunctionName(f).name,
|
||||
"int", "int");
|
||||
|
||||
schemaChange("DROP FUNCTION " + f + "(double, double)");
|
||||
|
||||
assertLastSchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.FUNCTION,
|
||||
KEYSPACE, parseFunctionName(f).name,
|
||||
"double", "double");
|
||||
assertSchemaChange("DROP FUNCTION " + f + "(double, double)",
|
||||
Change.DROPPED, Target.FUNCTION,
|
||||
KEYSPACE, functionName,
|
||||
"double", "double");
|
||||
|
||||
// The function with nested tuple should be created without throwing InvalidRequestException. See CASSANDRA-15857
|
||||
String f1 = createFunction(KEYSPACE,
|
||||
"list<tuple<int, int>>, double",
|
||||
"CREATE OR REPLACE FUNCTION %s(state list<tuple<int, int>>, val double) " +
|
||||
"RETURNS NULL ON NULL INPUT " +
|
||||
"RETURNS double " +
|
||||
"LANGUAGE javascript " +
|
||||
"AS '\"string\";';");
|
||||
String fl = createFunctionName(KEYSPACE);
|
||||
registerFunction(fl, "list<tuple<int, int>>, double");
|
||||
|
||||
assertLastSchemaChange(Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.FUNCTION,
|
||||
KEYSPACE, parseFunctionName(f1).name,
|
||||
"list<frozen<tuple<int, int>>>", "double"); // CASSANDRA-14825: remove frozen from param
|
||||
assertSchemaChange("CREATE OR REPLACE FUNCTION " + fl + "(state list<tuple<int, int>>, val double) " +
|
||||
"RETURNS NULL ON NULL INPUT " +
|
||||
"RETURNS double " +
|
||||
"LANGUAGE javascript " +
|
||||
"AS '\"string\";';",
|
||||
Change.CREATED, Target.FUNCTION,
|
||||
KEYSPACE, shortFunctionName(fl),
|
||||
"list<frozen<tuple<int, int>>>", "double");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ import org.junit.Test;
|
|||
import com.datastax.driver.core.Row;
|
||||
import org.apache.cassandra.cql3.CQLTester;
|
||||
import org.apache.cassandra.cql3.UntypedResultSet;
|
||||
import org.apache.cassandra.transport.Event;
|
||||
import org.apache.cassandra.transport.Event.SchemaChange.Change;
|
||||
import org.apache.cassandra.transport.Event.SchemaChange.Target;
|
||||
import org.apache.cassandra.transport.ProtocolVersion;
|
||||
import org.apache.cassandra.utils.UUIDGen;
|
||||
|
||||
|
|
@ -463,10 +464,10 @@ public class UFTypesTest extends CQLTester
|
|||
"LANGUAGE java\n" +
|
||||
"AS 'return values;';");
|
||||
// Same as above, dropping a function with explicity frozen tuple should be allowed.
|
||||
schemaChange("DROP FUNCTION " + toDrop + "(frozen<tuple<int, int>>);");
|
||||
assertLastSchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.FUNCTION,
|
||||
KEYSPACE, shortFunctionName(toDrop),
|
||||
"frozen<tuple<int, int>>");
|
||||
assertSchemaChange("DROP FUNCTION " + toDrop + "(frozen<tuple<int, int>>);",
|
||||
Change.DROPPED, Target.FUNCTION,
|
||||
KEYSPACE, shortFunctionName(toDrop),
|
||||
"frozen<tuple<int, int>>");
|
||||
|
||||
String functionName = createFunction(KEYSPACE,
|
||||
"tuple<int, int>",
|
||||
|
|
@ -492,10 +493,11 @@ public class UFTypesTest extends CQLTester
|
|||
assertRows(execute("SELECT a FROM %s WHERE b = " + functionName + "(?)", tuple(1, 2)),
|
||||
row(1));
|
||||
|
||||
schemaChange("DROP FUNCTION " + functionName + "(frozen<tuple<int, int>>);");
|
||||
assertLastSchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.FUNCTION,
|
||||
KEYSPACE, shortFunctionName(functionName),
|
||||
"frozen<tuple<int, int>>");
|
||||
assertSchemaChange("DROP FUNCTION " + functionName + "(frozen<tuple<int, int>>);",
|
||||
Change.DROPPED,
|
||||
Target.FUNCTION,
|
||||
KEYSPACE, shortFunctionName(functionName),
|
||||
"frozen<tuple<int, int>>");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -55,6 +55,8 @@ import org.apache.cassandra.exceptions.InvalidRequestException;
|
|||
import org.apache.cassandra.schema.KeyspaceMetadata;
|
||||
import org.apache.cassandra.service.ClientState;
|
||||
import org.apache.cassandra.transport.Event;
|
||||
import org.apache.cassandra.transport.Event.SchemaChange.Change;
|
||||
import org.apache.cassandra.transport.Event.SchemaChange.Target;
|
||||
import org.apache.cassandra.transport.ProtocolVersion;
|
||||
import org.apache.cassandra.transport.messages.ResultMessage;
|
||||
|
||||
|
|
@ -423,42 +425,40 @@ public class AggregationTest extends CQLTester
|
|||
"LANGUAGE javascript " +
|
||||
"AS '\"string\";';");
|
||||
|
||||
String a = createAggregate(KEYSPACE,
|
||||
"double",
|
||||
"CREATE OR REPLACE AGGREGATE %s(double) " +
|
||||
"SFUNC " + shortFunctionName(f) + " " +
|
||||
"STYPE double " +
|
||||
"INITCOND 0");
|
||||
String a = createAggregateName(KEYSPACE);
|
||||
String aggregateName = shortFunctionName(a);
|
||||
registerAggregate(a, "double");
|
||||
|
||||
assertLastSchemaChange(Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.AGGREGATE,
|
||||
KEYSPACE, parseFunctionName(a).name,
|
||||
"double");
|
||||
assertSchemaChange("CREATE OR REPLACE AGGREGATE " + a + "(double) " +
|
||||
"SFUNC " + shortFunctionName(f) + " " +
|
||||
"STYPE double " +
|
||||
"INITCOND 0",
|
||||
Change.CREATED, Target.AGGREGATE,
|
||||
KEYSPACE, aggregateName,
|
||||
"double");
|
||||
|
||||
schemaChange("CREATE OR REPLACE AGGREGATE " + a + "(double) " +
|
||||
"SFUNC " + shortFunctionName(f) + " " +
|
||||
"STYPE double " +
|
||||
"INITCOND 0");
|
||||
assertSchemaChange("CREATE OR REPLACE AGGREGATE " + a + "(double) " +
|
||||
"SFUNC " + shortFunctionName(f) + " " +
|
||||
"STYPE double " +
|
||||
"INITCOND 1",
|
||||
Change.UPDATED, Target.AGGREGATE,
|
||||
KEYSPACE, aggregateName,
|
||||
"double");
|
||||
|
||||
assertLastSchemaChange(Event.SchemaChange.Change.UPDATED, Event.SchemaChange.Target.AGGREGATE,
|
||||
KEYSPACE, parseFunctionName(a).name,
|
||||
"double");
|
||||
registerAggregate(a, "int");
|
||||
|
||||
createAggregateOverload(a,
|
||||
"int",
|
||||
"CREATE OR REPLACE AGGREGATE %s(int) " +
|
||||
"SFUNC " + shortFunctionName(f) + " " +
|
||||
"STYPE int " +
|
||||
"INITCOND 0");
|
||||
assertSchemaChange("CREATE OR REPLACE AGGREGATE " + a + "(int) " +
|
||||
"SFUNC " + shortFunctionName(f) + " " +
|
||||
"STYPE int " +
|
||||
"INITCOND 0",
|
||||
Change.CREATED, Target.AGGREGATE,
|
||||
KEYSPACE, aggregateName,
|
||||
"int");
|
||||
|
||||
assertLastSchemaChange(Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.AGGREGATE,
|
||||
KEYSPACE, parseFunctionName(a).name,
|
||||
"int");
|
||||
|
||||
schemaChange("DROP AGGREGATE " + a + "(double)");
|
||||
|
||||
assertLastSchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.AGGREGATE,
|
||||
KEYSPACE, parseFunctionName(a).name,
|
||||
"double");
|
||||
assertSchemaChange("DROP AGGREGATE " + a + "(double)",
|
||||
Change.DROPPED, Target.AGGREGATE,
|
||||
KEYSPACE, aggregateName,
|
||||
"double");
|
||||
|
||||
// The aggregate with nested tuple should be created without throwing InvalidRequestException. See CASSANDRA-15857
|
||||
String f1 = createFunction(KEYSPACE,
|
||||
|
|
@ -469,16 +469,16 @@ public class AggregationTest extends CQLTester
|
|||
"LANGUAGE javascript " +
|
||||
"AS '\"string\";';");
|
||||
|
||||
String a1 = createAggregate(KEYSPACE,
|
||||
"list<tuple<int, int>>",
|
||||
"CREATE OR REPLACE AGGREGATE %s(list<tuple<int, int>>) " +
|
||||
"SFUNC " + shortFunctionName(f1) + " " +
|
||||
"STYPE double " +
|
||||
"INITCOND 0");
|
||||
String a1 = createAggregateName(KEYSPACE);
|
||||
registerAggregate(a1, "list<tuple<int, int>>");
|
||||
|
||||
assertLastSchemaChange(Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.AGGREGATE,
|
||||
KEYSPACE, parseFunctionName(a1).name,
|
||||
"list<frozen<tuple<int, int>>>"); // CASSANDRA-14825: remove frozen from param
|
||||
assertSchemaChange("CREATE OR REPLACE AGGREGATE " + a1 + "(list<tuple<int, int>>) " +
|
||||
"SFUNC " + shortFunctionName(f1) + " " +
|
||||
"STYPE double " +
|
||||
"INITCOND 0",
|
||||
Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.AGGREGATE,
|
||||
KEYSPACE, parseFunctionName(a1).name,
|
||||
"list<frozen<tuple<int, int>>>"); // CASSANDRA-14825: remove frozen from param
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -1648,10 +1648,10 @@ public class AggregationTest extends CQLTester
|
|||
"FINALFUNC " + parseFunctionName(fFinal).name + ' ' +
|
||||
"INITCOND null");
|
||||
// Same as above, dropping a function with explicity frozen tuple should be allowed.
|
||||
schemaChange("DROP AGGREGATE " + toDrop + "(frozen<tuple<int, int>>);");
|
||||
assertLastSchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.AGGREGATE,
|
||||
KEYSPACE, shortFunctionName(toDrop),
|
||||
"frozen<tuple<int, int>>");
|
||||
assertSchemaChange("DROP AGGREGATE " + toDrop + "(frozen<tuple<int, int>>);",
|
||||
Change.DROPPED, Target.AGGREGATE,
|
||||
KEYSPACE, shortFunctionName(toDrop),
|
||||
"frozen<tuple<int, int>>");
|
||||
|
||||
String aggregation = createAggregate(KEYSPACE,
|
||||
"tuple<int, int>",
|
||||
|
|
@ -1664,10 +1664,10 @@ public class AggregationTest extends CQLTester
|
|||
assertRows(execute("SELECT " + aggregation + "(b) FROM %s"),
|
||||
row(tuple(7, 8)));
|
||||
|
||||
schemaChange("DROP AGGREGATE " + aggregation + "(frozen<tuple<int, int>>);");
|
||||
assertLastSchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.AGGREGATE,
|
||||
KEYSPACE, shortFunctionName(aggregation),
|
||||
"frozen<tuple<int, int>>");
|
||||
assertSchemaChange("DROP AGGREGATE " + aggregation + "(frozen<tuple<int, int>>);",
|
||||
Change.DROPPED, Target.AGGREGATE,
|
||||
KEYSPACE, shortFunctionName(aggregation),
|
||||
"frozen<tuple<int, int>>");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Reference in New Issue