use of org.apache.cassandra.cql3.QueryProcessor in project cassandra by apache.
the class ReprepareTestOldBehaviour method testReprepareMixedVersionWithoutReset.
@Test
public void testReprepareMixedVersionWithoutReset() throws Throwable {
try (ICluster<IInvokableInstance> c = init(builder().withNodes(2).withConfig(config -> config.with(GOSSIP, NETWORK, NATIVE_PROTOCOL)).withInstanceInitializer(PrepareBehaviour::oldBehaviour).start())) {
ForceHostLoadBalancingPolicy lbp = new ForceHostLoadBalancingPolicy();
c.schemaChange(withKeyspace("CREATE TABLE %s.tbl (pk int, ck int, v int, PRIMARY KEY (pk, ck));"));
// 1 has old behaviour
for (int firstContact : new int[] { 1, 2 }) {
for (boolean withUse : new boolean[] { true, false }) {
for (boolean clearBetweenExecutions : new boolean[] { true, false }) {
try (com.datastax.driver.core.Cluster cluster = com.datastax.driver.core.Cluster.builder().addContactPoint("127.0.0.1").addContactPoint("127.0.0.2").withLoadBalancingPolicy(lbp).build();
Session session = cluster.connect()) {
if (withUse)
session.execute(withKeyspace("USE %s"));
lbp.setPrimary(firstContact);
final PreparedStatement select = session.prepare(withKeyspace("SELECT * FROM %s.tbl"));
session.execute(select.bind());
if (clearBetweenExecutions)
c.get(2).runOnInstance(QueryProcessor::clearPreparedStatementsCache);
lbp.setPrimary(firstContact == 1 ? 2 : 1);
session.execute(select.bind());
if (clearBetweenExecutions)
c.get(2).runOnInstance(QueryProcessor::clearPreparedStatementsCache);
lbp.setPrimary(firstContact);
session.execute(select.bind());
c.get(2).runOnInstance(QueryProcessor::clearPreparedStatementsCache);
}
}
}
}
}
}
use of org.apache.cassandra.cql3.QueryProcessor in project cassandra by apache.
the class UFTest method testFunctionDropPreparedStatement.
@Test
public void testFunctionDropPreparedStatement() throws Throwable {
createTable("CREATE TABLE %s (key int PRIMARY KEY, d double)");
String fSin = createFunction(KEYSPACE_PER_TEST, "double", "CREATE FUNCTION %s ( input double ) " + "CALLED ON NULL INPUT " + "RETURNS double " + "LANGUAGE java " + "AS 'return Double.valueOf(Math.sin(input.doubleValue()));'");
FunctionName fSinName = parseFunctionName(fSin);
Assert.assertEquals(1, Schema.instance.getFunctions(parseFunctionName(fSin)).size());
// create a pairs of Select and Inserts. One statement in each pair uses the function so when we
// drop it those statements should be removed from the cache in QueryProcessor. The other statements
// should be unaffected.
ResultMessage.Prepared preparedSelect1 = QueryProcessor.instance.prepare(String.format("SELECT key, %s(d) FROM %s.%s", fSin, KEYSPACE, currentTable()), ClientState.forInternalCalls());
ResultMessage.Prepared preparedSelect2 = QueryProcessor.instance.prepare(String.format("SELECT key FROM %s.%s", KEYSPACE, currentTable()), ClientState.forInternalCalls());
ResultMessage.Prepared preparedInsert1 = QueryProcessor.instance.prepare(String.format("INSERT INTO %s.%s (key, d) VALUES (?, %s(?))", KEYSPACE, currentTable(), fSin), ClientState.forInternalCalls());
ResultMessage.Prepared preparedInsert2 = QueryProcessor.instance.prepare(String.format("INSERT INTO %s.%s (key, d) VALUES (?, ?)", KEYSPACE, currentTable()), ClientState.forInternalCalls());
Assert.assertNotNull(QueryProcessor.instance.getPrepared(preparedSelect1.statementId));
Assert.assertNotNull(QueryProcessor.instance.getPrepared(preparedSelect2.statementId));
Assert.assertNotNull(QueryProcessor.instance.getPrepared(preparedInsert1.statementId));
Assert.assertNotNull(QueryProcessor.instance.getPrepared(preparedInsert2.statementId));
execute("DROP FUNCTION " + fSin + "(double);");
// the statements which use the dropped function should be removed from cache, with the others remaining
Assert.assertNull(QueryProcessor.instance.getPrepared(preparedSelect1.statementId));
Assert.assertNotNull(QueryProcessor.instance.getPrepared(preparedSelect2.statementId));
Assert.assertNull(QueryProcessor.instance.getPrepared(preparedInsert1.statementId));
Assert.assertNotNull(QueryProcessor.instance.getPrepared(preparedInsert2.statementId));
execute("CREATE FUNCTION " + fSin + " ( input double ) " + "RETURNS NULL ON NULL INPUT " + "RETURNS double " + "LANGUAGE java " + "AS 'return Double.valueOf(Math.sin(input));'");
Assert.assertEquals(1, Schema.instance.getFunctions(fSinName).size());
preparedSelect1 = QueryProcessor.instance.prepare(String.format("SELECT key, %s(d) FROM %s.%s", fSin, KEYSPACE, currentTable()), ClientState.forInternalCalls());
preparedInsert1 = QueryProcessor.instance.prepare(String.format("INSERT INTO %s.%s (key, d) VALUES (?, %s(?))", KEYSPACE, currentTable(), fSin), ClientState.forInternalCalls());
Assert.assertNotNull(QueryProcessor.instance.getPrepared(preparedSelect1.statementId));
Assert.assertNotNull(QueryProcessor.instance.getPrepared(preparedInsert1.statementId));
dropPerTestKeyspace();
// again, only the 2 statements referencing the function should be removed from cache
// this time because the statements select from tables in KEYSPACE, only the function
// is scoped to KEYSPACE_PER_TEST
Assert.assertNull(QueryProcessor.instance.getPrepared(preparedSelect1.statementId));
Assert.assertNotNull(QueryProcessor.instance.getPrepared(preparedSelect2.statementId));
Assert.assertNull(QueryProcessor.instance.getPrepared(preparedInsert1.statementId));
Assert.assertNotNull(QueryProcessor.instance.getPrepared(preparedInsert2.statementId));
}
use of org.apache.cassandra.cql3.QueryProcessor in project cassandra by apache.
the class ReprepareFuzzTest method fuzzTest.
@Test
public void fuzzTest() throws Throwable {
try (ICluster<IInvokableInstance> c = builder().withNodes(1).withConfig(config -> config.with(GOSSIP, NETWORK, NATIVE_PROTOCOL)).withInstanceInitializer(PrepareBehaviour::alwaysNewBehaviour).start()) {
// Long string to make us invalidate caches occasionally
String veryLongString = "very";
for (int i = 0; i < 2; i++) veryLongString += veryLongString;
final String qualified = "SELECT pk as " + veryLongString + "%d, ck as " + veryLongString + "%d FROM ks%d.tbl";
final String unqualified = "SELECT pk as " + veryLongString + "%d, ck as " + veryLongString + "%d FROM tbl";
int KEYSPACES = 3;
final int STATEMENTS_PER_KS = 3;
for (int i = 0; i < KEYSPACES; i++) {
c.schemaChange(withKeyspace("CREATE KEYSPACE ks" + i + " WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};"));
c.schemaChange(withKeyspace("CREATE TABLE ks" + i + ".tbl (pk int, ck int, PRIMARY KEY (pk, ck));"));
for (int j = 0; j < i; j++) c.coordinator(1).execute("INSERT INTO ks" + i + ".tbl (pk, ck) VALUES (?, ?)", ConsistencyLevel.QUORUM, 1, j);
}
List<Thread> threads = new ArrayList<>();
AtomicBoolean interrupt = new AtomicBoolean(false);
AtomicReference<Throwable> thrown = new AtomicReference<>();
int INFREQUENT_ACTION_COEF = 10;
long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(60);
for (int i = 0; i < FBUtilities.getAvailableProcessors() * 2; i++) {
int seed = i;
threads.add(new Thread(() -> {
com.datastax.driver.core.Cluster cluster = null;
Session session = null;
try {
Random rng = new Random(seed);
int usedKsIdx = -1;
String usedKs = null;
Map<Pair<Integer, Integer>, PreparedStatement> qualifiedStatements = new HashMap<>();
Map<Pair<Integer, Integer>, PreparedStatement> unqualifiedStatements = new HashMap<>();
cluster = com.datastax.driver.core.Cluster.builder().addContactPoint("127.0.0.1").build();
session = cluster.connect();
while (!interrupt.get() && (System.nanoTime() < deadline)) {
final int ks = rng.nextInt(KEYSPACES);
final int statementIdx = rng.nextInt(STATEMENTS_PER_KS);
final Pair<Integer, Integer> statementId = Pair.create(ks, statementIdx);
int v = rng.nextInt(INFREQUENT_ACTION_COEF + 1);
Action[] pool;
if (v == INFREQUENT_ACTION_COEF)
pool = infrequent;
else
pool = frequent;
Action action = pool[rng.nextInt(pool.length)];
switch(action) {
case EXECUTE_QUALIFIED:
if (!qualifiedStatements.containsKey(statementId))
continue;
try {
int counter = 0;
for (Iterator<Object[]> iter = RowUtil.toObjects(session.execute(qualifiedStatements.get(statementId).bind())); iter.hasNext(); ) {
Object[] current = iter.next();
int v0 = (int) current[0];
int v1 = (int) current[1];
Assert.assertEquals(v0, 1);
Assert.assertEquals(v1, counter++);
}
Assert.assertEquals(ks, counter);
} catch (Throwable t) {
if (t.getCause() != null && t.getCause().getMessage().contains("Statement was prepared on keyspace"))
continue;
throw t;
}
break;
case EXECUTE_UNQUALIFIED:
if (!unqualifiedStatements.containsKey(statementId))
continue;
try {
int counter = 0;
for (Iterator<Object[]> iter = RowUtil.toObjects(session.execute(unqualifiedStatements.get(statementId).bind())); iter.hasNext(); ) {
Object[] current = iter.next();
int v0 = (int) current[0];
int v1 = (int) current[1];
Assert.assertEquals(v0, 1);
Assert.assertEquals(v1, counter++);
}
Assert.assertEquals(unqualifiedStatements.get(statementId).getQueryKeyspace() + " " + usedKs + " " + statementId, Integer.parseInt(unqualifiedStatements.get(statementId).getQueryKeyspace().replace("ks", "")), counter);
} catch (Throwable t) {
if (t.getCause() != null && t.getCause().getMessage().contains("Statement was prepared on keyspace"))
continue;
throw t;
}
break;
case PREPARE_QUALIFIED:
{
String qs = String.format(qualified, statementIdx, statementIdx, ks);
String keyspace = "ks" + ks;
PreparedStatement preparedQualified = session.prepare(qs);
// With prepared qualified, keyspace will be set to the keyspace of the statement when it was first executed
PreparedStatementHelper.assertHashWithoutKeyspace(preparedQualified, qs, keyspace);
qualifiedStatements.put(statementId, preparedQualified);
}
break;
case PREPARE_UNQUALIFIED:
try {
String qs = String.format(unqualified, statementIdx, statementIdx, ks);
PreparedStatement preparedUnqalified = session.prepare(qs);
Assert.assertEquals(preparedUnqalified.getQueryKeyspace(), usedKs);
PreparedStatementHelper.assertHashWithKeyspace(preparedUnqalified, qs, usedKs);
unqualifiedStatements.put(Pair.create(usedKsIdx, statementIdx), preparedUnqalified);
} catch (InvalidQueryException iqe) {
if (!iqe.getMessage().contains("No keyspace has been"))
throw iqe;
} catch (Throwable t) {
if (usedKs == null) {
// ignored
continue;
}
throw t;
}
break;
case CLEAR_CACHES:
c.get(1).runOnInstance(() -> {
SystemKeyspace.loadPreparedStatements((id, query, keyspace) -> {
if (rng.nextBoolean())
QueryProcessor.instance.evictPrepared(id);
return true;
});
});
break;
case RELOAD_FROM_TABLES:
c.get(1).runOnInstance(QueryProcessor::clearPreparedStatementsCache);
c.get(1).runOnInstance(() -> QueryProcessor.instance.preloadPreparedStatements());
break;
case SWITCH_KEYSPACE:
usedKsIdx = ks;
usedKs = "ks" + ks;
session.execute("USE " + usedKs);
break;
case FORGET_PREPARED:
Map<Pair<Integer, Integer>, PreparedStatement> toCleanup = rng.nextBoolean() ? qualifiedStatements : unqualifiedStatements;
Set<Pair<Integer, Integer>> toDrop = new HashSet<>();
for (Pair<Integer, Integer> e : toCleanup.keySet()) {
if (rng.nextBoolean())
toDrop.add(e);
}
for (Pair<Integer, Integer> e : toDrop) toCleanup.remove(e);
toDrop.clear();
break;
case RECONNECT:
session.close();
cluster.close();
cluster = com.datastax.driver.core.Cluster.builder().addContactPoint("127.0.0.1").build();
session = cluster.connect();
qualifiedStatements.clear();
unqualifiedStatements.clear();
usedKs = null;
usedKsIdx = -1;
break;
}
}
} catch (Throwable t) {
interrupt.set(true);
t.printStackTrace();
while (true) {
Throwable seen = thrown.get();
Throwable merged = Throwables.merge(seen, t);
if (thrown.compareAndSet(seen, merged))
break;
}
throw t;
} finally {
if (session != null)
session.close();
if (cluster != null)
cluster.close();
}
}));
}
for (Thread thread : threads) thread.start();
for (Thread thread : threads) thread.join();
if (thrown.get() != null)
throw thrown.get();
}
}
use of org.apache.cassandra.cql3.QueryProcessor in project cassandra by apache.
the class ReprepareTestBase method testReprepareTwoKeyspaces.
public void testReprepareTwoKeyspaces(BiConsumer<ClassLoader, Integer> instanceInitializer) throws Throwable {
try (ICluster<IInvokableInstance> c = init(builder().withNodes(2).withConfig(config -> config.with(GOSSIP, NETWORK, NATIVE_PROTOCOL)).withInstanceInitializer(instanceInitializer).start())) {
c.schemaChange(withKeyspace("CREATE KEYSPACE %s2 WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 2};"));
c.schemaChange(withKeyspace("CREATE TABLE %s.tbl (pk int, ck int, v int, PRIMARY KEY (pk, ck));"));
ForceHostLoadBalancingPolicy lbp = new ForceHostLoadBalancingPolicy();
for (int firstContact : new int[] { 1, 2 }) try (com.datastax.driver.core.Cluster cluster = com.datastax.driver.core.Cluster.builder().addContactPoint("127.0.0.1").addContactPoint("127.0.0.2").withLoadBalancingPolicy(lbp).build();
Session session = cluster.connect()) {
{
session.execute(withKeyspace("USE %s"));
c.stream().forEach((i) -> i.runOnInstance(QueryProcessor::clearPreparedStatementsCache));
lbp.setPrimary(firstContact);
final PreparedStatement select = session.prepare(withKeyspace("SELECT * FROM %s.tbl"));
session.execute(select.bind());
c.stream().forEach((i) -> i.runOnInstance(QueryProcessor::clearPreparedStatementsCache));
lbp.setPrimary(firstContact == 1 ? 2 : 1);
session.execute(withKeyspace("USE %s2"));
try {
session.execute(select.bind());
} catch (DriverInternalError e) {
Assert.assertTrue(e.getCause().getMessage().contains("can't execute it on"));
continue;
}
fail("Should have thrown");
}
}
}
}
use of org.apache.cassandra.cql3.QueryProcessor in project cassandra by apache.
the class ReprepareTestBase method testReprepare.
public void testReprepare(BiConsumer<ClassLoader, Integer> instanceInitializer, ReprepareTestConfiguration... configs) throws Throwable {
try (ICluster<IInvokableInstance> c = init(builder().withNodes(2).withConfig(config -> config.with(GOSSIP, NETWORK, NATIVE_PROTOCOL)).withInstanceInitializer(instanceInitializer).start())) {
ForceHostLoadBalancingPolicy lbp = new ForceHostLoadBalancingPolicy();
c.schemaChange(withKeyspace("CREATE TABLE %s.tbl (pk int, ck int, v int, PRIMARY KEY (pk, ck));"));
for (ReprepareTestConfiguration config : configs) {
// 1 has old behaviour
for (int firstContact : new int[] { 1, 2 }) {
try (com.datastax.driver.core.Cluster cluster = com.datastax.driver.core.Cluster.builder().addContactPoint("127.0.0.1").addContactPoint("127.0.0.2").withLoadBalancingPolicy(lbp).build();
Session session = cluster.connect()) {
lbp.setPrimary(firstContact);
final PreparedStatement select = session.prepare(withKeyspace("SELECT * FROM %s.tbl"));
session.execute(select.bind());
c.stream().forEach((i) -> i.runOnInstance(QueryProcessor::clearPreparedStatementsCache));
lbp.setPrimary(firstContact == 1 ? 2 : 1);
if (config.withUse)
session.execute(withKeyspace("USE %s"));
// Re-preparing on the node
if (!config.skipBrokenBehaviours && firstContact == 1)
session.execute(select.bind());
c.stream().forEach((i) -> i.runOnInstance(QueryProcessor::clearPreparedStatementsCache));
lbp.setPrimary(firstContact);
// Re-preparing on the node with old behaviour will break no matter where the statement was initially prepared
if (!config.skipBrokenBehaviours)
session.execute(select.bind());
c.stream().forEach((i) -> i.runOnInstance(QueryProcessor::clearPreparedStatementsCache));
}
}
}
}
}
Aggregations