mirror of https://github.com/apache/cassandra
Retrieve keyspaces metadata and schema version concistently in DescribeStatement
The fix makes the DescribeStatement to wait for the in-progress schema transformations to finish before returning the first page. This way, the metadata and schema version encoded in the result set metadata are guaranteed to be consistent. Patch by Jacek Lewandowski; reviewed by Benjamin Lerer, Ekaterina Dimitrova for CASSANDRA-18921
This commit is contained in:
parent
9697be1131
commit
86e07595f7
|
|
@ -1,4 +1,5 @@
|
|||
4.0.12
|
||||
* Retrieve keyspaces metadata and schema version concistently in DescribeStatement (CASSANDRA-18921)
|
||||
* Gossip NPE due to shutdown event corrupting empty statuses (CASSANDRA-18913)
|
||||
* Synchronize CQLSSTableWriter#build on the Schema.instance object (CASSANDRA-18317)
|
||||
* Fix closing iterator in SecondaryIndexBuilder (CASSANDRA-18361)
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ import org.apache.cassandra.service.pager.PagingState;
|
|||
import org.apache.cassandra.transport.messages.ResultMessage;
|
||||
import org.apache.cassandra.utils.ByteBufferUtil;
|
||||
import org.apache.cassandra.utils.FBUtilities;
|
||||
import org.apache.cassandra.utils.Pair;
|
||||
import org.apache.cassandra.utils.UUIDGen;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
|
@ -132,13 +133,12 @@ public abstract class DescribeStatement<T> extends CQLStatement.Raw implements C
|
|||
@Override
|
||||
public ResultMessage executeLocally(QueryState state, QueryOptions options)
|
||||
{
|
||||
Keyspaces keyspaces = Schema.instance.snapshot();
|
||||
UUID schemaVersion = Schema.instance.getVersion();
|
||||
Pair<Keyspaces, UUID> schema = Schema.instance.getSchemaBlocking();
|
||||
|
||||
keyspaces = Keyspaces.builder()
|
||||
.add(keyspaces)
|
||||
.add(VirtualKeyspaceRegistry.instance.virtualKeyspacesMetadata())
|
||||
.build();
|
||||
Keyspaces keyspaces = Keyspaces.builder()
|
||||
.add(schema.left)
|
||||
.add(VirtualKeyspaceRegistry.instance.virtualKeyspacesMetadata())
|
||||
.build();
|
||||
|
||||
PagingState pagingState = options.getPagingState();
|
||||
|
||||
|
|
@ -156,7 +156,7 @@ public abstract class DescribeStatement<T> extends CQLStatement.Raw implements C
|
|||
// (vint bytes) serialized schema hash (currently the result of Keyspaces.hashCode())
|
||||
//
|
||||
|
||||
long offset = getOffset(pagingState, schemaVersion);
|
||||
long offset = getOffset(pagingState, schema.right);
|
||||
int pageSize = options.getPageSize();
|
||||
|
||||
Stream<? extends T> stream = describe(state.getClientState(), keyspaces);
|
||||
|
|
@ -174,7 +174,7 @@ public abstract class DescribeStatement<T> extends CQLStatement.Raw implements C
|
|||
|
||||
if (pageSize > 0 && rows.size() == pageSize)
|
||||
{
|
||||
result.metadata.setHasMorePages(getPagingState(offset + pageSize, schemaVersion));
|
||||
result.metadata.setHasMorePages(getPagingState(offset + pageSize, schema.right));
|
||||
}
|
||||
|
||||
return new ResultMessage.Rows(result);
|
||||
|
|
|
|||
|
|
@ -528,8 +528,18 @@ public final class Schema implements SchemaProvider
|
|||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current keyspaces metadata and version synchronouly. If the schema is in the middle of a multistep
|
||||
* transformation, the method blocks until the update is completed.
|
||||
*/
|
||||
public synchronized Pair<Keyspaces, UUID> getSchemaBlocking()
|
||||
{
|
||||
return Pair.create(keyspaces, version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given schema version is the same as the current local schema.
|
||||
* Note that this method is non-blocking and may use a stale schema version for comparison - see {@link #getVersion()}.
|
||||
*/
|
||||
public boolean isSameVersion(UUID schemaVersion)
|
||||
{
|
||||
|
|
@ -538,6 +548,7 @@ public final class Schema implements SchemaProvider
|
|||
|
||||
/**
|
||||
* Checks whether the current schema is empty.
|
||||
* Note that this method is non-blocking and may use a stale schema version for comparison - see {@link #getVersion()}.
|
||||
*/
|
||||
public boolean isEmpty()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,16 +22,14 @@ import java.util.Optional;
|
|||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import com.datastax.driver.core.ResultSet;
|
||||
import com.datastax.driver.core.Row;
|
||||
import com.datastax.driver.core.SimpleStatement;
|
||||
import com.datastax.driver.core.exceptions.InvalidQueryException;
|
||||
|
||||
import org.apache.cassandra.config.DatabaseDescriptor;
|
||||
import org.apache.cassandra.cql3.CQLTester;
|
||||
import org.apache.cassandra.dht.Token;
|
||||
|
|
@ -41,36 +39,43 @@ import org.apache.cassandra.schema.Schema;
|
|||
import org.apache.cassandra.schema.TableId;
|
||||
import org.apache.cassandra.service.StorageService;
|
||||
import org.apache.cassandra.transport.ProtocolVersion;
|
||||
import org.jboss.byteman.contrib.bmunit.BMUnitRunner;
|
||||
|
||||
import static java.lang.String.format;
|
||||
import static org.apache.cassandra.schema.SchemaConstants.*;
|
||||
import static org.apache.cassandra.schema.SchemaConstants.AUTH_KEYSPACE_NAME;
|
||||
import static org.apache.cassandra.schema.SchemaConstants.DISTRIBUTED_KEYSPACE_NAME;
|
||||
import static org.apache.cassandra.schema.SchemaConstants.SCHEMA_KEYSPACE_NAME;
|
||||
import static org.apache.cassandra.schema.SchemaConstants.SYSTEM_KEYSPACE_NAME;
|
||||
import static org.apache.cassandra.schema.SchemaConstants.TRACE_KEYSPACE_NAME;
|
||||
import static org.apache.cassandra.schema.SchemaConstants.VIRTUAL_SCHEMA;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@RunWith(BMUnitRunner.class)
|
||||
public class DescribeStatementTest extends CQLTester
|
||||
{
|
||||
@Test
|
||||
public void testSchemaChangeDuringPaging()
|
||||
{
|
||||
SimpleStatement stmt = new SimpleStatement("DESCRIBE KEYSPACES");
|
||||
stmt.setFetchSize(1);
|
||||
ResultSet rs = executeNet(ProtocolVersion.CURRENT, stmt);
|
||||
Iterator<Row> iter = rs.iterator();
|
||||
assertTrue(iter.hasNext());
|
||||
SimpleStatement stmt = new SimpleStatement("DESCRIBE KEYSPACES");
|
||||
stmt.setFetchSize(1);
|
||||
ResultSet rs = executeNet(ProtocolVersion.CURRENT, stmt);
|
||||
Iterator<Row> iter = rs.iterator();
|
||||
assertTrue(iter.hasNext());
|
||||
iter.next();
|
||||
|
||||
createKeyspace("CREATE KEYSPACE %s WITH REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 1};");
|
||||
|
||||
try
|
||||
{
|
||||
iter.next();
|
||||
|
||||
createKeyspace("CREATE KEYSPACE %s WITH REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 1};");
|
||||
|
||||
try
|
||||
{
|
||||
iter.next();
|
||||
fail("Expected InvalidQueryException");
|
||||
}
|
||||
catch (InvalidQueryException e)
|
||||
{
|
||||
assertEquals(DescribeStatement.SCHEMA_CHANGED_WHILE_PAGING_MESSAGE, e.getMessage());
|
||||
}
|
||||
fail("Expected InvalidQueryException");
|
||||
}
|
||||
catch (InvalidQueryException e)
|
||||
{
|
||||
assertEquals(DescribeStatement.SCHEMA_CHANGED_WHILE_PAGING_MESSAGE, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -99,35 +104,35 @@ public class DescribeStatementTest extends CQLTester
|
|||
"LANGUAGE java " +
|
||||
"AS 'return \"Hello World\";'");
|
||||
|
||||
for (String describeKeyword : new String[]{"DESCRIBE", "DESC"})
|
||||
for (String describeKeyword : new String[]{ "DESCRIBE", "DESC" })
|
||||
{
|
||||
assertRowsNet(executeDescribeNet(describeKeyword + " FUNCTION " + fNonOverloaded),
|
||||
row(KEYSPACE_PER_TEST,
|
||||
"function",
|
||||
shortFunctionName(fNonOverloaded) + "()",
|
||||
"CREATE FUNCTION " + fNonOverloaded + "()\n" +
|
||||
" CALLED ON NULL INPUT\n" +
|
||||
" RETURNS int\n" +
|
||||
" LANGUAGE java\n" +
|
||||
" AS $$throw new RuntimeException();$$;"));
|
||||
" CALLED ON NULL INPUT\n" +
|
||||
" RETURNS int\n" +
|
||||
" LANGUAGE java\n" +
|
||||
" AS $$throw new RuntimeException();$$;"));
|
||||
|
||||
assertRowsNet(executeDescribeNet(describeKeyword + " FUNCTION " + fOverloaded),
|
||||
row(KEYSPACE_PER_TEST,
|
||||
"function",
|
||||
shortFunctionName(fOverloaded) + "(int, ascii)",
|
||||
"CREATE FUNCTION " + fOverloaded + "(input int, other_in ascii)\n" +
|
||||
" RETURNS NULL ON NULL INPUT\n" +
|
||||
" RETURNS text\n" +
|
||||
" LANGUAGE java\n" +
|
||||
" AS $$return \"Hello World\";$$;"),
|
||||
" RETURNS NULL ON NULL INPUT\n" +
|
||||
" RETURNS text\n" +
|
||||
" LANGUAGE java\n" +
|
||||
" AS $$return \"Hello World\";$$;"),
|
||||
row(KEYSPACE_PER_TEST,
|
||||
"function",
|
||||
shortFunctionName(fOverloaded) + "(text, ascii)",
|
||||
"CREATE FUNCTION " + fOverloaded + "(input text, other_in ascii)\n" +
|
||||
" RETURNS NULL ON NULL INPUT\n" +
|
||||
" RETURNS text\n" +
|
||||
" LANGUAGE java\n" +
|
||||
" AS $$return \"Hello World\";$$;"));
|
||||
" RETURNS NULL ON NULL INPUT\n" +
|
||||
" RETURNS text\n" +
|
||||
" LANGUAGE java\n" +
|
||||
" AS $$return \"Hello World\";$$;"));
|
||||
|
||||
assertRowsNet(executeDescribeNet(describeKeyword + " FUNCTIONS"),
|
||||
row(KEYSPACE_PER_TEST,
|
||||
|
|
@ -159,37 +164,37 @@ public class DescribeStatementTest extends CQLTester
|
|||
String aNonDeterministic = createAggregate(KEYSPACE_PER_TEST,
|
||||
"int",
|
||||
format("CREATE AGGREGATE %%s(int) " +
|
||||
"SFUNC %s " +
|
||||
"STYPE int " +
|
||||
"INITCOND 42",
|
||||
shortFunctionName(fIntState)));
|
||||
"SFUNC %s " +
|
||||
"STYPE int " +
|
||||
"INITCOND 42",
|
||||
shortFunctionName(fIntState)));
|
||||
String aDeterministic = createAggregate(KEYSPACE_PER_TEST,
|
||||
"int",
|
||||
format("CREATE AGGREGATE %%s(int) " +
|
||||
"SFUNC %s " +
|
||||
"STYPE int " +
|
||||
"FINALFUNC %s ",
|
||||
shortFunctionName(fIntState),
|
||||
shortFunctionName(fFinal)));
|
||||
"SFUNC %s " +
|
||||
"STYPE int " +
|
||||
"FINALFUNC %s ",
|
||||
shortFunctionName(fIntState),
|
||||
shortFunctionName(fFinal)));
|
||||
|
||||
for (String describeKeyword : new String[]{"DESCRIBE", "DESC"})
|
||||
for (String describeKeyword : new String[]{ "DESCRIBE", "DESC" })
|
||||
{
|
||||
assertRowsNet(executeDescribeNet(describeKeyword + " AGGREGATE " + aNonDeterministic),
|
||||
row(KEYSPACE_PER_TEST,
|
||||
"aggregate",
|
||||
shortFunctionName(aNonDeterministic) + "(int)",
|
||||
"CREATE AGGREGATE " + aNonDeterministic + "(int)\n" +
|
||||
" SFUNC " + shortFunctionName(fIntState) + "\n" +
|
||||
" STYPE int\n" +
|
||||
" INITCOND 42;"));
|
||||
" SFUNC " + shortFunctionName(fIntState) + "\n" +
|
||||
" STYPE int\n" +
|
||||
" INITCOND 42;"));
|
||||
assertRowsNet(executeDescribeNet(describeKeyword + " AGGREGATE " + aDeterministic),
|
||||
row(KEYSPACE_PER_TEST,
|
||||
"aggregate",
|
||||
shortFunctionName(aDeterministic) + "(int)",
|
||||
"CREATE AGGREGATE " + aDeterministic + "(int)\n" +
|
||||
" SFUNC " + shortFunctionName(fIntState) + "\n" +
|
||||
" STYPE int\n" +
|
||||
" FINALFUNC " + shortFunctionName(fFinal) + ";"));
|
||||
" SFUNC " + shortFunctionName(fIntState) + "\n" +
|
||||
" STYPE int\n" +
|
||||
" FINALFUNC " + shortFunctionName(fFinal) + ";"));
|
||||
assertRowsNet(executeDescribeNet(describeKeyword + " AGGREGATES"),
|
||||
row(KEYSPACE_PER_TEST,
|
||||
"aggregate",
|
||||
|
|
@ -211,35 +216,35 @@ public class DescribeStatementTest extends CQLTester
|
|||
"LANGUAGE java " +
|
||||
"AS 'throw new RuntimeException();';");
|
||||
|
||||
assertRowsNet(executeDescribeNet("DESCRIBE FUNCTION " + function),
|
||||
row(KEYSPACE_PER_TEST,
|
||||
"function",
|
||||
shortFunctionName(function) + "(tuple<int>, list<frozen<tuple<int, text>>>, tuple<frozen<tuple<int, text>>, text>)",
|
||||
"CREATE FUNCTION " + function + "(t tuple<int>, l list<frozen<tuple<int, text>>>, nt tuple<frozen<tuple<int, text>>, text>)\n" +
|
||||
" CALLED ON NULL INPUT\n" +
|
||||
" RETURNS tuple<int, text>\n" +
|
||||
" LANGUAGE java\n" +
|
||||
" AS $$throw new RuntimeException();$$;"));
|
||||
assertRowsNet(executeDescribeNet("DESCRIBE FUNCTION " + function),
|
||||
row(KEYSPACE_PER_TEST,
|
||||
"function",
|
||||
shortFunctionName(function) + "(tuple<int>, list<frozen<tuple<int, text>>>, tuple<frozen<tuple<int, text>>, text>)",
|
||||
"CREATE FUNCTION " + function + "(t tuple<int>, l list<frozen<tuple<int, text>>>, nt tuple<frozen<tuple<int, text>>, text>)\n" +
|
||||
" CALLED ON NULL INPUT\n" +
|
||||
" RETURNS tuple<int, text>\n" +
|
||||
" LANGUAGE java\n" +
|
||||
" AS $$throw new RuntimeException();$$;"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDescribeVirtualTables() throws Throwable
|
||||
{
|
||||
assertRowsNet(executeDescribeNet("DESCRIBE ONLY KEYSPACE system_virtual_schema;"),
|
||||
assertRowsNet(executeDescribeNet("DESCRIBE ONLY KEYSPACE system_virtual_schema;"),
|
||||
row("system_virtual_schema",
|
||||
"keyspace",
|
||||
"system_virtual_schema",
|
||||
"/*\n" +
|
||||
"/*\n" +
|
||||
"Warning: Keyspace system_virtual_schema is a virtual keyspace and cannot be recreated with CQL.\n" +
|
||||
"Structure, for reference:\n" +
|
||||
"VIRTUAL KEYSPACE system_virtual_schema;\n" +
|
||||
"*/"));
|
||||
|
||||
assertRowsNet(executeDescribeNet("DESCRIBE TABLE system_virtual_schema.columns;"),
|
||||
assertRowsNet(executeDescribeNet("DESCRIBE TABLE system_virtual_schema.columns;"),
|
||||
row("system_virtual_schema",
|
||||
"table",
|
||||
"columns",
|
||||
"/*\n" +
|
||||
"/*\n" +
|
||||
"Warning: Table system_virtual_schema.columns is a virtual table and cannot be recreated with CQL.\n" +
|
||||
"Structure, for reference:\n" +
|
||||
"VIRTUAL TABLE system_virtual_schema.columns (\n" +
|
||||
|
|
@ -277,23 +282,23 @@ public class DescribeStatementTest extends CQLTester
|
|||
// Test describe schema
|
||||
|
||||
Object[][] testSchemaOutput = rows(
|
||||
row(KEYSPACE, "keyspace", KEYSPACE,
|
||||
"CREATE KEYSPACE " + KEYSPACE +
|
||||
" WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}" +
|
||||
" AND durable_writes = true;"),
|
||||
row(KEYSPACE_PER_TEST, "keyspace", KEYSPACE_PER_TEST,
|
||||
"CREATE KEYSPACE " + KEYSPACE_PER_TEST +
|
||||
" WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}" +
|
||||
" AND durable_writes = true;"),
|
||||
row("test", "keyspace", "test", keyspaceOutput()),
|
||||
row("test", "table", "has_all_types", allTypesTable()),
|
||||
row("test", "table", "\"Test\"", testTableOutput()),
|
||||
row("test", "index", "\"Test_col_idx\"", indexOutput("\"Test_col_idx\"", "\"Test\"", "col")),
|
||||
row("test", "index", "\"Test_val_idx\"", indexOutput("\"Test_val_idx\"", "\"Test\"", "val")),
|
||||
row("test", "table", "users", userTableOutput()),
|
||||
row("test", "index", "myindex", indexOutput("myindex", "users", "age")),
|
||||
row("test", "table", "users_mv", usersMvTableOutput()),
|
||||
row("test", "materialized_view", "users_by_state", usersByStateMvOutput()));
|
||||
row(KEYSPACE, "keyspace", KEYSPACE,
|
||||
"CREATE KEYSPACE " + KEYSPACE +
|
||||
" WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}" +
|
||||
" AND durable_writes = true;"),
|
||||
row(KEYSPACE_PER_TEST, "keyspace", KEYSPACE_PER_TEST,
|
||||
"CREATE KEYSPACE " + KEYSPACE_PER_TEST +
|
||||
" WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}" +
|
||||
" AND durable_writes = true;"),
|
||||
row("test", "keyspace", "test", keyspaceOutput()),
|
||||
row("test", "table", "has_all_types", allTypesTable()),
|
||||
row("test", "table", "\"Test\"", testTableOutput()),
|
||||
row("test", "index", "\"Test_col_idx\"", indexOutput("\"Test_col_idx\"", "\"Test\"", "col")),
|
||||
row("test", "index", "\"Test_val_idx\"", indexOutput("\"Test_val_idx\"", "\"Test\"", "val")),
|
||||
row("test", "table", "users", userTableOutput()),
|
||||
row("test", "index", "myindex", indexOutput("myindex", "users", "age")),
|
||||
row("test", "table", "users_mv", usersMvTableOutput()),
|
||||
row("test", "materialized_view", "users_by_state", usersByStateMvOutput()));
|
||||
|
||||
assertRowsNet(executeDescribeNet(KEYSPACE_PER_TEST, "DESCRIBE SCHEMA"), testSchemaOutput);
|
||||
assertRowsNet(executeDescribeNet(KEYSPACE_PER_TEST, "DESC SCHEMA"), testSchemaOutput);
|
||||
|
|
@ -310,7 +315,7 @@ public class DescribeStatementTest extends CQLTester
|
|||
row(VIRTUAL_SCHEMA, "keyspace", VIRTUAL_SCHEMA),
|
||||
row("test", "keyspace", "test"));
|
||||
|
||||
for (String describeKeyword : new String[]{"DESCRIBE", "DESC"})
|
||||
for (String describeKeyword : new String[]{ "DESCRIBE", "DESC" })
|
||||
{
|
||||
assertRowsNet(executeDescribeNet(describeKeyword + " KEYSPACES"), testKeyspacesOutput);
|
||||
assertRowsNet(executeDescribeNet("test", describeKeyword + " KEYSPACES"), testKeyspacesOutput);
|
||||
|
|
@ -329,7 +334,7 @@ public class DescribeStatementTest extends CQLTester
|
|||
row("test", "table", "users_mv", usersMvTableOutput()),
|
||||
row("test", "materialized_view", "users_by_state", usersByStateMvOutput()));
|
||||
|
||||
for (String describeKeyword : new String[]{"DESCRIBE", "DESC"})
|
||||
for (String describeKeyword : new String[]{ "DESCRIBE", "DESC" })
|
||||
{
|
||||
assertRowsNet(executeDescribeNet(describeKeyword + " KEYSPACE test"), testKeyspaceOutput);
|
||||
assertRowsNet(executeDescribeNet(describeKeyword + " test"), testKeyspaceOutput);
|
||||
|
|
@ -338,7 +343,7 @@ public class DescribeStatementTest extends CQLTester
|
|||
}
|
||||
|
||||
// Test describe tables/table
|
||||
for (String cmd : new String[]{"describe TABLES", "DESC tables"})
|
||||
for (String cmd : new String[]{ "describe TABLES", "DESC tables" })
|
||||
assertRowsNet(executeDescribeNet("test", cmd),
|
||||
row("test", "table", "has_all_types"),
|
||||
row("test", "table", "\"Test\""),
|
||||
|
|
@ -353,7 +358,7 @@ public class DescribeStatementTest extends CQLTester
|
|||
row("test", "index", "\"Test_val_idx\"", indexOutput("\"Test_val_idx\"", "\"Test\"", "val")));
|
||||
|
||||
testDescribeTable("test", "users", row("test", "table", "users", userTableOutput()),
|
||||
row("test", "index", "myindex", indexOutput("myindex", "users", "age")));
|
||||
row("test", "index", "myindex", indexOutput("myindex", "users", "age")));
|
||||
|
||||
describeError("test", "DESCRIBE users2", "'users2' not found in keyspace 'test'");
|
||||
describeError("DESCRIBE test.users2", "'users2' not found in keyspace 'test'");
|
||||
|
|
@ -379,18 +384,18 @@ public class DescribeStatementTest extends CQLTester
|
|||
|
||||
private void testDescribeTable(String keyspace, String table, Object[]... rows) throws Throwable
|
||||
{
|
||||
for (String describeKeyword : new String[]{"describe", "desc"})
|
||||
for (String describeKeyword : new String[]{ "describe", "desc" })
|
||||
{
|
||||
for (String cmd : new String[]{describeKeyword + " table " + keyspace + "." + table,
|
||||
describeKeyword + " columnfamily " + keyspace + "." + table,
|
||||
describeKeyword + " " + keyspace + "." + table})
|
||||
for (String cmd : new String[]{ describeKeyword + " table " + keyspace + "." + table,
|
||||
describeKeyword + " columnfamily " + keyspace + "." + table,
|
||||
describeKeyword + " " + keyspace + "." + table })
|
||||
{
|
||||
assertRowsNet(executeDescribeNet(cmd), rows);
|
||||
}
|
||||
|
||||
for (String cmd : new String[]{describeKeyword + " table " + table,
|
||||
describeKeyword + " columnfamily " + table,
|
||||
describeKeyword + " " + table})
|
||||
for (String cmd : new String[]{ describeKeyword + " table " + table,
|
||||
describeKeyword + " columnfamily " + table,
|
||||
describeKeyword + " " + table })
|
||||
{
|
||||
assertRowsNet(executeDescribeNet(keyspace, cmd), rows);
|
||||
}
|
||||
|
|
@ -399,16 +404,16 @@ public class DescribeStatementTest extends CQLTester
|
|||
|
||||
private void testDescribeIndex(String keyspace, String index, Object[]... rows) throws Throwable
|
||||
{
|
||||
for (String describeKeyword : new String[]{"describe", "desc"})
|
||||
for (String describeKeyword : new String[]{ "describe", "desc" })
|
||||
{
|
||||
for (String cmd : new String[]{describeKeyword + " index " + keyspace + "." + index,
|
||||
describeKeyword + " " + keyspace + "." + index})
|
||||
for (String cmd : new String[]{ describeKeyword + " index " + keyspace + "." + index,
|
||||
describeKeyword + " " + keyspace + "." + index })
|
||||
{
|
||||
assertRowsNet(executeDescribeNet(cmd), rows);
|
||||
}
|
||||
|
||||
for (String cmd : new String[]{describeKeyword + " index " + index,
|
||||
describeKeyword + " " + index})
|
||||
for (String cmd : new String[]{ describeKeyword + " index " + index,
|
||||
describeKeyword + " " + index })
|
||||
{
|
||||
assertRowsNet(executeDescribeNet(keyspace, cmd), rows);
|
||||
}
|
||||
|
|
@ -417,16 +422,16 @@ public class DescribeStatementTest extends CQLTester
|
|||
|
||||
private void testDescribeMaterializedView(String keyspace, String view, Object[]... rows) throws Throwable
|
||||
{
|
||||
for (String describeKeyword : new String[]{"describe", "desc"})
|
||||
for (String describeKeyword : new String[]{ "describe", "desc" })
|
||||
{
|
||||
for (String cmd : new String[]{describeKeyword + " materialized view " + keyspace + "." + view,
|
||||
describeKeyword + " " + keyspace + "." + view})
|
||||
for (String cmd : new String[]{ describeKeyword + " materialized view " + keyspace + "." + view,
|
||||
describeKeyword + " " + keyspace + "." + view })
|
||||
{
|
||||
assertRowsNet(executeDescribeNet(cmd), rows);
|
||||
}
|
||||
|
||||
for (String cmd : new String[]{describeKeyword + " materialized view " + view,
|
||||
describeKeyword + " " + view})
|
||||
for (String cmd : new String[]{ describeKeyword + " materialized view " + view,
|
||||
describeKeyword + " " + view })
|
||||
{
|
||||
assertRowsNet(executeDescribeNet(keyspace, cmd), rows);
|
||||
}
|
||||
|
|
@ -436,12 +441,12 @@ public class DescribeStatementTest extends CQLTester
|
|||
@Test
|
||||
public void testDescribeCluster() throws Throwable
|
||||
{
|
||||
for (String describeKeyword : new String[]{"DESCRIBE", "DESC"})
|
||||
for (String describeKeyword : new String[]{ "DESCRIBE", "DESC" })
|
||||
{
|
||||
assertRowsNet(executeDescribeNet(describeKeyword + " CLUSTER"),
|
||||
row("Test Cluster",
|
||||
"ByteOrderedPartitioner",
|
||||
DatabaseDescriptor.getEndpointSnitch().getClass().getName()));
|
||||
row("Test Cluster",
|
||||
"ByteOrderedPartitioner",
|
||||
DatabaseDescriptor.getEndpointSnitch().getClass().getName()));
|
||||
|
||||
assertRowsNet(executeDescribeNet("system_virtual_schema", describeKeyword + " CLUSTER"),
|
||||
row("Test Cluster",
|
||||
|
|
@ -530,13 +535,13 @@ public class DescribeStatementTest extends CQLTester
|
|||
") WITH CLUSTERING ORDER BY (ck1 ASC, ck2 DESC)\n" +
|
||||
" AND " + tableParametersCql();
|
||||
|
||||
String mvCreateStatement ="CREATE MATERIALIZED VIEW " + KEYSPACE_PER_TEST + ".mv AS\n" +
|
||||
" SELECT *\n" +
|
||||
" FROM " + KEYSPACE_PER_TEST + "." + table + "\n" +
|
||||
" WHERE pk2 IS NOT NULL AND pk1 IS NOT NULL AND ck2 IS NOT NULL AND ck1 IS NOT NULL\n" +
|
||||
" PRIMARY KEY ((pk2, pk1), ck2, ck1)\n" +
|
||||
" WITH CLUSTERING ORDER BY (ck2 DESC, ck1 ASC)\n" +
|
||||
" AND " + mvParametersCql();
|
||||
String mvCreateStatement = "CREATE MATERIALIZED VIEW " + KEYSPACE_PER_TEST + ".mv AS\n" +
|
||||
" SELECT *\n" +
|
||||
" FROM " + KEYSPACE_PER_TEST + "." + table + "\n" +
|
||||
" WHERE pk2 IS NOT NULL AND pk1 IS NOT NULL AND ck2 IS NOT NULL AND ck1 IS NOT NULL\n" +
|
||||
" PRIMARY KEY ((pk2, pk1), ck2, ck1)\n" +
|
||||
" WITH CLUSTERING ORDER BY (ck2 DESC, ck1 ASC)\n" +
|
||||
" AND " + mvParametersCql();
|
||||
|
||||
try
|
||||
{
|
||||
|
|
@ -615,7 +620,7 @@ public class DescribeStatementTest extends CQLTester
|
|||
execute("DROP MATERIALIZED VIEW " + KEYSPACE_PER_TEST + ".mv");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDescribeMissingKeyspace() throws Throwable
|
||||
{
|
||||
|
|
@ -666,31 +671,31 @@ public class DescribeStatementTest extends CQLTester
|
|||
|
||||
assertRowsNet(executeDescribeNet(KEYSPACE_PER_TEST, "DESCRIBE TYPE " + type2),
|
||||
row(KEYSPACE_PER_TEST, "type", type2, "CREATE TYPE " + KEYSPACE_PER_TEST + "." + type2 + " (\n" +
|
||||
" x text,\n" +
|
||||
" y text\n" +
|
||||
");"));
|
||||
" x text,\n" +
|
||||
" y text\n" +
|
||||
");"));
|
||||
assertRowsNet(executeDescribeNet(KEYSPACE_PER_TEST, "DESCRIBE TYPE " + type1),
|
||||
row(KEYSPACE_PER_TEST, "type", type1, "CREATE TYPE " + KEYSPACE_PER_TEST + "." + type1 + " (\n" +
|
||||
" a int,\n" +
|
||||
" b frozen<" + type3 + ">\n" +
|
||||
");"));
|
||||
" a int,\n" +
|
||||
" b frozen<" + type3 + ">\n" +
|
||||
");"));
|
||||
|
||||
assertRowsNet(executeDescribeNet(KEYSPACE_PER_TEST, "DESCRIBE KEYSPACE " + KEYSPACE_PER_TEST),
|
||||
row(KEYSPACE_PER_TEST, "keyspace", KEYSPACE_PER_TEST, "CREATE KEYSPACE " + KEYSPACE_PER_TEST +
|
||||
" WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}" +
|
||||
" AND durable_writes = true;"),
|
||||
" WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}" +
|
||||
" AND durable_writes = true;"),
|
||||
row(KEYSPACE_PER_TEST, "type", type2, "CREATE TYPE " + KEYSPACE_PER_TEST + "." + type2 + " (\n" +
|
||||
" x text,\n" +
|
||||
" y text\n" +
|
||||
");"),
|
||||
" x text,\n" +
|
||||
" y text\n" +
|
||||
");"),
|
||||
row(KEYSPACE_PER_TEST, "type", type3, "CREATE TYPE " + KEYSPACE_PER_TEST + "." + type3 + " (\n" +
|
||||
" a text,\n" +
|
||||
" b frozen<" + type2 + ">\n" +
|
||||
");"),
|
||||
" a text,\n" +
|
||||
" b frozen<" + type2 + ">\n" +
|
||||
");"),
|
||||
row(KEYSPACE_PER_TEST, "type", type1, "CREATE TYPE " + KEYSPACE_PER_TEST + "." + type1 + " (\n" +
|
||||
" a int,\n" +
|
||||
" b frozen<" + type3 + ">\n" +
|
||||
");"));
|
||||
" a int,\n" +
|
||||
" b frozen<" + type3 + ">\n" +
|
||||
");"));
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
@ -702,26 +707,26 @@ public class DescribeStatementTest extends CQLTester
|
|||
|
||||
/**
|
||||
* Tests for the error reported in CASSANDRA-9064 by:
|
||||
*
|
||||
* <p>
|
||||
* - creating the table described in the bug report, using LCS,
|
||||
* - DESCRIBE-ing that table via cqlsh, then DROPping it,
|
||||
* - running the output of the DESCRIBE statement as a CREATE TABLE statement, and
|
||||
* - inserting a value into the table.
|
||||
*
|
||||
* <p>
|
||||
* The final two steps of the test should not fall down. If one does, that
|
||||
* indicates the output of DESCRIBE is not a correct CREATE TABLE statement.
|
||||
*/
|
||||
@Test
|
||||
public void testDescribeRoundtrip() throws Throwable
|
||||
{
|
||||
for (String withInternals : new String[]{"", " WITH INTERNALS"})
|
||||
for (String withInternals : new String[]{ "", " WITH INTERNALS" })
|
||||
{
|
||||
String table = createTable(KEYSPACE_PER_TEST, "CREATE TABLE %s (key int PRIMARY KEY) WITH compaction = {'class': 'LeveledCompactionStrategy'}");
|
||||
|
||||
String output = executeDescribeNet(KEYSPACE_PER_TEST, "DESCRIBE TABLE " + table + withInternals).all().get(0).getString("create_statement");
|
||||
|
||||
executeDescribeNet(KEYSPACE_PER_TEST, "CREATE MATERIALIZED VIEW " + table + "_view AS SELECT key FROM " + table
|
||||
+ " WHERE key IS NOT NULL PRIMARY KEY(key)");
|
||||
+ " WHERE key IS NOT NULL PRIMARY KEY(key)");
|
||||
|
||||
String mvCreateView = executeDescribeNet(KEYSPACE_PER_TEST, "DESCRIBE MATERIALIZED VIEW " + table + "_view").all().get(0).getString("create_statement");
|
||||
|
||||
|
|
@ -820,7 +825,8 @@ public class DescribeStatementTest extends CQLTester
|
|||
@Test
|
||||
public void testDescMaterializedViewShouldNotOmitQuotations() throws Throwable
|
||||
{
|
||||
try{
|
||||
try
|
||||
{
|
||||
execute("CREATE KEYSPACE testWithKeywords WITH REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 1};");
|
||||
execute("CREATE TABLE testWithKeywords.users_mv (username varchar, password varchar, gender varchar, session_token varchar, " +
|
||||
"state varchar, birth_year bigint, \"token\" text, PRIMARY KEY (\"token\"));");
|
||||
|
|
@ -850,14 +856,14 @@ public class DescribeStatementTest extends CQLTester
|
|||
final String functionName = KEYSPACE_PER_TEST + ".\"token\"";
|
||||
|
||||
createFunctionOverload(functionName,
|
||||
"int, ascii",
|
||||
"CREATE FUNCTION " + functionName + " (\"token\" int, other_in ascii) " +
|
||||
"RETURNS NULL ON NULL INPUT " +
|
||||
"RETURNS text " +
|
||||
"LANGUAGE java " +
|
||||
"AS 'return \"Hello World\";'");
|
||||
"int, ascii",
|
||||
"CREATE FUNCTION " + functionName + " (\"token\" int, other_in ascii) " +
|
||||
"RETURNS NULL ON NULL INPUT " +
|
||||
"RETURNS text " +
|
||||
"LANGUAGE java " +
|
||||
"AS 'return \"Hello World\";'");
|
||||
|
||||
for (String describeKeyword : new String[]{"DESCRIBE", "DESC"})
|
||||
for (String describeKeyword : new String[]{ "DESCRIBE", "DESC" })
|
||||
{
|
||||
|
||||
assertRowsNet(executeDescribeNet(describeKeyword + " FUNCTION " + functionName),
|
||||
|
|
@ -874,24 +880,24 @@ public class DescribeStatementTest extends CQLTester
|
|||
final String aggregationFunctionName = KEYSPACE_PER_TEST + ".\"token\"";
|
||||
final String aggregationName = KEYSPACE_PER_TEST + ".\"token\"";
|
||||
createFunctionOverload(aggregationName,
|
||||
"int, int",
|
||||
"CREATE FUNCTION " + aggregationFunctionName + " (\"token\" int, add_to int) " +
|
||||
"CALLED ON NULL INPUT " +
|
||||
"RETURNS int " +
|
||||
"LANGUAGE java " +
|
||||
"AS 'return token + add_to;'");
|
||||
"int, int",
|
||||
"CREATE FUNCTION " + aggregationFunctionName + " (\"token\" int, add_to int) " +
|
||||
"CALLED ON NULL INPUT " +
|
||||
"RETURNS int " +
|
||||
"LANGUAGE java " +
|
||||
"AS 'return token + add_to;'");
|
||||
|
||||
|
||||
String aggregate = createAggregate(KEYSPACE_PER_TEST,
|
||||
"int",
|
||||
format("CREATE AGGREGATE %%s(int) " +
|
||||
"SFUNC %s " +
|
||||
"STYPE int " +
|
||||
"INITCOND 42",
|
||||
shortFunctionName(aggregationFunctionName)));
|
||||
"int",
|
||||
format("CREATE AGGREGATE %%s(int) " +
|
||||
"SFUNC %s " +
|
||||
"STYPE int " +
|
||||
"INITCOND 42",
|
||||
shortFunctionName(aggregationFunctionName)));
|
||||
|
||||
|
||||
for (String describeKeyword : new String[]{"DESCRIBE", "DESC"})
|
||||
for (String describeKeyword : new String[]{ "DESCRIBE", "DESC" })
|
||||
{
|
||||
assertRowsNet(executeDescribeNet(describeKeyword + " AGGREGATE " + aggregate),
|
||||
row(KEYSPACE_PER_TEST,
|
||||
|
|
@ -975,12 +981,12 @@ public class DescribeStatementTest extends CQLTester
|
|||
private static String testTableOutput()
|
||||
{
|
||||
return "CREATE TABLE test.\"Test\" (\n" +
|
||||
" id int,\n" +
|
||||
" col int,\n" +
|
||||
" val text,\n" +
|
||||
" PRIMARY KEY (id, col)\n" +
|
||||
") WITH CLUSTERING ORDER BY (col ASC)\n" +
|
||||
" AND " + tableParametersCql();
|
||||
" id int,\n" +
|
||||
" col int,\n" +
|
||||
" val text,\n" +
|
||||
" PRIMARY KEY (id, col)\n" +
|
||||
") WITH CLUSTERING ORDER BY (col ASC)\n" +
|
||||
" AND " + tableParametersCql();
|
||||
}
|
||||
|
||||
private static String tableParametersCql()
|
||||
|
|
|
|||
Loading…
Reference in New Issue