Merge branch 'cassandra-2.2' into trunk

This commit is contained in:
Josh McKenzie 2015-06-24 12:13:15 -04:00
commit bc9b0be321
65 changed files with 6823 additions and 1646 deletions

View File

@ -1554,6 +1554,12 @@ public class DatabaseDescriptor
return conf.row_cache_size_in_mb;
}
@VisibleForTesting
public static void setRowCacheSizeInMB(long val)
{
conf.row_cache_size_in_mb = val;
}
public static int getRowCacheSavePeriod()
{
return conf.row_cache_save_period;

View File

@ -254,6 +254,15 @@ public class ResultSet
return new ResultMetadata(EnumSet.copyOf(flags), names, columnCount, pagingState);
}
/**
* Return only the column names requested by the user, excluding those added for post-query re-orderings,
* see definition of names and columnCount.
**/
public List<ColumnSpecification> requestNames()
{
return names.subList(0, columnCount);
}
// The maximum number of values that the ResultSet can hold. This can be bigger than columnCount due to CASSANDRA-4911
public int valueCount()
{

View File

@ -95,7 +95,7 @@ public abstract class UntypedResultSet implements Iterable<UntypedResultSet.Row>
public List<ColumnSpecification> metadata()
{
return cqlRows.metadata.names;
return cqlRows.metadata.requestNames();
}
}

View File

@ -38,9 +38,11 @@ import org.apache.cassandra.service.ClientState;
import org.apache.cassandra.service.ClientWarn;
import org.apache.cassandra.service.QueryState;
import org.apache.cassandra.service.StorageProxy;
import org.apache.cassandra.thrift.Column;
import org.apache.cassandra.tracing.Tracing;
import org.apache.cassandra.transport.messages.ResultMessage;
import org.apache.cassandra.utils.NoSpamLogger;
import org.apache.cassandra.utils.Pair;
/**
* A <code>BATCH</code> statement parsed from a CQL query.
@ -342,11 +344,32 @@ public class BatchStatement implements CQLStatement
private ResultMessage executeWithConditions(BatchQueryOptions options, QueryState state)
throws RequestExecutionException, RequestValidationException
{
Pair<CQL3CasRequest, Set<ColumnDefinition>> p = makeCasRequest(options, state);
CQL3CasRequest casRequest = p.left;
Set<ColumnDefinition> columnsWithConditions = p.right;
ColumnFamily result = StorageProxy.cas(casRequest.cfm.ksName,
casRequest.cfm.cfName,
casRequest.key,
casRequest,
options.getSerialConsistency(),
options.getConsistency(),
state.getClientState());
return new ResultMessage.Rows(ModificationStatement.buildCasResultSet(casRequest.cfm.ksName,
casRequest.key,
casRequest.cfm.cfName,
result,
columnsWithConditions,
true,
options.forStatement(0)));
}
private Pair<CQL3CasRequest,Set<ColumnDefinition>> makeCasRequest(BatchQueryOptions options, QueryState state)
{
long now = state.getTimestamp();
ByteBuffer key = null;
String ksName = null;
String cfName = null;
CQL3CasRequest casRequest = null;
Set<ColumnDefinition> columnsWithConditions = new LinkedHashSet<>();
@ -361,8 +384,6 @@ public class BatchStatement implements CQLStatement
if (key == null)
{
key = pks.get(0);
ksName = statement.cfm.ksName;
cfName = statement.cfm.cfName;
casRequest = new CQL3CasRequest(statement.cfm, key, true);
}
else if (!key.equals(pks.get(0)))
@ -383,23 +404,49 @@ public class BatchStatement implements CQLStatement
casRequest.addRowUpdate(clusteringPrefix, statement, statementOptions, timestamp);
}
ColumnFamily result = StorageProxy.cas(ksName, cfName, key, casRequest, options.getSerialConsistency(), options.getConsistency(), state.getClientState());
return new ResultMessage.Rows(ModificationStatement.buildCasResultSet(ksName, key, cfName, result, columnsWithConditions, true, options.forStatement(0)));
return Pair.create(casRequest, columnsWithConditions);
}
public ResultMessage executeInternal(QueryState queryState, QueryOptions options) throws RequestValidationException, RequestExecutionException
{
assert !hasConditions;
if (hasConditions)
return executeInternalWithConditions(BatchQueryOptions.withoutPerStatementVariables(options), queryState);
executeInternalWithoutCondition(queryState, options);
return new ResultMessage.Void();
}
private ResultMessage executeInternalWithoutCondition(QueryState queryState, QueryOptions options) throws RequestValidationException, RequestExecutionException
{
for (IMutation mutation : getMutations(BatchQueryOptions.withoutPerStatementVariables(options), true, queryState.getTimestamp()))
{
// We don't use counters internally.
assert mutation instanceof Mutation;
((Mutation) mutation).apply();
assert mutation instanceof Mutation || mutation instanceof CounterMutation;
if (mutation instanceof Mutation)
((Mutation) mutation).apply();
else if (mutation instanceof CounterMutation)
((CounterMutation) mutation).apply();
}
return null;
}
private ResultMessage executeInternalWithConditions(BatchQueryOptions options, QueryState state) throws RequestExecutionException, RequestValidationException
{
Pair<CQL3CasRequest, Set<ColumnDefinition>> p = makeCasRequest(options, state);
CQL3CasRequest request = p.left;
Set<ColumnDefinition> columnsWithConditions = p.right;
ColumnFamily result = ModificationStatement.casInternal(request, state);
return new ResultMessage.Rows(ModificationStatement.buildCasResultSet(request.cfm.ksName,
request.key,
request.cfm.cfName,
result,
columnsWithConditions,
true,
options.forStatement(0)));
}
public interface BatchVariables
{
public List<ByteBuffer> getVariablesForStatement(int statementInBatch);

View File

@ -36,10 +36,10 @@ import org.apache.cassandra.utils.Pair;
*/
public class CQL3CasRequest implements CASRequest
{
private final CFMetaData cfm;
private final ByteBuffer key;
private final long now;
private final boolean isBatch;
final CFMetaData cfm;
final ByteBuffer key;
final long now;
final boolean isBatch;
// We index RowCondition by the prefix of the row they applied to for 2 reasons:
// 1) this allows to keep things sorted to build the ColumnSlice array below

View File

@ -26,6 +26,7 @@ import com.google.common.collect.Lists;
import org.apache.cassandra.auth.Permission;
import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.config.ColumnDefinition;
import org.apache.cassandra.config.Schema;
import org.apache.cassandra.cql3.*;
import org.apache.cassandra.cql3.functions.Function;
import org.apache.cassandra.cql3.restrictions.Restriction;
@ -41,9 +42,12 @@ import org.apache.cassandra.exceptions.*;
import org.apache.cassandra.service.ClientState;
import org.apache.cassandra.service.QueryState;
import org.apache.cassandra.service.StorageProxy;
import org.apache.cassandra.service.paxos.Commit;
import org.apache.cassandra.thrift.ThriftValidation;
import org.apache.cassandra.transport.messages.ResultMessage;
import org.apache.cassandra.triggers.TriggerExecutor;
import org.apache.cassandra.utils.Pair;
import org.apache.cassandra.utils.UUIDGen;
import static org.apache.cassandra.cql3.statements.RequestValidations.checkFalse;
import static org.apache.cassandra.cql3.statements.RequestValidations.checkNotNull;
@ -485,6 +489,20 @@ public abstract class ModificationStatement implements CQLStatement
public ResultMessage executeWithCondition(QueryState queryState, QueryOptions options)
throws RequestExecutionException, RequestValidationException
{
CQL3CasRequest request = makeCasRequest(queryState, options);
ColumnFamily result = StorageProxy.cas(keyspace(),
columnFamily(),
request.key,
request,
options.getSerialConsistency(),
options.getConsistency(),
queryState.getClientState());
return new ResultMessage.Rows(buildCasResultSet(request.key, result, options));
}
private CQL3CasRequest makeCasRequest(QueryState queryState, QueryOptions options)
{
List<ByteBuffer> keys = buildPartitionKeyNames(options);
// We don't support IN for CAS operation so far
@ -498,15 +516,7 @@ public abstract class ModificationStatement implements CQLStatement
CQL3CasRequest request = new CQL3CasRequest(cfm, key, false);
addConditions(prefix, request, options);
request.addRowUpdate(prefix, this, options, now);
ColumnFamily result = StorageProxy.cas(keyspace(),
columnFamily(),
key,
request,
options.getSerialConsistency(),
options.getConsistency(),
queryState.getClientState());
return new ResultMessage.Rows(buildCasResultSet(key, result, options));
return request;
}
public void addConditions(Composite clusteringPrefix, CQL3CasRequest request, QueryOptions options) throws InvalidRequestException
@ -608,9 +618,13 @@ public abstract class ModificationStatement implements CQLStatement
public ResultMessage executeInternal(QueryState queryState, QueryOptions options) throws RequestValidationException, RequestExecutionException
{
if (hasConditions())
throw new UnsupportedOperationException();
return hasConditions()
? executeInternalWithCondition(queryState, options)
: executeInternalWithoutCondition(queryState, options);
}
public ResultMessage executeInternalWithoutCondition(QueryState queryState, QueryOptions options) throws RequestValidationException, RequestExecutionException
{
for (IMutation mutation : getMutations(options, true, queryState.getTimestamp()))
{
assert mutation instanceof Mutation || mutation instanceof CounterMutation;
@ -623,6 +637,40 @@ public abstract class ModificationStatement implements CQLStatement
return null;
}
public ResultMessage executeInternalWithCondition(QueryState state, QueryOptions options) throws RequestValidationException, RequestExecutionException
{
CQL3CasRequest request = makeCasRequest(state, options);
ColumnFamily result = casInternal(request, state);
return new ResultMessage.Rows(buildCasResultSet(request.key, result, options));
}
static ColumnFamily casInternal(CQL3CasRequest request, QueryState state)
{
long millis = state.getTimestamp() / 1000;
long nanos = ((state.getTimestamp() - (millis * 1000)) + 1) * 10;
UUID ballot = UUIDGen.getTimeUUID(millis, nanos);
CFMetaData metadata = Schema.instance.getCFMetaData(request.cfm.ksName, request.cfm.cfName);
ReadCommand readCommand = ReadCommand.create(request.cfm.ksName, request.key, request.cfm.cfName, request.now, request.readFilter());
Keyspace keyspace = Keyspace.open(request.cfm.ksName);
Row row = readCommand.getRow(keyspace);
ColumnFamily current = row.cf;
if (!request.appliesTo(current))
{
if (current == null)
current = ArrayBackedSortedColumns.factory.create(metadata);
return current;
}
ColumnFamily updates = request.makeUpdates(current);
updates = TriggerExecutor.instance.execute(request.key, updates);
Commit proposal = Commit.newProposal(request.key, ballot, updates);
proposal.makeMutation().apply();
return null;
}
/**
* Convert statement into a list of mutations to apply on the server
*

View File

@ -164,37 +164,13 @@ public class SelectStatement implements CQLStatement
int limit = getLimit(options);
long now = System.currentTimeMillis();
Pageable command = getPageableCommand(options, limit, now);
int pageSize = options.getPageSize();
// An aggregation query will never be paged for the user, but we always page it internally to avoid OOM.
// If we user provided a pageSize we'll use that to page internally (because why not), otherwise we use our default
// Note that if there are some nodes in the cluster with a version less than 2.0, we can't use paging (CASSANDRA-6707).
if (selection.isAggregate() && pageSize <= 0)
pageSize = DEFAULT_COUNT_PAGE_SIZE;
int pageSize = getPageSize(options);
if (pageSize <= 0 || command == null || !QueryPagers.mayNeedPaging(command, pageSize))
{
return execute(command, options, limit, now, state);
}
QueryPager pager = QueryPagers.pager(command, cl, state.getClientState(), options.getPagingState());
if (selection.isAggregate())
return pageAggregateQuery(pager, options, pageSize, now);
// We can't properly do post-query ordering if we page (see #6722)
checkFalse(needsPostQueryOrdering(),
"Cannot page queries with both ORDER BY and a IN restriction on the partition key;"
+ " you must either remove the ORDER BY or the IN and sort client side, or disable paging for this query");
List<Row> page = pager.fetchPage(pageSize);
ResultMessage.Rows msg = processResults(page, options, limit, now);
if (!pager.isExhausted())
msg.result.metadata.setHasMorePages(pager.state());
return msg;
return execute(pager, options, limit, now, pageSize);
}
private Pageable getPageableCommand(QueryOptions options, int limit, long now) throws RequestValidationException
@ -212,7 +188,21 @@ public class SelectStatement implements CQLStatement
return getPageableCommand(options, getLimit(options), System.currentTimeMillis());
}
private ResultMessage.Rows execute(Pageable command, QueryOptions options, int limit, long now, QueryState state) throws RequestValidationException, RequestExecutionException
private int getPageSize(QueryOptions options)
{
int pageSize = options.getPageSize();
// An aggregation query will never be paged for the user, but we always page it internally to avoid OOM.
// If we user provided a pageSize we'll use that to page internally (because why not), otherwise we use our default
// Note that if there are some nodes in the cluster with a version less than 2.0, we can't use paging (CASSANDRA-6707).
if (selection.isAggregate() && pageSize <= 0)
pageSize = DEFAULT_COUNT_PAGE_SIZE;
return pageSize;
}
private ResultMessage.Rows execute(Pageable command, QueryOptions options, int limit, long now, QueryState state)
throws RequestValidationException, RequestExecutionException
{
List<Row> rows;
if (command == null)
@ -229,6 +219,26 @@ public class SelectStatement implements CQLStatement
return processResults(rows, options, limit, now);
}
private ResultMessage.Rows execute(QueryPager pager, QueryOptions options, int limit, long now, int pageSize)
throws RequestValidationException, RequestExecutionException
{
if (selection.isAggregate())
return pageAggregateQuery(pager, options, pageSize, now);
// We can't properly do post-query ordering if we page (see #6722)
checkFalse(needsPostQueryOrdering(),
"Cannot page queries with both ORDER BY and a IN restriction on the partition key;"
+ " you must either remove the ORDER BY or the IN and sort client side, or disable paging for this query");
List<Row> page = pager.fetchPage(pageSize);
ResultMessage.Rows msg = processResults(page, options, limit, now);
if (!pager.isExhausted())
msg.result.metadata.setHasMorePages(pager.state());
return msg;
}
private ResultMessage.Rows pageAggregateQuery(QueryPager pager, QueryOptions options, int pageSize, long now)
throws RequestValidationException, RequestExecutionException
{
@ -267,13 +277,21 @@ public class SelectStatement implements CQLStatement
int limit = getLimit(options);
long now = System.currentTimeMillis();
Pageable command = getPageableCommand(options, limit, now);
List<Row> rows = command == null
? Collections.<Row>emptyList()
: (command instanceof Pageable.ReadCommands
? readLocally(keyspace(), ((Pageable.ReadCommands)command).commands)
: ((RangeSliceCommand)command).executeLocally());
int pageSize = getPageSize(options);
return processResults(rows, options, limit, now);
if (pageSize <= 0 || command == null || !QueryPagers.mayNeedPaging(command, pageSize))
{
List<Row> rows = command == null
? Collections.<Row>emptyList()
: (command instanceof Pageable.ReadCommands
? readLocally(keyspace(), ((Pageable.ReadCommands)command).commands)
: ((RangeSliceCommand)command).executeLocally());
return processResults(rows, options, limit, now);
}
QueryPager pager = QueryPagers.localPager(command);
return execute(pager, options, limit, now, pageSize);
}
public ResultSet process(List<Row> rows) throws InvalidRequestException

View File

@ -22,6 +22,8 @@ import java.util.concurrent.TimeoutException;
import org.apache.cassandra.auth.Permission;
import org.apache.cassandra.cql3.*;
import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.db.Keyspace;
import org.apache.cassandra.exceptions.*;
import org.apache.cassandra.transport.messages.ResultMessage;
import org.apache.cassandra.service.ClientState;
@ -71,6 +73,15 @@ public class TruncateStatement extends CFStatement implements CQLStatement
public ResultMessage executeInternal(QueryState state, QueryOptions options)
{
throw new UnsupportedOperationException();
try
{
ColumnFamilyStore cfs = Keyspace.open(keyspace()).getColumnFamilyStore(columnFamily());
cfs.truncateBlocking();
}
catch (Exception e)
{
throw new TruncateException(e);
}
return null;
}
}

View File

@ -228,7 +228,9 @@ public class StorageProxy implements StorageProxyMBean
Tracing.trace("Reading existing values for CAS precondition");
long timestamp = System.currentTimeMillis();
ReadCommand readCommand = ReadCommand.create(keyspaceName, key, cfName, timestamp, request.readFilter());
List<Row> rows = read(Arrays.asList(readCommand), consistencyForPaxos == ConsistencyLevel.LOCAL_SERIAL ? ConsistencyLevel.LOCAL_QUORUM : ConsistencyLevel.QUORUM);
List<Row> rows = read(Arrays.asList(readCommand), consistencyForPaxos == ConsistencyLevel.LOCAL_SERIAL
? ConsistencyLevel.LOCAL_QUORUM
: ConsistencyLevel.QUORUM);
ColumnFamily current = rows.get(0).cf;
if (!request.appliesTo(current))
{

View File

@ -82,10 +82,15 @@ public class UUIDGen
return new UUID(createTime(fromUnixTimestamp(when)), clockSeqAndNode);
}
@VisibleForTesting
public static UUID getTimeUUID(long when, long clockSeqAndNode)
public static UUID getTimeUUID(long when, long nanos)
{
return new UUID(createTime(fromUnixTimestamp(when)), clockSeqAndNode);
return new UUID(createTime(fromUnixTimestamp(when, nanos)), clockSeqAndNode);
}
@VisibleForTesting
public static UUID getTimeUUID(long when, long nanos, long clockSeqAndNode)
{
return new UUID(createTime(fromUnixTimestamp(when, nanos)), clockSeqAndNode);
}
/** creates a type 1 uuid from raw bytes. */
@ -169,7 +174,12 @@ public class UUIDGen
* @return
*/
private static long fromUnixTimestamp(long timestamp) {
return (timestamp - START_EPOCH) * 10000;
return fromUnixTimestamp(timestamp, 0L);
}
private static long fromUnixTimestamp(long timestamp, long nanos)
{
return ((timestamp - START_EPOCH) * 10000) + nanos;
}
/**

View File

@ -0,0 +1,92 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import org.junit.Test;
public class ManyRowsTest extends CQLTester
{
/**
* Migrated from cql_tests.py:TestCQL.large_count_test()
*/
@Test
public void testLargeCount() throws Throwable
{
createTable("CREATE TABLE %s (k int, v int, PRIMARY KEY (k))");
// We know we page at 10K, so test counting just before, at 10K, just after and
// a bit after that.
for (int k = 1; k < 10000; k++)
execute("INSERT INTO %s (k) VALUES (?)", k);
assertRows(execute("SELECT COUNT(*) FROM %s"), row(9999L));
execute("INSERT INTO %s (k) VALUES (?)", 10000);
assertRows(execute("SELECT COUNT(*) FROM %s"), row(10000L));
execute("INSERT INTO %s (k) VALUES (?)", 10001);
assertRows(execute("SELECT COUNT(*) FROM %s"), row(10001L));
for (int k = 10002; k < 15001; k++)
execute("INSERT INTO %s (k) VALUES (?)", k);
assertRows(execute("SELECT COUNT(*) FROM %s"), row(15000L));
}
/**
* Test for CASSANDRA-8410,
* migrated from cql_tests.py:TestCQL.large_clustering_in_test()
*/
@Test
public void testLargeClustering() throws Throwable
{
createTable("CREATE TABLE %s (k int, c int, v int, PRIMARY KEY (k, c) )");
execute("INSERT INTO %s (k, c, v) VALUES (?, ?, ?)", 0, 0, 0);
// try to fetch one existing row and 9999 non-existing rows
List<Integer> inValues = new ArrayList(10000);
for (int i = 0; i < 10000; i++)
inValues.add(i);
assertRows(execute("SELECT * FROM %s WHERE k=? AND c IN ?", 0, inValues),
row(0, 0, 0));
// insert approximately 1000 random rows between 0 and 10k
Random rnd = new Random();
Set<Integer> clusteringValues = new HashSet<>();
for (int i = 0; i < 1000; i++)
clusteringValues.add(rnd.nextInt(10000));
clusteringValues.add(0);
for (int i : clusteringValues) // TODO - this was done in parallel by dtests
execute("INSERT INTO %s (k, c, v) VALUES (?, ?, ?)", 0, i, i);
assertRowCount(execute("SELECT * FROM %s WHERE k=? AND c IN ?", 0, inValues), clusteringValues.size());
}
}

View File

@ -1,40 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
import org.junit.Test;
public class AliasTest extends CQLTester
{
@Test
public void testAlias() throws Throwable
{
createTable("CREATE TABLE %s (id int PRIMARY KEY, name text)");
for (int i = 0; i < 5; i++)
execute("INSERT INTO %s (id, name) VALUES (?, ?) USING TTL 10 AND TIMESTAMP 0", i, Integer.toString(i));
assertInvalidMessage("Aliases aren't allowed in the where clause" ,
"SELECT id AS user_id, name AS user_name FROM %s WHERE user_id = 0");
// test that select throws a meaningful exception for aliases in order by clause
assertInvalidMessage("Aliases are not allowed in order by clause",
"SELECT id AS user_id, name AS user_name FROM %s WHERE id IN (0) ORDER BY user_name");
}
}

View File

@ -35,11 +35,18 @@ import org.junit.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.datastax.driver.core.*;
import static junit.framework.Assert.assertNotNull;
import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.ColumnDefinitions;
import com.datastax.driver.core.DataType;
import com.datastax.driver.core.ProtocolVersion;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Row;
import com.datastax.driver.core.Session;
import org.apache.cassandra.SchemaLoader;
import org.apache.cassandra.concurrent.ScheduledExecutors;
import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.config.Schema;
import org.apache.cassandra.cql3.functions.FunctionName;
import org.apache.cassandra.cql3.statements.ParsedStatement;
@ -51,6 +58,7 @@ import org.apache.cassandra.db.marshal.TupleType;
import org.apache.cassandra.exceptions.CassandraException;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.exceptions.SyntaxException;
import org.apache.cassandra.dht.Murmur3Partitioner;
import org.apache.cassandra.io.util.FileUtils;
import org.apache.cassandra.serializers.TypeSerializer;
import org.apache.cassandra.service.ClientState;
@ -71,6 +79,7 @@ public abstract class CQLTester
public static final String KEYSPACE = "cql_test_keyspace";
public static final String KEYSPACE_PER_TEST = "cql_test_keyspace_alt";
protected static final boolean USE_PREPARED_VALUES = Boolean.valueOf(System.getProperty("cassandra.test.use_prepared", "true"));
protected static final long ROW_CACHE_SIZE_IN_MB = Integer.valueOf(System.getProperty("cassandra.test.row_cache_size_in_mb", "0"));
private static final AtomicInteger seqNumber = new AtomicInteger();
private static org.apache.cassandra.transport.Server server;
@ -79,7 +88,7 @@ public abstract class CQLTester
private static final Cluster[] cluster;
private static final Session[] session;
static int maxProtocolVersion;
public static int maxProtocolVersion;
static {
int version;
for (version = 1; version <= Server.CURRENT_VERSION; )
@ -129,9 +138,12 @@ public abstract class CQLTester
private boolean usePrepared = USE_PREPARED_VALUES;
@BeforeClass
public static void setUpClass() throws Throwable
public static void setUpClass()
{
schemaChange(String.format("CREATE KEYSPACE IF NOT EXISTS %s WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}", KEYSPACE));
if (ROW_CACHE_SIZE_IN_MB > 0)
DatabaseDescriptor.setRowCacheSizeInMB(ROW_CACHE_SIZE_IN_MB);
DatabaseDescriptor.setPartitioner(Murmur3Partitioner.instance);
}
@AfterClass
@ -151,6 +163,7 @@ public abstract class CQLTester
@Before
public void beforeTest() throws Throwable
{
schemaChange(String.format("CREATE KEYSPACE IF NOT EXISTS %s WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}", KEYSPACE));
schemaChange(String.format("CREATE KEYSPACE IF NOT EXISTS %s WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'}", KEYSPACE_PER_TEST));
}
@ -178,16 +191,16 @@ public abstract class CQLTester
{
try
{
for (int i = tablesToDrop.size() - 1; i >=0; i--)
for (int i = tablesToDrop.size() - 1; i >= 0; i--)
schemaChange(String.format("DROP TABLE IF EXISTS %s.%s", KEYSPACE, tablesToDrop.get(i)));
for (int i = aggregatesToDrop.size() - 1; i >=0; i--)
for (int i = aggregatesToDrop.size() - 1; i >= 0; i--)
schemaChange(String.format("DROP AGGREGATE IF EXISTS %s", aggregatesToDrop.get(i)));
for (int i = functionsToDrop.size() - 1; i >=0; i--)
for (int i = functionsToDrop.size() - 1; i >= 0; i--)
schemaChange(String.format("DROP FUNCTION IF EXISTS %s", functionsToDrop.get(i)));
for (int i = typesToDrop.size() - 1; i >=0; i--)
for (int i = typesToDrop.size() - 1; i >= 0; i--)
schemaChange(String.format("DROP TYPE IF EXISTS %s.%s", KEYSPACE, typesToDrop.get(i)));
// Dropping doesn't delete the sstables. It's not a huge deal but it's cleaner to cleanup after us
@ -198,10 +211,10 @@ public abstract class CQLTester
final CountDownLatch latch = new CountDownLatch(1);
ScheduledExecutors.nonPeriodicTasks.execute(new Runnable()
{
public void run()
{
latch.countDown();
}
public void run()
{
latch.countDown();
}
});
latch.await(2, TimeUnit.SECONDS);
@ -272,9 +285,25 @@ public abstract class CQLTester
}
}
public boolean usePrepared()
public void compact()
{
return USE_PREPARED_VALUES;
try
{
String currentTable = currentTable();
if (currentTable != null)
Keyspace.open(KEYSPACE).getColumnFamilyStore(currentTable).forceMajorCompaction();
}
catch (InterruptedException | ExecutionException e)
{
throw new RuntimeException(e);
}
}
public void cleanupCache()
{
String currentTable = currentTable();
if (currentTable != null)
Keyspace.open(KEYSPACE).getColumnFamilyStore(currentTable).cleanupCache();
}
public static FunctionName parseFunctionName(String qualifiedName)
@ -379,14 +408,20 @@ public abstract class CQLTester
protected String createTable(String query)
{
String currentTable = "table_" + seqNumber.getAndIncrement();
tables.add(currentTable);
String currentTable = createTableName();
String fullQuery = formatQuery(query);
logger.info(fullQuery);
schemaChange(fullQuery);
return currentTable;
}
protected String createTableName()
{
String currentTable = "table_" + seqNumber.getAndIncrement();
tables.add(currentTable);
return currentTable;
}
protected void createTableMayThrow(String query) throws Throwable
{
String currentTable = "table_" + seqNumber.getAndIncrement();
@ -424,6 +459,37 @@ public abstract class CQLTester
schemaChange(fullQuery);
}
/**
* Index creation is asynchronous, this method searches in the system table IndexInfo
* for the specified index and returns true if it finds it, which indicates the
* index was built. If we haven't found it after 5 seconds we give-up.
*/
protected boolean waitForIndex(String keyspace, String table, String index) throws Throwable
{
long start = System.currentTimeMillis();
boolean indexCreated = false;
String indedName = String.format("%s.%s", table, index);
while (!indexCreated)
{
Object[][] results = getRows(execute("select index_name from system.\"IndexInfo\" where table_name = ?", keyspace));
for(int i = 0; i < results.length; i++)
{
if (indedName.equals(results[i][0]))
{
indexCreated = true;
break;
}
}
if (System.currentTimeMillis() - start > 5000)
break;
Thread.sleep(10);
}
return indexCreated;
}
protected void createIndexMayThrow(String query) throws Throwable
{
String fullQuery = formatQuery(query);
@ -593,7 +659,7 @@ public abstract class CQLTester
Object[] expected = rows[i];
UntypedResultSet.Row actual = iter.next();
Assert.assertEquals(String.format("Invalid number of (expected) values provided for row %d", i), meta.size(), expected.length);
Assert.assertEquals(String.format("Invalid number of (expected) values provided for row %d", i), expected.length, meta.size());
for (int j = 0; j < meta.size(); j++)
{
@ -602,8 +668,17 @@ public abstract class CQLTester
ByteBuffer actualValue = actual.getBytes(column.name.toString());
if (!Objects.equal(expectedByteValue, actualValue))
Assert.fail(String.format("Invalid value for row %d column %d (%s of type %s), expected <%s> but got <%s>",
i, j, column.name, column.type.asCQL3Type(), formatValue(expectedByteValue, column.type), formatValue(actualValue, column.type)));
{
Object actualValueDecoded = column.type.getSerializer().deserialize(actualValue);
if (!actualValueDecoded.equals(expected[j]))
Assert.fail(String.format("Invalid value for row %d column %d (%s of type %s), expected <%s> but got <%s>",
i,
j,
column.name,
column.type.asCQL3Type(),
formatValue(expectedByteValue, column.type),
formatValue(actualValue, column.type)));
}
}
i++;
}
@ -621,6 +696,65 @@ public abstract class CQLTester
Assert.assertTrue(String.format("Got %s rows than expected. Expected %d but got %d", rows.length>i ? "less" : "more", rows.length, i), i == rows.length);
}
protected void assertRowCount(UntypedResultSet result, int numExpectedRows)
{
if (result == null)
{
if (numExpectedRows > 0)
Assert.fail(String.format("No rows returned by query but %d expected", numExpectedRows));
return;
}
List<ColumnSpecification> meta = result.metadata();
Iterator<UntypedResultSet.Row> iter = result.iterator();
int i = 0;
while (iter.hasNext() && i < numExpectedRows)
{
UntypedResultSet.Row actual = iter.next();
assertNotNull(actual);
i++;
}
if (iter.hasNext())
{
while (iter.hasNext())
{
iter.next();
i++;
}
Assert.fail(String.format("Got less rows than expected. Expected %d but got %d.", numExpectedRows, i));
}
Assert.assertTrue(String.format("Got %s rows than expected. Expected %d but got %d", numExpectedRows>i ? "less" : "more", numExpectedRows, i), i == numExpectedRows);
}
protected Object[][] getRows(UntypedResultSet result)
{
if (result == null)
return new Object[0][];
List<Object[]> ret = new ArrayList<>();
List<ColumnSpecification> meta = result.metadata();
Iterator<UntypedResultSet.Row> iter = result.iterator();
while (iter.hasNext())
{
UntypedResultSet.Row rowVal = iter.next();
Object[] row = new Object[meta.size()];
for (int j = 0; j < meta.size(); j++)
{
ColumnSpecification column = meta.get(j);
ByteBuffer val = rowVal.getBytes(column.name.toString());
row[j] = val == null ? null : column.type.getSerializer().deserialize(val);
}
ret.add(row);
}
Object[][] a = new Object[ret.size()][];
return ret.toArray(a);
}
protected void assertColumnNames(UntypedResultSet result, String... expectedColumnNames)
{
if (result == null)

View File

@ -1,283 +0,0 @@
package org.apache.cassandra.cql3;
import org.junit.Test;
public class ContainsRelationTest extends CQLTester
{
@Test
public void testSetContains() throws Throwable
{
createTable("CREATE TABLE %s (account text, id int, categories set<text>, PRIMARY KEY (account, id))");
createIndex("CREATE INDEX ON %s(categories)");
execute("INSERT INTO %s (account, id , categories) VALUES (?, ?, ?)", "test", 5, set("lmn"));
assertEmpty(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?", "xyz", "lmn"));
assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS ?", "lmn"),
row("test", 5, set("lmn"))
);
assertRows(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?", "test", "lmn"),
row("test", 5, set("lmn"))
);
assertRows(execute("SELECT * FROM %s WHERE account = ? AND id = ? AND categories CONTAINS ?", "test", 5, "lmn"),
row("test", 5, set("lmn"))
);
assertInvalidMessage("Unsupported null value for indexed column categories",
"SELECT * FROM %s WHERE account = ? AND id = ? AND categories CONTAINS ?", "test", 5, null);
assertInvalidMessage("Unsupported unset value for indexed column categories",
"SELECT * FROM %s WHERE account = ? AND id = ? AND categories CONTAINS ?", "test", 5, unset());
assertInvalidMessage("Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING",
"SELECT * FROM %s WHERE account = ? AND categories CONTAINS ? AND categories CONTAINS ?", "xyz", "lmn", "notPresent");
assertEmpty(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ? AND categories CONTAINS ? ALLOW FILTERING", "xyz", "lmn", "notPresent"));
}
@Test
public void testListContains() throws Throwable
{
createTable("CREATE TABLE %s (account text, id int, categories list<text>, PRIMARY KEY (account, id))");
createIndex("CREATE INDEX ON %s(categories)");
execute("INSERT INTO %s (account, id , categories) VALUES (?, ?, ?)", "test", 5, list("lmn"));
assertEmpty(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?", "xyz", "lmn"));
assertRows(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?;", "test", "lmn"),
row("test", 5, list("lmn"))
);
assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS ?", "lmn"),
row("test", 5, list("lmn"))
);
assertRows(execute("SELECT * FROM %s WHERE account = ? AND id = ? AND categories CONTAINS ?;", "test", 5, "lmn"),
row("test", 5, list("lmn"))
);
assertInvalidMessage("Unsupported null value for indexed column categories",
"SELECT * FROM %s WHERE account = ? AND id = ? AND categories CONTAINS ?", "test", 5, null);
assertInvalidMessage("Unsupported unset value for indexed column categories",
"SELECT * FROM %s WHERE account = ? AND id = ? AND categories CONTAINS ?", "test", 5, unset());
assertInvalidMessage("Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING",
"SELECT * FROM %s WHERE account = ? AND id = ? AND categories CONTAINS ? AND categories CONTAINS ?",
"test", 5, "lmn", "notPresent");
assertEmpty(execute("SELECT * FROM %s WHERE account = ? AND id = ? AND categories CONTAINS ? AND categories CONTAINS ? ALLOW FILTERING",
"test", 5, "lmn", "notPresent"));
}
@Test
public void testListContainsWithFiltering() throws Throwable
{
createTable("CREATE TABLE %s (e int PRIMARY KEY, f list<text>, s int)");
createIndex("CREATE INDEX ON %s(f)");
for(int i = 0; i < 3; i++)
{
execute("INSERT INTO %s (e, f, s) VALUES (?, ?, ?)", i, list("Dubai"), 4);
}
for(int i = 3; i < 5; i++)
{
execute("INSERT INTO %s (e, f, s) VALUES (?, ?, ?)", i, list("Dubai"), 3);
}
assertRows(execute("SELECT * FROM %s WHERE f CONTAINS ? AND s=? allow filtering", "Dubai", 3),
row(3, list("Dubai"), 3),
row(4, list("Dubai"), 3));
}
@Test
public void testMapKeyContains() throws Throwable
{
createTable("CREATE TABLE %s (account text, id int, categories map<text,text>, PRIMARY KEY (account, id))");
createIndex("CREATE INDEX ON %s(keys(categories))");
execute("INSERT INTO %s (account, id , categories) VALUES (?, ?, ?)", "test", 5, map("lmn", "foo"));
assertEmpty(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS KEY ?", "xyz", "lmn"));
assertRows(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS KEY ?", "test", "lmn"),
row("test", 5, map("lmn", "foo"))
);
assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS KEY ?", "lmn"),
row("test", 5, map("lmn", "foo"))
);
assertRows(execute("SELECT * FROM %s WHERE account = ? AND id = ? AND categories CONTAINS KEY ?", "test", 5, "lmn"),
row("test", 5, map("lmn", "foo"))
);
assertInvalidMessage("Unsupported null value for indexed column categories",
"SELECT * FROM %s WHERE account = ? AND id = ? AND categories CONTAINS KEY ?", "test", 5, null);
assertInvalidMessage("Unsupported unset value for indexed column categories",
"SELECT * FROM %s WHERE account = ? AND id = ? AND categories CONTAINS KEY ?", "test", 5, unset());
assertInvalidMessage("Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING",
"SELECT * FROM %s WHERE account = ? AND id = ? AND categories CONTAINS KEY ? AND categories CONTAINS KEY ?",
"test", 5, "lmn", "notPresent");
assertEmpty(execute("SELECT * FROM %s WHERE account = ? AND id = ? AND categories CONTAINS KEY ? AND categories CONTAINS KEY ? ALLOW FILTERING",
"test", 5, "lmn", "notPresent"));
assertInvalidMessage("Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING",
"SELECT * FROM %s WHERE account = ? AND id = ? AND categories CONTAINS KEY ? AND categories CONTAINS ?",
"test", 5, "lmn", "foo");
}
@Test
public void testMapValueContains() throws Throwable
{
createTable("CREATE TABLE %s (account text, id int, categories map<text,text>, PRIMARY KEY (account, id))");
createIndex("CREATE INDEX ON %s(categories)");
execute("INSERT INTO %s (account, id , categories) VALUES (?, ?, ?)", "test", 5, map("lmn", "foo"));
assertEmpty(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?", "xyz", "foo"));
assertRows(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?", "test", "foo"),
row("test", 5, map("lmn", "foo"))
);
assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS ?", "foo"),
row("test", 5, map("lmn", "foo"))
);
assertRows(execute("SELECT * FROM %s WHERE account = ? AND id = ? AND categories CONTAINS ?", "test", 5, "foo"),
row("test", 5, map("lmn", "foo"))
);
assertInvalidMessage("Unsupported null value for indexed column categories",
"SELECT * FROM %s WHERE account = ? AND id = ? AND categories CONTAINS ?", "test", 5, null);
assertInvalidMessage("Unsupported unset value for indexed column categories",
"SELECT * FROM %s WHERE account = ? AND id = ? AND categories CONTAINS ?", "test", 5, unset());
assertInvalidMessage("Cannot execute this query as it might involve data filtering and thus may have unpredictable performance. If you want to execute this query despite the performance unpredictability, use ALLOW FILTERING",
"SELECT * FROM %s WHERE account = ? AND id = ? AND categories CONTAINS ? AND categories CONTAINS ?"
, "test", 5, "foo", "notPresent");
assertEmpty(execute("SELECT * FROM %s WHERE account = ? AND id = ? AND categories CONTAINS ? AND categories CONTAINS ? ALLOW FILTERING"
, "test", 5, "foo", "notPresent"));
}
// See CASSANDRA-7525
@Test
public void testQueryMultipleIndexTypes() throws Throwable
{
createTable("CREATE TABLE %s (account text, id int, categories map<text,text>, PRIMARY KEY (account, id))");
// create an index on
createIndex("CREATE INDEX id_index ON %s(id)");
createIndex("CREATE INDEX categories_values_index ON %s(categories)");
execute("INSERT INTO %s (account, id , categories) VALUES (?, ?, ?)", "test", 5, map("lmn", "foo"));
assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS ? AND id = ? ALLOW FILTERING", "foo", 5),
row("test", 5, map("lmn", "foo"))
);
assertRows(
execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ? AND id = ? ALLOW FILTERING", "test", "foo", 5),
row("test", 5, map("lmn", "foo"))
);
}
// See CASSANDRA-8033
@Test
public void testFilterForContains() throws Throwable
{
createTable("CREATE TABLE %s (k1 int, k2 int, v set<int>, PRIMARY KEY ((k1, k2)))");
createIndex("CREATE INDEX ON %s(k2)");
execute("INSERT INTO %s (k1, k2, v) VALUES (?, ?, ?)", 0, 0, set(1, 2, 3));
execute("INSERT INTO %s (k1, k2, v) VALUES (?, ?, ?)", 0, 1, set(2, 3, 4));
execute("INSERT INTO %s (k1, k2, v) VALUES (?, ?, ?)", 1, 0, set(3, 4, 5));
execute("INSERT INTO %s (k1, k2, v) VALUES (?, ?, ?)", 1, 1, set(4, 5, 6));
assertRows(execute("SELECT * FROM %s WHERE k2 = ?", 1),
row(0, 1, set(2, 3, 4)),
row(1, 1, set(4, 5, 6))
);
assertRows(execute("SELECT * FROM %s WHERE k2 = ? AND v CONTAINS ? ALLOW FILTERING", 1, 6),
row(1, 1, set(4, 5, 6))
);
assertEmpty(execute("SELECT * FROM %s WHERE k2 = ? AND v CONTAINS ? ALLOW FILTERING", 1, 7));
}
// See CASSANDRA-8073
@Test
public void testIndexLookupWithClusteringPrefix() throws Throwable
{
createTable("CREATE TABLE %s (a int, b int, c int, d set<int>, PRIMARY KEY (a, b, c))");
createIndex("CREATE INDEX ON %s(d)");
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 0, set(1, 2, 3));
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, set(3, 4, 5));
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 0, set(1, 2, 3));
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, set(3, 4, 5));
assertRows(execute("SELECT * FROM %s WHERE a=? AND b=? AND d CONTAINS ?", 0, 1, 3),
row(0, 1, 0, set(1, 2, 3)),
row(0, 1, 1, set(3, 4, 5))
);
assertRows(execute("SELECT * FROM %s WHERE a=? AND b=? AND d CONTAINS ?", 0, 1, 2),
row(0, 1, 0, set(1, 2, 3))
);
assertRows(execute("SELECT * FROM %s WHERE a=? AND b=? AND d CONTAINS ?", 0, 1, 5),
row(0, 1, 1, set(3, 4, 5))
);
}
@Test
public void testContainsKeyAndContainsWithIndexOnMapKey() throws Throwable
{
createTable("CREATE TABLE %s (account text, id int, categories map<text,text>, PRIMARY KEY (account, id))");
createIndex("CREATE INDEX ON %s(keys(categories))");
execute("INSERT INTO %s (account, id , categories) VALUES (?, ?, ?)", "test", 5, map("lmn", "foo"));
execute("INSERT INTO %s (account, id , categories) VALUES (?, ?, ?)", "test", 6, map("lmn", "foo2"));
assertInvalidMessage("No secondary indexes on the restricted columns support the provided operators: 'categories CONTAINS <value>'",
"SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?", "test", "foo");
assertRows(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS KEY ?", "test", "lmn"),
row("test", 5, map("lmn", "foo")),
row("test", 6, map("lmn", "foo2")));
assertRows(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS KEY ? AND categories CONTAINS ? ALLOW FILTERING",
"test", "lmn", "foo"),
row("test", 5, map("lmn", "foo")));
assertRows(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ? AND categories CONTAINS KEY ? ALLOW FILTERING",
"test", "foo", "lmn"),
row("test", 5, map("lmn", "foo")));
}
@Test
public void testContainsKeyAndContainsWithIndexOnMapValue() throws Throwable
{
createTable("CREATE TABLE %s (account text, id int, categories map<text,text>, PRIMARY KEY (account, id))");
createIndex("CREATE INDEX ON %s(categories)");
execute("INSERT INTO %s (account, id , categories) VALUES (?, ?, ?)", "test", 5, map("lmn", "foo"));
execute("INSERT INTO %s (account, id , categories) VALUES (?, ?, ?)", "test", 6, map("lmn2", "foo"));
assertInvalidMessage("No secondary indexes on the restricted columns support the provided operators: 'categories CONTAINS KEY <value>'",
"SELECT * FROM %s WHERE account = ? AND categories CONTAINS KEY ?", "test", "lmn");
assertRows(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?", "test", "foo"),
row("test", 5, map("lmn", "foo")),
row("test", 6, map("lmn2", "foo")));
assertRows(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS KEY ? AND categories CONTAINS ? ALLOW FILTERING",
"test", "lmn", "foo"),
row("test", 5, map("lmn", "foo")));
assertRows(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ? AND categories CONTAINS KEY ? ALLOW FILTERING",
"test", "foo", "lmn"),
row("test", 5, map("lmn", "foo")));
}
}

View File

@ -1,37 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
import org.junit.Test;
public class CreateAndAlterKeyspaceTest extends CQLTester
{
@Test
// tests CASSANDRA-9565
public void testCreateAndAlterWithDoubleWith() throws Throwable
{
String[] stmts = new String[] {"ALTER KEYSPACE WITH WITH DURABLE_WRITES = true",
"ALTER KEYSPACE ks WITH WITH DURABLE_WRITES = true",
"CREATE KEYSPACE WITH WITH DURABLE_WRITES = true",
"CREATE KEYSPACE ks WITH WITH DURABLE_WRITES = true"};
for (String stmt : stmts) {
assertInvalidSyntaxMessage("no viable alternative at input 'WITH'", stmt);
}
}
}

View File

@ -1,101 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
import java.util.Locale;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
public class CreateIndexStatementTest extends CQLTester
{
@Test
public void testCreateAndDropIndex() throws Throwable
{
testCreateAndDropIndex("test", false);
testCreateAndDropIndex("test2", true);
}
@Test
public void testCreateAndDropIndexWithQuotedIdentifier() throws Throwable
{
testCreateAndDropIndex("\"quoted_ident\"", false);
testCreateAndDropIndex("\"quoted_ident2\"", true);
}
@Test
public void testCreateAndDropIndexWithCamelCaseIdentifier() throws Throwable
{
testCreateAndDropIndex("CamelCase", false);
testCreateAndDropIndex("CamelCase2", true);
}
/**
* Test creating and dropping an index with the specified name.
*
* @param indexName the index name
* @param addKeyspaceOnDrop add the keyspace name in the drop statement
* @throws Throwable if an error occurs
*/
private void testCreateAndDropIndex(String indexName, boolean addKeyspaceOnDrop) throws Throwable
{
execute("USE system");
assertInvalidMessage("Index '" + removeQuotes(indexName.toLowerCase(Locale.US)) + "' could not be found", "DROP INDEX " + indexName + ";");
createTable("CREATE TABLE %s (a int primary key, b int);");
createIndex("CREATE INDEX " + indexName + " ON %s(b);");
createIndex("CREATE INDEX IF NOT EXISTS " + indexName + " ON %s(b);");
assertInvalidMessage("Index already exists", "CREATE INDEX " + indexName + " ON %s(b)");
execute("INSERT INTO %s (a, b) values (?, ?);", 0, 0);
execute("INSERT INTO %s (a, b) values (?, ?);", 1, 1);
execute("INSERT INTO %s (a, b) values (?, ?);", 2, 2);
execute("INSERT INTO %s (a, b) values (?, ?);", 3, 1);
assertRows(execute("SELECT * FROM %s where b = ?", 1), row(1, 1), row(3, 1));
assertInvalidMessage("Index '" + removeQuotes(indexName.toLowerCase(Locale.US)) + "' could not be found in any of the tables of keyspace 'system'", "DROP INDEX " + indexName);
if (addKeyspaceOnDrop)
{
dropIndex("DROP INDEX " + KEYSPACE + "." + indexName);
}
else
{
execute("USE " + KEYSPACE);
execute("DROP INDEX " + indexName);
}
assertInvalidMessage("No secondary indexes on the restricted columns support the provided operators",
"SELECT * FROM %s where b = ?", 1);
dropIndex("DROP INDEX IF EXISTS " + indexName);
assertInvalidMessage("Index '" + removeQuotes(indexName.toLowerCase(Locale.US)) + "' could not be found", "DROP INDEX " + indexName);
}
/**
* Removes the quotes from the specified index name.
*
* @param indexName the index name from which the quotes must be removed.
* @return the unquoted index name.
*/
private static String removeQuotes(String indexName)
{
return StringUtils.remove(indexName, '\"');
}
}

View File

@ -1,69 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
import org.junit.Test;
import org.apache.cassandra.utils.ByteBufferUtil;
import static junit.framework.Assert.assertFalse;
public class CreateTableTest extends CQLTester
{
@Test
public void testCQL3PartitionKeyOnlyTable()
{
createTable("CREATE TABLE %s (id text PRIMARY KEY);");
assertFalse(currentTableMetadata().isThriftCompatible());
}
@Test
public void testCreateTableWithSmallintColumns() throws Throwable
{
createTable("CREATE TABLE %s (a text, b smallint, c smallint, primary key (a, b));");
execute("INSERT INTO %s (a, b, c) VALUES ('1', 1, 2)");
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", "2", Short.MAX_VALUE, Short.MIN_VALUE);
assertRows(execute("SELECT * FROM %s"),
row("1", (short) 1, (short) 2),
row("2", Short.MAX_VALUE, Short.MIN_VALUE));
assertInvalidMessage("Expected 2 bytes for a smallint (4)",
"INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", "3", 1, 2);
assertInvalidMessage("Expected 2 bytes for a smallint (0)",
"INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", "3", (short) 1, ByteBufferUtil.EMPTY_BYTE_BUFFER);
}
@Test
public void testCreateTinyintColumns() throws Throwable
{
createTable("CREATE TABLE %s (a text, b tinyint, c tinyint, primary key (a, b));");
execute("INSERT INTO %s (a, b, c) VALUES ('1', 1, 2)");
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", "2", Byte.MAX_VALUE, Byte.MIN_VALUE);
assertRows(execute("SELECT * FROM %s"),
row("1", (byte) 1, (byte) 2),
row("2", Byte.MAX_VALUE, Byte.MIN_VALUE));
assertInvalidMessage("Expected 1 byte for a tinyint (4)",
"INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", "3", 1, 2);
assertInvalidMessage("Expected 1 byte for a tinyint (0)",
"INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", "3", (byte) 1, ByteBufferUtil.EMPTY_BYTE_BUFFER);
}
}

View File

@ -1,121 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Collections;
import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.config.Schema;
import org.apache.cassandra.config.TriggerDefinition;
import org.apache.cassandra.db.ColumnFamily;
import org.apache.cassandra.db.Mutation;
import org.apache.cassandra.triggers.ITrigger;
import org.junit.Test;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class CreateTriggerStatementTest extends CQLTester
{
@Test
public void testCreateTrigger() throws Throwable
{
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a))");
execute("CREATE TRIGGER trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'");
assertTriggerExists("trigger_1", TestTrigger.class);
execute("CREATE TRIGGER trigger_2 ON %s USING '" + TestTrigger.class.getName() + "'");
assertTriggerExists("trigger_2", TestTrigger.class);
assertInvalid("CREATE TRIGGER trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'");
execute("CREATE TRIGGER \"Trigger 3\" ON %s USING '" + TestTrigger.class.getName() + "'");
assertTriggerExists("Trigger 3", TestTrigger.class);
}
@Test
public void testCreateTriggerIfNotExists() throws Throwable
{
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
execute("CREATE TRIGGER IF NOT EXISTS trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'");
assertTriggerExists("trigger_1", TestTrigger.class);
execute("CREATE TRIGGER IF NOT EXISTS trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'");
assertTriggerExists("trigger_1", TestTrigger.class);
}
@Test
public void testDropTrigger() throws Throwable
{
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a))");
execute("CREATE TRIGGER trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'");
assertTriggerExists("trigger_1", TestTrigger.class);
execute("DROP TRIGGER trigger_1 ON %s");
assertTriggerDoesNotExists("trigger_1", TestTrigger.class);
execute("CREATE TRIGGER trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'");
assertTriggerExists("trigger_1", TestTrigger.class);
assertInvalid("DROP TRIGGER trigger_2 ON %s");
execute("CREATE TRIGGER \"Trigger 3\" ON %s USING '" + TestTrigger.class.getName() + "'");
assertTriggerExists("Trigger 3", TestTrigger.class);
execute("DROP TRIGGER \"Trigger 3\" ON %s");
assertTriggerDoesNotExists("Trigger 3", TestTrigger.class);
}
@Test
public void testDropTriggerIfExists() throws Throwable
{
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a))");
execute("DROP TRIGGER IF EXISTS trigger_1 ON %s");
assertTriggerDoesNotExists("trigger_1", TestTrigger.class);
execute("CREATE TRIGGER trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'");
assertTriggerExists("trigger_1", TestTrigger.class);
execute("DROP TRIGGER IF EXISTS trigger_1 ON %s");
assertTriggerDoesNotExists("trigger_1", TestTrigger.class);
}
private void assertTriggerExists(String name, Class<?> clazz)
{
CFMetaData cfm = Schema.instance.getCFMetaData(keyspace(), currentTable()).copy();
assertTrue("the trigger does not exist", cfm.containsTriggerDefinition(TriggerDefinition.create(name,
clazz.getName())));
}
private void assertTriggerDoesNotExists(String name, Class<?> clazz)
{
CFMetaData cfm = Schema.instance.getCFMetaData(keyspace(), currentTable()).copy();
assertFalse("the trigger exists", cfm.containsTriggerDefinition(TriggerDefinition.create(name,
clazz.getName())));
}
public static class TestTrigger implements ITrigger
{
public Collection<Mutation> augment(ByteBuffer key, ColumnFamily update)
{
return Collections.emptyList();
}
}
}

View File

@ -1,149 +0,0 @@
/*
*
* * Licensed to the Apache Software Foundation (ASF) under one
* * or more contributor license agreements. See the NOTICE file
* * distributed with this work for additional information
* * regarding copyright ownership. The ASF licenses this file
* * to you under the Apache License, Version 2.0 (the
* * "License"); you may not use this file except in compliance
* * with the License. You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
package org.apache.cassandra.cql3;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import org.apache.cassandra.utils.FBUtilities;
import static org.junit.Assert.fail;
public class IndexedValuesValidationTest extends CQLTester
{
private static final int TOO_BIG = 1024 * 65;
// CASSANDRA-8280/8081
// reject updates with indexed values where value > 64k
@Test
public void testIndexOnCompositeValueOver64k() throws Throwable
{
createTable("CREATE TABLE %s(a int, b int, c blob, PRIMARY KEY (a))");
createIndex("CREATE INDEX ON %s(c)");
failInsert("INSERT INTO %s (a, b, c) VALUES (0, 0, ?)", ByteBuffer.allocate(TOO_BIG));
}
@Test
public void testIndexOnClusteringColumnInsertPartitionKeyAndClusteringsOver64k() throws Throwable
{
createTable("CREATE TABLE %s(a blob, b blob, c blob, d int, PRIMARY KEY (a, b, c))");
createIndex("CREATE INDEX ON %s(b)");
// CompositeIndexOnClusteringKey creates index entries composed of the
// PK plus all of the non-indexed clustering columns from the primary row
// so we should reject where len(a) + len(c) > 65560 as this will form the
// total clustering in the index table
ByteBuffer a = ByteBuffer.allocate(100);
ByteBuffer b = ByteBuffer.allocate(10);
ByteBuffer c = ByteBuffer.allocate(FBUtilities.MAX_UNSIGNED_SHORT - 99);
failInsert("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, 0)", a, b, c);
}
@Test
public void testCompactTableWithValueOver64k() throws Throwable
{
createTable("CREATE TABLE %s(a int, b blob, PRIMARY KEY (a)) WITH COMPACT STORAGE");
createIndex("CREATE INDEX ON %s(b)");
failInsert("INSERT INTO %s (a, b) VALUES (0, ?)", ByteBuffer.allocate(TOO_BIG));
}
@Test
public void testIndexOnCollectionValueInsertPartitionKeyAndCollectionKeyOver64k() throws Throwable
{
createTable("CREATE TABLE %s(a blob , b map<blob, int>, PRIMARY KEY (a))");
createIndex("CREATE INDEX ON %s(b)");
// A collection key > 64k by itself will be rejected from
// the primary table.
// To test index validation we need to ensure that
// len(b) < 64k, but len(a) + len(b) > 64k as that will
// form the clustering in the index table
ByteBuffer a = ByteBuffer.allocate(100);
ByteBuffer b = ByteBuffer.allocate(FBUtilities.MAX_UNSIGNED_SHORT - 100);
failInsert("UPDATE %s SET b[?] = 0 WHERE a = ?", b, a);
}
@Test
public void testIndexOnCollectionKeyInsertPartitionKeyAndClusteringOver64k() throws Throwable
{
createTable("CREATE TABLE %s(a blob, b blob, c map<blob, int>, PRIMARY KEY (a, b))");
createIndex("CREATE INDEX ON %s(KEYS(c))");
// Basically the same as the case with non-collection clustering
// CompositeIndexOnCollectionKeyy creates index entries composed of the
// PK plus all of the clustering columns from the primary row, except the
// collection element - which becomes the partition key in the index table
ByteBuffer a = ByteBuffer.allocate(100);
ByteBuffer b = ByteBuffer.allocate(FBUtilities.MAX_UNSIGNED_SHORT - 100);
ByteBuffer c = ByteBuffer.allocate(10);
failInsert("UPDATE %s SET c[?] = 0 WHERE a = ? and b = ?", c, a, b);
}
@Test
public void testIndexOnPartitionKeyInsertValueOver64k() throws Throwable
{
createTable("CREATE TABLE %s(a int, b int, c blob, PRIMARY KEY ((a, b)))");
createIndex("CREATE INDEX ON %s(a)");
succeedInsert("INSERT INTO %s (a, b, c) VALUES (0, 0, ?)", ByteBuffer.allocate(TOO_BIG));
}
@Test
public void testIndexOnClusteringColumnInsertValueOver64k() throws Throwable
{
createTable("CREATE TABLE %s(a int, b int, c blob, PRIMARY KEY (a, b))");
createIndex("CREATE INDEX ON %s(b)");
succeedInsert("INSERT INTO %s (a, b, c) VALUES (0, 0, ?)", ByteBuffer.allocate(TOO_BIG));
}
@Test
public void testIndexOnFullCollectionEntryInsertCollectionValueOver64k() throws Throwable
{
createTable("CREATE TABLE %s(a int, b frozen<map<int, blob>>, PRIMARY KEY (a))");
createIndex("CREATE INDEX ON %s(full(b))");
Map<Integer, ByteBuffer> map = new HashMap();
map.put(0, ByteBuffer.allocate(1024 * 65));
failInsert("INSERT INTO %s (a, b) VALUES (0, ?)", map);
}
public void failInsert(String insertCQL, Object...args) throws Throwable
{
try
{
execute(insertCQL, args);
fail("Expected statement to fail validation");
}
catch (Exception e)
{
// as expected
}
}
public void succeedInsert(String insertCQL, Object...args) throws Throwable
{
execute(insertCQL, args);
flush();
}
}

View File

@ -1,112 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
import org.junit.Test;
public class ModificationTest extends CQLTester
{
@Test
public void testModificationWithUnset() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, s text, i int)");
// insert using nulls
execute("INSERT INTO %s (k, s, i) VALUES (10, ?, ?)", "text", 10);
execute("INSERT INTO %s (k, s, i) VALUES (10, ?, ?)", null, null);
assertRows(execute("SELECT s, i FROM %s WHERE k = 10"),
row(null, null) // sending null deletes the data
);
// insert using UNSET
execute("INSERT INTO %s (k, s, i) VALUES (11, ?, ?)", "text", 10);
execute("INSERT INTO %s (k, s, i) VALUES (11, ?, ?)", unset(), unset());
assertRows(execute("SELECT s, i FROM %s WHERE k=11"),
row("text", 10) // unset columns does not delete the existing data
);
assertInvalidMessage("Invalid unset value for column k", "UPDATE %s SET i = 0 WHERE k = ?", unset());
assertInvalidMessage("Invalid unset value for column k", "DELETE FROM %s WHERE k = ?", unset());
assertInvalidMessage("Invalid unset value for argument in call to function blobasint", "SELECT * FROM %s WHERE k = blobAsInt(?)", unset());
}
@Test
public void testTtlWithUnset() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, i int)");
execute("INSERT INTO %s (k, i) VALUES (1, 1) USING TTL ?", unset()); // treat as 'unlimited'
assertRows(execute("SELECT ttl(i) FROM %s"),
row(new Object[] {null})
);
}
@Test
public void testTimestampWithUnset() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, i int)");
execute("INSERT INTO %s (k, i) VALUES (1, 1) USING TIMESTAMP ?", unset()); // treat as 'now'
}
@Test
public void testCounterUpdatesWithUnset() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, c counter)");
// set up
execute("UPDATE %s SET c = c + 1 WHERE k = 10");
assertRows(execute("SELECT c FROM %s WHERE k = 10"),
row(1L)
);
// increment
execute("UPDATE %s SET c = c + ? WHERE k = 10", 1L);
assertRows(execute("SELECT c FROM %s WHERE k = 10"),
row(2L)
);
execute("UPDATE %s SET c = c + ? WHERE k = 10", unset());
assertRows(execute("SELECT c FROM %s WHERE k = 10"),
row(2L) // no change to the counter value
);
// decrement
execute("UPDATE %s SET c = c - ? WHERE k = 10", 1L);
assertRows(execute("SELECT c FROM %s WHERE k = 10"),
row(1L)
);
execute("UPDATE %s SET c = c - ? WHERE k = 10", unset());
assertRows(execute("SELECT c FROM %s WHERE k = 10"),
row(1L) // no change to the counter value
);
}
@Test
public void testBatchWithUnset() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, s text, i int)");
// test batch and update
String qualifiedTable = keyspace() + "." + currentTable();
execute("BEGIN BATCH " +
"INSERT INTO %s (k, s, i) VALUES (100, 'batchtext', 7); " +
"INSERT INTO " + qualifiedTable + " (k, s, i) VALUES (111, 'batchtext', 7); " +
"UPDATE " + qualifiedTable + " SET s=?, i=? WHERE k = 100; " +
"UPDATE " + qualifiedTable + " SET s=?, i=? WHERE k=111; " +
"APPLY BATCH;", null, unset(), unset(), null);
assertRows(execute("SELECT k, s, i FROM %s where k in (100,111)"),
row(100, null, 7),
row(111, "batchtext", null)
);
}
}

View File

@ -1,35 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
import org.junit.Test;
public class RangeDeletionTest extends CQLTester
{
@Test
public void testCassandra8558() throws Throwable
{
createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c))");
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 1, 1, 1, 1);
flush();
execute("DELETE FROM %s WHERE a=? AND b=?", 1, 1);
flush();
assertEmpty(execute("SELECT * FROM %s WHERE a=? AND b=? AND c=?", 1, 1, 1));
}
}

View File

@ -1,233 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
import org.junit.Test;
public class SelectionOrderingTest extends CQLTester
{
@Test
public void testNormalSelectionOrderSingleClustering() throws Throwable
{
for (String descOption : new String[]{"", " WITH CLUSTERING ORDER BY (b DESC)"})
{
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))" + descOption);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 0, 0);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 1, 1);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 2, 2);
assertRows(execute("SELECT * FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0, 0, 0),
row(0, 1, 1),
row(0, 2, 2)
);
assertRows(execute("SELECT * FROM %s WHERE a=? ORDER BY b DESC", 0),
row(0, 2, 2),
row(0, 1, 1),
row(0, 0, 0)
);
// order by the only column in the selection
assertRows(execute("SELECT b FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0), row(1), row(2));
assertRows(execute("SELECT b FROM %s WHERE a=? ORDER BY b DESC", 0),
row(2), row(1), row(0));
// order by a column not in the selection
assertRows(execute("SELECT c FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0), row(1), row(2));
assertRows(execute("SELECT c FROM %s WHERE a=? ORDER BY b DESC", 0),
row(2), row(1), row(0));
}
}
@Test
public void testFunctionSelectionOrderSingleClustering() throws Throwable
{
for (String descOption : new String[]{"", " WITH CLUSTERING ORDER BY (b DESC)"})
{
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))" + descOption);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 0, 0);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 1, 1);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 2, 2);
// order by the only column in the selection
assertRows(execute("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0), row(1), row(2));
assertRows(execute("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b DESC", 0),
row(2), row(1), row(0));
// order by a column not in the selection
assertRows(execute("SELECT blobAsInt(intAsBlob(c)) FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0), row(1), row(2));
assertRows(execute("SELECT blobAsInt(intAsBlob(c)) FROM %s WHERE a=? ORDER BY b DESC", 0),
row(2), row(1), row(0));
assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY c ASC", 0);
assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY c DESC", 0);
}
}
@Test
public void testFieldSelectionOrderSingleClustering() throws Throwable
{
String type = createType("CREATE TYPE %s (a int)");
for (String descOption : new String[]{"", " WITH CLUSTERING ORDER BY (b DESC)"})
{
createTable("CREATE TABLE %s (a int, b int, c frozen<" + type + " >, PRIMARY KEY (a, b))" + descOption);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, {a: ?})", 0, 0, 0);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, {a: ?})", 0, 1, 1);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, {a: ?})", 0, 2, 2);
// order by a column not in the selection
assertRows(execute("SELECT c.a FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0), row(1), row(2));
assertRows(execute("SELECT c.a FROM %s WHERE a=? ORDER BY b DESC", 0),
row(2), row(1), row(0));
assertRows(execute("SELECT blobAsInt(intAsBlob(c.a)) FROM %s WHERE a=? ORDER BY b DESC", 0),
row(2), row(1), row(0));
dropTable("DROP TABLE %s");
}
}
@Test
public void testNormalSelectionOrderMultipleClustering() throws Throwable
{
createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c))");
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 0, 0);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 1);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 2, 2);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 0, 3);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 4);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 2, 5);
assertRows(execute("SELECT * FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0, 0, 0, 0),
row(0, 0, 1, 1),
row(0, 0, 2, 2),
row(0, 1, 0, 3),
row(0, 1, 1, 4),
row(0, 1, 2, 5)
);
assertRows(execute("SELECT * FROM %s WHERE a=? ORDER BY b DESC", 0),
row(0, 1, 2, 5),
row(0, 1, 1, 4),
row(0, 1, 0, 3),
row(0, 0, 2, 2),
row(0, 0, 1, 1),
row(0, 0, 0, 0)
);
assertRows(execute("SELECT * FROM %s WHERE a=? ORDER BY b DESC, c DESC", 0),
row(0, 1, 2, 5),
row(0, 1, 1, 4),
row(0, 1, 0, 3),
row(0, 0, 2, 2),
row(0, 0, 1, 1),
row(0, 0, 0, 0)
);
assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY c ASC", 0);
assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY c DESC", 0);
assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY b ASC, c DESC", 0);
assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY b DESC, c ASC", 0);
assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY d ASC", 0);
// select and order by b
assertRows(execute("SELECT b FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0), row(0), row(0), row(1), row(1), row(1));
assertRows(execute("SELECT b FROM %s WHERE a=? ORDER BY b DESC", 0),
row(1), row(1), row(1), row(0), row(0), row(0));
// select c, order by b
assertRows(execute("SELECT c FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0), row(1), row(2), row(0), row(1), row(2));
assertRows(execute("SELECT c FROM %s WHERE a=? ORDER BY b DESC", 0),
row(2), row(1), row(0), row(2), row(1), row(0));
// select c, order by b, c
assertRows(execute("SELECT c FROM %s WHERE a=? ORDER BY b ASC, c ASC", 0),
row(0), row(1), row(2), row(0), row(1), row(2));
assertRows(execute("SELECT c FROM %s WHERE a=? ORDER BY b DESC, c DESC", 0),
row(2), row(1), row(0), row(2), row(1), row(0));
// select d, order by b, c
assertRows(execute("SELECT d FROM %s WHERE a=? ORDER BY b ASC, c ASC", 0),
row(0), row(1), row(2), row(3), row(4), row(5));
assertRows(execute("SELECT d FROM %s WHERE a=? ORDER BY b DESC, c DESC", 0),
row(5), row(4), row(3), row(2), row(1), row(0));
}
@Test
public void testFunctionSelectionOrderMultipleClustering() throws Throwable
{
createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c))");
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 0, 0);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 1);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 2, 2);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 0, 3);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 4);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 2, 5);
assertInvalid("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY c ASC", 0);
assertInvalid("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY c DESC", 0);
assertInvalid("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b ASC, c DESC", 0);
assertInvalid("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b DESC, c ASC", 0);
assertInvalid("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY d ASC", 0);
// select and order by b
assertRows(execute("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0), row(0), row(0), row(1), row(1), row(1));
assertRows(execute("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b DESC", 0),
row(1), row(1), row(1), row(0), row(0), row(0));
assertRows(execute("SELECT b, blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0, 0), row(0, 0), row(0, 0), row(1, 1), row(1, 1), row(1, 1));
assertRows(execute("SELECT b, blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b DESC", 0),
row(1, 1), row(1, 1), row(1, 1), row(0, 0), row(0, 0), row(0, 0));
// select c, order by b
assertRows(execute("SELECT blobAsInt(intAsBlob(c)) FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0), row(1), row(2), row(0), row(1), row(2));
assertRows(execute("SELECT blobAsInt(intAsBlob(c)) FROM %s WHERE a=? ORDER BY b DESC", 0),
row(2), row(1), row(0), row(2), row(1), row(0));
// select c, order by b, c
assertRows(execute("SELECT blobAsInt(intAsBlob(c)) FROM %s WHERE a=? ORDER BY b ASC, c ASC", 0),
row(0), row(1), row(2), row(0), row(1), row(2));
assertRows(execute("SELECT blobAsInt(intAsBlob(c)) FROM %s WHERE a=? ORDER BY b DESC, c DESC", 0),
row(2), row(1), row(0), row(2), row(1), row(0));
// select d, order by b, c
assertRows(execute("SELECT blobAsInt(intAsBlob(d)) FROM %s WHERE a=? ORDER BY b ASC, c ASC", 0),
row(0), row(1), row(2), row(3), row(4), row(5));
assertRows(execute("SELECT blobAsInt(intAsBlob(d)) FROM %s WHERE a=? ORDER BY b DESC, c DESC", 0),
row(5), row(4), row(3), row(2), row(1), row(0));
}
}

View File

@ -1,280 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
import org.junit.Test;
/**
* Test column ranges and ordering with static column in table
*/
public class StaticColumnsQueryTest extends CQLTester
{
@Test
public void testSingleClustering() throws Throwable
{
createTable("CREATE TABLE %s (p text, c text, v text, s text static, PRIMARY KEY (p, c))");
execute("INSERT INTO %s(p, c, v, s) values (?, ?, ?, ?)", "p1", "k1", "v1", "sv1");
execute("INSERT INTO %s(p, c, v) values (?, ?, ?)", "p1", "k2", "v2");
execute("INSERT INTO %s(p, s) values (?, ?)", "p2", "sv2");
assertRows(execute("SELECT * FROM %s WHERE p=?", "p1"),
row("p1", "k1", "sv1", "v1"),
row("p1", "k2", "sv1", "v2")
);
assertRows(execute("SELECT * FROM %s WHERE p=?", "p2"),
row("p2", null, "sv2", null)
);
// Ascending order
assertRows(execute("SELECT * FROM %s WHERE p=? ORDER BY c ASC", "p1"),
row("p1", "k1", "sv1", "v1"),
row("p1", "k2", "sv1", "v2")
);
assertRows(execute("SELECT * FROM %s WHERE p=? ORDER BY c ASC", "p2"),
row("p2", null, "sv2", null)
);
// Descending order
assertRows(execute("SELECT * FROM %s WHERE p=? ORDER BY c DESC", "p1"),
row("p1", "k2", "sv1", "v2"),
row("p1", "k1", "sv1", "v1")
);
assertRows(execute("SELECT * FROM %s WHERE p=? ORDER BY c DESC", "p2"),
row("p2", null, "sv2", null)
);
// No order with one relation
assertRows(execute("SELECT * FROM %s WHERE p=? AND c>=?", "p1", "k1"),
row("p1", "k1", "sv1", "v1"),
row("p1", "k2", "sv1", "v2")
);
assertRows(execute("SELECT * FROM %s WHERE p=? AND c>=?", "p1", "k2"),
row("p1", "k2", "sv1", "v2")
);
assertEmpty(execute("SELECT * FROM %s WHERE p=? AND c>=?", "p1", "k3"));
assertRows(execute("SELECT * FROM %s WHERE p=? AND c =?", "p1", "k1"),
row("p1", "k1", "sv1", "v1")
);
assertRows(execute("SELECT * FROM %s WHERE p=? AND c<=?", "p1", "k1"),
row("p1", "k1", "sv1", "v1")
);
assertEmpty(execute("SELECT * FROM %s WHERE p=? AND c<=?", "p1", "k0"));
// Ascending with one relation
assertRows(execute("SELECT * FROM %s WHERE p=? AND c>=? ORDER BY c ASC", "p1", "k1"),
row("p1", "k1", "sv1", "v1"),
row("p1", "k2", "sv1", "v2")
);
assertRows(execute("SELECT * FROM %s WHERE p=? AND c>=? ORDER BY c ASC", "p1", "k2"),
row("p1", "k2", "sv1", "v2")
);
assertEmpty(execute("SELECT * FROM %s WHERE p=? AND c>=? ORDER BY c ASC", "p1", "k3"));
assertRows(execute("SELECT * FROM %s WHERE p=? AND c =? ORDER BY c ASC", "p1", "k1"),
row("p1", "k1", "sv1", "v1")
);
assertRows(execute("SELECT * FROM %s WHERE p=? AND c<=? ORDER BY c ASC", "p1", "k1"),
row("p1", "k1", "sv1", "v1")
);
assertEmpty(execute("SELECT * FROM %s WHERE p=? AND c<=? ORDER BY c ASC", "p1", "k0"));
// Descending with one relation
assertRows(execute("SELECT * FROM %s WHERE p=? AND c>=? ORDER BY c DESC", "p1", "k1"),
row("p1", "k2", "sv1", "v2"),
row("p1", "k1", "sv1", "v1")
);
assertRows(execute("SELECT * FROM %s WHERE p=? AND c>=? ORDER BY c DESC", "p1", "k2"),
row("p1", "k2", "sv1", "v2")
);
assertEmpty(execute("SELECT * FROM %s WHERE p=? AND c>=? ORDER BY c DESC", "p1", "k3"));
assertRows(execute("SELECT * FROM %s WHERE p=? AND c =? ORDER BY c DESC", "p1", "k1"),
row("p1", "k1", "sv1", "v1")
);
assertRows(execute("SELECT * FROM %s WHERE p=? AND c<=? ORDER BY c DESC", "p1", "k1"),
row("p1", "k1", "sv1", "v1")
);
assertEmpty(execute("SELECT * FROM %s WHERE p=? AND c<=? ORDER BY c DESC", "p1", "k0"));
// IN
assertRows(execute("SELECT * FROM %s WHERE p=? AND c IN (?, ?)", "p1", "k1", "k2"),
row("p1", "k1", "sv1", "v1"),
row("p1", "k2", "sv1", "v2")
);
assertRows(execute("SELECT * FROM %s WHERE p=? AND c IN (?, ?) ORDER BY c ASC", "p1", "k1", "k2"),
row("p1", "k1", "sv1", "v1"),
row("p1", "k2", "sv1", "v2")
);
assertRows(execute("SELECT * FROM %s WHERE p=? AND c IN (?, ?) ORDER BY c DESC", "p1", "k1", "k2"),
row("p1", "k2", "sv1", "v2"),
row("p1", "k1", "sv1", "v1")
);
}
@Test
public void testSingleClusteringReversed() throws Throwable
{
createTable("CREATE TABLE %s (p text, c text, v text, s text static, PRIMARY KEY (p, c)) WITH CLUSTERING ORDER BY (c DESC)");
execute("INSERT INTO %s(p, c, v, s) values (?, ?, ?, ?)", "p1", "k1", "v1", "sv1");
execute("INSERT INTO %s(p, c, v) values (?, ?, ?)", "p1", "k2", "v2");
execute("INSERT INTO %s(p, s) values (?, ?)", "p2", "sv2");
assertRows(execute("SELECT * FROM %s WHERE p=?", "p1"),
row("p1", "k2", "sv1", "v2"),
row("p1", "k1", "sv1", "v1")
);
assertRows(execute("SELECT * FROM %s WHERE p=?", "p2"),
row("p2", null, "sv2", null)
);
// Ascending order
assertRows(execute("SELECT * FROM %s WHERE p=? ORDER BY c ASC", "p1"),
row("p1", "k1", "sv1", "v1"),
row("p1", "k2", "sv1", "v2")
);
assertRows(execute("SELECT * FROM %s WHERE p=? ORDER BY c ASC", "p2"),
row("p2", null, "sv2", null)
);
// Descending order
assertRows(execute("SELECT * FROM %s WHERE p=? ORDER BY c DESC", "p1"),
row("p1", "k2", "sv1", "v2"),
row("p1", "k1", "sv1", "v1")
);
assertRows(execute("SELECT * FROM %s WHERE p=? ORDER BY c DESC", "p2"),
row("p2", null, "sv2", null)
);
// No order with one relation
assertRows(execute("SELECT * FROM %s WHERE p=? AND c>=?", "p1", "k1"),
row("p1", "k2", "sv1", "v2"),
row("p1", "k1", "sv1", "v1")
);
assertRows(execute("SELECT * FROM %s WHERE p=? AND c>=?", "p1", "k2"),
row("p1", "k2", "sv1", "v2")
);
assertEmpty(execute("SELECT * FROM %s WHERE p=? AND c>=?", "p1", "k3"));
assertRows(execute("SELECT * FROM %s WHERE p=? AND c=?", "p1", "k1"),
row("p1", "k1", "sv1", "v1")
);
assertRows(execute("SELECT * FROM %s WHERE p=? AND c<=?", "p1", "k1"),
row("p1", "k1", "sv1", "v1")
);
assertEmpty(execute("SELECT * FROM %s WHERE p=? AND c<=?", "p1", "k0"));
// Ascending with one relation
assertRows(execute("SELECT * FROM %s WHERE p=? AND c>=? ORDER BY c ASC", "p1", "k1"),
row("p1", "k1", "sv1", "v1"),
row("p1", "k2", "sv1", "v2")
);
assertRows(execute("SELECT * FROM %s WHERE p=? AND c>=? ORDER BY c ASC", "p1", "k2"),
row("p1", "k2", "sv1", "v2")
);
assertEmpty(execute("SELECT * FROM %s WHERE p=? AND c>=? ORDER BY c ASC", "p1", "k3"));
assertRows(execute("SELECT * FROM %s WHERE p=? AND c=? ORDER BY c ASC", "p1", "k1"),
row("p1", "k1", "sv1", "v1")
);
assertRows(execute("SELECT * FROM %s WHERE p=? AND c<=? ORDER BY c ASC", "p1", "k1"),
row("p1", "k1", "sv1", "v1")
);
assertEmpty(execute("SELECT * FROM %s WHERE p=? AND c<=? ORDER BY c ASC", "p1", "k0"));
// Descending with one relation
assertRows(execute("SELECT * FROM %s WHERE p=? AND c>=? ORDER BY c DESC", "p1", "k1"),
row("p1", "k2", "sv1", "v2"),
row("p1", "k1", "sv1", "v1")
);
assertRows(execute("SELECT * FROM %s WHERE p=? AND c>=? ORDER BY c DESC", "p1", "k2"),
row("p1", "k2", "sv1", "v2")
);
assertEmpty(execute("SELECT * FROM %s WHERE p=? AND c>=? ORDER BY c DESC", "p1", "k3"));
assertRows(execute("SELECT * FROM %s WHERE p=? AND c=? ORDER BY c DESC", "p1", "k1"),
row("p1", "k1", "sv1", "v1")
);
assertRows(execute("SELECT * FROM %s WHERE p=? AND c<=? ORDER BY c DESC", "p1", "k1"),
row("p1", "k1", "sv1", "v1")
);
assertEmpty(execute("SELECT * FROM %s WHERE p=? AND c<=? ORDER BY c DESC", "p1", "k0"));
// IN
assertRows(execute("SELECT * FROM %s WHERE p=? AND c IN (?, ?)", "p1", "k1", "k2"),
row("p1", "k2", "sv1", "v2"),
row("p1", "k1", "sv1", "v1")
);
assertRows(execute("SELECT * FROM %s WHERE p=? AND c IN (?, ?) ORDER BY c ASC", "p1", "k1", "k2"),
row("p1", "k1", "sv1", "v1"),
row("p1", "k2", "sv1", "v2")
);
assertRows(execute("SELECT * FROM %s WHERE p=? AND c IN (?, ?) ORDER BY c DESC", "p1", "k1", "k2"),
row("p1", "k2", "sv1", "v2"),
row("p1", "k1", "sv1", "v1")
);
}
}

View File

@ -27,6 +27,7 @@ import org.junit.Test;
import org.apache.cassandra.SchemaLoader;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
public class ThriftCompatibilityTest extends SchemaLoader
{

View File

@ -3,13 +3,16 @@ package org.apache.cassandra.cql3.selection;
import java.util.Collections;
import com.google.common.collect.ImmutableList;
import org.junit.BeforeClass;
import org.junit.Test;
import org.apache.cassandra.config.ColumnDefinition;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.config.Schema;
import org.apache.cassandra.cql3.*;
import org.apache.cassandra.cql3.statements.SelectStatement;
import org.apache.cassandra.db.marshal.*;
import org.apache.cassandra.dht.ByteOrderedPartitioner;
import org.apache.cassandra.exceptions.RequestValidationException;
import org.apache.cassandra.service.ClientState;
import org.apache.cassandra.utils.ByteBufferUtil;
@ -25,6 +28,12 @@ public class SelectionColumnMappingTest extends CQLTester
UserType userType;
String functionName;
@BeforeClass
public static void setUpClass()
{
DatabaseDescriptor.setPartitioner(ByteOrderedPartitioner.instance);
}
@Test
public void testSelectionColumnMapping() throws Throwable
{

View File

@ -15,10 +15,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.entities;
import java.util.UUID;
import org.junit.Test;
import org.apache.cassandra.cql3.CQLTester;
public class CollectionsTest extends CQLTester
{
@Test
@ -85,26 +89,26 @@ public class CollectionsTest extends CQLTester
execute("DELETE s[?] FROM %s WHERE k = 0", "v1");
assertRows(execute("SELECT s FROM %s WHERE k = 0"),
row(set("v2", "v3", "v4"))
row(set("v2", "v3", "v4"))
);
// Full overwrite
execute("UPDATE %s SET s = ? WHERE k = 0", set("v6", "v5"));
assertRows(execute("SELECT s FROM %s WHERE k = 0"),
row(set("v5", "v6"))
row(set("v5", "v6"))
);
execute("UPDATE %s SET s = s + ? WHERE k = 0", set("v7"));
assertRows(execute("SELECT s FROM %s WHERE k = 0"),
row(set("v5", "v6", "v7"))
row(set("v5", "v6", "v7"))
);
execute("UPDATE %s SET s = s - ? WHERE k = 0", set("v6", "v5"));
assertRows(execute("SELECT s FROM %s WHERE k = 0"),
row(set("v7"))
row(set("v7"))
);
execute("DELETE s[?] FROM %s WHERE k = 0", set("v7"));
@ -115,7 +119,7 @@ public class CollectionsTest extends CQLTester
execute("DELETE s FROM %s WHERE k = 0");
assertRows(execute("SELECT s FROM %s WHERE k = 0"),
row((Object)null)
row((Object) null)
);
}
@ -146,38 +150,38 @@ public class CollectionsTest extends CQLTester
execute("UPDATE %s SET m = ? WHERE k = 0", map("v6", 6, "v5", 5));
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map("v5", 5, "v6", 6))
row(map("v5", 5, "v6", 6))
);
execute("UPDATE %s SET m = m + ? WHERE k = 0", map("v7", 7));
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map("v5", 5, "v6", 6, "v7", 7))
row(map("v5", 5, "v6", 6, "v7", 7))
);
execute("DELETE m[?] FROM %s WHERE k = 0", "v7");
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map("v5", 5, "v6", 6))
row(map("v5", 5, "v6", 6))
);
execute("DELETE m[?] FROM %s WHERE k = 0", "v6");
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row(map("v5", 5))
row(map("v5", 5))
);
execute("DELETE m[?] FROM %s WHERE k = 0", "v5");
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row((Object)null)
row((Object) null)
);
// Deleting a non-existing key should succeed
execute("DELETE m[?] FROM %s WHERE k = 0", "v5");
assertRows(execute("SELECT m FROM %s WHERE k = 0"),
row((Object) null)
row((Object) null)
);
// The empty map is parsed as an empty set (because we don't have enough info at parsing
@ -246,18 +250,18 @@ public class CollectionsTest extends CQLTester
Object m = map("k", "v");
execute("INSERT INTO %s (k, m) VALUES (10, ?)", m);
assertRows(execute("SELECT m FROM %s WHERE k = 10"),
row(m)
row(m)
);
// test putting an unset map, should not delete the contents
execute("INSERT INTO %s (k, m) VALUES (10, ?)", unset());
assertRows(execute("SELECT m FROM %s WHERE k = 10"),
row(m)
row(m)
);
// test unset variables in a map update operaiotn, should not delete the contents
execute("UPDATE %s SET m['k'] = ? WHERE k = 10", unset());
assertRows(execute("SELECT m FROM %s WHERE k = 10"),
row(m)
row(m)
);
assertInvalidMessage("Invalid unset map key", "UPDATE %s SET m[?] = 'foo' WHERE k = 10", unset());
@ -273,19 +277,19 @@ public class CollectionsTest extends CQLTester
Object l = list("foo", "foo");
execute("INSERT INTO %s (k, l) VALUES (10, ?)", l);
assertRows(execute("SELECT l FROM %s WHERE k = 10"),
row(l)
row(l)
);
// replace list with unset value
execute("INSERT INTO %s (k, l) VALUES (10, ?)", unset());
assertRows(execute("SELECT l FROM %s WHERE k = 10"),
row(l)
row(l)
);
// add to position
execute("UPDATE %s SET l[1] = ? WHERE k = 10", unset());
assertRows(execute("SELECT l FROM %s WHERE k = 10"),
row(l)
row(l)
);
// set in index
@ -294,13 +298,13 @@ public class CollectionsTest extends CQLTester
// remove element by index
execute("DELETE l[?] FROM %s WHERE k = 10", unset());
assertRows(execute("SELECT l FROM %s WHERE k = 10"),
row(l)
row(l)
);
// remove all occurrences of element
execute("UPDATE %s SET l = l - ? WHERE k = 10", unset());
assertRows(execute("SELECT l FROM %s WHERE k = 10"),
row(l)
row(l)
);
// select with in clause
@ -316,25 +320,269 @@ public class CollectionsTest extends CQLTester
Object s = set("bar", "baz", "foo");
execute("INSERT INTO %s (k, s) VALUES (10, ?)", s);
assertRows(execute("SELECT s FROM %s WHERE k = 10"),
row(s)
row(s)
);
// replace set with unset value
execute("INSERT INTO %s (k, s) VALUES (10, ?)", unset());
assertRows(execute("SELECT s FROM %s WHERE k = 10"),
row(s)
row(s)
);
// add to set
execute("UPDATE %s SET s = s + ? WHERE k = 10", unset());
assertRows(execute("SELECT s FROM %s WHERE k = 10"),
row(s)
row(s)
);
// remove all occurrences of element
execute("UPDATE %s SET s = s - ? WHERE k = 10", unset());
assertRows(execute("SELECT s FROM %s WHERE k = 10"),
row(s)
row(s)
);
}
/**
* Migrated from cql_tests.py:TestCQL.set_test()
*/
@Test
public void testSet() throws Throwable
{
createTable("CREATE TABLE %s ( fn text, ln text, tags set<text>, PRIMARY KEY (fn, ln) )");
execute("UPDATE %s SET tags = tags + { 'foo' } WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET tags = tags + { 'bar' } WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET tags = tags + { 'foo' } WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET tags = tags + { 'foobar' } WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET tags = tags - { 'bar' } WHERE fn='Tom' AND ln='Bombadil'");
assertRows(execute("SELECT tags FROM %s"),
row(set("foo", "foobar")));
execute("UPDATE %s SET tags = { 'a', 'c', 'b' } WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(set("a", "b", "c")));
execute("UPDATE %s SET tags = { 'm', 'n' } WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(set("m", "n")));
execute("DELETE tags['m'] FROM %s WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(set("n")));
execute("DELETE tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'");
assertEmpty(execute("SELECT tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'"));
}
/**
* Migrated from cql_tests.py:TestCQL.map_test()
*/
@Test
public void testMap() throws Throwable
{
createTable("CREATE TABLE %s (fn text, ln text, m map<text, int>, PRIMARY KEY (fn, ln))");
execute("UPDATE %s SET m['foo'] = 3 WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET m['bar'] = 4 WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET m['woot'] = 5 WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET m['bar'] = 6 WHERE fn='Tom' AND ln='Bombadil'");
execute("DELETE m['foo'] FROM %s WHERE fn='Tom' AND ln='Bombadil'");
assertRows(execute("SELECT m FROM %s"),
row(map("bar", 6, "woot", 5)));
execute("UPDATE %s SET m = { 'a' : 4 , 'c' : 3, 'b' : 2 } WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT m FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(map("a", 4, "b", 2, "c", 3)));
execute("UPDATE %s SET m = { 'm' : 4 , 'n' : 1, 'o' : 2 } WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT m FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(map("m", 4, "n", 1, "o", 2)));
execute("UPDATE %s SET m = {} WHERE fn='Bilbo' AND ln='Baggins'");
assertEmpty(execute("SELECT m FROM %s WHERE fn='Bilbo' AND ln='Baggins'"));
}
/**
* Migrated from cql_tests.py:TestCQL.list_test()
*/
@Test
public void testList() throws Throwable
{
createTable("CREATE TABLE %s (fn text, ln text, tags list<text>, PRIMARY KEY (fn, ln))");
execute("UPDATE %s SET tags = tags + [ 'foo' ] WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET tags = tags + [ 'bar' ] WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET tags = tags + [ 'foo' ] WHERE fn='Tom' AND ln='Bombadil'");
execute("UPDATE %s SET tags = tags + [ 'foobar' ] WHERE fn='Tom' AND ln='Bombadil'");
assertRows(execute("SELECT tags FROM %s"),
row(list("foo", "bar", "foo", "foobar")));
execute("UPDATE %s SET tags = [ 'a', 'c', 'b', 'c' ] WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(list("a", "c", "b", "c")));
execute("UPDATE %s SET tags = [ 'm', 'n' ] + tags WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(list("m", "n", "a", "c", "b", "c")));
execute("UPDATE %s SET tags[2] = 'foo', tags[4] = 'bar' WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(list("m", "n", "foo", "c", "bar", "c")));
execute("DELETE tags[2] FROM %s WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(list("m", "n", "c", "bar", "c")));
execute("UPDATE %s SET tags = tags - [ 'bar' ] WHERE fn='Bilbo' AND ln='Baggins'");
assertRows(execute("SELECT tags FROM %s WHERE fn='Bilbo' AND ln='Baggins'"),
row(list("m", "n", "c", "c")));
}
/**
* Migrated from cql_tests.py:TestCQL.multi_collection_test()
*/
@Test
public void testMultiCollections() throws Throwable
{
UUID id = UUID.fromString("b017f48f-ae67-11e1-9096-005056c00008");
createTable("CREATE TABLE %s (k uuid PRIMARY KEY, L list<int>, M map<text, int>, S set<int> )");
execute("UPDATE %s SET L = [1, 3, 5] WHERE k = ?", id);
execute("UPDATE %s SET L = L + [7, 11, 13] WHERE k = ?;", id);
execute("UPDATE %s SET S = {1, 3, 5} WHERE k = ?", id);
execute("UPDATE %s SET S = S + {7, 11, 13} WHERE k = ?", id);
execute("UPDATE %s SET M = {'foo': 1, 'bar' : 3} WHERE k = ?", id);
execute("UPDATE %s SET M = M + {'foobar' : 4} WHERE k = ?", id);
assertRows(execute("SELECT L, M, S FROM %s WHERE k = ?", id),
row(list(1, 3, 5, 7, 11, 13),
map("bar", 3, "foo", 1, "foobar", 4),
set(1, 3, 5, 7, 11, 13)));
}
/**
* Migrated from cql_tests.py:TestCQL.collection_and_regular_test()
*/
@Test
public void testCollectionAndRegularColumns() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, l list<int>, c int)");
execute("INSERT INTO %s (k, l, c) VALUES(3, [0, 1, 2], 4)");
execute("UPDATE %s SET l[0] = 1, c = 42 WHERE k = 3");
assertRows(execute("SELECT l, c FROM %s WHERE k = 3"),
row(list(1, 1, 2), 42));
}
/**
* Migrated from cql_tests.py:TestCQL.multi_list_set_test()
*/
@Test
public void testMultipleLists() throws Throwable
{
createTable(" CREATE TABLE %s (k int PRIMARY KEY, l1 list<int>, l2 list<int>)");
execute("INSERT INTO %s (k, l1, l2) VALUES (0, [1, 2, 3], [4, 5, 6])");
execute("UPDATE %s SET l2[1] = 42, l1[1] = 24 WHERE k = 0");
assertRows(execute("SELECT l1, l2 FROM %s WHERE k = 0"),
row(list(1, 24, 3), list(4, 42, 6)));
}
/**
* Test you can add columns in a table with collections (#4982 bug),
* migrated from cql_tests.py:TestCQL.alter_with_collections_test()
*/
@Test
public void testAlterCollections() throws Throwable
{
createTable("CREATE TABLE %s (key int PRIMARY KEY, aset set<text>)");
execute("ALTER TABLE %s ADD c text");
execute("ALTER TABLE %s ADD alist list<text>");
}
/**
* Migrated from cql_tests.py:TestCQL.collection_compact_test()
*/
@Test
public void testCompactCollections() throws Throwable
{
String tableName = KEYSPACE + "." + createTableName();
assertInvalid(String.format("CREATE TABLE %s (user ascii PRIMARY KEY, mails list < text >) WITH COMPACT STORAGE;", tableName));
}
/**
* Migrated from cql_tests.py:TestCQL.collection_function_test()
*/
@Test
public void testFunctionsOnCollections() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, l set<int>)");
assertInvalid("SELECT ttl(l) FROM %s WHERE k = 0");
assertInvalid("SELECT writetime(l) FROM %s WHERE k = 0");
}
/**
* Migrated from cql_tests.py:TestCQL.bug_5376()
*/
@Test
public void testInClauseWithCollections() throws Throwable
{
createTable("CREATE TABLE %s (key text, c bigint, v text, x set < text >, PRIMARY KEY(key, c) )");
assertInvalid("select * from %s where key = 'foo' and c in (1,3,4)");
}
/**
* Test for bug #5795,
* migrated from cql_tests.py:TestCQL.nonpure_function_collection_test()
*/
@Test
public void testNonPureFunctionCollection() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, v list<timeuuid>)");
// we just want to make sure this doesn't throw
execute("INSERT INTO %s (k, v) VALUES (0, [now()])");
}
/**
* Test for 5805 bug,
* migrated from cql_tests.py:TestCQL.collection_flush_test()
*/
@Test
public void testCollectionFlush() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, s set<int>)");
execute("INSERT INTO %s (k, s) VALUES (1, {1})");
flush();
execute("INSERT INTO %s (k, s) VALUES (1, {2})");
flush();
assertRows(execute("SELECT * FROM %s"),
row(1, set(2)));
}
/**
* Test for 6276,
* migrated from cql_tests.py:TestCQL.drop_and_readd_collection_test()
*/
@Test
public void testDropAndReaddCollection() throws Throwable
{
createTable("create table %s (k int primary key, v set<text>, x int)");
execute("insert into %s (k, v) VALUES (0, {'fffffffff'})");
flush();
execute("alter table %s drop v");
assertInvalid("alter table %s add v set<int>");
}
}

View File

@ -0,0 +1,115 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3.validation.entities;
import org.junit.Test;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.exceptions.InvalidRequestException;
public class CountersTest extends CQLTester
{
/**
* Check for a table with counters,
* migrated from cql_tests.py:TestCQL.counters_test()
*/
@Test
public void testCounters() throws Throwable
{
createTable("CREATE TABLE %s (userid int, url text, total counter, PRIMARY KEY (userid, url)) WITH COMPACT STORAGE");
execute("UPDATE %s SET total = total + 1 WHERE userid = 1 AND url = 'http://foo.com'");
assertRows(execute("SELECT total FROM %s WHERE userid = 1 AND url = 'http://foo.com'"),
row(1L));
execute("UPDATE %s SET total = total - 4 WHERE userid = 1 AND url = 'http://foo.com'");
assertRows(execute("SELECT total FROM %s WHERE userid = 1 AND url = 'http://foo.com'"),
row(-3L));
execute("UPDATE %s SET total = total+1 WHERE userid = 1 AND url = 'http://foo.com'");
assertRows(execute("SELECT total FROM %s WHERE userid = 1 AND url = 'http://foo.com'"),
row(-2L));
execute("UPDATE %s SET total = total -2 WHERE userid = 1 AND url = 'http://foo.com'");
assertRows(execute("SELECT total FROM %s WHERE userid = 1 AND url = 'http://foo.com'"),
row(-4L));
}
/**
* Test for the validation bug of #4706,
* migrated from cql_tests.py:TestCQL.validate_counter_regular_test()
*/
@Test
public void testRegularCounters() throws Throwable
{
assertInvalidThrowMessage("Cannot add a non counter column",
ConfigurationException.class,
String.format("CREATE TABLE %s.%s (id bigint PRIMARY KEY, count counter, things set<text>)", KEYSPACE, createTableName()));
}
/**
* Migrated from cql_tests.py:TestCQL.collection_counter_test()
*/
@Test
public void testCountersOnCollections() throws Throwable
{
String tableName = KEYSPACE + "." + createTableName();
assertInvalidThrow(InvalidRequestException.class,
String.format("CREATE TABLE %s (k int PRIMARY KEY, l list<counter>)", tableName));
tableName = KEYSPACE + "." + createTableName();
assertInvalidThrow(InvalidRequestException.class,
String.format("CREATE TABLE %s (k int PRIMARY KEY, s set<counter>)", tableName));
tableName = KEYSPACE + "." + createTableName();
assertInvalidThrow(InvalidRequestException.class,
String.format("CREATE TABLE %s (k int PRIMARY KEY, m map<text, counter>)", tableName));
}
@Test
public void testCounterUpdatesWithUnset() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, c counter)");
// set up
execute("UPDATE %s SET c = c + 1 WHERE k = 10");
assertRows(execute("SELECT c FROM %s WHERE k = 10"),
row(1L)
);
// increment
execute("UPDATE %s SET c = c + ? WHERE k = 10", 1L);
assertRows(execute("SELECT c FROM %s WHERE k = 10"),
row(2L)
);
execute("UPDATE %s SET c = c + ? WHERE k = 10", unset());
assertRows(execute("SELECT c FROM %s WHERE k = 10"),
row(2L) // no change to the counter value
);
// decrement
execute("UPDATE %s SET c = c - ? WHERE k = 10", 1L);
assertRows(execute("SELECT c FROM %s WHERE k = 10"),
row(1L)
);
execute("UPDATE %s SET c = c - ? WHERE k = 10", unset());
assertRows(execute("SELECT c FROM %s WHERE k = 10"),
row(1L) // no change to the counter value
);
}
}

View File

@ -15,22 +15,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.entities;
import org.junit.Test;
public class TimestampTest extends CQLTester
import org.apache.cassandra.cql3.CQLTester;
public class DateTypeTest extends CQLTester
{
/**
* Check dates are correctly recognized and validated,
* migrated from cql_tests.py:TestCQL.date_test()
*/
@Test
public void testNegativeTimestamps() throws Throwable
public void testDate() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, v int)");
createTable("CREATE TABLE %s (k int PRIMARY KEY, t timestamp)");
execute("INSERT INTO %s (k, v) VALUES (?, ?) USING TIMESTAMP ?", 1, 1, -42L);
assertRows(execute("SELECT writetime(v) FROM %s WHERE k = ?", 1),
row(-42L)
);
assertInvalid("INSERT INTO %s (k, v) VALUES (?, ?) USING TIMESTAMP ?", 2, 2, Long.MIN_VALUE);
execute("INSERT INTO %s (k, t) VALUES (0, '2011-02-03')");
assertInvalid("INSERT INTO %s (k, t) VALUES (0, '2011-42-42')");
}
}

View File

@ -15,14 +15,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.entities;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.db.marshal.*;
import org.apache.cassandra.dht.ByteOrderedPartitioner;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.exceptions.InvalidRequestException;
import org.apache.cassandra.exceptions.SyntaxException;
import org.apache.commons.lang3.StringUtils;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.ArrayList;
@ -33,6 +37,12 @@ import static org.junit.Assert.assertEquals;
public class FrozenCollectionsTest extends CQLTester
{
@BeforeClass
public static void setUpClass()
{
DatabaseDescriptor.setPartitioner(new ByteOrderedPartitioner());
}
@Test
public void testPartitionKeyUsage() throws Throwable
{

View File

@ -15,11 +15,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.entities;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.cql3.Json;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.dht.ByteOrderedPartitioner;
import org.apache.cassandra.serializers.SimpleDateSerializer;
import org.apache.cassandra.serializers.TimeSerializer;
import org.apache.cassandra.utils.ByteBufferUtil;
import org.junit.BeforeClass;
import org.junit.Test;
import java.math.BigDecimal;
@ -35,6 +41,11 @@ import static org.junit.Assert.fail;
public class JsonTest extends CQLTester
{
@BeforeClass
public static void setUp()
{
DatabaseDescriptor.setPartitioner(ByteOrderedPartitioner.instance);
}
@Test
public void testFromJsonFct() throws Throwable

View File

@ -15,10 +15,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.entities;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.cql3.UntypedResultSet;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.dht.ByteOrderedPartitioner;
import org.apache.cassandra.exceptions.InvalidRequestException;
import org.apache.commons.lang3.StringUtils;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.ArrayList;
@ -30,6 +35,12 @@ import static org.junit.Assert.fail;
public class SecondaryIndexOnMapEntriesTest extends CQLTester
{
@BeforeClass
public static void setUp()
{
DatabaseDescriptor.setPartitioner(ByteOrderedPartitioner.instance);
}
@Test
public void testShouldNotCreateIndexOnFrozenMaps() throws Throwable
{

View File

@ -0,0 +1,645 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3.validation.entities;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.exceptions.SyntaxException;
import org.apache.cassandra.utils.FBUtilities;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class SecondaryIndexTest extends CQLTester
{
private static final int TOO_BIG = 1024 * 65;
@Test
public void testCreateAndDropIndex() throws Throwable
{
testCreateAndDropIndex("test", false);
testCreateAndDropIndex("test2", true);
}
@Test
public void testCreateAndDropIndexWithQuotedIdentifier() throws Throwable
{
testCreateAndDropIndex("\"quoted_ident\"", false);
testCreateAndDropIndex("\"quoted_ident2\"", true);
}
@Test
public void testCreateAndDropIndexWithCamelCaseIdentifier() throws Throwable
{
testCreateAndDropIndex("CamelCase", false);
testCreateAndDropIndex("CamelCase2", true);
}
/**
* Test creating and dropping an index with the specified name.
*
* @param indexName the index name
* @param addKeyspaceOnDrop add the keyspace name in the drop statement
* @throws Throwable if an error occurs
*/
private void testCreateAndDropIndex(String indexName, boolean addKeyspaceOnDrop) throws Throwable
{
execute("USE system");
assertInvalidMessage("Index '" + removeQuotes(indexName.toLowerCase(Locale.US)) + "' could not be found", "DROP INDEX " + indexName + ";");
createTable("CREATE TABLE %s (a int primary key, b int);");
createIndex("CREATE INDEX " + indexName + " ON %s(b);");
createIndex("CREATE INDEX IF NOT EXISTS " + indexName + " ON %s(b);");
assertInvalidMessage("Index already exists", "CREATE INDEX " + indexName + " ON %s(b)");
execute("INSERT INTO %s (a, b) values (?, ?);", 0, 0);
execute("INSERT INTO %s (a, b) values (?, ?);", 1, 1);
execute("INSERT INTO %s (a, b) values (?, ?);", 2, 2);
execute("INSERT INTO %s (a, b) values (?, ?);", 3, 1);
assertRows(execute("SELECT * FROM %s where b = ?", 1), row(1, 1), row(3, 1));
assertInvalidMessage("Index '" + removeQuotes(indexName.toLowerCase(Locale.US)) + "' could not be found in any of the tables of keyspace 'system'",
"DROP INDEX " + indexName);
if (addKeyspaceOnDrop)
{
dropIndex("DROP INDEX " + KEYSPACE + "." + indexName);
}
else
{
execute("USE " + KEYSPACE);
execute("DROP INDEX " + indexName);
}
assertInvalidMessage("No secondary indexes on the restricted columns support the provided operators",
"SELECT * FROM %s where b = ?", 1);
dropIndex("DROP INDEX IF EXISTS " + indexName);
assertInvalidMessage("Index '" + removeQuotes(indexName.toLowerCase(Locale.US)) + "' could not be found", "DROP INDEX " + indexName);
}
/**
* Removes the quotes from the specified index name.
*
* @param indexName the index name from which the quotes must be removed.
* @return the unquoted index name.
*/
private static String removeQuotes(String indexName)
{
return StringUtils.remove(indexName, '\"');
}
/**
* Check that you can query for an indexed column even with a key EQ clause,
* migrated from cql_tests.py:TestCQL.static_cf_test()
*/
@Test
public void testSelectWithEQ() throws Throwable
{
createTable("CREATE TABLE %s (userid uuid PRIMARY KEY, firstname text, lastname text, age int)");
createIndex("CREATE INDEX byAge ON %s(age)");
UUID id1 = UUID.fromString("550e8400-e29b-41d4-a716-446655440000");
UUID id2 = UUID.fromString("f47ac10b-58cc-4372-a567-0e02b2c3d479");
execute("INSERT INTO %s (userid, firstname, lastname, age) VALUES (?, 'Frodo', 'Baggins', 32)", id1);
execute("UPDATE %s SET firstname = 'Samwise', lastname = 'Gamgee', age = 33 WHERE userid = ?", id2);
assertEmpty(execute("SELECT firstname FROM %s WHERE userid = ? AND age = 33", id1));
assertRows(execute("SELECT firstname FROM %s WHERE userid = ? AND age = 33", id2),
row("Samwise"));
}
/**
* Check CREATE INDEX without name and validate the index can be dropped,
* migrated from cql_tests.py:TestCQL.nameless_index_test()
*/
@Test
public void testNamelessIndex() throws Throwable
{
createTable(" CREATE TABLE %s (id text PRIMARY KEY, birth_year int)");
createIndex("CREATE INDEX on %s (birth_year)");
execute("INSERT INTO %s (id, birth_year) VALUES ('Tom', 42)");
execute("INSERT INTO %s (id, birth_year) VALUES ('Paul', 24)");
execute("INSERT INTO %s (id, birth_year) VALUES ('Bob', 42)");
assertRows(execute("SELECT id FROM %s WHERE birth_year = 42"),
row("Tom"),
row("Bob"));
execute("DROP INDEX %s_birth_year_idx");
assertInvalid("SELECT id FROM users WHERE birth_year = 42");
}
/**
* Test range queries with 2ndary indexes (#4257),
* migrated from cql_tests.py:TestCQL.range_query_2ndary_test()
*/
@Test
public void testRangeQuery() throws Throwable
{
createTable("CREATE TABLE %s (id int primary key, row int, setid int)");
createIndex("CREATE INDEX indextest_setid_idx ON %s (setid)");
execute("INSERT INTO %s (id, row, setid) VALUES (?, ?, ?)", 0, 0, 0);
execute("INSERT INTO %s (id, row, setid) VALUES (?, ?, ?)", 1, 1, 0);
execute("INSERT INTO %s (id, row, setid) VALUES (?, ?, ?)", 2, 2, 0);
execute("INSERT INTO %s (id, row, setid) VALUES (?, ?, ?)", 3, 3, 0);
assertInvalid("SELECT * FROM %s WHERE setid = 0 AND row < 1");
assertRows(execute("SELECT * FROM %s WHERE setid = 0 AND row < 1 ALLOW FILTERING"),
row(0, 0, 0));
}
/**
* Check for unknown compression parameters options (#4266),
* migrated from cql_tests.py:TestCQL.compression_option_validation_test()
*/
@Test
public void testUnknownCompressionOptions() throws Throwable
{
String tableName = createTableName();
assertInvalidThrow(SyntaxException.class, String.format(
"CREATE TABLE %s (key varchar PRIMARY KEY, password varchar, gender varchar) WITH compression_parameters:sstable_compressor = 'DeflateCompressor'", tableName));
assertInvalidThrow(ConfigurationException.class, String.format(
"CREATE TABLE %s (key varchar PRIMARY KEY, password varchar, gender varchar) WITH compression = { 'sstable_compressor': 'DeflateCompressor' }", tableName));
}
/**
* Check one can use arbitrary name for datacenter when creating keyspace (#4278),
* migrated from cql_tests.py:TestCQL.keyspace_creation_options_test()
*/
@Test
public void testDataCenterName() throws Throwable
{
execute("CREATE KEYSPACE Foo WITH replication = { 'class' : 'NetworkTopologyStrategy', 'us-east' : 1, 'us-west' : 1 };");
}
/**
* Migrated from cql_tests.py:TestCQL.indexes_composite_test()
*/
@Test
public void testIndexOnComposite() throws Throwable
{
String tableName = createTable("CREATE TABLE %s (blog_id int, timestamp int, author text, content text, PRIMARY KEY (blog_id, timestamp))");
execute("INSERT INTO %s (blog_id, timestamp, author, content) VALUES (?, ?, ?, ?)", 0, 0, "bob", "1st post");
execute("INSERT INTO %s (blog_id, timestamp, author, content) VALUES (?, ?, ?, ?)", 0, 1, "tom", "2nd post");
execute("INSERT INTO %s (blog_id, timestamp, author, content) VALUES (?, ?, ?, ?)", 0, 2, "bob", "3rd post");
execute("INSERT INTO %s (blog_id, timestamp, author, content) VALUES (?, ?, ?, ?)", 0, 3, "tom", "4th post");
execute("INSERT INTO %s (blog_id, timestamp, author, content) VALUES (?, ?, ?, ?)", 1, 0, "bob", "5th post");
createIndex("CREATE INDEX authoridx ON %s (author)");
assertTrue(waitForIndex(keyspace(), tableName, "authoridx"));
assertRows(execute("SELECT blog_id, timestamp FROM %s WHERE author = 'bob'"),
row(1, 0),
row(0, 0),
row(0, 2));
execute("INSERT INTO %s (blog_id, timestamp, author, content) VALUES (?, ?, ?, ?)", 1, 1, "tom", "6th post");
execute("INSERT INTO %s (blog_id, timestamp, author, content) VALUES (?, ?, ?, ?)", 1, 2, "tom", "7th post");
execute("INSERT INTO %s (blog_id, timestamp, author, content) VALUES (?, ?, ?, ?)", 1, 3, "bob", "8th post");
assertRows(execute("SELECT blog_id, timestamp FROM %s WHERE author = 'bob'"),
row(1, 0),
row(1, 3),
row(0, 0),
row(0, 2));
execute("DELETE FROM %s WHERE blog_id = 0 AND timestamp = 2");
assertRows(execute("SELECT blog_id, timestamp FROM %s WHERE author = 'bob'"),
row(1, 0),
row(1, 3),
row(0, 0));
}
/**
* Test for the validation bug of #4709,
* migrated from cql_tests.py:TestCQL.refuse_in_with_indexes_test()
*/
@Test
public void testInvalidIndexSelect() throws Throwable
{
createTable("create table %s (pk varchar primary key, col1 varchar, col2 varchar)");
createIndex("create index on %s (col1)");
createIndex("create index on %s (col2)");
execute("insert into %s (pk, col1, col2) values ('pk1','foo1','bar1')");
execute("insert into %s (pk, col1, col2) values ('pk1a','foo1','bar1')");
execute("insert into %s (pk, col1, col2) values ('pk1b','foo1','bar1')");
execute("insert into %s (pk, col1, col2) values ('pk1c','foo1','bar1')");
execute("insert into %s (pk, col1, col2) values ('pk2','foo2','bar2')");
execute("insert into %s (pk, col1, col2) values ('pk3','foo3','bar3')");
assertInvalid("select * from %s where col2 in ('bar1', 'bar2')");
//Migrated from cql_tests.py:TestCQL.bug_6050_test()
createTable("CREATE TABLE %s (k int PRIMARY KEY, a int, b int)");
createIndex("CREATE INDEX ON %s (a)");
assertInvalid("SELECT * FROM %s WHERE a = 3 AND b IN (1, 3)");
}
/**
* Migrated from cql_tests.py:TestCQL.edge_2i_on_complex_pk_test()
*/
@Test
public void testIndexesOnComplexPrimaryKey() throws Throwable
{
createTable("CREATE TABLE %s (pk0 int, pk1 int, ck0 int, ck1 int, ck2 int, value int, PRIMARY KEY ((pk0, pk1), ck0, ck1, ck2))");
execute("CREATE INDEX ON %s (pk0)");
execute("CREATE INDEX ON %s (ck0)");
execute("CREATE INDEX ON %s (ck1)");
execute("CREATE INDEX ON %s (ck2)");
execute("INSERT INTO %s (pk0, pk1, ck0, ck1, ck2, value) VALUES (0, 1, 2, 3, 4, 5)");
execute("INSERT INTO %s (pk0, pk1, ck0, ck1, ck2, value) VALUES (1, 2, 3, 4, 5, 0)");
execute("INSERT INTO %s (pk0, pk1, ck0, ck1, ck2, value) VALUES (2, 3, 4, 5, 0, 1)");
execute("INSERT INTO %s (pk0, pk1, ck0, ck1, ck2, value) VALUES (3, 4, 5, 0, 1, 2)");
execute("INSERT INTO %s (pk0, pk1, ck0, ck1, ck2, value) VALUES (4, 5, 0, 1, 2, 3)");
execute("INSERT INTO %s (pk0, pk1, ck0, ck1, ck2, value) VALUES (5, 0, 1, 2, 3, 4)");
assertRows(execute("SELECT value FROM %s WHERE pk0 = 2"),
row(1));
assertRows(execute("SELECT value FROM %s WHERE ck0 = 0"),
row(3));
assertRows(execute("SELECT value FROM %s WHERE pk0 = 3 AND pk1 = 4 AND ck1 = 0"),
row(2));
assertRows(execute("SELECT value FROM %s WHERE pk0 = 5 AND pk1 = 0 AND ck0 = 1 AND ck2 = 3 ALLOW FILTERING"),
row(4));
}
/**
* Test for CASSANDRA-5240,
* migrated from cql_tests.py:TestCQL.bug_5240_test()
*/
@Test
public void testIndexOnCompoundRowKey() throws Throwable
{
createTable("CREATE TABLE %s (interval text, seq int, id int, severity int, PRIMARY KEY ((interval, seq), id) ) WITH CLUSTERING ORDER BY (id DESC)");
execute("CREATE INDEX ON %s (severity)");
execute("insert into %s (interval, seq, id , severity) values('t',1, 1, 1)");
execute("insert into %s (interval, seq, id , severity) values('t',1, 2, 1)");
execute("insert into %s (interval, seq, id , severity) values('t',1, 3, 2)");
execute("insert into %s (interval, seq, id , severity) values('t',1, 4, 3)");
execute("insert into %s (interval, seq, id , severity) values('t',2, 1, 3)");
execute("insert into %s (interval, seq, id , severity) values('t',2, 2, 3)");
execute("insert into %s (interval, seq, id , severity) values('t',2, 3, 1)");
execute("insert into %s (interval, seq, id , severity) values('t',2, 4, 2)");
assertRows(execute("select * from %s where severity = 3 and interval = 't' and seq =1"),
row("t", 1, 4, 3));
}
/**
* Migrated from cql_tests.py:TestCQL.secondary_index_counters()
*/
@Test
public void testIndexOnCountersInvalid() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, c counter)");
assertInvalid("CREATE INDEX ON test(c)");
}
/**
* Migrated from cql_tests.py:TestCQL.collection_indexing_test()
*/
@Test
public void testIndexOnCollections() throws Throwable
{
createTable(" CREATE TABLE %s ( k int, v int, l list<int>, s set<text>, m map<text, int>, PRIMARY KEY (k, v))");
createIndex("CREATE INDEX ON %s (l)");
createIndex("CREATE INDEX ON %s (s)");
createIndex("CREATE INDEX ON %s (m)");
execute("INSERT INTO %s (k, v, l, s, m) VALUES (0, 0, [1, 2], {'a'}, {'a' : 1})");
execute("INSERT INTO %s (k, v, l, s, m) VALUES (0, 1, [3, 4], {'b', 'c'}, {'a' : 1, 'b' : 2})");
execute("INSERT INTO %s (k, v, l, s, m) VALUES (0, 2, [1], {'a', 'c'}, {'c' : 3})");
execute("INSERT INTO %s (k, v, l, s, m) VALUES (1, 0, [1, 2, 4], {}, {'b' : 1})");
execute("INSERT INTO %s (k, v, l, s, m) VALUES (1, 1, [4, 5], {'d'}, {'a' : 1, 'b' : 3})");
// lists
assertRows(execute("SELECT k, v FROM %s WHERE l CONTAINS 1"), row(1, 0), row(0, 0), row(0, 2));
assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND l CONTAINS 1"), row(0, 0), row(0, 2));
assertRows(execute("SELECT k, v FROM %s WHERE l CONTAINS 2"), row(1, 0), row(0, 0));
assertEmpty(execute("SELECT k, v FROM %s WHERE l CONTAINS 6"));
// sets
assertRows(execute("SELECT k, v FROM %s WHERE s CONTAINS 'a'"), row(0, 0), row(0, 2));
assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND s CONTAINS 'a'"), row(0, 0), row(0, 2));
assertRows(execute("SELECT k, v FROM %s WHERE s CONTAINS 'd'"), row(1, 1));
assertEmpty(execute("SELECT k, v FROM %s WHERE s CONTAINS 'e'"));
// maps
assertRows(execute("SELECT k, v FROM %s WHERE m CONTAINS 1"), row(1, 0), row(1, 1), row(0, 0), row(0, 1));
assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND m CONTAINS 1"), row(0, 0), row(0, 1));
assertRows(execute("SELECT k, v FROM %s WHERE m CONTAINS 2"), row(0, 1));
assertEmpty(execute("SELECT k, v FROM %s WHERE m CONTAINS 4"));
}
/**
* Migrated from cql_tests.py:TestCQL.map_keys_indexing()
*/
@Test
public void testIndexOnMapKeys() throws Throwable
{
createTable("CREATE TABLE %s (k int, v int, m map<text, int>, PRIMARY KEY (k, v))");
createIndex("CREATE INDEX ON %s(keys(m))");
execute("INSERT INTO %s (k, v, m) VALUES (0, 0, {'a' : 1})");
execute("INSERT INTO %s (k, v, m) VALUES (0, 1, {'a' : 1, 'b' : 2})");
execute("INSERT INTO %s (k, v, m) VALUES (0, 2, {'c' : 3})");
execute("INSERT INTO %s (k, v, m) VALUES (1, 0, {'b' : 1})");
execute("INSERT INTO %s (k, v, m) VALUES (1, 1, {'a' : 1, 'b' : 3})");
// maps
assertRows(execute("SELECT k, v FROM %s WHERE m CONTAINS KEY 'a'"), row(1, 1), row(0, 0), row(0, 1));
assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND m CONTAINS KEY 'a'"), row(0, 0), row(0, 1));
assertRows(execute("SELECT k, v FROM %s WHERE m CONTAINS KEY 'c'"), row(0, 2));
assertEmpty(execute("SELECT k, v FROM %s WHERE m CONTAINS KEY 'd'"));
// we're not allowed to create a value index if we already have a key one
assertInvalid("CREATE INDEX ON %s(m)");
}
/**
* Test for #6950 bug,
* migrated from cql_tests.py:TestCQL.key_index_with_reverse_clustering()
*/
@Test
public void testIndexOnKeyWithReverseClustering() throws Throwable
{
createTable(" CREATE TABLE %s (k1 int, k2 int, v int, PRIMARY KEY ((k1, k2), v) ) WITH CLUSTERING ORDER BY (v DESC)");
createIndex("CREATE INDEX ON %s (k2)");
execute("INSERT INTO %s (k1, k2, v) VALUES (0, 0, 1)");
execute("INSERT INTO %s (k1, k2, v) VALUES (0, 1, 2)");
execute("INSERT INTO %s (k1, k2, v) VALUES (0, 0, 3)");
execute("INSERT INTO %s (k1, k2, v) VALUES (1, 0, 4)");
execute("INSERT INTO %s (k1, k2, v) VALUES (1, 1, 5)");
execute("INSERT INTO %s (k1, k2, v) VALUES (2, 0, 7)");
execute("INSERT INTO %s (k1, k2, v) VALUES (2, 1, 8)");
execute("INSERT INTO %s (k1, k2, v) VALUES (3, 0, 1)");
assertRows(execute("SELECT * FROM %s WHERE k2 = 0 AND v >= 2 ALLOW FILTERING"),
row(2, 0, 7),
row(0, 0, 3),
row(1, 0, 4));
}
/**
* Test for CASSANDRA-6612,
* migrated from cql_tests.py:TestCQL.bug_6612_test()
*/
@Test
public void testSelectCountOnIndexedColumn() throws Throwable
{
createTable("CREATE TABLE %s (username text, session_id text, app_name text, account text, last_access timestamp, created_on timestamp, PRIMARY KEY (username, session_id, app_name, account))");
createIndex("create index ON %s (app_name)");
createIndex("create index ON %s (last_access)");
assertRows(execute("select count(*) from %s where app_name='foo' and account='bar' and last_access > 4 allow filtering"), row(0L));
execute("insert into %s (username, session_id, app_name, account, last_access, created_on) values ('toto', 'foo', 'foo', 'bar', 12, 13)");
assertRows(execute("select count(*) from %s where app_name='foo' and account='bar' and last_access > 4 allow filtering"), row(1L));
}
/**
* Test for CASSANDRA-5732, Can not query secondary index
* migrated from cql_tests.py:TestCQL.bug_5732_test(),
* which was executing with a row cache size of 100 MB
* and restarting the node, here we just cleanup the cache.
*/
@Test
public void testCanQuerySecondaryIndex() throws Throwable
{
String tableName = createTable("CREATE TABLE %s (k int PRIMARY KEY, v int,)");
execute("ALTER TABLE %s WITH CACHING='ALL'");
execute("INSERT INTO %s (k,v) VALUES (0,0)");
execute("INSERT INTO %s (k,v) VALUES (1,1)");
createIndex("CREATE INDEX testindex on %s (v)");
assertTrue(waitForIndex(keyspace(), tableName, "testindex"));
assertRows(execute("SELECT k FROM %s WHERE v = 0"), row(0));
cleanupCache();
assertRows(execute("SELECT k FROM %s WHERE v = 0"), row(0));
}
// CASSANDRA-8280/8081
// reject updates with indexed values where value > 64k
@Test
public void testIndexOnCompositeValueOver64k() throws Throwable
{
createTable("CREATE TABLE %s(a int, b int, c blob, PRIMARY KEY (a))");
createIndex("CREATE INDEX ON %s(c)");
failInsert("INSERT INTO %s (a, b, c) VALUES (0, 0, ?)", ByteBuffer.allocate(TOO_BIG));
}
@Test
public void testIndexOnClusteringColumnInsertPartitionKeyAndClusteringsOver64k() throws Throwable
{
createTable("CREATE TABLE %s(a blob, b blob, c blob, d int, PRIMARY KEY (a, b, c))");
createIndex("CREATE INDEX ON %s(b)");
// CompositeIndexOnClusteringKey creates index entries composed of the
// PK plus all of the non-indexed clustering columns from the primary row
// so we should reject where len(a) + len(c) > 65560 as this will form the
// total clustering in the index table
ByteBuffer a = ByteBuffer.allocate(100);
ByteBuffer b = ByteBuffer.allocate(10);
ByteBuffer c = ByteBuffer.allocate(FBUtilities.MAX_UNSIGNED_SHORT - 99);
failInsert("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, 0)", a, b, c);
}
@Test
public void testCompactTableWithValueOver64k() throws Throwable
{
createTable("CREATE TABLE %s(a int, b blob, PRIMARY KEY (a)) WITH COMPACT STORAGE");
createIndex("CREATE INDEX ON %s(b)");
failInsert("INSERT INTO %s (a, b) VALUES (0, ?)", ByteBuffer.allocate(TOO_BIG));
}
@Test
public void testIndexOnCollectionValueInsertPartitionKeyAndCollectionKeyOver64k() throws Throwable
{
createTable("CREATE TABLE %s(a blob , b map<blob, int>, PRIMARY KEY (a))");
createIndex("CREATE INDEX ON %s(b)");
// A collection key > 64k by itself will be rejected from
// the primary table.
// To test index validation we need to ensure that
// len(b) < 64k, but len(a) + len(b) > 64k as that will
// form the clustering in the index table
ByteBuffer a = ByteBuffer.allocate(100);
ByteBuffer b = ByteBuffer.allocate(FBUtilities.MAX_UNSIGNED_SHORT - 100);
failInsert("UPDATE %s SET b[?] = 0 WHERE a = ?", b, a);
}
@Test
public void testIndexOnCollectionKeyInsertPartitionKeyAndClusteringOver64k() throws Throwable
{
createTable("CREATE TABLE %s(a blob, b blob, c map<blob, int>, PRIMARY KEY (a, b))");
createIndex("CREATE INDEX ON %s(KEYS(c))");
// Basically the same as the case with non-collection clustering
// CompositeIndexOnCollectionKeyy creates index entries composed of the
// PK plus all of the clustering columns from the primary row, except the
// collection element - which becomes the partition key in the index table
ByteBuffer a = ByteBuffer.allocate(100);
ByteBuffer b = ByteBuffer.allocate(FBUtilities.MAX_UNSIGNED_SHORT - 100);
ByteBuffer c = ByteBuffer.allocate(10);
failInsert("UPDATE %s SET c[?] = 0 WHERE a = ? and b = ?", c, a, b);
}
@Test
public void testIndexOnPartitionKeyInsertValueOver64k() throws Throwable
{
createTable("CREATE TABLE %s(a int, b int, c blob, PRIMARY KEY ((a, b)))");
createIndex("CREATE INDEX ON %s(a)");
succeedInsert("INSERT INTO %s (a, b, c) VALUES (0, 0, ?)", ByteBuffer.allocate(TOO_BIG));
}
@Test
public void testIndexOnClusteringColumnInsertValueOver64k() throws Throwable
{
createTable("CREATE TABLE %s(a int, b int, c blob, PRIMARY KEY (a, b))");
createIndex("CREATE INDEX ON %s(b)");
succeedInsert("INSERT INTO %s (a, b, c) VALUES (0, 0, ?)", ByteBuffer.allocate(TOO_BIG));
}
@Test
public void testIndexOnFullCollectionEntryInsertCollectionValueOver64k() throws Throwable
{
createTable("CREATE TABLE %s(a int, b frozen<map<int, blob>>, PRIMARY KEY (a))");
createIndex("CREATE INDEX ON %s(full(b))");
Map<Integer, ByteBuffer> map = new HashMap();
map.put(0, ByteBuffer.allocate(1024 * 65));
failInsert("INSERT INTO %s (a, b) VALUES (0, ?)", map);
}
public void failInsert(String insertCQL, Object...args) throws Throwable
{
try
{
execute(insertCQL, args);
fail("Expected statement to fail validation");
}
catch (Exception e)
{
// as expected
}
}
public void succeedInsert(String insertCQL, Object...args) throws Throwable
{
execute(insertCQL, args);
flush();
}
/**
* Migrated from cql_tests.py:TestCQL.clustering_indexing_test()
*/
@Test
public void testIndexesOnClustering() throws Throwable
{
createTable("CREATE TABLE %s ( id1 int, id2 int, author text, time bigint, v1 text, v2 text, PRIMARY KEY ((id1, id2), author, time))");
createIndex("CREATE INDEX ON %s (time)");
execute("CREATE INDEX ON %s (id2)");
execute("INSERT INTO %s (id1, id2, author, time, v1, v2) VALUES(0, 0, 'bob', 0, 'A', 'A')");
execute("INSERT INTO %s (id1, id2, author, time, v1, v2) VALUES(0, 0, 'bob', 1, 'B', 'B')");
execute("INSERT INTO %s (id1, id2, author, time, v1, v2) VALUES(0, 1, 'bob', 2, 'C', 'C')");
execute("INSERT INTO %s (id1, id2, author, time, v1, v2) VALUES(0, 0, 'tom', 0, 'D', 'D')");
execute("INSERT INTO %s (id1, id2, author, time, v1, v2) VALUES(0, 1, 'tom', 1, 'E', 'E')");
assertRows(execute("SELECT v1 FROM %s WHERE time = 1"),
row("B"), row("E"));
assertRows(execute("SELECT v1 FROM %s WHERE id2 = 1"),
row("C"), row("E"));
assertRows(execute("SELECT v1 FROM %s WHERE id1 = 0 AND id2 = 0 AND author = 'bob' AND time = 0"),
row("A"));
// Test for CASSANDRA-8206
execute("UPDATE %s SET v2 = null WHERE id1 = 0 AND id2 = 0 AND author = 'bob' AND time = 1");
assertRows(execute("SELECT v1 FROM %s WHERE id2 = 0"),
row("A"), row("B"), row("D"));
assertRows(execute("SELECT v1 FROM %s WHERE time = 1"),
row("B"), row("E"));
}
/**
* Migrated from cql_tests.py:TestCQL.invalid_clustering_indexing_test()
*/
@Test
public void testIndexesOnClusteringInvalid() throws Throwable
{
createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY ((a, b))) WITH COMPACT STORAGE");
assertInvalid("CREATE INDEX ON %s (a)");
assertInvalid("CREATE INDEX ON %s (b)");
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b)) WITH COMPACT STORAGE");
assertInvalid("CREATE INDEX ON %s (a)");
assertInvalid("CREATE INDEX ON %s (b)");
assertInvalid("CREATE INDEX ON %s (c)");
createTable("CREATE TABLE %s (a int, b int, c int static , PRIMARY KEY (a, b))");
assertInvalid("CREATE INDEX ON %s (c)");
}
}

View File

@ -0,0 +1,271 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3.validation.entities;
import java.util.Arrays;
import org.junit.Test;
import org.apache.cassandra.cql3.CQLTester;
import static junit.framework.Assert.assertNull;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class StaticColumnsTest extends CQLTester
{
/**
* Migrated from cql_tests.py:TestCQL.static_columns_test()
*/
@Test
public void testStaticColumns() throws Throwable
{
createTable("CREATE TABLE %s ( k int, p int, s int static, v int, PRIMARY KEY (k, p))");
execute("INSERT INTO %s(k, s) VALUES (0, 42)");
assertRows(execute("SELECT * FROM %s"), row(0, null, 42, null));
// Check that writetime works (//7081) -- we can't predict the exact value easily so
// we just check that it's non zero
Object[][] row = getRows(execute("SELECT s, writetime(s) FROM %s WHERE k=0"));
assertEquals(42, row[0][0]);
assertTrue((Long)row[0][1] > 0);
execute("INSERT INTO %s (k, p, s, v) VALUES (0, 0, 12, 0)");
execute("INSERT INTO %s (k, p, s, v) VALUES (0, 1, 24, 1)");
// Check the static columns in indeed "static"
assertRows(execute("SELECT * FROM %s"), row(0, 0, 24, 0), row(0, 1, 24, 1));
// Check we do correctly get the static column value with a SELECT *, even
// if we're only slicing part of the partition
assertRows(execute("SELECT * FROM %s WHERE k=0 AND p=0"), row(0, 0, 24, 0));
assertRows(execute("SELECT * FROM %s WHERE k=0 AND p=1"), row(0, 1, 24, 1));
// Test for IN on the clustering key (//6769)
assertRows(execute("SELECT * FROM %s WHERE k=0 AND p IN (0, 1)"), row(0, 0, 24, 0), row(0, 1, 24, 1));
// Check things still work if we don't select the static column. We also want
// this to not request the static columns internally at all, though that part
// require debugging to assert
assertRows(execute("SELECT p, v FROM %s WHERE k=0 AND p=1"), row(1, 1));
// Check selecting only a static column with distinct only yield one value
// (as we only query the static columns)
assertRows(execute("SELECT DISTINCT s FROM %s WHERE k=0"), row(24));
// But without DISTINCT, we still get one result per row
assertRows(execute("SELECT s FROM %s WHERE k=0"),row(24),row(24));
// but that querying other columns does correctly yield the full partition
assertRows(execute("SELECT s, v FROM %s WHERE k=0"),row(24, 0),row(24, 1));
assertRows(execute("SELECT s, v FROM %s WHERE k=0 AND p=1"),row(24, 1));
assertRows(execute("SELECT p, s FROM %s WHERE k=0 AND p=1"), row(1, 24));
assertRows(execute("SELECT k, p, s FROM %s WHERE k=0 AND p=1"),row(0, 1, 24));
// Check that deleting a row don't implicitely deletes statics
execute("DELETE FROM %s WHERE k=0 AND p=0");
assertRows(execute("SELECT * FROM %s"),row(0, 1, 24, 1));
// But that explicitely deleting the static column does remove it
execute("DELETE s FROM %s WHERE k=0");
assertRows(execute("SELECT * FROM %s"), row(0, 1, null, 1));
// Check we can add a static column ...
execute("ALTER TABLE %s ADD s2 int static");
assertRows(execute("SELECT * FROM %s"), row(0, 1, null, null, 1));
execute("INSERT INTO %s (k, p, s2, v) VALUES(0, 2, 42, 2)");
assertRows(execute("SELECT * FROM %s"), row(0, 1, null, 42, 1), row(0, 2, null, 42, 2));
// ... and that we can drop it
execute("ALTER TABLE %s DROP s2");
assertRows(execute("SELECT * FROM %s"), row(0, 1, null, 1), row(0, 2, null, 2));
}
/**
* Migrated from cql_tests.py:TestCQL.static_columns_with_2i_test()
*/
@Test
public void testStaticColumnsWithSecondaryIndex() throws Throwable
{
createTable(" CREATE TABLE %s (k int, p int, s int static, v int, PRIMARY KEY (k, p) ) ");
createIndex("CREATE INDEX ON %s (v)");
execute("INSERT INTO %s (k, p, s, v) VALUES (0, 0, 42, 1)");
execute("INSERT INTO %s (k, p, v) VALUES (0, 1, 1)");
execute("INSERT INTO %s (k, p, v) VALUES (0, 2, 2)");
assertRows(execute("SELECT * FROM %s WHERE v = 1"), row(0, 0, 42, 1), row(0, 1, 42, 1));
assertRows(execute("SELECT p, s FROM %s WHERE v = 1"), row(0, 42), row(1, 42));
assertRows(execute("SELECT p FROM %s WHERE v = 1"), row(0), row(1));
// We don't support that
assertInvalid("SELECT s FROM %s WHERE v = 1");
}
/**
* Migrated from cql_tests.py:TestCQL.static_columns_with_distinct_test()
*/
@Test
public void testStaticColumnsWithDistinct() throws Throwable
{
createTable("CREATE TABLE %s( k int, p int, s int static, PRIMARY KEY (k, p) ) ");
execute("INSERT INTO %s (k, p) VALUES (1, 1)");
execute("INSERT INTO %s (k, p) VALUES (1, 2)");
assertRows(execute("SELECT k, s FROM %s"), row(1, null), row(1, null));
assertRows(execute("SELECT DISTINCT k, s FROM %s"), row(1, null));
Object[][] rows = getRows(execute("SELECT DISTINCT s FROM %s WHERE k=1"));
assertNull(rows[0][0]);
assertEmpty(execute("SELECT DISTINCT s FROM %s WHERE k=2"));
execute("INSERT INTO %s (k, p, s) VALUES (2, 1, 3)");
execute("INSERT INTO %s (k, p) VALUES (2, 2)");
assertRows(execute("SELECT k, s FROM %s"), row(1, null), row(1, null), row(2, 3), row(2, 3));
assertRows(execute("SELECT DISTINCT k, s FROM %s"), row(1, null), row(2, 3));
rows = getRows(execute("SELECT DISTINCT s FROM %s WHERE k=1"));
assertNull(rows[0][0]);
assertRows(execute("SELECT DISTINCT s FROM %s WHERE k=2"), row(3));
assertInvalid("SELECT DISTINCT s FROM %s");
// paging to test for CASSANDRA-8108
execute("TRUNCATE %s");
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
execute("INSERT INTO %s (k, p, s) VALUES (?, ?, ?)", i, j, i);
rows = getRows(execute("SELECT DISTINCT k, s FROM %s"));
checkDistinctRows(rows, true, 0, 10, 0, 10);
String keys = "0, 1, 2, 3, 4, 5, 6, 7, 8, 9";
rows = getRows(execute("SELECT DISTINCT k, s FROM %s WHERE k IN (" + keys + ")"));
checkDistinctRows(rows, false, 0, 10, 0, 10);
// additional testing for CASSANRA-8087
createTable("CREATE TABLE %s( k int, c1 int, c2 int, s1 int static, s2 int static, PRIMARY KEY (k, c1, c2))");
for (int i = 0; i < 10; i++)
for (int j = 0; j < 5; j++)
for (int k = 0; k < 5; k++)
execute("INSERT INTO %s (k, c1, c2, s1, s2) VALUES (?, ?, ?, ?, ?)", i, j, k, i, i + 1);
rows = getRows(execute("SELECT DISTINCT k, s1 FROM %s"));
checkDistinctRows(rows, true, 0, 10, 0, 10);
rows = getRows(execute("SELECT DISTINCT k, s2 FROM %s"));
checkDistinctRows(rows, true, 0, 10, 1, 11);
rows = getRows(execute("SELECT DISTINCT k, s1 FROM %s LIMIT 10"));
checkDistinctRows(rows, true, 0, 10, 0, 10);
rows = getRows(execute("SELECT DISTINCT k, s1 FROM %s WHERE k IN (" + keys + ")"));
checkDistinctRows(rows, false, 0, 10, 0, 10);
rows = getRows(execute("SELECT DISTINCT k, s2 FROM %s WHERE k IN (" + keys + ")"));
checkDistinctRows(rows, false, 0, 10, 1, 11);
rows = getRows(execute("SELECT DISTINCT k, s1 FROM %s WHERE k IN (" + keys + ")"));
checkDistinctRows(rows, true, 0, 10, 0, 10);
}
void checkDistinctRows(Object[][] rows, boolean sort, int... ranges)
{
assertTrue(ranges.length % 2 == 0);
int numdim = ranges.length / 2;
int[] from = new int[numdim];
int[] to = new int[numdim];
for (int i = 0, j = 0; i < ranges.length && j < numdim; i+= 2, j++)
{
from[j] = ranges[i];
to[j] = ranges[i+1];
}
//sort the rows
for (int i = 0; i < numdim; i++)
{
int[] vals = new int[rows.length];
for (int j = 0; j < rows.length; j++)
vals[j] = (Integer)rows[j][i];
if (sort)
Arrays.sort(vals);
for (int j = from[i]; j < to[i]; j++)
assertEquals(j, vals[j - from[i]]);
}
}
/**
* Test LIMIT when static columns are present (#6956),
* migrated from cql_tests.py:TestCQL.static_with_limit_test()
*/
@Test
public void testStaticColumnsWithLimit() throws Throwable
{
createTable(" CREATE TABLE %s (k int, s int static, v int, PRIMARY KEY (k, v))");
execute("INSERT INTO %s (k, s) VALUES(0, 42)");
for (int i = 0; i < 4; i++)
execute("INSERT INTO %s(k, v) VALUES(0, ?)", i);
assertRows(execute("SELECT * FROM %s WHERE k = 0 LIMIT 1"),
row(0, 0, 42));
assertRows(execute("SELECT * FROM %s WHERE k = 0 LIMIT 2"),
row(0, 0, 42),
row(0, 1, 42));
assertRows(execute("SELECT * FROM %s WHERE k = 0 LIMIT 3"),
row(0, 0, 42),
row(0, 1, 42),
row(0, 2, 42));
}
/**
* Test for bug of #7455,
* migrated from cql_tests.py:TestCQL.static_with_empty_clustering_test()
*/
@Test
public void testStaticColumnsWithEmptyClustering() throws Throwable
{
createTable("CREATE TABLE %s (pkey text, ckey text, value text, static_value text static, PRIMARY KEY(pkey, ckey))");
execute("INSERT INTO %s (pkey, static_value) VALUES ('partition1', 'static value')");
execute("INSERT INTO %s (pkey, ckey, value) VALUES('partition1', '', 'value')");
assertRows(execute("SELECT * FROM %s"),
row("partition1", "", "static value", "value"));
}
/**
* Migrated from cql_tests.py:TestCQL.alter_clustering_and_static_test()
*/
@Test
public void testAlterClusteringAndStatic() throws Throwable
{
createTable("CREATE TABLE %s (bar int, PRIMARY KEY (bar))");
// We shouldn 't allow static when there is not clustering columns
assertInvalid("ALTER TABLE %s ADD bar2 text static");
}
}

View File

@ -0,0 +1,155 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3.validation.entities;
import org.junit.Test;
import junit.framework.Assert;
import org.apache.cassandra.cql3.CQLTester;
import static junit.framework.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class TimestampTest extends CQLTester
{
@Test
public void testNegativeTimestamps() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, v int)");
execute("INSERT INTO %s (k, v) VALUES (?, ?) USING TIMESTAMP ?", 1, 1, -42L);
assertRows(execute("SELECT writetime(v) FROM %s WHERE k = ?", 1),
row(-42L)
);
assertInvalid("INSERT INTO %s (k, v) VALUES (?, ?) USING TIMESTAMP ?", 2, 2, Long.MIN_VALUE);
}
/**
* Test timestmp and ttl
* migrated from cql_tests.py:TestCQL.timestamp_and_ttl_test()
*/
@Test
public void testTimestampTTL() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, c text, d text)");
execute("INSERT INTO %s (k, c) VALUES (1, 'test')");
execute("INSERT INTO %s (k, c) VALUES (2, 'test') USING TTL 400");
Object[][] res = getRows(execute("SELECT k, c, writetime(c), ttl(c) FROM %s"));
Assert.assertEquals(2, res.length);
for (Object[] r : res)
{
assertTrue(r[2] instanceof Integer || r[2] instanceof Long);
if (r[0].equals(1))
assertNull(r[3]);
else
assertTrue(r[3] instanceof Integer || r[2] instanceof Long);
}
// wrap writetime(), ttl() in other functions (test for CASSANDRA-8451)
res = getRows(execute("SELECT k, c, blobAsBigint(bigintAsBlob(writetime(c))), ttl(c) FROM %s"));
Assert.assertEquals(2, res.length);
for (Object[] r : res)
{
assertTrue(r[2] instanceof Integer || r[2] instanceof Long);
if (r[0].equals(1))
assertNull(r[3]);
else
assertTrue(r[3] instanceof Integer || r[2] instanceof Long);
}
res = getRows(execute("SELECT k, c, writetime(c), blobAsInt(intAsBlob(ttl(c))) FROM %s"));
Assert.assertEquals(2, res.length);
for (Object[] r : res)
{
assertTrue(r[2] instanceof Integer || r[2] instanceof Long);
if (r[0].equals(1))
assertNull(r[3]);
else
assertTrue(r[3] instanceof Integer || r[2] instanceof Long);
}
assertInvalid("SELECT k, c, writetime(k) FROM %s");
assertRows(execute("SELECT k, d, writetime(d) FROM %s WHERE k = 1"),
row(1, null, null));
}
/**
* Migrated from cql_tests.py:TestCQL.invalid_custom_timestamp_test()
*/
@Test
public void testInvalidCustomTimestamp() throws Throwable
{
// Conditional updates
createTable("CREATE TABLE %s (k int, v int, PRIMARY KEY (k, v))");
execute("BEGIN BATCH " +
"INSERT INTO %1$s (k, v) VALUES(0, 0) IF NOT EXISTS; " +
"INSERT INTO %1$s (k, v) VALUES(0, 1) IF NOT EXISTS; " +
"APPLY BATCH");
assertInvalid("BEGIN BATCH " +
"INSERT INTO %1$s (k, v) VALUES(0, 2) IF NOT EXISTS USING TIMESTAMP 1; " +
"INSERT INTO %1$s (k, v) VALUES(0, 3) IF NOT EXISTS; " +
"APPLY BATCH");
assertInvalid("BEGIN BATCH " +
"USING TIMESTAMP 1 INSERT INTO %1$s (k, v) VALUES(0, 4) IF NOT EXISTS; " +
"INSERT INTO %1$s (k, v) VALUES(0, 1) IF NOT EXISTS; " +
"APPLY BATCH");
execute("INSERT INTO %s (k, v) VALUES(1, 0) IF NOT EXISTS");
assertInvalid("INSERT INTO %s (k, v) VALUES(1, 1) IF NOT EXISTS USING TIMESTAMP 5");
// Counters
createTable("CREATE TABLE %s (k int PRIMARY KEY, c counter)");
execute("UPDATE %s SET c = c + 1 WHERE k = 0");
assertInvalid("UPDATE %s USING TIMESTAMP 10 SET c = c + 1 WHERE k = 0");
execute("BEGIN COUNTER BATCH " +
"UPDATE %1$s SET c = c + 1 WHERE k = 0; " +
"UPDATE %1$s SET c = c + 1 WHERE k = 0; " +
"APPLY BATCH");
assertInvalid("BEGIN COUNTER BATCH " +
"UPDATE %1$s USING TIMESTAMP 3 SET c = c + 1 WHERE k = 0; " +
"UPDATE %1$s SET c = c + 1 WHERE k = 0; " +
"APPLY BATCH");
assertInvalid("BEGIN COUNTER BATCH " +
"USING TIMESTAMP 3 UPDATE %1$s SET c = c + 1 WHERE k = 0; " +
"UPDATE %1$s SET c = c + 1 WHERE k = 0; " +
"APPLY BATCH");
}
@Test
public void testInsertTimestampWithUnset() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, i int)");
execute("INSERT INTO %s (k, i) VALUES (1, 1) USING TIMESTAMP ?", unset()); // treat as 'now'
}
}

View File

@ -0,0 +1,81 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3.validation.entities;
import java.util.Date;
import java.util.UUID;
import org.junit.Test;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.exceptions.SyntaxException;
import org.apache.cassandra.utils.UUIDGen;
import static org.junit.Assert.assertEquals;
public class TimeuuidTest extends CQLTester
{
/**
* Migrated from cql_tests.py:TestCQL.timeuuid_test()
*/
@Test
public void testTimeuuid() throws Throwable
{
createTable("CREATE TABLE %s (k int, t timeuuid, PRIMARY KEY(k, t))");
assertInvalidThrow(SyntaxException.class, "INSERT INTO %s (k, t) VALUES (0, 2012-11-07 18:18:22-0800)");
for (int i = 0; i < 4; i++)
execute("INSERT INTO %s (k, t) VALUES (0, now())");
Object[][] rows = getRows(execute("SELECT * FROM %s"));
assertEquals(4, rows.length);
assertRowCount(execute("SELECT * FROM %s WHERE k = 0 AND t >= ?", rows[0][1]), 4);
assertEmpty(execute("SELECT * FROM %s WHERE k = 0 AND t < ?", rows[0][1]));
assertRowCount(execute("SELECT * FROM %s WHERE k = 0 AND t > ? AND t <= ?", rows[0][1], rows[2][1]), 2);
assertRowCount(execute("SELECT * FROM %s WHERE k = 0 AND t = ?", rows[0][1]), 1);
assertInvalid("SELECT dateOf(k) FROM %s WHERE k = 0 AND t = ?", rows[0][1]);
for (int i = 0; i < 4; i++)
{
long timestamp = UUIDGen.unixTimestamp((UUID) rows[i][1]);
assertRows(execute("SELECT dateOf(t), unixTimestampOf(t) FROM %s WHERE k = 0 AND t = ?", rows[i][1]),
row(new Date(timestamp), timestamp));
}
assertEmpty(execute("SELECT t FROM %s WHERE k = 0 AND t > maxTimeuuid(1234567) AND t < minTimeuuid('2012-11-07 18:18:22-0800')"));
}
/**
* Test for 5386,
* migrated from cql_tests.py:TestCQL.function_and_reverse_type_test()
*/
@Test
public void testDescClusteringOnTimeuuid() throws Throwable
{
createTable("CREATE TABLE %s (k int, c timeuuid, v int, PRIMARY KEY (k, c)) WITH CLUSTERING ORDER BY (c DESC)");
execute("INSERT INTO %s (k, c, v) VALUES (0, now(), 0)");
}
}

View File

@ -15,10 +15,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.entities;
import org.junit.Test;
import org.apache.cassandra.cql3.CQLTester;
public class TupleTypeTest extends CQLTester
{
@Test
@ -31,21 +33,20 @@ public class TupleTypeTest extends CQLTester
execute("INSERT INTO %s (k, t) VALUES (?, ?)", 0, tuple(3, "foo", 3.4));
execute("INSERT INTO %s (k, t) VALUES (?, ?)", 1, tuple(8, "bar", 0.2));
assertAllRows(
row(0, tuple(3, "foo", 3.4)),
row(1, tuple(8, "bar", 0.2))
assertAllRows(row(1, tuple(8, "bar", 0.2)),
row(0, tuple(3, "foo", 3.4))
);
// nulls
execute("INSERT INTO %s (k, t) VALUES (?, ?)", 2, tuple(5, null, 3.4));
assertRows(execute("SELECT * FROM %s WHERE k=?", 2),
row(2, tuple(5, null, 3.4))
row(2, tuple(5, null, 3.4))
);
// incomplete tuple
execute("INSERT INTO %s (k, t) VALUES (?, ?)", 3, tuple(5, "bar"));
assertRows(execute("SELECT * FROM %s WHERE k=?", 3),
row(3, tuple(5, "bar"))
row(3, tuple(5, "bar"))
);
}
}
@ -58,8 +59,8 @@ public class TupleTypeTest extends CQLTester
execute("INSERT INTO %s (k, t) VALUES (?, ?)", 0, tuple(3, tuple("foo", 3.4)));
execute("INSERT INTO %s (k, t) VALUES (?, ?)", 1, tuple(8, tuple("bar", 0.2)));
assertAllRows(
row(0, tuple(3, tuple("foo", 3.4))),
row(1, tuple(8, tuple("bar", 0.2)))
row(1, tuple(8, tuple("bar", 0.2))),
row(0, tuple(3, tuple("foo", 3.4)))
);
}
@ -105,10 +106,66 @@ public class TupleTypeTest extends CQLTester
createTable("CREATE TABLE %s (k int PRIMARY KEY, t tuple<int, text, double>)");
// invalid positional field substitution
assertInvalidMessage("Invalid unset value for tuple field number 1",
"INSERT INTO %s (k, t) VALUES(0, (3, ?, 2.1))", unset());
"INSERT INTO %s (k, t) VALUES(0, (3, ?, 2.1))", unset());
createIndex("CREATE INDEX tuple_index ON %s (t)");
// select using unset
assertInvalidMessage("Invalid unset value for tuple field number 0", "SELECT * FROM %s WHERE k = ? and t = (?,?,?)", unset(), unset(), unset(), unset());
}
/**
* Test the syntax introduced by #4851,
* migrated from cql_tests.py:TestCQL.tuple_notation_test()
*/
@Test
public void testTupleNotation() throws Throwable
{
createTable("CREATE TABLE %s (k int, v1 int, v2 int, v3 int, PRIMARY KEY (k, v1, v2, v3))");
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
for (int k = 0; k < 2; k++)
execute("INSERT INTO %s (k, v1, v2, v3) VALUES (0, ?, ?, ?)", i, j, k);
assertRows(execute("SELECT v1, v2, v3 FROM %s WHERE k = 0"),
row(0, 0, 0),
row(0, 0, 1),
row(0, 1, 0),
row(0, 1, 1),
row(1, 0, 0),
row(1, 0, 1),
row(1, 1, 0),
row(1, 1, 1));
assertRows(execute("SELECT v1, v2, v3 FROM %s WHERE k = 0 AND (v1, v2, v3) >= (1, 0, 1)"),
row(1, 0, 1),
row(1, 1, 0),
row(1, 1, 1));
assertRows(execute("SELECT v1, v2, v3 FROM %s WHERE k = 0 AND (v1, v2) >= (1, 1)"),
row(1, 1, 0),
row(1, 1, 1));
assertRows(execute("SELECT v1, v2, v3 FROM %s WHERE k = 0 AND (v1, v2) > (0, 1) AND (v1, v2, v3) <= (1, 1, 0)"),
row(1, 0, 0),
row(1, 0, 1),
row(1, 1, 0));
assertInvalid("SELECT v1, v2, v3 FROM %s WHERE k = 0 AND (v1, v3) > (1, 0)");
}
/**
* Test for CASSANDRA-8062,
* migrated from cql_tests.py:TestCQL.test_v2_protocol_IN_with_tuples()
*/
@Test
public void testSelectInStatementWithTuples() throws Throwable
{ // TODO - the dtest was using v2 protocol
createTable("CREATE TABLE %s (k int, c1 int, c2 text, PRIMARY KEY (k, c1, c2))");
execute("INSERT INTO %s (k, c1, c2) VALUES (0, 0, 'a')");
execute("INSERT INTO %s (k, c1, c2) VALUES (0, 0, 'b')");
execute("INSERT INTO %s (k, c1, c2) VALUES (0, 0, 'c')");
assertRows(execute("SELECT * FROM %s WHERE k=0 AND (c1, c2) IN ((0, 'b'), (0, 'c'))"),
row(0, 0, "b"),
row(0, 0, "c"));
}
}

View File

@ -15,7 +15,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.entities;
import org.apache.cassandra.cql3.UntypedResultSet;
import org.apache.cassandra.cql3.CQLTester;
import org.junit.Test;
import static org.junit.Assert.assertEquals;

View File

@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.entities;
import java.lang.reflect.Field;
import java.util.*;
@ -30,11 +30,15 @@ import org.slf4j.LoggerFactory;
import org.apache.cassandra.auth.*;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.cql3.Attributes;
import org.apache.cassandra.cql3.CQLStatement;
import org.apache.cassandra.cql3.QueryProcessor;
import org.apache.cassandra.cql3.functions.Function;
import org.apache.cassandra.cql3.functions.FunctionName;
import org.apache.cassandra.cql3.functions.Functions;
import org.apache.cassandra.cql3.statements.BatchStatement;
import org.apache.cassandra.cql3.statements.ModificationStatement;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.exceptions.*;
import org.apache.cassandra.service.ClientState;
import org.apache.cassandra.utils.Pair;

View File

@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.entities;
import java.util.*;
@ -25,9 +25,13 @@ import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.apache.cassandra.cql3.Attributes;
import org.apache.cassandra.cql3.CQLStatement;
import org.apache.cassandra.cql3.QueryProcessor;
import org.apache.cassandra.cql3.functions.Function;
import org.apache.cassandra.cql3.statements.BatchStatement;
import org.apache.cassandra.cql3.statements.ModificationStatement;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.service.ClientState;
import static org.junit.Assert.assertTrue;
@ -322,7 +326,7 @@ public class UFIdentificationTest extends CQLTester
private ModificationStatement modificationStatement(String cql)
{
return (ModificationStatement)QueryProcessor.getStatement(cql, ClientState.forInternalCalls()).statement;
return (ModificationStatement) QueryProcessor.getStatement(cql, ClientState.forInternalCalls()).statement;
}
private void assertFunctions(String cql, String... function)

View File

@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.entities;
import java.math.BigDecimal;
import java.math.BigInteger;
@ -31,14 +31,20 @@ import java.util.TreeSet;
import java.util.UUID;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import com.datastax.driver.core.*;
import com.datastax.driver.core.exceptions.InvalidQueryException;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.cql3.QueryProcessor;
import org.apache.cassandra.cql3.UntypedResultSet;
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.CQLTester;
import org.apache.cassandra.db.marshal.CollectionType;
import org.apache.cassandra.dht.ByteOrderedPartitioner;
import org.apache.cassandra.exceptions.FunctionExecutionException;
import org.apache.cassandra.exceptions.InvalidRequestException;
import org.apache.cassandra.service.ClientState;
@ -50,6 +56,11 @@ import org.apache.cassandra.utils.UUIDGen;
public class UFTest extends CQLTester
{
@BeforeClass
public static void setUp()
{
DatabaseDescriptor.setPartitioner(ByteOrderedPartitioner.instance);
}
@Test
public void testSchemaChange() throws Throwable
@ -140,8 +151,8 @@ public class UFTest extends CQLTester
// should be unaffected.
ResultMessage.Prepared preparedSelect1 = QueryProcessor.prepare(
String.format("SELECT key, %s(d) FROM %s.%s", fSin, KEYSPACE, currentTable()),
ClientState.forInternalCalls(), false);
String.format("SELECT key, %s(d) FROM %s.%s", fSin, KEYSPACE, currentTable()),
ClientState.forInternalCalls(), false);
ResultMessage.Prepared preparedSelect2 = QueryProcessor.prepare(
String.format("SELECT key FROM %s.%s", KEYSPACE, currentTable()),
ClientState.forInternalCalls(), false);

View File

@ -15,12 +15,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.entities;
import java.util.UUID;
import org.junit.BeforeClass;
import org.junit.Test;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.dht.ByteOrderedPartitioner;
public class UserTypesTest extends CQLTester
{
@BeforeClass
public static void setUpClass()
{
DatabaseDescriptor.setPartitioner(new ByteOrderedPartitioner());
}
@Test
public void testInvalidField() throws Throwable
{
@ -66,7 +79,7 @@ public class UserTypesTest extends CQLTester
flush();
assertRows(execute("SELECT v.x FROM %s WHERE k = ? AND v = {x:?}", 1, -104.99251),
row(-104.99251)
row(-104.99251)
);
}
@ -121,10 +134,10 @@ public class UserTypesTest extends CQLTester
createTable("CREATE TABLE %s (k int PRIMARY KEY, v frozen<" + myType + ">, z frozen<" + myOtherType + ">)");
assertInvalidMessage("Invalid unset value for field 'y' of user defined type " + myType,
"INSERT INTO %s (k, v) VALUES (10, {x:?, y:?})", 1, unset());
"INSERT INTO %s (k, v) VALUES (10, {x:?, y:?})", 1, unset());
assertInvalidMessage("Invalid unset value for field 'y' of user defined type " + myType,
"INSERT INTO %s (k, v, z) VALUES (10, {x:?, y:?}, {a:{x: ?, y: ?}})", 1, 1, 1, unset());
"INSERT INTO %s (k, v, z) VALUES (10, {x:?, y:?}, {a:{x: ?, y: ?}})", 1, 1, 1, unset());
}
@Test
@ -331,4 +344,61 @@ public class UserTypesTest extends CQLTester
row(3, 3, null),
row(null, 4, null));
}
/**
* Migrated from cql_tests.py:TestCQL.user_types_test()
*/
@Test
public void testUserTypes() throws Throwable
{
UUID userID_1 = UUID.fromString("550e8400-e29b-41d4-a716-446655440000");
String addressType = createType("CREATE TYPE %s (street text, city text, zip_code int, phones set<text >)");
String nameType = createType("CREATE TYPE %s (firstname text, lastname text)");
createTable("CREATE TABLE %s (id uuid PRIMARY KEY, name frozen < " + nameType + " >, addresses map < text, frozen < " + addressType + " >> )");
execute("INSERT INTO %s (id, name) VALUES(?, { firstname: 'Paul', lastname: 'smith' } )", userID_1);
assertRows(execute("SELECT name.firstname FROM %s WHERE id = ?", userID_1), row("Paul"));
execute("UPDATE %s SET addresses = addresses + { 'home': { street: '...', city:'SF', zip_code:94102, phones:{ } } } WHERE id = ?", userID_1);
// TODO: deserialize the value here and check it 's right.
execute("SELECT addresses FROM %s WHERE id = ? ", userID_1);
}
/**
* Test user type test that does a little more nesting,
* migrated from cql_tests.py:TestCQL.more_user_types_test()
*/
@Test
public void testNestedUserTypes() throws Throwable
{
String type1 = createType("CREATE TYPE %s ( s set<text>, m map<text, text>, l list<text>)");
String type2 = createType("CREATE TYPE %s ( s set < frozen < " + type1 + " >>,)");
createTable("CREATE TABLE %s (id int PRIMARY KEY, val frozen<" + type2 + ">)");
execute("INSERT INTO %s (id, val) VALUES (0, { s : {{ s : {'foo', 'bar'}, m : { 'foo' : 'bar' }, l : ['foo', 'bar']} }})");
// TODO: check result once we have an easy way to do it. For now we just check it doesn't crash
execute("SELECT * FROM %s");
}
/**
* Migrated from cql_tests.py:TestCQL.add_field_to_udt_test()
*/
@Test
public void testAddFieldToUdt() throws Throwable
{
String typeName = createType("CREATE TYPE %s (fooint int, fooset set <text>)");
createTable("CREATE TABLE %s (key int PRIMARY KEY, data frozen <" + typeName + ">)");
execute("INSERT INTO %s (key, data) VALUES (1, {fooint: 1, fooset: {'2'}})");
execute("ALTER TYPE " + keyspace() + "." + typeName + " ADD foomap map <int,text>");
execute("INSERT INTO %s (key, data) VALUES (1, {fooint: 1, fooset: {'2'}, foomap: {3 : 'bar'}})");
}
}

View File

@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.miscellaneous;
import java.util.List;
import java.util.concurrent.ExecutionException;
@ -23,6 +23,7 @@ import java.util.concurrent.Future;
import junit.framework.Assert;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.db.Keyspace;
import org.apache.cassandra.db.compaction.CompactionInterruptedException;

View File

@ -0,0 +1,331 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3.validation.miscellaneous;
import java.math.BigInteger;
import org.junit.Test;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNull;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.exceptions.SyntaxException;
import org.apache.cassandra.utils.ByteBufferUtil;
/**
* Any tests that do not fit in any other category,
* migrated from python dtests, CASSANDRA-9160
**/
public class OverflowTest extends CQLTester
{
/**
* Test support for nulls
* migrated from cql_tests.py:TestCQL.null_support_test()
*/
@Test
public void testNullSupport() throws Throwable
{
createTable("CREATE TABLE %s (k int, c int, v1 int, v2 set<text>, PRIMARY KEY (k, c))");
execute("INSERT INTO %s (k, c, v1, v2) VALUES (0, 0, null, {'1', '2'})");
execute("INSERT INTO %s (k, c, v1) VALUES (0, 1, 1)");
assertRows(execute("SELECT * FROM %s"),
row(0, 0, null, set("1", "2")),
row(0, 1, 1, null));
execute("INSERT INTO %s (k, c, v1) VALUES (0, 1, null)");
execute("INSERT INTO %s (k, c, v2) VALUES (0, 0, null)");
assertRows(execute("SELECT * FROM %s"),
row(0, 0, null, null),
row(0, 1, null, null));
assertInvalid("INSERT INTO %s (k, c, v2) VALUES (0, 2, {1, null})");
assertInvalid("SELECT * FROM %s WHERE k = null");
assertInvalid("INSERT INTO %s (k, c, v2) VALUES (0, 0, { 'foo', 'bar', null })");
}
/**
* Test reserved keywords
* migrated from cql_tests.py:TestCQL.reserved_keyword_test()
*/
@Test
public void testReservedKeywords() throws Throwable
{
createTable("CREATE TABLE %s (key text PRIMARY KEY, count counter)");
String tableName = createTableName();
assertInvalidThrow(SyntaxException.class, String.format("CREATE TABLE %s.%s (select text PRIMARY KEY, x int)", keyspace(), tableName));
}
/**
* Test identifiers
* migrated from cql_tests.py:TestCQL.identifier_test()
*/
@Test
public void testIdentifiers() throws Throwable
{
createTable("CREATE TABLE %s (key_23 int PRIMARY KEY, CoLuMn int)");
execute("INSERT INTO %s (Key_23, Column) VALUES (0, 0)");
execute("INSERT INTO %s (KEY_23, COLUMN) VALUES (0, 0)");
assertInvalid("INSERT INTO %s (key_23, column, column) VALUES (0, 0, 0)");
assertInvalid("INSERT INTO %s (key_23, column, COLUMN) VALUES (0, 0, 0)");
assertInvalid("INSERT INTO %s (key_23, key_23, column) VALUES (0, 0, 0)");
assertInvalid("INSERT INTO %s (key_23, KEY_23, column) VALUES (0, 0, 0)");
String tableName = createTableName();
assertInvalidThrow(SyntaxException.class, String.format("CREATE TABLE %s.%s (select int PRIMARY KEY, column int)", keyspace(), tableName));
}
/**
* Test table options
* migrated from cql_tests.py:TestCQL.table_options_test()
*/
@Test
public void testTableOptions() throws Throwable
{
createTable("CREATE TABLE %s ( k int PRIMARY KEY, c int ) WITH "
+ "comment = 'My comment' "
+ "AND read_repair_chance = 0.5 "
+ "AND dclocal_read_repair_chance = 0.5 "
+ "AND gc_grace_seconds = 4 "
+ "AND bloom_filter_fp_chance = 0.01 "
+ "AND compaction = { 'class' : 'LeveledCompactionStrategy', 'sstable_size_in_mb' : 10 } "
+ "AND compression = { 'sstable_compression' : '' } "
+ "AND caching = 'all' ");
execute("ALTER TABLE %s WITH "
+ "comment = 'other comment' "
+ "AND read_repair_chance = 0.3 "
+ "AND dclocal_read_repair_chance = 0.3 "
+ "AND gc_grace_seconds = 100 "
+ "AND bloom_filter_fp_chance = 0.1 "
+ "AND compaction = { 'class': 'SizeTieredCompactionStrategy', 'min_sstable_size' : 42 } "
+ "AND compression = { 'sstable_compression' : 'SnappyCompressor' } "
+ "AND caching = 'rows_only' ");
}
/**
* Migrated from cql_tests.py:TestCQL.unescaped_string_test()
*/
@Test
public void testUnescapedString() throws Throwable
{
createTable("CREATE TABLE %s ( k text PRIMARY KEY, c text, )");
//The \ in this query string is not forwarded to cassandra.
//The ' is being escaped in python, but only ' is forwarded
//over the wire instead of \'.
assertInvalidThrow(SyntaxException.class, "INSERT INTO %s (k, c) VALUES ('foo', 'CQL is cassandra\'s best friend')");
}
/**
* Migrated from cql_tests.py:TestCQL.boolean_test()
*/
@Test
public void testBoolean() throws Throwable
{
createTable("CREATE TABLE %s (k boolean PRIMARY KEY, b boolean)");
execute("INSERT INTO %s (k, b) VALUES (true, false)");
assertRows(execute("SELECT * FROM %s WHERE k = true"),
row(true, false));
}
/**
* Migrated from cql_tests.py:TestCQL.float_with_exponent_test()
*/
@Test
public void testFloatWithExponent() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, d double, f float)");
execute("INSERT INTO %s (k, d, f) VALUES (0, 3E+10, 3.4E3)");
execute("INSERT INTO %s (k, d, f) VALUES (1, 3.E10, -23.44E-3)");
execute("INSERT INTO %s (k, d, f) VALUES (2, 3, -2)");
}
/**
* Test regression from #5189,
* migrated from cql_tests.py:TestCQL.compact_metadata_test()
*/
@Test
public void testCompactMetadata() throws Throwable
{
createTable("CREATE TABLE %s (id int primary key, i int ) WITH COMPACT STORAGE");
execute("INSERT INTO %s (id, i) VALUES (1, 2)");
assertRows(execute("SELECT * FROM %s"),
row(1, 2));
}
/**
* Migrated from cql_tests.py:TestCQL.conversion_functions_test()
*/
@Test
public void testConversionFunctions() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, i varint, b blob)");
execute("INSERT INTO %s (k, i, b) VALUES (0, blobAsVarint(bigintAsBlob(3)), textAsBlob('foobar'))");
assertRows(execute("SELECT i, blobAsText(b) FROM %s WHERE k = 0"),
row(BigInteger.valueOf(3), "foobar"));
}
/**
* Migrated from cql_tests.py:TestCQL.empty_blob_test()
*/
@Test
public void testEmptyBlob() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, b blob)");
execute("INSERT INTO %s (k, b) VALUES (0, 0x)");
assertRows(execute("SELECT * FROM %s"),
row(0, ByteBufferUtil.bytes("")));
}
private Object[][] fill() throws Throwable
{
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
execute("INSERT INTO %s (k1, k2, v) VALUES (?, ?, ?)", i, j, i + j);
return getRows(execute("SELECT * FROM %s"));
}
/**
* Migrated from cql_tests.py:TestCQL.empty_in_test()
*/
@Test
public void testEmpty() throws Throwable
{
createTable("CREATE TABLE %s (k1 int, k2 int, v int, PRIMARY KEY (k1, k2))");
// Inserts a few rows to make sure we don 't actually query something
Object[][] rows = fill();
// Test empty IN() in SELECT
assertEmpty(execute("SELECT v FROM %s WHERE k1 IN ()"));
assertEmpty(execute("SELECT v FROM %s WHERE k1 = 0 AND k2 IN ()"));
// Test empty IN() in DELETE
execute("DELETE FROM %s WHERE k1 IN ()");
assertArrayEquals(rows, getRows(execute("SELECT * FROM %s")));
// Test empty IN() in UPDATE
execute("UPDATE %s SET v = 3 WHERE k1 IN () AND k2 = 2");
assertArrayEquals(rows, getRows(execute("SELECT * FROM %s")));
// Same test, but for compact
createTable("CREATE TABLE %s (k1 int, k2 int, v int, PRIMARY KEY (k1, k2)) WITH COMPACT STORAGE");
rows = fill();
assertEmpty(execute("SELECT v FROM %s WHERE k1 IN ()"));
assertEmpty(execute("SELECT v FROM %s WHERE k1 = 0 AND k2 IN ()"));
// Test empty IN() in DELETE
execute("DELETE FROM %s WHERE k1 IN ()");
assertArrayEquals(rows, getRows(execute("SELECT * FROM %s")));
// Test empty IN() in UPDATE
execute("UPDATE %s SET v = 3 WHERE k1 IN () AND k2 = 2");
assertArrayEquals(rows, getRows(execute("SELECT * FROM %s")));
}
/**
* Migrated from cql_tests.py:TestCQL.function_with_null_test()
*/
@Test
public void testFunctionWithNull() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, t timeuuid,)");
execute("INSERT INTO %s (k) VALUES (0)");
Object[][] rows = getRows(execute("SELECT dateOf(t) FROM %s WHERE k=0"));
assertNull(rows[0][0]);
}
/**
* Migrated from cql_tests.py:TestCQL.column_name_validation_test()
*/
@Test
public void testColumnNameValidation() throws Throwable
{
createTable("CREATE TABLE %s (k text, c int, v timeuuid, PRIMARY KEY (k, c))");
assertInvalid("INSERT INTO %s (k, c) VALUES ('', 0)");
// Insert a value that don't fit 'int'
assertInvalid("INSERT INTO %s (k, c) VALUES (0, 10000000000)");
// Insert a non-version 1 uuid
assertInvalid("INSERT INTO %s (k, c, v) VALUES (0, 0, 550e8400-e29b-41d4-a716-446655440000)");
}
/**
* Migrated from cql_tests.py:TestCQL.nan_infinity_test()
*/
@Test
public void testNanInfinityValues() throws Throwable
{
createTable("CREATE TABLE %s (f float PRIMARY KEY)");
execute("INSERT INTO %s (f) VALUES (NaN)");
execute("INSERT INTO %s (f) VALUES (-NaN)");
execute("INSERT INTO %s (f) VALUES (Infinity)");
execute("INSERT INTO %s (f) VALUES (-Infinity)");
Object[][] selected = getRows(execute("SELECT * FROM %s"));
// selected should be[[nan],[inf],[-inf]],
// but assert element - wise because NaN!=NaN
assertEquals(3, selected.length);
assertEquals(1, selected[0].length);
assertTrue(Float.isNaN((Float) selected[0][0]));
assertTrue(Float.isInfinite((Float) selected[1][0])); //inf
assertTrue(((Float) selected[1][0]) > 0);
assertTrue(Float.isInfinite((Float) selected[2][0])); //-inf
assertTrue(((Float) selected[2][0]) < 0);
}
/**
* Migrated from cql_tests.py:TestCQL.blobAs_functions_test()
*/
@Test
public void testBlobAsFunction() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, v int)");
// A blob that is not 4 bytes should be rejected
assertInvalid("INSERT INTO %s (k, v) VALUES (0, blobAsInt(0x01))");
execute("INSERT INTO %s (k, v) VALUES (0, blobAsInt(0x00000001))");
assertRows(execute("select v from %s where k=0"), row(1));
}
}

View File

@ -15,10 +15,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.miscellaneous;
import org.junit.Test;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.exceptions.SyntaxException;
public class PgStringTest extends CQLTester

View File

@ -15,10 +15,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.miscellaneous;
import org.junit.Test;
import org.apache.cassandra.cql3.CQLTester;
public class RoleSyntaxTest extends CQLTester
{
@Test

View File

@ -15,10 +15,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.miscellaneous;
import org.junit.Test;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.db.Keyspace;
import org.apache.cassandra.io.sstable.metadata.StatsMetadata;

View File

@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.miscellaneous;
import java.util.concurrent.TimeUnit;
@ -25,6 +25,7 @@ import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.db.filter.TombstoneOverwhelmingException;
import static junit.framework.Assert.assertTrue;
@ -33,7 +34,7 @@ import static junit.framework.Assert.fail;
/**
* Test that TombstoneOverwhelmingException gets thrown when it should be and doesn't when it shouldn't be.
*/
public class SliceQueryFilterWithTombstonesTest extends CQLTester
public class TombstonesTest extends CQLTester
{
static final int ORIGINAL_THRESHOLD = DatabaseDescriptor.getTombstoneFailureThreshold();
static final int THRESHOLD = 100;

View File

@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.operations;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
@ -27,8 +27,10 @@ import org.apache.commons.lang3.time.DateUtils;
import org.junit.Assert;
import org.junit.Test;
import org.apache.cassandra.cql3.QueryProcessor;
import org.apache.cassandra.cql3.functions.Functions;
import org.apache.cassandra.cql3.functions.UDAggregate;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.exceptions.FunctionExecutionException;
import org.apache.cassandra.exceptions.InvalidRequestException;
import org.apache.cassandra.serializers.Int32Serializer;

View File

@ -15,15 +15,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.operations;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.db.Keyspace;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.exceptions.SyntaxException;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class AlterTableTest extends CQLTester
public class AlterTest extends CQLTester
{
@Test
public void testAddList() throws Throwable
@ -110,4 +114,90 @@ public class AlterTableTest extends CQLTester
assertEquals(256, cfs.metadata.getMinIndexInterval());
assertEquals(512, cfs.metadata.getMaxIndexInterval());
}
/**
* Migrated from cql_tests.py:TestCQL.create_alter_options_test()
*/
@Test
public void testCreateAlterKeyspaces() throws Throwable
{
assertInvalidThrow(SyntaxException.class, "CREATE KEYSPACE ks1");
assertInvalidThrow(ConfigurationException.class, "CREATE KEYSPACE ks1 WITH replication= { 'replication_factor' : 1 }");
execute("CREATE KEYSPACE ks1 WITH replication={ 'class' : 'SimpleStrategy', 'replication_factor' : 1 }");
execute("CREATE KEYSPACE ks2 WITH replication={ 'class' : 'SimpleStrategy', 'replication_factor' : 1 } AND durable_writes=false");
assertRows(execute("SELECT keyspace_name, durable_writes FROM system.schema_keyspaces"),
row("ks1", true),
row(KEYSPACE, true),
row(KEYSPACE_PER_TEST, true),
row("ks2", false));
execute("ALTER KEYSPACE ks1 WITH replication = { 'class' : 'NetworkTopologyStrategy', 'dc1' : 1 } AND durable_writes=False");
execute("ALTER KEYSPACE ks2 WITH durable_writes=true");
assertRows(execute("SELECT keyspace_name, durable_writes, strategy_class FROM system.schema_keyspaces"),
row("ks1", false, "org.apache.cassandra.locator.NetworkTopologyStrategy"),
row(KEYSPACE, true, "org.apache.cassandra.locator.SimpleStrategy"),
row(KEYSPACE_PER_TEST, true, "org.apache.cassandra.locator.SimpleStrategy"),
row("ks2", true, "org.apache.cassandra.locator.SimpleStrategy"));
execute("USE ks1");
assertInvalidThrow(ConfigurationException.class, "CREATE TABLE cf1 (a int PRIMARY KEY, b int) WITH compaction = { 'min_threshold' : 4 }");
execute("CREATE TABLE cf1 (a int PRIMARY KEY, b int) WITH compaction = { 'class' : 'SizeTieredCompactionStrategy', 'min_threshold' : 7 }");
assertRows(execute("SELECT columnfamily_name, min_compaction_threshold FROM system.schema_columnfamilies WHERE keyspace_name='ks1'"),
row("cf1", 7));
// clean-up
execute("DROP KEYSPACE ks1");
execute("DROP KEYSPACE ks2");
}
/**
* Test for bug of 5232,
* migrated from cql_tests.py:TestCQL.alter_bug_test()
*/
@Test
public void testAlterStatementWithAdd() throws Throwable
{
createTable("CREATE TABLE %s (id int PRIMARY KEY, t text)");
execute("UPDATE %s SET t = '111' WHERE id = 1");
execute("ALTER TABLE %s ADD l list<text>");
assertRows(execute("SELECT * FROM %s"),
row(1, null, "111"));
execute("ALTER TABLE %s ADD m map<int, text>");
assertRows(execute("SELECT * FROM %s"),
row(1, null, null, "111"));
}
/**
* Test for 7744,
* migrated from cql_tests.py:TestCQL.downgrade_to_compact_bug_test()
*/
@Test
public void testDowngradeToCompact() throws Throwable
{
createTable("create table %s (k int primary key, v set<text>)");
execute("insert into %s (k, v) VALUES (0, {'f'})");
flush();
execute("alter table %s drop v");
execute("alter table %s add v int");
}
@Test
// tests CASSANDRA-9565
public void testDoubleWith() throws Throwable
{
String[] stmts = new String[] { "ALTER KEYSPACE WITH WITH DURABLE_WRITES = true",
"ALTER KEYSPACE ks WITH WITH DURABLE_WRITES = true" };
for (String stmt : stmts) {
assertInvalidSyntaxMessage("no viable alternative at input 'WITH'", stmt);
}
}
}

View File

@ -0,0 +1,106 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3.validation.operations;
import org.junit.Test;
import org.apache.cassandra.cql3.CQLTester;
public class BatchTest extends CQLTester
{
/**
* Test batch statements
* migrated from cql_tests.py:TestCQL.batch_test()
*/
@Test
public void testBatch() throws Throwable
{
createTable("CREATE TABLE %s (userid text PRIMARY KEY, name text, password text)");
String query = "BEGIN BATCH\n"
+ "INSERT INTO %1$s (userid, password, name) VALUES ('user2', 'ch@ngem3b', 'second user');\n"
+ "UPDATE %1$s SET password = 'ps22dhds' WHERE userid = 'user3';\n"
+ "INSERT INTO %1$s (userid, password) VALUES ('user4', 'ch@ngem3c');\n"
+ "DELETE name FROM %1$s WHERE userid = 'user1';\n"
+ "APPLY BATCH;";
execute(query);
}
/**
* Migrated from cql_tests.py:TestCQL.batch_and_list_test()
*/
@Test
public void testBatchAndList() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, l list<int>)");
execute("BEGIN BATCH " +
"UPDATE %1$s SET l = l +[ 1 ] WHERE k = 0; " +
"UPDATE %1$s SET l = l + [ 2 ] WHERE k = 0; " +
"UPDATE %1$s SET l = l + [ 3 ] WHERE k = 0; " +
"APPLY BATCH");
assertRows(execute("SELECT l FROM %s WHERE k = 0"),
row(list(1, 2, 3)));
execute("BEGIN BATCH " +
"UPDATE %1$s SET l =[ 1 ] + l WHERE k = 1; " +
"UPDATE %1$s SET l = [ 2 ] + l WHERE k = 1; " +
"UPDATE %1$s SET l = [ 3 ] + l WHERE k = 1; " +
"APPLY BATCH ");
assertRows(execute("SELECT l FROM %s WHERE k = 1"),
row(list(3, 2, 1)));
}
/**
* Migrated from cql_tests.py:TestCQL.bug_6115_test()
*/
@Test
public void testBatchDeleteInsert() throws Throwable
{
createTable("CREATE TABLE %s (k int, v int, PRIMARY KEY (k, v))");
execute("INSERT INTO %s (k, v) VALUES (0, 1)");
execute("BEGIN BATCH DELETE FROM %1$s WHERE k=0 AND v=1; INSERT INTO %1$s (k, v) VALUES (0, 2); APPLY BATCH");
assertRows(execute("SELECT * FROM %s"),
row(0, 2));
}
@Test
public void testBatchWithUnset() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, s text, i int)");
// test batch and update
String qualifiedTable = keyspace() + "." + currentTable();
execute("BEGIN BATCH " +
"INSERT INTO %s (k, s, i) VALUES (100, 'batchtext', 7); " +
"INSERT INTO " + qualifiedTable + " (k, s, i) VALUES (111, 'batchtext', 7); " +
"UPDATE " + qualifiedTable + " SET s=?, i=? WHERE k = 100; " +
"UPDATE " + qualifiedTable + " SET s=?, i=? WHERE k=111; " +
"APPLY BATCH;", null, unset(), unset(), null);
assertRows(execute("SELECT k, s, i FROM %s where k in (100,111)"),
row(100, null, 7),
row(111, "batchtext", null)
);
}
}

View File

@ -0,0 +1,498 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3.validation.operations;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Collections;
import java.util.UUID;
import org.junit.Assert;
import org.junit.Test;
import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.config.Schema;
import org.apache.cassandra.config.TriggerDefinition;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.db.ColumnFamily;
import org.apache.cassandra.db.Mutation;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.exceptions.SyntaxException;
import org.apache.cassandra.triggers.ITrigger;
import org.apache.cassandra.utils.ByteBufferUtil;
import static junit.framework.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class CreateTest extends CQLTester
{
@Test
public void testCQL3PartitionKeyOnlyTable()
{
createTable("CREATE TABLE %s (id text PRIMARY KEY);");
assertFalse(currentTableMetadata().isThriftCompatible());
}
@Test
public void testCreateTableWithSmallintColumns() throws Throwable
{
createTable("CREATE TABLE %s (a text, b smallint, c smallint, primary key (a, b));");
execute("INSERT INTO %s (a, b, c) VALUES ('1', 1, 2)");
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", "2", Short.MAX_VALUE, Short.MIN_VALUE);
assertRows(execute("SELECT * FROM %s"),
row("2", Short.MAX_VALUE, Short.MIN_VALUE),
row("1", (short) 1, (short) 2));
assertInvalidMessage("Expected 2 bytes for a smallint (4)",
"INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", "3", 1, 2);
assertInvalidMessage("Expected 2 bytes for a smallint (0)",
"INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", "3", (short) 1, ByteBufferUtil.EMPTY_BYTE_BUFFER);
}
@Test
public void testCreateTinyintColumns() throws Throwable
{
createTable("CREATE TABLE %s (a text, b tinyint, c tinyint, primary key (a, b));");
execute("INSERT INTO %s (a, b, c) VALUES ('1', 1, 2)");
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", "2", Byte.MAX_VALUE, Byte.MIN_VALUE);
assertRows(execute("SELECT * FROM %s"),
row("2", Byte.MAX_VALUE, Byte.MIN_VALUE),
row("1", (byte) 1, (byte) 2));
assertInvalidMessage("Expected 1 byte for a tinyint (4)",
"INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", "3", 1, 2);
assertInvalidMessage("Expected 1 byte for a tinyint (0)",
"INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", "3", (byte) 1, ByteBufferUtil.EMPTY_BYTE_BUFFER);
}
/**
* Creation and basic operations on a static table,
* migrated from cql_tests.py:TestCQL.static_cf_test()
*/
@Test
public void testStaticTable() throws Throwable
{
createTable("CREATE TABLE %s (userid uuid PRIMARY KEY, firstname text, lastname text, age int)");
UUID id1 = UUID.fromString("550e8400-e29b-41d4-a716-446655440000");
UUID id2 = UUID.fromString("f47ac10b-58cc-4372-a567-0e02b2c3d479");
execute("INSERT INTO %s (userid, firstname, lastname, age) VALUES (?, ?, ?, ?)", id1, "Frodo", "Baggins", 32);
execute("UPDATE %s SET firstname = ?, lastname = ?, age = ? WHERE userid = ?", "Samwise", "Gamgee", 33, id2);
assertRows(execute("SELECT firstname, lastname FROM %s WHERE userid = ?", id1),
row("Frodo", "Baggins"));
assertRows(execute("SELECT * FROM %s WHERE userid = ?", id1),
row(id1, 32, "Frodo", "Baggins"));
assertRows(execute("SELECT * FROM %s"),
row(id2, 33, "Samwise", "Gamgee"),
row(id1, 32, "Frodo", "Baggins")
);
String batch = "BEGIN BATCH "
+ "INSERT INTO %1$s (userid, age) VALUES (?, ?) "
+ "UPDATE %1$s SET age = ? WHERE userid = ? "
+ "DELETE firstname, lastname FROM %1$s WHERE userid = ? "
+ "DELETE firstname, lastname FROM %1$s WHERE userid = ? "
+ "APPLY BATCH";
execute(batch, id1, 36, 37, id2, id1, id2);
assertRows(execute("SELECT * FROM %s"),
row(id2, 37, null, null),
row(id1, 36, null, null));
}
/**
* Creation and basic operations on a static table with compact storage,
* migrated from cql_tests.py:TestCQL.noncomposite_static_cf_test()
*/
@Test
public void testDenseStaticTable() throws Throwable
{
createTable("CREATE TABLE %s (userid uuid PRIMARY KEY, firstname text, lastname text, age int) WITH COMPACT STORAGE");
UUID id1 = UUID.fromString("550e8400-e29b-41d4-a716-446655440000");
UUID id2 = UUID.fromString("f47ac10b-58cc-4372-a567-0e02b2c3d479");
execute("INSERT INTO %s (userid, firstname, lastname, age) VALUES (?, ?, ?, ?)", id1, "Frodo", "Baggins", 32);
execute("UPDATE %s SET firstname = ?, lastname = ?, age = ? WHERE userid = ?", "Samwise", "Gamgee", 33, id2);
assertRows(execute("SELECT firstname, lastname FROM %s WHERE userid = ?", id1),
row("Frodo", "Baggins"));
assertRows(execute("SELECT * FROM %s WHERE userid = ?", id1),
row(id1, 32, "Frodo", "Baggins"));
assertRows(execute("SELECT * FROM %s"),
row(id2, 33, "Samwise", "Gamgee"),
row(id1, 32, "Frodo", "Baggins")
);
String batch = "BEGIN BATCH "
+ "INSERT INTO %1$s (userid, age) VALUES (?, ?) "
+ "UPDATE %1$s SET age = ? WHERE userid = ? "
+ "DELETE firstname, lastname FROM %1$s WHERE userid = ? "
+ "DELETE firstname, lastname FROM %1$s WHERE userid = ? "
+ "APPLY BATCH";
execute(batch, id1, 36, 37, id2, id1, id2);
assertRows(execute("SELECT * FROM %s"),
row(id2, 37, null, null),
row(id1, 36, null, null));
}
/**
* Creation and basic operations on a non-composite table with compact storage,
* migrated from cql_tests.py:TestCQL.dynamic_cf_test()
*/
@Test
public void testDenseNonCompositeTable() throws Throwable
{
createTable("CREATE TABLE %s (userid uuid, url text, time bigint, PRIMARY KEY (userid, url)) WITH COMPACT STORAGE");
UUID id1 = UUID.fromString("550e8400-e29b-41d4-a716-446655440000");
UUID id2 = UUID.fromString("f47ac10b-58cc-4372-a567-0e02b2c3d479");
UUID id3 = UUID.fromString("810e8500-e29b-41d4-a716-446655440000");
execute("INSERT INTO %s (userid, url, time) VALUES (?, ?, ?)", id1, "http://foo.bar", 42L);
execute("INSERT INTO %s (userid, url, time) VALUES (?, ?, ?)", id1, "http://foo-2.bar", 24L);
execute("INSERT INTO %s (userid, url, time) VALUES (?, ?, ?)", id1, "http://bar.bar", 128L);
execute("UPDATE %s SET time = 24 WHERE userid = ? and url = 'http://bar.foo'", id2);
execute("UPDATE %s SET time = 12 WHERE userid IN (?, ?) and url = 'http://foo-3'", id2, id1);
assertRows(execute("SELECT url, time FROM %s WHERE userid = ?", id1),
row("http://bar.bar", 128L),
row("http://foo-2.bar", 24L),
row("http://foo-3", 12L),
row("http://foo.bar", 42L));
assertRows(execute("SELECT * FROM %s WHERE userid = ?", id2),
row(id2, "http://bar.foo", 24L),
row(id2, "http://foo-3", 12L));
assertRows(execute("SELECT time FROM %s"),
row(24L), // id2
row(12L),
row(128L), // id1
row(24L),
row(12L),
row(42L)
);
// Check we don't allow empty values for url since this is the full underlying cell name (#6152)
assertInvalid("INSERT INTO %s (userid, url, time) VALUES (?, '', 42)", id3);
}
/**
* Creation and basic operations on a composite table with compact storage,
* migrated from cql_tests.py:TestCQL.dense_cf_test()
*/
@Test
public void testDenseCompositeTable() throws Throwable
{
createTable("CREATE TABLE %s (userid uuid, ip text, port int, time bigint, PRIMARY KEY (userid, ip, port)) WITH COMPACT STORAGE");
UUID id1 = UUID.fromString("550e8400-e29b-41d4-a716-446655440000");
UUID id2 = UUID.fromString("f47ac10b-58cc-4372-a567-0e02b2c3d479");
execute("INSERT INTO %s (userid, ip, port, time) VALUES (?, '192.168.0.1', 80, 42)", id1);
execute("INSERT INTO %s (userid, ip, port, time) VALUES (?, '192.168.0.2', 80, 24)", id1);
execute("INSERT INTO %s (userid, ip, port, time) VALUES (?, '192.168.0.2', 90, 42)", id1);
execute("UPDATE %s SET time = 24 WHERE userid = ? AND ip = '192.168.0.2' AND port = 80", id2);
// we don't have to include all of the clustering columns (see CASSANDRA-7990)
execute("INSERT INTO %s (userid, ip, time) VALUES (?, '192.168.0.3', 42)", id2);
execute("UPDATE %s SET time = 42 WHERE userid = ? AND ip = '192.168.0.4'", id2);
assertRows(execute("SELECT ip, port, time FROM %s WHERE userid = ?", id1),
row("192.168.0.1", 80, 42L),
row("192.168.0.2", 80, 24L),
row("192.168.0.2", 90, 42L));
assertRows(execute("SELECT ip, port, time FROM %s WHERE userid = ? and ip >= '192.168.0.2'", id1),
row("192.168.0.2", 80, 24L),
row("192.168.0.2", 90, 42L));
assertRows(execute("SELECT ip, port, time FROM %s WHERE userid = ? and ip = '192.168.0.2'", id1),
row("192.168.0.2", 80, 24L),
row("192.168.0.2", 90, 42L));
assertEmpty(execute("SELECT ip, port, time FROM %s WHERE userid = ? and ip > '192.168.0.2'", id1));
assertRows(execute("SELECT ip, port, time FROM %s WHERE userid = ? AND ip = '192.168.0.3'", id2),
row("192.168.0.3", null, 42L));
assertRows(execute("SELECT ip, port, time FROM %s WHERE userid = ? AND ip = '192.168.0.4'", id2),
row("192.168.0.4", null, 42L));
execute("DELETE time FROM %s WHERE userid = ? AND ip = '192.168.0.2' AND port = 80", id1);
assertRowCount(execute("SELECT * FROM %s WHERE userid = ?", id1), 2);
execute("DELETE FROM %s WHERE userid = ?", id1);
assertEmpty(execute("SELECT * FROM %s WHERE userid = ?", id1));
execute("DELETE FROM %s WHERE userid = ? AND ip = '192.168.0.3'", id2);
assertEmpty(execute("SELECT * FROM %s WHERE userid = ? AND ip = '192.168.0.3'", id2));
}
/**
* Creation and basic operations on a composite table,
* migrated from cql_tests.py:TestCQL.sparse_cf_test()
*/
@Test
public void testSparseCompositeTable() throws Throwable
{
createTable("CREATE TABLE %s (userid uuid, posted_month int, posted_day int, body text, posted_by text, PRIMARY KEY (userid, posted_month, posted_day))");
UUID id1 = UUID.fromString("550e8400-e29b-41d4-a716-446655440000");
UUID id2 = UUID.fromString("f47ac10b-58cc-4372-a567-0e02b2c3d479");
execute("INSERT INTO %s (userid, posted_month, posted_day, body, posted_by) VALUES (?, 1, 12, 'Something else', 'Frodo Baggins')", id1);
execute("INSERT INTO %s (userid, posted_month, posted_day, body, posted_by) VALUES (?, 1, 24, 'Something something', 'Frodo Baggins')", id1);
execute("UPDATE %s SET body = 'Yo Froddo', posted_by = 'Samwise Gamgee' WHERE userid = ? AND posted_month = 1 AND posted_day = 3", id2);
execute("UPDATE %s SET body = 'Yet one more message' WHERE userid = ? AND posted_month = 1 and posted_day = 30", id1);
assertRows(execute("SELECT body, posted_by FROM %s WHERE userid = ? AND posted_month = 1 AND posted_day = 24", id1),
row("Something something", "Frodo Baggins"));
assertRows(execute("SELECT posted_day, body, posted_by FROM %s WHERE userid = ? AND posted_month = 1 AND posted_day > 12", id1),
row(24, "Something something", "Frodo Baggins"),
row(30, "Yet one more message", null));
assertRows(execute("SELECT posted_day, body, posted_by FROM %s WHERE userid = ? AND posted_month = 1", id1),
row(12, "Something else", "Frodo Baggins"),
row(24, "Something something", "Frodo Baggins"),
row(30, "Yet one more message", null));
}
/**
* Check invalid create table statements,
* migrated from cql_tests.py:TestCQL.create_invalid_test()
*/
@Test
public void testInvalidCreateTableStatements() throws Throwable
{
assertInvalidThrow(SyntaxException.class, "CREATE TABLE test ()");
assertInvalid("CREATE TABLE test (c1 text, c2 text, c3 text)");
assertInvalid("CREATE TABLE test (key1 text PRIMARY KEY, key2 text PRIMARY KEY)");
assertInvalid("CREATE TABLE test (key text PRIMARY KEY, key int)");
assertInvalid("CREATE TABLE test (key text PRIMARY KEY, c int, c text)");
assertInvalid("CREATE TABLE test (key text, key2 text, c int, d text, PRIMARY KEY (key, key2)) WITH COMPACT STORAGE");
}
/**
* Check obsolete properties from CQL2 are rejected
* migrated from cql_tests.py:TestCQL.invalid_old_property_test()
*/
@Test
public void testObsoleteTableProperties() throws Throwable
{
assertInvalidThrow(SyntaxException.class, "CREATE TABLE test (foo text PRIMARY KEY, c int) WITH default_validation=timestamp");
createTable("CREATE TABLE %s (foo text PRIMARY KEY, c int)");
assertInvalidThrow(SyntaxException.class, "ALTER TABLE %s WITH default_validation=int");
}
/**
* Test create and drop keyspace
* migrated from cql_tests.py:TestCQL.keyspace_test()
*/
@Test
public void testKeyspace() throws Throwable
{
assertInvalidThrow(SyntaxException.class, "CREATE KEYSPACE %s testXYZ ");
execute("CREATE KEYSPACE testXYZ WITH replication = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 }");
assertInvalid(
"CREATE KEYSPACE My_much_much_too_long_identifier_that_should_not_work WITH replication = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 }");
execute("DROP KEYSPACE testXYZ");
assertInvalidThrow(ConfigurationException.class, "DROP KEYSPACE non_existing");
execute("CREATE KEYSPACE testXYZ WITH replication = { 'class' : 'SimpleStrategy', 'replication_factor' : 1 }");
// clean-up
execute("DROP KEYSPACE testXYZ");
}
/**
* Test create and drop table
* migrated from cql_tests.py:TestCQL.table_test()
*/
@Test
public void testTable() throws Throwable
{
String table1 = createTable(" CREATE TABLE %s (k int PRIMARY KEY, c int)");
createTable(" CREATE TABLE %s (k int, name int, value int, PRIMARY KEY(k, name)) WITH COMPACT STORAGE ");
createTable(" CREATE TABLE %s (k int, c int, PRIMARY KEY (k),)");
String table4 = createTableName();
// repeated column
assertInvalidMessage("Multiple definition of identifier k", String.format("CREATE TABLE %s (k int PRIMARY KEY, c int, k text)", table4));
// compact storage limitations
assertInvalidThrow(SyntaxException.class,
String.format("CREATE TABLE %s (k int, name, int, c1 int, c2 int, PRIMARY KEY(k, name)) WITH COMPACT STORAGE", table4));
execute(String.format("DROP TABLE %s.%s", keyspace(), table1));
createTable(String.format("CREATE TABLE %s.%s ( k int PRIMARY KEY, c1 int, c2 int, ) ", keyspace(), table1));
}
/**
* Test truncate statement,
* migrated from cql_tests.py:TestCQL.table_test().
*/
@Test
public void testTruncate() throws Throwable
{
createTable(" CREATE TABLE %s (k int, name int, value int, PRIMARY KEY(k, name)) WITH COMPACT STORAGE ");
execute("TRUNCATE %s");
}
/**
* Migrated from cql_tests.py:TestCQL.multiordering_validation_test()
*/
@Test
public void testMultiOrderingValidation() throws Throwable
{
String tableName = KEYSPACE + "." + createTableName();
assertInvalid(String.format("CREATE TABLE test (k int, c1 int, c2 int, PRIMARY KEY (k, c1, c2)) WITH CLUSTERING ORDER BY (c2 DESC)", tableName));
tableName = KEYSPACE + "." + createTableName();
assertInvalid(String.format("CREATE TABLE test (k int, c1 int, c2 int, PRIMARY KEY (k, c1, c2)) WITH CLUSTERING ORDER BY (c2 ASC, c1 DESC)", tableName));
tableName = KEYSPACE + "." + createTableName();
assertInvalid(String.format("CREATE TABLE test (k int, c1 int, c2 int, PRIMARY KEY (k, c1, c2)) WITH CLUSTERING ORDER BY (c1 DESC, c2 DESC, c3 DESC)", tableName));
createTable("CREATE TABLE %s (k int, c1 int, c2 int, PRIMARY KEY (k, c1, c2)) WITH CLUSTERING ORDER BY (c1 DESC, c2 DESC)");
createTable("CREATE TABLE %s (k int, c1 int, c2 int, PRIMARY KEY (k, c1, c2)) WITH CLUSTERING ORDER BY (c1 ASC, c2 DESC)");
}
@Test
public void testCreateTrigger() throws Throwable
{
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a))");
execute("CREATE TRIGGER trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'");
assertTriggerExists("trigger_1", TestTrigger.class);
execute("CREATE TRIGGER trigger_2 ON %s USING '" + TestTrigger.class.getName() + "'");
assertTriggerExists("trigger_2", TestTrigger.class);
assertInvalid("CREATE TRIGGER trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'");
execute("CREATE TRIGGER \"Trigger 3\" ON %s USING '" + TestTrigger.class.getName() + "'");
assertTriggerExists("Trigger 3", TestTrigger.class);
}
@Test
public void testCreateTriggerIfNotExists() throws Throwable
{
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))");
execute("CREATE TRIGGER IF NOT EXISTS trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'");
assertTriggerExists("trigger_1", TestTrigger.class);
execute("CREATE TRIGGER IF NOT EXISTS trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'");
assertTriggerExists("trigger_1", TestTrigger.class);
}
@Test
public void testDropTrigger() throws Throwable
{
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a))");
execute("CREATE TRIGGER trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'");
assertTriggerExists("trigger_1", TestTrigger.class);
execute("DROP TRIGGER trigger_1 ON %s");
assertTriggerDoesNotExists("trigger_1", TestTrigger.class);
execute("CREATE TRIGGER trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'");
assertTriggerExists("trigger_1", TestTrigger.class);
assertInvalid("DROP TRIGGER trigger_2 ON %s");
execute("CREATE TRIGGER \"Trigger 3\" ON %s USING '" + TestTrigger.class.getName() + "'");
assertTriggerExists("Trigger 3", TestTrigger.class);
execute("DROP TRIGGER \"Trigger 3\" ON %s");
assertTriggerDoesNotExists("Trigger 3", TestTrigger.class);
}
@Test
public void testDropTriggerIfExists() throws Throwable
{
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a))");
execute("DROP TRIGGER IF EXISTS trigger_1 ON %s");
assertTriggerDoesNotExists("trigger_1", TestTrigger.class);
execute("CREATE TRIGGER trigger_1 ON %s USING '" + TestTrigger.class.getName() + "'");
assertTriggerExists("trigger_1", TestTrigger.class);
execute("DROP TRIGGER IF EXISTS trigger_1 ON %s");
assertTriggerDoesNotExists("trigger_1", TestTrigger.class);
}
@Test
// tests CASSANDRA-9565
public void testDoubleWith() throws Throwable
{
String[] stmts = new String[] { "CREATE KEYSPACE WITH WITH DURABLE_WRITES = true",
"CREATE KEYSPACE ks WITH WITH DURABLE_WRITES = true" };
for (String stmt : stmts) {
assertInvalidSyntaxMessage("no viable alternative at input 'WITH'", stmt);
}
}
private void assertTriggerExists(String name, Class<?> clazz)
{
CFMetaData cfm = Schema.instance.getCFMetaData(keyspace(), currentTable()).copy();
assertTrue("the trigger does not exist", cfm.containsTriggerDefinition(TriggerDefinition.create(name,
clazz.getName())));
}
private void assertTriggerDoesNotExists(String name, Class<?> clazz)
{
CFMetaData cfm = Schema.instance.getCFMetaData(keyspace(), currentTable()).copy();
Assert.assertFalse("the trigger exists", cfm.containsTriggerDefinition(TriggerDefinition.create(name,
clazz.getName())));
}
public static class TestTrigger implements ITrigger
{
public TestTrigger() { }
public Collection<Mutation> augment(ByteBuffer key, ColumnFamily update)
{
return Collections.emptyList();
}
}
}

View File

@ -0,0 +1,329 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3.validation.operations;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import org.apache.cassandra.cql3.CQLTester;
import static org.junit.Assert.assertEquals;
public class DeleteTest extends CQLTester
{
/** Test for cassandra 8558 */
@Test
public void testRangeDeletion() throws Throwable
{
createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c))");
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 1, 1, 1, 1);
flush();
execute("DELETE FROM %s WHERE a=? AND b=?", 1, 1);
flush();
assertEmpty(execute("SELECT * FROM %s WHERE a=? AND b=? AND c=?", 1, 1, 1));
}
/**
* Test simple deletion and in particular check for #4193 bug
* migrated from cql_tests.py:TestCQL.deletion_test()
*/
@Test
public void testDeletion() throws Throwable
{
createTable("CREATE TABLE %s (username varchar, id int, name varchar, stuff varchar, PRIMARY KEY(username, id))");
execute("INSERT INTO %s (username, id, name, stuff) VALUES (?, ?, ?, ?)", "abc", 2, "rst", "some value");
execute("INSERT INTO %s (username, id, name, stuff) VALUES (?, ?, ?, ?)", "abc", 4, "xyz", "some other value");
assertRows(execute("SELECT * FROM %s"),
row("abc", 2, "rst", "some value"),
row("abc", 4, "xyz", "some other value"));
execute("DELETE FROM %s WHERE username='abc' AND id=2");
assertRows(execute("SELECT * FROM %s"),
row("abc", 4, "xyz", "some other value"));
createTable("CREATE TABLE %s (username varchar, id int, name varchar, stuff varchar, PRIMARY KEY(username, id, name)) WITH COMPACT STORAGE");
execute("INSERT INTO %s (username, id, name, stuff) VALUES (?, ?, ?, ?)", "abc", 2, "rst", "some value");
execute("INSERT INTO %s (username, id, name, stuff) VALUES (?, ?, ?, ?)", "abc", 4, "xyz", "some other value");
assertRows(execute("SELECT * FROM %s"),
row("abc", 2, "rst", "some value"),
row("abc", 4, "xyz", "some other value"));
execute("DELETE FROM %s WHERE username='abc' AND id=2");
assertRows(execute("SELECT * FROM %s"),
row("abc", 4, "xyz", "some other value"));
}
/**
* Test deletion by 'composite prefix' (range tombstones)
* migrated from cql_tests.py:TestCQL.range_tombstones_test()
*/
@Test
public void testDeleteByCompositePrefix() throws Throwable
{ // This test used 3 nodes just to make sure RowMutation are correctly serialized
createTable("CREATE TABLE %s ( k int, c1 int, c2 int, v1 int, v2 int, PRIMARY KEY (k, c1, c2))");
int numRows = 5;
int col1 = 2;
int col2 = 2;
int cpr = col1 * col2;
for (int i = 0; i < numRows; i++)
for (int j = 0; j < col1; j++)
for (int k = 0; k < col2; k++)
{
int n = (i * cpr) + (j * col2) + k;
execute("INSERT INTO %s (k, c1, c2, v1, v2) VALUES (?, ?, ?, ?, ?)", i, j, k, n, n);
}
for (int i = 0; i < numRows; i++)
{
Object[][] rows = getRows(execute("SELECT v1, v2 FROM %s where k = ?", i));
for (int x = i * cpr; x < (i + 1) * cpr; x++)
{
assertEquals(x, rows[x - i * cpr][0]);
assertEquals(x, rows[x - i * cpr][1]);
}
}
for (int i = 0; i < numRows; i++)
execute("DELETE FROM %s WHERE k = ? AND c1 = 0", i);
for (int i = 0; i < numRows; i++)
{
Object[][] rows = getRows(execute("SELECT v1, v2 FROM %s WHERE k = ?", i));
for (int x = i * cpr + col1; x < (i + 1) * cpr; x++)
{
assertEquals(x, rows[x - i * cpr - col1][0]);
assertEquals(x, rows[x - i * cpr - col1][1]);
}
}
for (int i = 0; i < numRows; i++)
{
Object[][] rows = getRows(execute("SELECT v1, v2 FROM %s WHERE k = ?", i));
for (int x = i * cpr + col1; x < (i + 1) * cpr; x++)
{
assertEquals(x, rows[x - i * cpr - col1][0]);
assertEquals(x, rows[x - i * cpr - col1][1]);
}
}
}
/**
* Test deletion by 'composite prefix' (range tombstones) with compaction
* migrated from cql_tests.py:TestCQL.range_tombstones_compaction_test()
*/
@Test
public void testDeleteByCompositePrefixWithCompaction() throws Throwable
{
createTable("CREATE TABLE %s (k int, c1 int, c2 int, v1 text, PRIMARY KEY (k, c1, c2))");
for (int c1 = 0; c1 < 4; c1++)
for (int c2 = 0; c2 < 2; c2++)
execute("INSERT INTO %s (k, c1, c2, v1) VALUES (0, ?, ?, ?)", c1, c2, String.format("%d%d", c1, c2));
flush();
execute("DELETE FROM %s WHERE k = 0 AND c1 = 1");
flush();
compact();
Object[][] rows = getRows(execute("SELECT v1 FROM %s WHERE k = 0"));
int idx = 0;
for (int c1 = 0; c1 < 4; c1++)
for (int c2 = 0; c2 < 2; c2++)
if (c1 != 1)
assertEquals(String.format("%d%d", c1, c2), rows[idx++][0]);
}
/**
* Test deletion of rows
* migrated from cql_tests.py:TestCQL.delete_row_test()
*/
@Test
public void testRowDeletion() throws Throwable
{
createTable("CREATE TABLE %s (k int, c1 int, c2 int, v1 int, v2 int, PRIMARY KEY (k, c1, c2))");
execute("INSERT INTO %s (k, c1, c2, v1, v2) VALUES (?, ?, ?, ?, ?)", 0, 0, 0, 0, 0);
execute("INSERT INTO %s (k, c1, c2, v1, v2) VALUES (?, ?, ?, ?, ?)", 0, 0, 1, 1, 1);
execute("INSERT INTO %s (k, c1, c2, v1, v2) VALUES (?, ?, ?, ?, ?)", 0, 0, 2, 2, 2);
execute("INSERT INTO %s (k, c1, c2, v1, v2) VALUES (?, ?, ?, ?, ?)", 0, 1, 0, 3, 3);
execute("DELETE FROM %s WHERE k = 0 AND c1 = 0 AND c2 = 0");
assertRowCount(execute("SELECT * FROM %s"), 3);
}
/**
* Check the semantic of CQL row existence (part of #4361),
* migrated from cql_tests.py:TestCQL.row_existence_test()
*/
@Test
public void testRowExistence() throws Throwable
{
createTable("CREATE TABLE %s (k int, c int, v1 int, v2 int, PRIMARY KEY (k, c))");
execute("INSERT INTO %s (k, c, v1, v2) VALUES (1, 1, 1, 1)");
assertRows(execute("SELECT * FROM %s"),
row(1, 1, 1, 1));
assertInvalid("DELETE c FROM %s WHERE k = 1 AND c = 1");
execute("DELETE v2 FROM %s WHERE k = 1 AND c = 1");
assertRows(execute("SELECT * FROM %s"),
row(1, 1, 1, null));
execute("DELETE v1 FROM %s WHERE k = 1 AND c = 1");
assertRows(execute("SELECT * FROM %s"),
row(1, 1, null, null));
execute("DELETE FROM %s WHERE k = 1 AND c = 1");
assertEmpty(execute("SELECT * FROM %s"));
execute("INSERT INTO %s (k, c) VALUES (2, 2)");
assertRows(execute("SELECT * FROM %s"),
row(2, 2, null, null));
}
/**
* Migrated from cql_tests.py:TestCQL.remove_range_slice_test()
*/
@Test
public void testRemoveRangeSlice() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, v int)");
for (int i = 0; i < 3; i++)
execute("INSERT INTO %s (k, v) VALUES (?, ?)", i, i);
execute("DELETE FROM %s WHERE k = 1");
assertRows(execute("SELECT * FROM %s"),
row(0, 0),
row(2, 2));
}
/**
* Test deletions
* migrated from cql_tests.py:TestCQL.no_range_ghost_test()
*/
@Test
public void testNoRangeGhost() throws Throwable
{
createTable("CREATE TABLE %s ( k int PRIMARY KEY, v int ) ");
for (int k = 0; k < 5; k++)
execute("INSERT INTO %s (k, v) VALUES (?, 0)", k);
Object[][] rows = getRows(execute("SELECT k FROM %s"));
int[] ordered = sortIntRows(rows);
for (int k = 0; k < 5; k++)
assertEquals(k, ordered[k]);
execute("DELETE FROM %s WHERE k=2");
rows = getRows(execute("SELECT k FROM %s"));
ordered = sortIntRows(rows);
int idx = 0;
for (int k = 0; k < 5; k++)
if (k != 2)
assertEquals(k, ordered[idx++]);
// Example from #3505
createTable("CREATE TABLE %s ( KEY varchar PRIMARY KEY, password varchar, gender varchar, birth_year bigint)");
execute("INSERT INTO %s (KEY, password) VALUES ('user1', 'ch@ngem3a')");
execute("UPDATE %s SET gender = 'm', birth_year = 1980 WHERE KEY = 'user1'");
assertRows(execute("SELECT * FROM %s WHERE KEY='user1'"),
row("user1", 1980L, "m", "ch@ngem3a"));
execute("TRUNCATE %s");
assertEmpty(execute("SELECT * FROM %s"));
assertEmpty(execute("SELECT * FROM %s WHERE KEY='user1'"));
}
private int[] sortIntRows(Object[][] rows)
{
int[] ret = new int[rows.length];
for (int i = 0; i < ret.length; i++)
ret[i] = rows[i][0] == null ? Integer.MIN_VALUE : (Integer) rows[i][0];
Arrays.sort(ret);
return ret;
}
/**
* Migrated from cql_tests.py:TestCQL.range_with_deletes_test()
*/
@Test
public void testRandomDeletions() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, v int,)");
int nb_keys = 30;
int nb_deletes = 5;
List<Integer> deletions = new ArrayList<>(nb_keys);
for (int i = 0; i < nb_keys; i++)
{
execute("INSERT INTO %s (k, v) VALUES (?, ?)", i, i);
deletions.add(i);
}
Collections.shuffle(deletions);
for (int i = 0; i < nb_deletes; i++)
execute("DELETE FROM %s WHERE k = ?", deletions.get(i));
assertRowCount(execute("SELECT * FROM %s LIMIT ?", (nb_keys / 2)), nb_keys / 2);
}
/**
* Test for CASSANDRA-8558, deleted row still can be selected out
* migrated from cql_tests.py:TestCQL.bug_8558_test()
*/
@Test
public void testDeletedRowCannotBeSelected() throws Throwable
{
createTable("CREATE TABLE %s (a int, b int, c text,primary key(a,b))");
execute("INSERT INTO %s (a,b,c) VALUES(1,1,'1')");
flush();
execute("DELETE FROM %s where a=1 and b=1");
flush();
assertEmpty(execute("select * from %s where a=1 and b=1"));
}
}

View File

@ -0,0 +1,59 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3.validation.operations;
import org.junit.Test;
import org.apache.cassandra.cql3.CQLTester;
public class InsertTest extends CQLTester
{
@Test
public void testInsertWithUnset() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, s text, i int)");
// insert using nulls
execute("INSERT INTO %s (k, s, i) VALUES (10, ?, ?)", "text", 10);
execute("INSERT INTO %s (k, s, i) VALUES (10, ?, ?)", null, null);
assertRows(execute("SELECT s, i FROM %s WHERE k = 10"),
row(null, null) // sending null deletes the data
);
// insert using UNSET
execute("INSERT INTO %s (k, s, i) VALUES (11, ?, ?)", "text", 10);
execute("INSERT INTO %s (k, s, i) VALUES (11, ?, ?)", unset(), unset());
assertRows(execute("SELECT s, i FROM %s WHERE k=11"),
row("text", 10) // unset columns does not delete the existing data
);
assertInvalidMessage("Invalid unset value for column k", "UPDATE %s SET i = 0 WHERE k = ?", unset());
assertInvalidMessage("Invalid unset value for column k", "DELETE FROM %s WHERE k = ?", unset());
assertInvalidMessage("Invalid unset value for argument in call to function blobasint", "SELECT * FROM %s WHERE k = blobAsInt(?)", unset());
}
@Test
public void testInsertTtlWithUnset() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, i int)");
execute("INSERT INTO %s (k, i) VALUES (1, 1) USING TTL ?", unset()); // treat as 'unlimited'
assertRows(execute("SELECT ttl(i) FROM %s"),
row(new Object[]{ null })
);
}
}

View File

@ -0,0 +1,861 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3.validation.operations;
import org.junit.Test;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.exceptions.InvalidRequestException;
import org.apache.cassandra.exceptions.SyntaxException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class InsertUpdateIfCondition extends CQLTester
{
/**
* Migrated from cql_tests.py:TestCQL.cas_simple_test()
*/
@Test
public void testSimpleCas() throws Throwable
{
createTable("CREATE TABLE %s (tkn int, consumed boolean, PRIMARY KEY (tkn))");
for (int i = 0; i < 10; i++)
{
execute("INSERT INTO %s (tkn, consumed) VALUES (?, FALSE)", i);
assertRows(execute("UPDATE %s SET consumed = TRUE WHERE tkn = ? IF consumed = FALSE", i), row(true));
assertRows(execute("UPDATE %s SET consumed = TRUE WHERE tkn = ? IF consumed = FALSE", i), row(false, true));
}
}
/**
* Migrated from cql_tests.py:TestCQL.conditional_update_test()
*/
@Test
public void testConditionalUpdate() throws Throwable
{
createTable(" CREATE TABLE %s (k int PRIMARY KEY, v1 int, v2 text, v3 int)");
// Shouldn't apply
assertRows(execute("UPDATE %s SET v1 = 3, v2 = 'bar' WHERE k = 0 IF v1 = 4"), row(false));
assertRows(execute("UPDATE %s SET v1 = 3, v2 = 'bar' WHERE k = 0 IF EXISTS"), row(false));
// Should apply
assertRows(execute("INSERT INTO %s (k, v1, v2) VALUES (0, 2, 'foo') IF NOT EXISTS"), row(true));
// Shouldn't apply
assertRows(execute("INSERT INTO %s (k, v1, v2) VALUES (0, 5, 'bar') IF NOT EXISTS"), row(false, 0, 2, "foo", null));
assertRows(execute("SELECT * FROM %s"), row(0, 2, "foo", null));
// Shouldn't apply
assertRows(execute("UPDATE %s SET v1 = 3, v2 = 'bar' WHERE k = 0 IF v1 = 4"), row(false, 2));
assertRows(execute("SELECT * FROM %s"), row(0, 2, "foo", null));
// Should apply (note: we want v2 before v1 in the statement order to exercise #5786)
assertRows(execute("UPDATE %s SET v2 = 'bar', v1 = 3 WHERE k = 0 IF v1 = 2"), row(true));
assertRows(execute("UPDATE %s SET v2 = 'bar', v1 = 3 WHERE k = 0 IF EXISTS"), row(true));
assertRows(execute("SELECT * FROM %s"), row(0, 3, "bar", null));
// Shouldn't apply, only one condition is ok
assertRows(execute("UPDATE %s SET v1 = 5, v2 = 'foobar' WHERE k = 0 IF v1 = 3 AND v2 = 'foo'"), row(false, 3, "bar"));
assertRows(execute("SELECT * FROM %s"), row(0, 3, "bar", null));
// Should apply
assertRows(execute("UPDATE %s SET v1 = 5, v2 = 'foobar' WHERE k = 0 IF v1 = 3 AND v2 = 'bar'"), row(true));
assertRows(execute("SELECT * FROM %s"), row(0, 5, "foobar", null));
// Shouldn't apply
assertRows(execute("DELETE v2 FROM %s WHERE k = 0 IF v1 = 3"), row(false, 5));
assertRows(execute("SELECT * FROM %s"), row(0, 5, "foobar", null));
// Shouldn't apply
assertRows(execute("DELETE v2 FROM %s WHERE k = 0 IF v1 = null"), row(false, 5));
assertRows(execute("SELECT * FROM %s"), row(0, 5, "foobar", null));
// Should apply
assertRows(execute("DELETE v2 FROM %s WHERE k = 0 IF v1 = 5"), row(true));
assertRows(execute("SELECT * FROM %s"), row(0, 5, null, null));
// Shouln't apply
assertRows(execute("DELETE v1 FROM %s WHERE k = 0 IF v3 = 4"), row(false, null));
// Should apply
assertRows(execute("DELETE v1 FROM %s WHERE k = 0 IF v3 = null"), row(true));
assertRows(execute("SELECT * FROM %s"), row(0, null, null, null));
// Should apply
assertRows(execute("DELETE FROM %s WHERE k = 0 IF v1 = null"), row(true));
assertEmpty(execute("SELECT * FROM %s"));
// Shouldn't apply
assertRows(execute("UPDATE %s SET v1 = 3, v2 = 'bar' WHERE k = 0 IF EXISTS"), row(false));
// Should apply
assertRows(execute("DELETE FROM %s WHERE k = 0 IF v1 IN (null)"), row(true));
}
/**
* Migrated from cql_tests.py:TestCQL.non_eq_conditional_update_test()
*/
@Test
public void testNonEqConditionalUpdate() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, v1 int, v2 text, v3 int)");
// non-EQ conditions
execute("INSERT INTO %s (k, v1, v2) VALUES (0, 2, 'foo')");
assertRows(execute("UPDATE %s SET v2 = 'bar' WHERE k = 0 IF v1 < 3"), row(true));
assertRows(execute("UPDATE %s SET v2 = 'bar' WHERE k = 0 IF v1 <= 3"), row(true));
assertRows(execute("UPDATE %s SET v2 = 'bar' WHERE k = 0 IF v1 > 1"), row(true));
assertRows(execute("UPDATE %s SET v2 = 'bar' WHERE k = 0 IF v1 >= 1"), row(true));
assertRows(execute("UPDATE %s SET v2 = 'bar' WHERE k = 0 IF v1 != 1"), row(true));
assertRows(execute("UPDATE %s SET v2 = 'bar' WHERE k = 0 IF v1 != 2"), row(false, 2));
assertRows(execute("UPDATE %s SET v2 = 'bar' WHERE k = 0 IF v1 IN (0, 1, 2)"), row(true));
assertRows(execute("UPDATE %s SET v2 = 'bar' WHERE k = 0 IF v1 IN (142, 276)"), row(false, 2));
assertRows(execute("UPDATE %s SET v2 = 'bar' WHERE k = 0 IF v1 IN ()"), row(false, 2));
}
/**
* Migrated from cql_tests.py:TestCQL.conditional_delete_test()
*/
@Test
public void testConditionalDelete() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, v1 int,)");
assertRows(execute("DELETE FROM %s WHERE k=1 IF EXISTS"), row(false));
execute("INSERT INTO %s (k, v1) VALUES (1, 2)");
assertRows(execute("DELETE FROM %s WHERE k=1 IF EXISTS"), row(true));
assertEmpty(execute("SELECT * FROM %s WHERE k=1"));
assertRows(execute("DELETE FROM %s WHERE k=1 IF EXISTS"), row(false));
execute("UPDATE %s USING TTL 1 SET v1=2 WHERE k=1");
Thread.sleep(1001);
assertRows(execute("DELETE FROM %s WHERE k=1 IF EXISTS"), row(false));
assertEmpty(execute("SELECT * FROM %s WHERE k=1"));
execute("INSERT INTO %s (k, v1) VALUES (2, 2) USING TTL 1");
Thread.sleep(1001);
assertRows(execute("DELETE FROM %s WHERE k=2 IF EXISTS"), row(false));
assertEmpty(execute("SELECT * FROM %s WHERE k=2"));
execute("INSERT INTO %s (k, v1) VALUES (3, 2)");
assertRows(execute("DELETE v1 FROM %s WHERE k=3 IF EXISTS"), row(true));
assertRows(execute("SELECT * FROM %s WHERE k=3"), row(3, null));
assertRows(execute("DELETE v1 FROM %s WHERE k=3 IF EXISTS"), row(true));
assertRows(execute("DELETE FROM %s WHERE k=3 IF EXISTS"), row(true));
// static columns
createTable("CREATE TABLE %s (k text, s text static, i int, v text, PRIMARY KEY (k, i) )");
execute("INSERT INTO %s (k, s, i, v) VALUES ('k', 's', 0, 'v')");
assertRows(execute("DELETE v FROM %s WHERE k='k' AND i=0 IF EXISTS"), row(true));
assertRows(execute("DELETE FROM %s WHERE k='k' AND i=0 IF EXISTS"), row(true));
assertRows(execute("DELETE v FROM %s WHERE k='k' AND i=0 IF EXISTS"), row(false));
assertRows(execute("DELETE FROM %s WHERE k='k' AND i=0 IF EXISTS"), row(false));
// CASSANDRA-6430
assertInvalid("DELETE FROM %s WHERE k = 'k' IF EXISTS");
assertInvalid("DELETE FROM %s WHERE k = 'k' IF v = 'foo'");
assertInvalid("DELETE FROM %s WHERE i = 0 IF EXISTS");
assertInvalid("DELETE FROM %s WHERE k = 0 AND i > 0 IF EXISTS");
assertInvalid("DELETE FROM %s WHERE k = 0 AND i > 0 IF v = 'foo'");
}
/**
* Migrated from cql_tests.py:TestCQL.static_columns_cas_test()
*/
@Test
public void testStaticColumnsCas() throws Throwable
{
createTable("CREATE TABLE %s (id int, k text, version int static, v text, PRIMARY KEY (id, k))");
// Test that INSERT IF NOT EXISTS concerns only the static column if no clustering nor regular columns
// is provided, but concerns the CQL3 row targetted by the clustering columns otherwise
execute("INSERT INTO %s (id, k, v) VALUES (1, 'foo', 'foo')");
assertRows(execute("INSERT INTO %s (id, k, version) VALUES (1, 'foo', 1) IF NOT EXISTS"), row(false, 1, "foo", null, "foo"));
assertRows(execute("INSERT INTO %s (id, version) VALUES (1, 1) IF NOT EXISTS"), row(true));
assertRows(execute("SELECT * FROM %s"), row(1, "foo", 1, "foo"));
execute("DELETE FROM %s WHERE id = 1");
execute("INSERT INTO %s(id, version) VALUES (0, 0)");
assertRows(execute("UPDATE %s SET v='foo', version=1 WHERE id=0 AND k='k1' IF version = 0"), row(true));
assertRows(execute("SELECT * FROM %s"), row(0, "k1", 1, "foo"));
assertRows(execute("UPDATE %s SET v='bar', version=1 WHERE id=0 AND k='k2' IF version = 0"), row(false, 1));
assertRows(execute("SELECT * FROM %s"), row(0, "k1", 1, "foo"));
assertRows(execute("UPDATE %s SET v='bar', version=2 WHERE id=0 AND k='k2' IF version = 1"), row(true));
assertRows(execute("SELECT * FROM %s"), row(0, "k1", 2, "foo"), row(0, "k2", 2, "bar"));
// Testing batches
assertRows(execute("BEGIN BATCH " +
"UPDATE %1$s SET v='foobar' WHERE id=0 AND k='k1'; " +
"UPDATE %1$s SET v='barfoo' WHERE id=0 AND k='k2'; " +
"UPDATE %1$s SET version=3 WHERE id=0 IF version=1; " +
"APPLY BATCH "),
row(false, 0, null, 2));
assertRows(execute("BEGIN BATCH " +
"UPDATE %1$s SET v = 'foobar' WHERE id = 0 AND k = 'k1'; " +
"UPDATE %1$s SET v = 'barfoo' WHERE id = 0 AND k = 'k2'; " +
"UPDATE %1$s SET version = 3 WHERE id = 0 IF version = 2; " +
"APPLY BATCH "),
row(true));
assertRows(execute("SELECT * FROM %s"),
row(0, "k1", 3, "foobar"),
row(0, "k2", 3, "barfoo"));
assertRows(execute("BEGIN BATCH " +
"UPDATE %1$s SET version = 4 WHERE id = 0 IF version = 3; " +
"UPDATE %1$s SET v='row1' WHERE id=0 AND k='k1' IF v='foo'; " +
"UPDATE %1$s SET v='row2' WHERE id=0 AND k='k2' IF v='bar'; " +
"APPLY BATCH "),
row(false, 0, "k1", 3, "foobar"),
row(false, 0, "k2", 3, "barfoo"));
assertRows(execute("BEGIN BATCH " +
"UPDATE %1$s SET version = 4 WHERE id = 0 IF version = 3; " +
"UPDATE %1$s SET v='row1' WHERE id = 0 AND k='k1' IF v='foobar'; " +
"UPDATE %1$s SET v='row2' WHERE id = 0 AND k='k2' IF v='barfoo'; " +
"APPLY BATCH "),
row(true));
assertRows(execute("SELECT * FROM %s"),
row(0, "k1", 4, "row1"),
row(0, "k2", 4, "row2"));
assertInvalid("BEGIN BATCH " +
"UPDATE %1$s SET version=5 WHERE id=0 IF version=4; " +
"UPDATE %1$s SET v='row1' WHERE id=0 AND k='k1'; " +
"UPDATE %1$s SET v='row2' WHERE id=1 AND k='k2'; " +
"APPLY BATCH ");
assertRows(execute("BEGIN BATCH " +
"INSERT INTO %1$s (id, k, v) VALUES (1, 'k1', 'val1') IF NOT EXISTS; " +
"INSERT INTO %1$s (id, k, v) VALUES (1, 'k2', 'val2') IF NOT EXISTS; " +
"APPLY BATCH "),
row(true));
assertRows(execute("SELECT * FROM %s WHERE id=1"),
row(1, "k1", null, "val1"),
row(1, "k2", null, "val2"));
assertRows(execute("INSERT INTO %s (id, k, v) VALUES (1, 'k2', 'val2') IF NOT EXISTS"), row(false, 1, "k2", null, "val2"));
assertRows(execute("BEGIN BATCH " +
"INSERT INTO %1$s (id, k, v) VALUES (1, 'k2', 'val2') IF NOT EXISTS; " +
"INSERT INTO %1$s (id, k, v) VALUES (1, 'k3', 'val3') IF NOT EXISTS; " +
"APPLY BATCH"),
row(false, 1, "k2", null, "val2"));
assertRows(execute("BEGIN BATCH " +
"UPDATE %1$s SET v = 'newVal' WHERE id = 1 AND k = 'k2' IF v = 'val0'; " +
"INSERT INTO %1$s (id, k, v) VALUES (1, 'k3', 'val3') IF NOT EXISTS; " +
"APPLY BATCH"),
row(false, 1, "k2", null, "val2"));
assertRows(execute("SELECT * FROM %s WHERE id=1"),
row(1, "k1", null, "val1"),
row(1, "k2", null, "val2"));
assertRows(execute("BEGIN BATCH " +
"UPDATE %1$s SET v = 'newVal' WHERE id = 1 AND k = 'k2' IF v = 'val2'; " +
"INSERT INTO %1$s (id, k, v, version) VALUES(1, 'k3', 'val3', 1) IF NOT EXISTS; " +
"APPLY BATCH"),
row(true));
assertRows(execute("SELECT * FROM %s WHERE id=1"),
row(1, "k1", 1, "val1"),
row(1, "k2", 1, "newVal"),
row(1, "k3", 1, "val3"));
assertRows(execute("BEGIN BATCH " +
"UPDATE %1$s SET v = 'newVal1' WHERE id = 1 AND k = 'k2' IF v = 'val2'; " +
"UPDATE %1$s SET v = 'newVal2' WHERE id = 1 AND k = 'k2' IF v = 'val3'; " +
"APPLY BATCH"),
row(false, 1, "k2", "newVal"));
}
/**
* Migrated from cql_tests.py:TestCQL.bug_6069_test()
*/
@Test
public void testInsertSetIfNotExists() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, s set<int>)");
assertRows(execute("INSERT INTO %s (k, s) VALUES (0, {1, 2, 3}) IF NOT EXISTS"),
row(true));
assertRows(execute("SELECT * FROM %s "), row(0, set(1, 2, 3)));
}
/**
* Migrated from cql_tests.py:TestCQL.cas_and_ttl_test()
*/
@Test
public void testCasAndTTL() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, v int, lock boolean)");
execute("INSERT INTO %s (k, v, lock) VALUES (0, 0, false)");
execute("UPDATE %s USING TTL 1 SET lock=true WHERE k=0");
Thread.sleep(1001);
assertRows(execute("UPDATE %s SET v = 1 WHERE k = 0 IF lock = null"),
row(true));
}
/**
* Test for CAS with compact storage table, and #6813 in particular,
* migrated from cql_tests.py:TestCQL.cas_and_compact_test()
*/
@Test
public void testCompactStorage() throws Throwable
{
createTable("CREATE TABLE %s (partition text, key text, owner text, PRIMARY KEY (partition, key) ) WITH COMPACT STORAGE");
execute("INSERT INTO %s (partition, key, owner) VALUES ('a', 'b', null)");
assertRows(execute("UPDATE %s SET owner='z' WHERE partition='a' AND key='b' IF owner=null"), row(true));
assertRows(execute("UPDATE %s SET owner='b' WHERE partition='a' AND key='b' IF owner='a'"), row(false, "z"));
assertRows(execute("UPDATE %s SET owner='b' WHERE partition='a' AND key='b' IF owner='z'"), row(true));
assertRows(execute("INSERT INTO %s (partition, key, owner) VALUES ('a', 'c', 'x') IF NOT EXISTS"), row(true));
}
/**
* Migrated from cql_tests.py:TestCQL.whole_list_conditional_test()
*/
@Test
public void testWholeList() throws Throwable
{
for (boolean frozen : new boolean[] {false, true})
{
createTable(String.format("CREATE TABLE %%s (k int PRIMARY KEY, l %s)",
frozen
? "frozen<list<text>>"
: "list<text>"));
execute("INSERT INTO %s(k, l) VALUES (0, ['foo', 'bar', 'foobar'])");
check_applies_list("l = ['foo', 'bar', 'foobar']");
check_applies_list("l != ['baz']");
check_applies_list("l > ['a']");
check_applies_list("l >= ['a']");
check_applies_list("l < ['z']");
check_applies_list("l <= ['z']");
check_applies_list("l IN (null, ['foo', 'bar', 'foobar'], ['a'])");
// multiple conditions
check_applies_list("l > ['aaa', 'bbb'] AND l > ['aaa']");
check_applies_list("l != null AND l IN (['foo', 'bar', 'foobar'])");
// should not apply
check_does_not_apply_list("l = ['baz']");
check_does_not_apply_list("l != ['foo', 'bar', 'foobar']");
check_does_not_apply_list("l > ['z']");
check_does_not_apply_list("l >= ['z']");
check_does_not_apply_list("l < ['a']");
check_does_not_apply_list("l <= ['a']");
check_does_not_apply_list("l IN (['a'], null)");
check_does_not_apply_list("l IN ()");
// multiple conditions
check_does_not_apply_list("l IN () AND l IN (['foo', 'bar', 'foobar'])");
check_does_not_apply_list("l > ['zzz'] AND l < ['zzz']");
check_invalid_list("l = [null]", InvalidRequestException.class);
check_invalid_list("l < null", InvalidRequestException.class);
check_invalid_list("l <= null", InvalidRequestException.class);
check_invalid_list("l > null", InvalidRequestException.class);
check_invalid_list("l >= null", InvalidRequestException.class);
check_invalid_list("l IN null", SyntaxException.class);
check_invalid_list("l IN 367", SyntaxException.class);
check_invalid_list("l CONTAINS KEY 123", SyntaxException.class);
// not supported yet
check_invalid_list("m CONTAINS 'bar'", SyntaxException.class);
}
}
void check_applies_list(String condition) throws Throwable
{
assertRows(execute("UPDATE %s SET l = ['foo', 'bar', 'foobar'] WHERE k=0 IF " + condition), row(true));
assertRows(execute("SELECT * FROM %s"), row(0, list("foo", "bar", "foobar")));
}
void check_does_not_apply_list(String condition) throws Throwable
{
assertRows(execute("UPDATE %s SET l = ['foo', 'bar', 'foobar'] WHERE k=0 IF " + condition),
row(false, list("foo", "bar", "foobar")));
assertRows(execute("SELECT * FROM %s"), row(0, list("foo", "bar", "foobar")));
}
void check_invalid_list(String condition, Class<? extends Throwable> expected) throws Throwable
{
assertInvalidThrow(expected, "UPDATE %s SET l = ['foo', 'bar', 'foobar'] WHERE k=0 IF " + condition);
assertRows(execute("SELECT * FROM %s"), row(0, list("foo", "bar", "foobar")));
}
/**
* Migrated from cql_tests.py:TestCQL.list_item_conditional_test()
*/
@Test
public void testListItem() throws Throwable
{
for (boolean frozen : new boolean[]{ false, true })
{
createTable(String.format("CREATE TABLE %%s (k int PRIMARY KEY, l %s)",
frozen
? "frozen<list<text>>"
: "list<text>"));
execute("INSERT INTO %s(k, l) VALUES (0, ['foo', 'bar', 'foobar'])");
assertInvalid("DELETE FROM %s WHERE k=0 IF l[null] = 'foobar'");
assertInvalid("DELETE FROM %s WHERE k=0 IF l[-2] = 'foobar'");
assertRows(execute("DELETE FROM %s WHERE k=0 IF l[1] = null"), row(false, list("foo", "bar", "foobar")));
assertRows(execute("DELETE FROM %s WHERE k=0 IF l[1] = 'foobar'"), row(false, list("foo", "bar", "foobar")));
assertRows(execute("SELECT * FROM %s"), row(0, list("foo", "bar", "foobar")));
assertRows(execute("DELETE FROM %s WHERE k=0 IF l[1] = 'bar'"), row(true));
assertEmpty(execute("SELECT * FROM %s"));
}
}
/**
* Test expanded functionality from CASSANDRA-6839,
* migrated from cql_tests.py:TestCQL.expanded_list_item_conditional_test()
*/
@Test
public void testExpandedListItem() throws Throwable
{
for (boolean frozen : new boolean[] {false, true})
{
createTable(String.format("CREATE TABLE %%s (k int PRIMARY KEY, l %s)",
frozen
? "frozen<list<text>>"
: "list<text>"));
execute("INSERT INTO %s (k, l) VALUES (0, ['foo', 'bar', 'foobar'])");
check_applies_list("l[1] < 'zzz'");
check_applies_list("l[1] <= 'bar'");
check_applies_list("l[1] > 'aaa'");
check_applies_list("l[1] >= 'bar'");
check_applies_list("l[1] != 'xxx'");
check_applies_list("l[1] != null");
check_applies_list("l[1] IN (null, 'xxx', 'bar')");
check_applies_list("l[1] > 'aaa' AND l[1] < 'zzz'");
// check beyond end of list
check_applies_list("l[3] = null");
check_applies_list("l[3] IN (null, 'xxx', 'bar')");
check_does_not_apply_list("l[1] < 'aaa'");
check_does_not_apply_list("l[1] <= 'aaa'");
check_does_not_apply_list("l[1] > 'zzz'");
check_does_not_apply_list("l[1] >= 'zzz'");
check_does_not_apply_list("l[1] != 'bar'");
check_does_not_apply_list("l[1] IN (null, 'xxx')");
check_does_not_apply_list("l[1] IN ()");
check_does_not_apply_list("l[1] != null AND l[1] IN ()");
// check beyond end of list
check_does_not_apply_list("l[3] != null");
check_does_not_apply_list("l[3] = 'xxx'");
check_invalid_list("l[1] < null", InvalidRequestException.class);
check_invalid_list("l[1] <= null", InvalidRequestException.class);
check_invalid_list("l[1] > null", InvalidRequestException.class);
check_invalid_list("l[1] >= null", InvalidRequestException.class);
check_invalid_list("l[1] IN null", SyntaxException.class);
check_invalid_list("l[1] IN 367", SyntaxException.class);
check_invalid_list("l[1] IN (1, 2, 3)", InvalidRequestException.class);
check_invalid_list("l[1] CONTAINS 367", SyntaxException.class);
check_invalid_list("l[1] CONTAINS KEY 367", SyntaxException.class);
check_invalid_list("l[null] = null", InvalidRequestException.class);
}
}
/**
* Migrated from cql_tests.py:TestCQL.whole_set_conditional_test()
*/
@Test
public void testWholeSet() throws Throwable
{
for (boolean frozen : new boolean[] {false, true})
{
createTable(String.format("CREATE TABLE %%s (k int PRIMARY KEY, s %s)",
frozen
? "frozen<set<text>>"
: "set<text>"));
execute("INSERT INTO %s (k, s) VALUES (0, {'bar', 'foo'})");
check_applies_set("s = {'bar', 'foo'}");
check_applies_set("s = {'foo', 'bar'}");
check_applies_set("s != {'baz'}");
check_applies_set("s > {'a'}");
check_applies_set("s >= {'a'}");
check_applies_set("s < {'z'}");
check_applies_set("s <= {'z'}");
check_applies_set("s IN (null, {'bar', 'foo'}, {'a'})");
// multiple conditions
check_applies_set("s > {'a'} AND s < {'z'}");
check_applies_set("s IN (null, {'bar', 'foo'}, {'a'}) AND s IN ({'a'}, {'bar', 'foo'}, null)");
// should not apply
check_does_not_apply_set("s = {'baz'}");
check_does_not_apply_set("s != {'bar', 'foo'}");
check_does_not_apply_set("s > {'z'}");
check_does_not_apply_set("s >= {'z'}");
check_does_not_apply_set("s < {'a'}");
check_does_not_apply_set("s <= {'a'}");
check_does_not_apply_set("s IN ({'a'}, null)");
check_does_not_apply_set("s IN ()");
check_does_not_apply_set("s != null AND s IN ()");
check_invalid_set("s = {null}", InvalidRequestException.class);
check_invalid_set("s < null", InvalidRequestException.class);
check_invalid_set("s <= null", InvalidRequestException.class);
check_invalid_set("s > null", InvalidRequestException.class);
check_invalid_set("s >= null", InvalidRequestException.class);
check_invalid_set("s IN null", SyntaxException.class);
check_invalid_set("s IN 367", SyntaxException.class);
check_invalid_set("s CONTAINS KEY 123", SyntaxException.class);
// element access is not allow for sets
check_invalid_set("s['foo'] = 'foobar'", InvalidRequestException.class);
// not supported yet
check_invalid_set("m CONTAINS 'bar'", SyntaxException.class);
}
}
void check_applies_set(String condition) throws Throwable
{
assertRows(execute("UPDATE %s SET s = {'bar', 'foo'} WHERE k=0 IF " + condition), row(true));
assertRows(execute("SELECT * FROM %s"), row(0, set("bar", "foo")));
}
void check_does_not_apply_set(String condition) throws Throwable
{
assertRows(execute("UPDATE %s SET s = {'bar', 'foo'} WHERE k=0 IF " + condition), row(false, set("bar", "foo")));
assertRows(execute("SELECT * FROM %s"), row(0, set("bar", "foo")));
}
void check_invalid_set(String condition, Class<? extends Throwable> expected) throws Throwable
{
assertInvalidThrow(expected, "UPDATE %s SET s = {'bar', 'foo'} WHERE k=0 IF " + condition);
assertRows(execute("SELECT * FROM %s"), row(0, set("bar", "foo")));
}
/**
* Migrated from cql_tests.py:TestCQL.whole_map_conditional_test()
*/
@Test
public void testWholeMap() throws Throwable
{
for (boolean frozen : new boolean[] {false, true})
{
createTable(String.format("CREATE TABLE %%s (k int PRIMARY KEY, m %s)",
frozen
? "frozen<map<text, text>>"
: "map<text, text>"));
execute("INSERT INTO %s (k, m) VALUES (0, {'foo' : 'bar'})");
check_applies_map("m = {'foo': 'bar'}");
check_applies_map("m > {'a': 'a'}");
check_applies_map("m >= {'a': 'a'}");
check_applies_map("m < {'z': 'z'}");
check_applies_map("m <= {'z': 'z'}");
check_applies_map("m != {'a': 'a'}");
check_applies_map("m IN (null, {'a': 'a'}, {'foo': 'bar'})");
// multiple conditions
check_applies_map("m > {'a': 'a'} AND m < {'z': 'z'}");
check_applies_map("m != null AND m IN (null, {'a': 'a'}, {'foo': 'bar'})");
// should not apply
check_does_not_apply_map("m = {'a': 'a'}");
check_does_not_apply_map("m > {'z': 'z'}");
check_does_not_apply_map("m >= {'z': 'z'}");
check_does_not_apply_map("m < {'a': 'a'}");
check_does_not_apply_map("m <= {'a': 'a'}");
check_does_not_apply_map("m != {'foo': 'bar'}");
check_does_not_apply_map("m IN ({'a': 'a'}, null)");
check_does_not_apply_map("m IN ()");
check_does_not_apply_map("m = null AND m != null");
check_invalid_map("m = {null: null}", InvalidRequestException.class);
check_invalid_map("m = {'a': null}", InvalidRequestException.class);
check_invalid_map("m = {null: 'a'}", InvalidRequestException.class);
check_invalid_map("m < null", InvalidRequestException.class);
check_invalid_map("m IN null", SyntaxException.class);
// not supported yet
check_invalid_map("m CONTAINS 'bar'", SyntaxException.class);
check_invalid_map("m CONTAINS KEY 'foo'", SyntaxException.class);
check_invalid_map("m CONTAINS null", SyntaxException.class);
check_invalid_map("m CONTAINS KEY null", SyntaxException.class);
}
}
/**
* Migrated from cql_tests.py:TestCQL.map_item_conditional_test()
*/
@Test
public void testMapItem() throws Throwable
{
for (boolean frozen : new boolean[]{ false, true })
{
createTable(String.format("CREATE TABLE %%s (k int PRIMARY KEY, m %s)",
frozen
? "frozen<map<text, text>>"
: "map<text, text>"));
execute("INSERT INTO %s (k, m) VALUES (0, {'foo' : 'bar'})");
assertInvalid("DELETE FROM %s WHERE k=0 IF m[null] = 'foo'");
assertRows(execute("DELETE FROM %s WHERE k=0 IF m['foo'] = 'foo'"), row(false, map("foo", "bar")));
assertRows(execute("DELETE FROM %s WHERE k=0 IF m['foo'] = null"), row(false, map("foo", "bar")));
assertRows(execute("SELECT * FROM %s"), row(0, map("foo", "bar")));
assertRows(execute("DELETE FROM %s WHERE k=0 IF m['foo'] = 'bar'"), row(true));
assertEmpty(execute("SELECT * FROM %s"));
execute("INSERT INTO %s(k, m) VALUES (1, null)");
if (frozen)
assertInvalid("UPDATE %s set m['foo'] = 'bar', m['bar'] = 'foo' WHERE k = 1 IF m['foo'] IN ('blah', null)");
else
assertRows(execute("UPDATE %s set m['foo'] = 'bar', m['bar'] = 'foo' WHERE k = 1 IF m['foo'] IN ('blah', null)"), row(true));
}
}
/**
* Test expanded functionality from CASSANDRA-6839,
* migrated from cql_tests.py:TestCQL.expanded_map_item_conditional_test()
*/
@Test
public void testExpandedMapItem() throws Throwable
{
for (boolean frozen : new boolean[]{ false, true })
{
createTable(String.format("CREATE TABLE %%s (k int PRIMARY KEY, m %s)",
frozen
? "frozen<map<text, text>>"
: "map<text, text>"));
execute("INSERT INTO %s (k, m) VALUES (0, {'foo' : 'bar'})");
check_applies_map("m['xxx'] = null");
check_applies_map("m['foo'] < 'zzz'");
check_applies_map("m['foo'] <= 'bar'");
check_applies_map("m['foo'] > 'aaa'");
check_applies_map("m['foo'] >= 'bar'");
check_applies_map("m['foo'] != 'xxx'");
check_applies_map("m['foo'] != null");
check_applies_map("m['foo'] IN (null, 'xxx', 'bar')");
check_applies_map("m['xxx'] IN (null, 'xxx', 'bar')"); // m['xxx'] is not set
// multiple conditions
check_applies_map("m['foo'] < 'zzz' AND m['foo'] > 'aaa'");
check_does_not_apply_map("m['foo'] < 'aaa'");
check_does_not_apply_map("m['foo'] <= 'aaa'");
check_does_not_apply_map("m['foo'] > 'zzz'");
check_does_not_apply_map("m['foo'] >= 'zzz'");
check_does_not_apply_map("m['foo'] != 'bar'");
check_does_not_apply_map("m['xxx'] != null"); // m['xxx'] is not set
check_does_not_apply_map("m['foo'] IN (null, 'xxx')");
check_does_not_apply_map("m['foo'] IN ()");
check_does_not_apply_map("m['foo'] != null AND m['foo'] = null");
check_invalid_map("m['foo'] < null", InvalidRequestException.class);
check_invalid_map("m['foo'] <= null", InvalidRequestException.class);
check_invalid_map("m['foo'] > null", InvalidRequestException.class);
check_invalid_map("m['foo'] >= null", InvalidRequestException.class);
check_invalid_map("m['foo'] IN null", SyntaxException.class);
check_invalid_map("m['foo'] IN 367", SyntaxException.class);
check_invalid_map("m['foo'] IN (1, 2, 3)", InvalidRequestException.class);
check_invalid_map("m['foo'] CONTAINS 367", SyntaxException.class);
check_invalid_map("m['foo'] CONTAINS KEY 367", SyntaxException.class);
check_invalid_map("m[null] = null", InvalidRequestException.class);
}
}
void check_applies_map(String condition) throws Throwable
{
assertRows(execute("UPDATE %s SET m = {'foo': 'bar'} WHERE k=0 IF " + condition), row(true));
assertRows(execute("SELECT * FROM %s"), row(0, map("foo", "bar")));
}
void check_does_not_apply_map(String condition) throws Throwable
{
assertRows(execute("UPDATE %s SET m = {'foo': 'bar'} WHERE k=0 IF " + condition), row(false, map("foo", "bar")));
assertRows(execute("SELECT * FROM %s"), row(0, map("foo", "bar")));
}
void check_invalid_map(String condition, Class<? extends Throwable> expected) throws Throwable
{
assertInvalidThrow(expected, "UPDATE %s SET m = {'foo': 'bar'} WHERE k=0 IF " + condition);
assertRows(execute("SELECT * FROM %s"), row(0, map("foo", "bar")));
}
/**
* Test for 7499,
* migrated from cql_tests.py:TestCQL.cas_and_list_index_test()
*/
@Test
public void testCasAndListIndex() throws Throwable
{
createTable("CREATE TABLE %s ( k int PRIMARY KEY, v text, l list<text>)");
execute("INSERT INTO %s (k, v, l) VALUES(0, 'foobar', ['foi', 'bar'])");
assertRows(execute("UPDATE %s SET l[0] = 'foo' WHERE k = 0 IF v = 'barfoo'"), row(false, "foobar"));
assertRows(execute("UPDATE %s SET l[0] = 'foo' WHERE k = 0 IF v = 'foobar'"), row(true));
assertRows(execute("SELECT * FROM %s"), row(0, list("foo", "bar"), "foobar"));
}
/**
* Migrated from cql_tests.py:TestCQL.conditional_ddl_keyspace_test()
*/
@Test
public void testDropCreateKeyspaceIfNotExists() throws Throwable
{
String keyspace = KEYSPACE_PER_TEST;
dropPerTestKeyspace();
// try dropping when doesn't exist
dropPerTestKeyspace();
// create and confirm
schemaChange("CREATE KEYSPACE IF NOT EXISTS " + keyspace + " WITH replication = { 'class':'SimpleStrategy', 'replication_factor':1} and durable_writes = true ");
assertRows(execute("select durable_writes from system.schema_keyspaces where keyspace_name = ?", keyspace), row(true));
// unsuccessful create since it's already there, confirm settings don't change
schemaChange("CREATE KEYSPACE IF NOT EXISTS " + keyspace + " WITH replication = {'class':'SimpleStrategy', 'replication_factor':1} and durable_writes = false ");
assertRows(execute("select durable_writes from system.schema_keyspaces where keyspace_name = ?", keyspace), row(true));
// drop and confirm
schemaChange("DROP KEYSPACE IF EXISTS " + keyspace);
assertEmpty(execute("select * from system.schema_keyspaces where keyspace_name = ?", keyspace));
}
/**
* Migrated from cql_tests.py:TestCQL.conditional_ddl_table_test()
*/
@Test
public void testDropCreateTableIfNotExists() throws Throwable
{
String tableName = createTableName();
String fullTableName = KEYSPACE + "." + tableName;
// try dropping when doesn't exist
schemaChange("DROP TABLE IF EXISTS " + fullTableName);
// create and confirm
schemaChange("CREATE TABLE IF NOT EXISTS " + fullTableName + " (id text PRIMARY KEY, value1 blob) with comment = 'foo'");
assertRows(execute("select comment from system.schema_columnfamilies where keyspace_name = ? and columnfamily_name = ?", KEYSPACE, tableName),
row("foo"));
// unsuccessful create since it's already there, confirm settings don't change
schemaChange("CREATE TABLE IF NOT EXISTS " + fullTableName + " (id text PRIMARY KEY, value2 blob)with comment = 'bar'");
assertRows(execute("select comment from system.schema_columnfamilies where keyspace_name = ? and columnfamily_name = ?", KEYSPACE, tableName),
row("foo"));
// drop and confirm
schemaChange("DROP TABLE IF EXISTS " + fullTableName);
assertEmpty(execute("select * from system.schema_columnfamilies where keyspace_name = ? and columnfamily_name = ?", KEYSPACE, tableName));
}
/**
* Migrated from cql_tests.py:TestCQL.conditional_ddl_index_test()
*/
@Test
public void testDropCreateIndexIfNotExists() throws Throwable
{
String tableName = createTable("CREATE TABLE %s (id text PRIMARY KEY, value1 blob, value2 blob)with comment = 'foo'");
execute("use " + KEYSPACE);
// try dropping when doesn't exist
schemaChange("DROP INDEX IF EXISTS myindex");
// create and confirm
createIndex("CREATE INDEX IF NOT EXISTS myindex ON %s (value1)");
assertTrue(waitForIndex(KEYSPACE, tableName, "myindex"));
// unsuccessful create since it's already there
execute("CREATE INDEX IF NOT EXISTS myindex ON %s (value1)");
// drop and confirm
execute("DROP INDEX IF EXISTS myindex");
Object[][] rows = getRows(execute("select index_name from system.\"IndexInfo\" where table_name = ?", tableName));
assertEquals(0, rows.length);
}
/**
* Migrated from cql_tests.py:TestCQL.conditional_ddl_type_test()
*/
@Test
public void testDropCreateTypeIfNotExists() throws Throwable
{
execute("use " + KEYSPACE);
// try dropping when doesn 't exist
execute("DROP TYPE IF EXISTS mytype");
// create and confirm
execute("CREATE TYPE IF NOT EXISTS mytype (somefield int)");
assertRows(execute("SELECT type_name from system.schema_usertypes where keyspace_name = ? and type_name = ?", KEYSPACE, "mytype"),
row("mytype"));
// unsuccessful create since it 's already there
// TODO: confirm this create attempt doesn't alter type field from int to blob
execute("CREATE TYPE IF NOT EXISTS mytype (somefield blob)");
// drop and confirm
execute("DROP TYPE IF EXISTS mytype");
assertEmpty(execute("SELECT type_name from system.schema_usertypes where keyspace_name = ? and type_name = ?", KEYSPACE, "mytype"));
}
}

View File

@ -0,0 +1,112 @@
package org.apache.cassandra.cql3.validation.operations;
import org.junit.BeforeClass;
import org.junit.Test;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.dht.ByteOrderedPartitioner;
import org.apache.cassandra.exceptions.InvalidRequestException;
public class SelectLimitTest extends CQLTester
{
@BeforeClass
public static void setUp()
{
DatabaseDescriptor.setPartitioner(ByteOrderedPartitioner.instance);
}
/**
* Test limit across a partition range, requires byte ordered partitioner,
* migrated from cql_tests.py:TestCQL.limit_range_test()
*/
@Test
public void testPartitionRange() throws Throwable
{
createTable("CREATE TABLE %s (userid int, url text, time bigint, PRIMARY KEY (userid, url)) WITH COMPACT STORAGE");
for (int i = 0; i < 100; i++)
for (String tld : new String[] { "com", "org", "net" })
execute("INSERT INTO %s (userid, url, time) VALUES (?, ?, ?)", i, String.format("http://foo.%s", tld), 42L);
assertRows(execute("SELECT * FROM %s WHERE token(userid) >= token(2) LIMIT 1"),
row(2, "http://foo.com", 42L));
assertRows(execute("SELECT * FROM %s WHERE token(userid) > token(2) LIMIT 1"),
row(3, "http://foo.com", 42L));
}
/**
* Test limit across a column range,
* migrated from cql_tests.py:TestCQL.limit_multiget_test()
*/
@Test
public void testColumnRange() throws Throwable
{
createTable("CREATE TABLE %s (userid int, url text, time bigint, PRIMARY KEY (userid, url)) WITH COMPACT STORAGE");
for (int i = 0; i < 100; i++)
for (String tld : new String[] { "com", "org", "net" })
execute("INSERT INTO %s (userid, url, time) VALUES (?, ?, ?)", i, String.format("http://foo.%s", tld), 42L);
// Check that we do limit the output to 1 *and* that we respect query
// order of keys (even though 48 is after 2)
assertRows(execute("SELECT * FROM %s WHERE userid IN (48, 2) LIMIT 1"),
row(2, "http://foo.com", 42L));
}
/**
* Test limit queries on a sparse table,
* migrated from cql_tests.py:TestCQL.limit_sparse_test()
*/
@Test
public void testSparseTable() throws Throwable
{
createTable("CREATE TABLE %s (userid int, url text, day int, month text, year int, PRIMARY KEY (userid, url))");
for (int i = 0; i < 100; i++)
for (String tld : new String[] { "com", "org", "net" })
execute("INSERT INTO %s (userid, url, day, month, year) VALUES (?, ?, 1, 'jan', 2012)", i, String.format("http://foo.%s", tld));
assertRowCount(execute("SELECT * FROM %s LIMIT 4"), 4);
}
/**
* Check for #7052 bug,
* migrated from cql_tests.py:TestCQL.limit_compact_table()
*/
@Test
public void testLimitInCompactTable() throws Throwable
{
createTable("CREATE TABLE %s (k int, v int, PRIMARY KEY (k, v) ) WITH COMPACT STORAGE ");
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
execute("INSERT INTO %s(k, v) VALUES (?, ?)", i, j);
assertRows(execute("SELECT v FROM %s WHERE k=0 AND v > 0 AND v <= 4 LIMIT 2"),
row(1),
row(2));
assertRows(execute("SELECT v FROM %s WHERE k=0 AND v > -1 AND v <= 4 LIMIT 2"),
row(0),
row(1));
assertRows(execute("SELECT * FROM %s WHERE k IN (0, 1, 2) AND v > 0 AND v <= 4 LIMIT 2"),
row(0, 1),
row(0, 2));
assertRows(execute("SELECT * FROM %s WHERE k IN (0, 1, 2) AND v > -1 AND v <= 4 LIMIT 2"),
row(0, 0),
row(0, 1));
assertRows(execute("SELECT * FROM %s WHERE k IN (0, 1, 2) AND v > 0 AND v <= 4 LIMIT 6"),
row(0, 1),
row(0, 2),
row(0, 3),
row(1, 1),
row(1, 2),
row(1, 3));
// strict bound (v > 1) over a range of partitions is not supported for compact storage if limit is provided
assertInvalidThrow(InvalidRequestException.class, "SELECT * FROM %s WHERE v > 1 AND v <= 3 LIMIT 6 ALLOW FILTERING");
}
}

View File

@ -15,11 +15,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.operations;
import org.junit.Test;
public class MultiColumnRelationTest extends CQLTester
import org.apache.cassandra.cql3.CQLTester;
import static org.junit.Assert.assertEquals;
public class SelectMultiColumnRelationTest extends CQLTester
{
@Test
public void testSingleClusteringInvalidQueries() throws Throwable
@ -933,4 +937,26 @@ public class MultiColumnRelationTest extends CQLTester
assertInvalidMessage("Invalid unset value for in(i,j)",
"SELECT * from %s WHERE (i, j) IN ? ALLOW FILTERING", unset());
}
}
/**
* Check select on tuple relations, see CASSANDRA-8613
* migrated from cql_tests.py:TestCQL.simple_tuple_query_test()
*/
@Test
public void testSimpleTupleQuery() throws Throwable
{
createTable("create table %s (a int, b int, c int, d int , e int, PRIMARY KEY (a, b, c, d, e))");
execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 2, 0, 0, 0)");
execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 1, 0, 0, 0)");
execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 0, 0, 0)");
execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 1, 1, 1)");
execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 2, 2, 2)");
execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 3, 3, 3)");
execute("INSERT INTO %s (a, b, c, d, e) VALUES (0, 0, 1, 1, 1)");
assertRows(execute("SELECT * FROM %s WHERE b=0 AND (c, d, e) > (1, 1, 1) ALLOW FILTERING"),
row(0, 0, 2, 2, 2),
row(0, 0, 3, 3, 3));
}
}

View File

@ -0,0 +1,504 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3.validation.operations;
import org.junit.Test;
import org.apache.cassandra.cql3.CQLTester;
import static org.junit.Assert.assertTrue;
public class SelectOrderByTest extends CQLTester
{
@Test
public void testNormalSelectionOrderSingleClustering() throws Throwable
{
for (String descOption : new String[]{"", " WITH CLUSTERING ORDER BY (b DESC)"})
{
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))" + descOption);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 0, 0);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 1, 1);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 2, 2);
assertRows(execute("SELECT * FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0, 0, 0),
row(0, 1, 1),
row(0, 2, 2)
);
assertRows(execute("SELECT * FROM %s WHERE a=? ORDER BY b DESC", 0),
row(0, 2, 2),
row(0, 1, 1),
row(0, 0, 0)
);
// order by the only column in the selection
assertRows(execute("SELECT b FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0), row(1), row(2));
assertRows(execute("SELECT b FROM %s WHERE a=? ORDER BY b DESC", 0),
row(2), row(1), row(0));
// order by a column not in the selection
assertRows(execute("SELECT c FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0), row(1), row(2));
assertRows(execute("SELECT c FROM %s WHERE a=? ORDER BY b DESC", 0),
row(2), row(1), row(0));
}
}
@Test
public void testFunctionSelectionOrderSingleClustering() throws Throwable
{
for (String descOption : new String[]{"", " WITH CLUSTERING ORDER BY (b DESC)"})
{
createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a, b))" + descOption);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 0, 0);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 1, 1);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, ?)", 0, 2, 2);
// order by the only column in the selection
assertRows(execute("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0), row(1), row(2));
assertRows(execute("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b DESC", 0),
row(2), row(1), row(0));
// order by a column not in the selection
assertRows(execute("SELECT blobAsInt(intAsBlob(c)) FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0), row(1), row(2));
assertRows(execute("SELECT blobAsInt(intAsBlob(c)) FROM %s WHERE a=? ORDER BY b DESC", 0),
row(2), row(1), row(0));
assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY c ASC", 0);
assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY c DESC", 0);
}
}
@Test
public void testFieldSelectionOrderSingleClustering() throws Throwable
{
String type = createType("CREATE TYPE %s (a int)");
for (String descOption : new String[]{"", " WITH CLUSTERING ORDER BY (b DESC)"})
{
createTable("CREATE TABLE %s (a int, b int, c frozen<" + type + " >, PRIMARY KEY (a, b))" + descOption);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, {a: ?})", 0, 0, 0);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, {a: ?})", 0, 1, 1);
execute("INSERT INTO %s (a, b, c) VALUES (?, ?, {a: ?})", 0, 2, 2);
// order by a column not in the selection
assertRows(execute("SELECT c.a FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0), row(1), row(2));
assertRows(execute("SELECT c.a FROM %s WHERE a=? ORDER BY b DESC", 0),
row(2), row(1), row(0));
assertRows(execute("SELECT blobAsInt(intAsBlob(c.a)) FROM %s WHERE a=? ORDER BY b DESC", 0),
row(2), row(1), row(0));
dropTable("DROP TABLE %s");
}
}
@Test
public void testNormalSelectionOrderMultipleClustering() throws Throwable
{
createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c))");
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 0, 0);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 1);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 2, 2);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 0, 3);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 4);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 2, 5);
assertRows(execute("SELECT * FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0, 0, 0, 0),
row(0, 0, 1, 1),
row(0, 0, 2, 2),
row(0, 1, 0, 3),
row(0, 1, 1, 4),
row(0, 1, 2, 5)
);
assertRows(execute("SELECT * FROM %s WHERE a=? ORDER BY b DESC", 0),
row(0, 1, 2, 5),
row(0, 1, 1, 4),
row(0, 1, 0, 3),
row(0, 0, 2, 2),
row(0, 0, 1, 1),
row(0, 0, 0, 0)
);
assertRows(execute("SELECT * FROM %s WHERE a=? ORDER BY b DESC, c DESC", 0),
row(0, 1, 2, 5),
row(0, 1, 1, 4),
row(0, 1, 0, 3),
row(0, 0, 2, 2),
row(0, 0, 1, 1),
row(0, 0, 0, 0)
);
assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY c ASC", 0);
assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY c DESC", 0);
assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY b ASC, c DESC", 0);
assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY b DESC, c ASC", 0);
assertInvalid("SELECT * FROM %s WHERE a=? ORDER BY d ASC", 0);
// select and order by b
assertRows(execute("SELECT b FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0), row(0), row(0), row(1), row(1), row(1));
assertRows(execute("SELECT b FROM %s WHERE a=? ORDER BY b DESC", 0),
row(1), row(1), row(1), row(0), row(0), row(0));
// select c, order by b
assertRows(execute("SELECT c FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0), row(1), row(2), row(0), row(1), row(2));
assertRows(execute("SELECT c FROM %s WHERE a=? ORDER BY b DESC", 0),
row(2), row(1), row(0), row(2), row(1), row(0));
// select c, order by b, c
assertRows(execute("SELECT c FROM %s WHERE a=? ORDER BY b ASC, c ASC", 0),
row(0), row(1), row(2), row(0), row(1), row(2));
assertRows(execute("SELECT c FROM %s WHERE a=? ORDER BY b DESC, c DESC", 0),
row(2), row(1), row(0), row(2), row(1), row(0));
// select d, order by b, c
assertRows(execute("SELECT d FROM %s WHERE a=? ORDER BY b ASC, c ASC", 0),
row(0), row(1), row(2), row(3), row(4), row(5));
assertRows(execute("SELECT d FROM %s WHERE a=? ORDER BY b DESC, c DESC", 0),
row(5), row(4), row(3), row(2), row(1), row(0));
}
@Test
public void testFunctionSelectionOrderMultipleClustering() throws Throwable
{
createTable("CREATE TABLE %s (a int, b int, c int, d int, PRIMARY KEY (a, b, c))");
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 0, 0);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 1, 1);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 0, 2, 2);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 0, 3);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 1, 4);
execute("INSERT INTO %s (a, b, c, d) VALUES (?, ?, ?, ?)", 0, 1, 2, 5);
assertInvalid("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY c ASC", 0);
assertInvalid("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY c DESC", 0);
assertInvalid("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b ASC, c DESC", 0);
assertInvalid("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b DESC, c ASC", 0);
assertInvalid("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY d ASC", 0);
// select and order by b
assertRows(execute("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0), row(0), row(0), row(1), row(1), row(1));
assertRows(execute("SELECT blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b DESC", 0),
row(1), row(1), row(1), row(0), row(0), row(0));
assertRows(execute("SELECT b, blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0, 0), row(0, 0), row(0, 0), row(1, 1), row(1, 1), row(1, 1));
assertRows(execute("SELECT b, blobAsInt(intAsBlob(b)) FROM %s WHERE a=? ORDER BY b DESC", 0),
row(1, 1), row(1, 1), row(1, 1), row(0, 0), row(0, 0), row(0, 0));
// select c, order by b
assertRows(execute("SELECT blobAsInt(intAsBlob(c)) FROM %s WHERE a=? ORDER BY b ASC", 0),
row(0), row(1), row(2), row(0), row(1), row(2));
assertRows(execute("SELECT blobAsInt(intAsBlob(c)) FROM %s WHERE a=? ORDER BY b DESC", 0),
row(2), row(1), row(0), row(2), row(1), row(0));
// select c, order by b, c
assertRows(execute("SELECT blobAsInt(intAsBlob(c)) FROM %s WHERE a=? ORDER BY b ASC, c ASC", 0),
row(0), row(1), row(2), row(0), row(1), row(2));
assertRows(execute("SELECT blobAsInt(intAsBlob(c)) FROM %s WHERE a=? ORDER BY b DESC, c DESC", 0),
row(2), row(1), row(0), row(2), row(1), row(0));
// select d, order by b, c
assertRows(execute("SELECT blobAsInt(intAsBlob(d)) FROM %s WHERE a=? ORDER BY b ASC, c ASC", 0),
row(0), row(1), row(2), row(3), row(4), row(5));
assertRows(execute("SELECT blobAsInt(intAsBlob(d)) FROM %s WHERE a=? ORDER BY b DESC, c DESC", 0),
row(5), row(4), row(3), row(2), row(1), row(0));
}
/**
* Check ORDER BY support in SELECT statement
* migrated from cql_tests.py:TestCQL.order_by_test()
*/
@Test
public void testSimpleOrderBy() throws Throwable
{
createTable("CREATE TABLE %s (k int, c int, v int, PRIMARY KEY (k, c)) WITH COMPACT STORAGE");
for (int i = 0; i < 10; i++)
execute("INSERT INTO %s (k, c, v) VALUES (0, ?, ?)", i, i);
assertRows(execute("SELECT v FROM %s WHERE k = 0 ORDER BY c DESC"),
row(9), row(8), row(7), row(6), row(5), row(4), row(3), row(2), row(1), row(0));
createTable("CREATE TABLE %s (k int, c1 int, c2 int, v int, PRIMARY KEY (k, c1, c2)) WITH COMPACT STORAGE");
for (int i = 0; i < 4; i++)
for (int j = 0; j < 2; j++)
execute("INSERT INTO %s (k, c1, c2, v) VALUES (0, ?, ?, ?)", i, j, i * 2 + j);
assertInvalid("SELECT v FROM %s WHERE k = 0 ORDER BY c DESC");
assertInvalid("SELECT v FROM %s WHERE k = 0 ORDER BY c2 DESC");
assertInvalid("SELECT v FROM %s WHERE k = 0 ORDER BY k DESC");
assertRows(execute("SELECT v FROM %s WHERE k = 0 ORDER BY c1 DESC"),
row(7), row(6), row(5), row(4), row(3), row(2), row(1), row(0));
assertRows(execute("SELECT v FROM %s WHERE k = 0 ORDER BY c1"),
row(0), row(1), row(2), row(3), row(4), row(5), row(6), row(7));
}
/**
* More ORDER BY checks (#4160)
* migrated from cql_tests.py:TestCQL.more_order_by_test()
*/
@Test
public void testMoreOrderBy() throws Throwable
{
createTable("CREATE TABLE %s (row text, number int, string text, PRIMARY KEY(row, number)) WITH COMPACT STORAGE ");
execute("INSERT INTO %s (row, number, string) VALUES ('row', 1, 'one')");
execute("INSERT INTO %s (row, number, string) VALUES ('row', 2, 'two')");
execute("INSERT INTO %s (row, number, string) VALUES ('row', 3, 'three')");
execute("INSERT INTO %s (row, number, string) VALUES ('row', 4, 'four')");
assertRows(execute("SELECT number FROM %s WHERE row='row' AND number < 3 ORDER BY number ASC"),
row(1), row(2));
assertRows(execute("SELECT number FROM %s WHERE row='row' AND number >= 3 ORDER BY number ASC"),
row(3), row(4));
assertRows(execute("SELECT number FROM %s WHERE row='row' AND number < 3 ORDER BY number DESC"),
row(2), row(1));
assertRows(execute("SELECT number FROM %s WHERE row='row' AND number >= 3 ORDER BY number DESC"),
row(4), row(3));
assertRows(execute("SELECT number FROM %s WHERE row='row' AND number > 3 ORDER BY number DESC"),
row(4));
assertRows(execute("SELECT number FROM %s WHERE row='row' AND number <= 3 ORDER BY number DESC"),
row(3), row(2), row(1));
}
/**
* Check we don't allow order by on row key (#4246)
* migrated from cql_tests.py:TestCQL.order_by_validation_test()
*/
@Test
public void testInvalidOrderBy() throws Throwable
{
createTable("CREATE TABLE %s( k1 int, k2 int, v int, PRIMARY KEY (k1, k2))");
execute("INSERT INTO %s (k1, k2, v) VALUES (?, ?, ?)", 0, 0, 0);
execute("INSERT INTO %s (k1, k2, v) VALUES (?, ?, ?)", 1, 1, 1);
execute("INSERT INTO %s (k1, k2, v) VALUES (?, ?, ?)", 2, 2, 2);
assertInvalid("SELECT * FROM %s ORDER BY k2");
}
/**
* Check that order-by works with IN (#4327)
* migrated from cql_tests.py:TestCQL.order_by_with_in_test()
*/
@Test
public void testOrderByForInClause() throws Throwable
{
createTable("CREATE TABLE %s (my_id varchar, col1 int, value varchar, PRIMARY KEY (my_id, col1))");
execute("INSERT INTO %s (my_id, col1, value) VALUES ( 'key1', 1, 'a')");
execute("INSERT INTO %s (my_id, col1, value) VALUES ( 'key2', 3, 'c')");
execute("INSERT INTO %s (my_id, col1, value) VALUES ( 'key3', 2, 'b')");
execute("INSERT INTO %s (my_id, col1, value) VALUES ( 'key4', 4, 'd')");
assertRows(execute("SELECT col1 FROM %s WHERE my_id in('key1', 'key2', 'key3') ORDER BY col1"),
row(1), row(2), row(3));
assertRows(execute("SELECT col1, my_id FROM %s WHERE my_id in('key1', 'key2', 'key3') ORDER BY col1"),
row(1, "key1"), row(2, "key3"), row(3, "key2"));
assertRows(execute("SELECT my_id, col1 FROM %s WHERE my_id in('key1', 'key2', 'key3') ORDER BY col1"),
row("key1", 1), row("key3", 2), row("key2", 3));
}
/**
* Test reversed comparators
* migrated from cql_tests.py:TestCQL.reversed_comparator_test()
*/
@Test
public void testReversedComparator() throws Throwable
{
createTable("CREATE TABLE %s (k int, c int, v int, PRIMARY KEY (k, c)) WITH CLUSTERING ORDER BY (c DESC);");
for(int i =0; i < 10; i++)
execute("INSERT INTO %s (k, c, v) VALUES (0, ?, ?)", i, i);
assertRows(execute("SELECT c, v FROM %s WHERE k = 0 ORDER BY c ASC"),
row(0, 0), row(1, 1), row(2, 2), row(3, 3), row(4, 4),
row(5, 5), row(6, 6), row(7, 7), row(8, 8), row(9, 9));
assertRows(execute("SELECT c, v FROM %s WHERE k = 0 ORDER BY c DESC"),
row(9, 9), row(8, 8), row(7, 7), row(6, 6), row(5, 5),
row(4, 4), row(3, 3), row(2, 2), row(1, 1), row(0, 0));
createTable("CREATE TABLE %s (k int, c1 int, c2 int, v text, PRIMARY KEY (k, c1, c2)) WITH CLUSTERING ORDER BY (c1 ASC, c2 DESC)");
for(int i = 0; i < 10; i++)
for(int j = 0; j < 10; j++)
execute("INSERT INTO %s (k, c1, c2, v) VALUES (0, ?, ?, ?)", i, j, String.format("%d%d", i, j));
assertInvalid("SELECT c1, c2, v FROM %s WHERE k = 0 ORDER BY c1 ASC, c2 ASC");
assertInvalid("SELECT c1, c2, v FROM %s WHERE k = 0 ORDER BY c1 DESC, c2 DESC");
Object[][] expectedRows = new Object[100][];
for(int i = 0; i < 10; i++)
for(int j = 9; j >= 0; j--)
expectedRows[i * 10 + (9 - j)] = row(i, j, String.format("%d%d", i, j));
assertRows(execute("SELECT c1, c2, v FROM %s WHERE k = 0 ORDER BY c1 ASC"),
expectedRows);
assertRows(execute("SELECT c1, c2, v FROM %s WHERE k = 0 ORDER BY c1 ASC, c2 DESC"),
expectedRows);
for(int i = 9; i >= 0; i--)
for(int j = 0; j < 10; j++)
expectedRows[(9 - i) * 10 + j] = row(i, j, String.format("%d%d", i, j));
assertRows(execute("SELECT c1, c2, v FROM %s WHERE k = 0 ORDER BY c1 DESC, c2 ASC"),
expectedRows);
assertInvalid("SELECT c1, c2, v FROM %s WHERE k = 0 ORDER BY c2 DESC, c1 ASC");
}
/**
* Migrated from cql_tests.py:TestCQL.multiordering_test()
*/
@Test
public void testMultiordering() throws Throwable
{
createTable("CREATE TABLE %s (k text, c1 int, c2 int, PRIMARY KEY (k, c1, c2) ) WITH CLUSTERING ORDER BY (c1 ASC, c2 DESC)");
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
execute("INSERT INTO %s (k, c1, c2) VALUES ('foo', ?, ?)", i, j);
assertRows(execute("SELECT c1, c2 FROM %s WHERE k = 'foo'"),
row(0, 1), row(0, 0), row(1, 1), row(1, 0));
assertRows(execute("SELECT c1, c2 FROM %s WHERE k = 'foo' ORDER BY c1 ASC, c2 DESC"),
row(0, 1), row(0, 0), row(1, 1), row(1, 0));
assertRows(execute("SELECT c1, c2 FROM %s WHERE k = 'foo' ORDER BY c1 DESC, c2 ASC"),
row(1, 0), row(1, 1), row(0, 0), row(0, 1));
assertInvalid("SELECT c1, c2 FROM %s WHERE k = 'foo' ORDER BY c2 DESC");
assertInvalid("SELECT c1, c2 FROM %s WHERE k = 'foo' ORDER BY c2 ASC");
assertInvalid("SELECT c1, c2 FROM %s WHERE k = 'foo' ORDER BY c1 ASC, c2 ASC");
}
/**
* Migrated from cql_tests.py:TestCQL.in_with_desc_order_test()
*/
@Test
public void testSelectInStatementWithDesc() throws Throwable
{
createTable("CREATE TABLE %s (k int, c1 int, c2 int, PRIMARY KEY (k, c1, c2))");
execute("INSERT INTO %s(k, c1, c2) VALUES (0, 0, 0)");
execute("INSERT INTO %s(k, c1, c2) VALUES (0, 0, 1)");
execute("INSERT INTO %s(k, c1, c2) VALUES (0, 0, 2)");
assertRows(execute("SELECT * FROM %s WHERE k=0 AND c1 = 0 AND c2 IN (2, 0) ORDER BY c1 DESC"),
row(0, 0, 2),
row(0, 0, 0));
}
/**
* Test that columns don't need to be selected for ORDER BY when there is a IN (#4911),
* migrated from cql_tests.py:TestCQL.in_order_by_without_selecting_test()
*/
@Test
public void testInOrderByWithoutSelecting() throws Throwable
{
createTable("CREATE TABLE %s (k int, c1 int, c2 int, v int, PRIMARY KEY (k, c1, c2))");
execute("INSERT INTO %s (k, c1, c2, v) VALUES (0, 0, 0, 0)");
execute("INSERT INTO %s (k, c1, c2, v) VALUES (0, 0, 1, 1)");
execute("INSERT INTO %s (k, c1, c2, v) VALUES (0, 0, 2, 2)");
execute("INSERT INTO %s (k, c1, c2, v) VALUES (1, 1, 0, 3)");
execute("INSERT INTO %s (k, c1, c2, v) VALUES (1, 1, 1, 4)");
execute("INSERT INTO %s (k, c1, c2, v) VALUES (1, 1, 2, 5)");
assertRows(execute("SELECT * FROM %s WHERE k=0 AND c1 = 0 AND c2 IN (2, 0)"),
row(0, 0, 0, 0),
row(0, 0, 2, 2));
assertRows(execute("SELECT * FROM %s WHERE k=0 AND c1 = 0 AND c2 IN (2, 0) ORDER BY c1 ASC, c2 ASC"),
row(0, 0, 0, 0),
row(0, 0, 2, 2));
// check that we don 't need to select the column on which we order
assertRows(execute("SELECT v FROM %s WHERE k=0 AND c1 = 0 AND c2 IN (2, 0)"),
row(0),
row(2));
assertRows(execute("SELECT v FROM %s WHERE k=0 AND c1 = 0 AND c2 IN (2, 0) ORDER BY c1 ASC"),
row(0),
row(2));
assertRows(execute("SELECT v FROM %s WHERE k=0 AND c1 = 0 AND c2 IN (2, 0) ORDER BY c1 DESC"),
row(2),
row(0));
assertRows(execute("SELECT v FROM %s WHERE k IN (1, 0)"),
row(0),
row(1),
row(2),
row(3),
row(4),
row(5));
assertRows(execute("SELECT v FROM %s WHERE k IN (1, 0) ORDER BY c1 ASC"),
row(0),
row(1),
row(2),
row(3),
row(4),
row(5));
// we should also be able to use functions in the select clause (additional test for CASSANDRA - 8286)
Object[][] results = getRows(execute("SELECT writetime(v) FROM %s WHERE k IN (1, 0) ORDER BY c1 ASC"));
// since we don 't know the write times, just assert that the order matches the order we expect
assertTrue(isFirstIntSorted(results));
}
private boolean isFirstIntSorted(Object[][] rows)
{
for (int i = 1; i < rows.length; i++)
{
Long prev = (Long)rows[i-1][0];
Long curr = (Long)rows[i][0];
if (prev > curr)
return false;
}
return true;
}
}

View File

@ -1,28 +1,27 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.operations;
import java.util.Arrays;
import org.junit.BeforeClass;
import org.junit.Test;
public class SelectWithTokenFunctionTest extends CQLTester
import static junit.framework.Assert.assertNull;
import static org.junit.Assert.assertEquals;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.dht.ByteOrderedPartitioner;
/**
* SELECT statement tests that require a ByteOrderedPartitioner
*/
public class SelectOrderedPartitionerTest extends CQLTester
{
@BeforeClass
public static void setUp()
{
DatabaseDescriptor.setPartitioner(ByteOrderedPartitioner.instance);
}
@Test
public void testTokenFunctionWithSingleColumnPartitionKey() throws Throwable
{
@ -230,4 +229,253 @@ public class SelectWithTokenFunctionTest extends CQLTester
execute("SELECT * FROM %s WHERE token(a, b) > token(0, 0) AND (c, d) > (0, 0) ALLOW FILTERING;");
execute("SELECT * FROM %s WHERE (c, d) > (0, 0) AND token(a, b) > token(0, 0) ALLOW FILTERING;");
}
/**
* Test undefined columns
* migrated from cql_tests.py:TestCQL.undefined_column_handling_test()
*/
@Test
public void testUndefinedColumns() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, v1 int, v2 int,)");
execute("INSERT INTO %s (k, v1, v2) VALUES (0, 0, 0)");
execute("INSERT INTO %s (k, v1) VALUES (1, 1)");
execute("INSERT INTO %s (k, v1, v2) VALUES (2, 2, 2)");
Object[][] rows = getRows(execute("SELECT v2 FROM %s"));
assertEquals(0, rows[0][0]);
assertEquals(null, rows[1][0]);
assertEquals(2, rows[2][0]);
rows = getRows(execute("SELECT v2 FROM %s WHERE k = 1"));
assertEquals(1, rows.length);
assertNull(rows[0][0]);
}
/**
* Check table with only a PK (#4361),
* migrated from cql_tests.py:TestCQL.only_pk_test()
*/
@Test
public void testPrimaryKeyOnly() throws Throwable
{
createTable("CREATE TABLE %s (k int, c int, PRIMARY KEY (k, c))");
for (int k = 0; k < 2; k++)
for (int c = 0; c < 2; c++)
execute("INSERT INTO %s (k, c) VALUES (?, ?)", k, c);
assertRows(execute("SELECT * FROM %s"),
row(0, 0),
row(0, 1),
row(1, 0),
row(1, 1));
// Check for dense tables too
createTable(" CREATE TABLE %s (k int, c int, PRIMARY KEY (k, c)) WITH COMPACT STORAGE");
for (int k = 0; k < 2; k++)
for (int c = 0; c < 2; c++)
execute("INSERT INTO %s (k, c) VALUES (?, ?)", k, c);
assertRows(execute("SELECT * FROM %s"),
row(0, 0),
row(0, 1),
row(1, 0),
row(1, 1));
}
/**
* Migrated from cql_tests.py:TestCQL.composite_index_with_pk_test()
*/
@Test
public void testCompositeIndexWithPK() throws Throwable
{
createTable("CREATE TABLE %s (blog_id int, time1 int, time2 int, author text, content text, PRIMARY KEY (blog_id, time1, time2))");
createIndex("CREATE INDEX ON %s(author)");
execute("INSERT INTO %s (blog_id, time1, time2, author, content) VALUES (?, ?, ?, ?, ?)", 1, 0, 0, "foo", "bar1");
execute("INSERT INTO %s (blog_id, time1, time2, author, content) VALUES (?, ?, ?, ?, ?)", 1, 0, 1, "foo", "bar2");
execute("INSERT INTO %s (blog_id, time1, time2, author, content) VALUES (?, ?, ?, ?, ?)", 2, 1, 0, "foo", "baz");
execute("INSERT INTO %s (blog_id, time1, time2, author, content) VALUES (?, ?, ?, ?, ?)", 3, 0, 1, "gux", "qux");
assertRows(execute("SELECT blog_id, content FROM %s WHERE author='foo'"),
row(1, "bar1"),
row(1, "bar2"),
row(2, "baz"));
assertRows(execute("SELECT blog_id, content FROM %s WHERE time1 > 0 AND author='foo' ALLOW FILTERING"),
row(2, "baz"));
assertRows(execute("SELECT blog_id, content FROM %s WHERE time1 = 1 AND author='foo' ALLOW FILTERING"),
row(2, "baz"));
assertRows(execute("SELECT blog_id, content FROM %s WHERE time1 = 1 AND time2 = 0 AND author='foo' ALLOW FILTERING"),
row(2, "baz"));
assertEmpty(execute("SELECT content FROM %s WHERE time1 = 1 AND time2 = 1 AND author='foo' ALLOW FILTERING"));
assertEmpty(execute("SELECT content FROM %s WHERE time1 = 1 AND time2 > 0 AND author='foo' ALLOW FILTERING"));
assertInvalid("SELECT content FROM %s WHERE time2 >= 0 AND author='foo'");
assertInvalid("SELECT blog_id, content FROM %s WHERE time1 > 0 AND author='foo'");
assertInvalid("SELECT blog_id, content FROM %s WHERE time1 = 1 AND author='foo'");
assertInvalid("SELECT blog_id, content FROM %s WHERE time1 = 1 AND time2 = 0 AND author='foo'");
assertInvalid("SELECT content FROM %s WHERE time1 = 1 AND time2 = 1 AND author='foo'");
assertInvalid("SELECT content FROM %s WHERE time1 = 1 AND time2 > 0 AND author='foo'");
}
/**
* Test for LIMIT bugs from 4579,
* migrated from cql_tests.py:TestCQL.limit_bugs_test()
*/
@Test
public void testLimitBug() throws Throwable
{
createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, PRIMARY KEY (a, b))");
execute("INSERT INTO %s (a, b, c, d, e) VALUES (1, 1, 1, 1, 1);");
execute("INSERT INTO %s (a, b, c, d, e) VALUES (2, 2, 2, 2, 2);");
execute("INSERT INTO %s (a, b, c, d, e) VALUES (3, 3, 3, 3, 3);");
execute("INSERT INTO %s (a, b, c, d, e) VALUES (4, 4, 4, 4, 4);");
assertRows(execute("SELECT * FROM %s"),
row(1, 1, 1, 1, 1),
row(2, 2, 2, 2, 2),
row(3, 3, 3, 3, 3),
row(4, 4, 4, 4, 4));
assertRows(execute("SELECT * FROM %s LIMIT 1"),
row(1, 1, 1, 1, 1));
assertRows(execute("SELECT * FROM %s LIMIT 2"),
row(1, 1, 1, 1, 1),
row(2, 2, 2, 2, 2));
createTable("CREATE TABLE %s (a int primary key, b int, c int,)");
execute("INSERT INTO %s (a, b, c) VALUES (1, 1, 1)");
execute("INSERT INTO %s (a, b, c) VALUES (2, 2, 2)");
execute("INSERT INTO %s (a, b, c) VALUES (3, 3, 3)");
execute("INSERT INTO %s (a, b, c) VALUES (4, 4, 4)");
assertRows(execute("SELECT * FROM %s"),
row(1, 1, 1),
row(2, 2, 2),
row(3, 3, 3),
row(4, 4, 4));
assertRows(execute("SELECT * FROM %s LIMIT 1"),
row(1, 1, 1));
assertRows(execute("SELECT * FROM %s LIMIT 2"),
row(1, 1, 1),
row(2, 2, 2));
assertRows(execute("SELECT * FROM %s LIMIT 3"),
row(1, 1, 1),
row(2, 2, 2),
row(3, 3, 3));
assertRows(execute("SELECT * FROM %s LIMIT 4"),
row(1, 1, 1),
row(2, 2, 2),
row(3, 3, 3),
row(4, 4, 4));
assertRows(execute("SELECT * FROM %s LIMIT 5"),
row(1, 1, 1),
row(2, 2, 2),
row(3, 3, 3),
row(4, 4, 4));
}
/**
* Test for #4612 bug and more generally order by when multiple C* rows are queried
* migrated from cql_tests.py:TestCQL.order_by_multikey_test()
*/
@Test
public void testOrderByMultikey() throws Throwable
{
createTable("CREATE TABLE %s (my_id varchar, col1 int, col2 int, value varchar, PRIMARY KEY (my_id, col1, col2))");
execute("INSERT INTO %s (my_id, col1, col2, value) VALUES ( 'key1', 1, 1, 'a');");
execute("INSERT INTO %s (my_id, col1, col2, value) VALUES ( 'key2', 3, 3, 'a');");
execute("INSERT INTO %s (my_id, col1, col2, value) VALUES ( 'key3', 2, 2, 'b');");
execute("INSERT INTO %s (my_id, col1, col2, value) VALUES ( 'key4', 2, 1, 'b');");
assertRows(execute("SELECT col1 FROM %s WHERE my_id in('key1', 'key2', 'key3') ORDER BY col1"),
row(1), row(2), row(3));
assertRows(execute("SELECT col1, value, my_id, col2 FROM %s WHERE my_id in('key3', 'key4') ORDER BY col1, col2"),
row(2, "b", "key4", 1), row(2, "b", "key3", 2));
assertInvalid("SELECT col1 FROM %s ORDER BY col1");
assertInvalid("SELECT col1 FROM %s WHERE my_id > 'key1' ORDER BY col1");
}
/**
* Migrated from cql_tests.py:TestCQL.composite_index_collections_test()
*/
@Test
public void testIndexOnCompositeWithCollections() throws Throwable
{
createTable("CREATE TABLE %s (blog_id int, time1 int, time2 int, author text, content set<text>, PRIMARY KEY (blog_id, time1, time2))");
createIndex("CREATE INDEX ON %s (author)");
execute("INSERT INTO %s (blog_id, time1, time2, author, content) VALUES (?, ?, ?, ?, { 'bar1', 'bar2' })", 1, 0, 0, "foo");
execute("INSERT INTO %s (blog_id, time1, time2, author, content) VALUES (?, ?, ?, ?, { 'bar2', 'bar3' })", 1, 0, 1, "foo");
execute("INSERT INTO %s (blog_id, time1, time2, author, content) VALUES (?, ?, ?, ?, { 'baz' })", 2, 1, 0, "foo");
execute("INSERT INTO %s (blog_id, time1, time2, author, content) VALUES (?, ?, ?, ?, { 'qux' })", 3, 0, 1, "gux");
assertRows(execute("SELECT blog_id, content FROM %s WHERE author='foo'"),
row(1, set("bar1", "bar2")),
row(1, set("bar2", "bar3")),
row(2, set("baz")));
}
/**
* Migrated from cql_tests.py:TestCQL.truncate_clean_cache_test()
*/
@Test
public void testTruncateWithCaching() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY, v1 int, v2 int,) WITH CACHING = ALL;");
for (int i = 0; i < 3; i++)
execute("INSERT INTO %s (k, v1, v2) VALUES (?, ?, ?)", i, i, i * 2);
assertRows(execute("SELECT v1, v2 FROM %s WHERE k IN (0, 1, 2)"),
row(0, 0),
row(1, 2),
row(2, 4));
execute("TRUNCATE %s");
assertEmpty(execute("SELECT v1, v2 FROM %s WHERE k IN (0, 1, 2)"));
}
/**
* Migrated from cql_tests.py:TestCQL.range_key_ordered_test()
*/
@Test
public void testRangeKey() throws Throwable
{
createTable("CREATE TABLE %s (k int PRIMARY KEY)");
execute("INSERT INTO %s (k) VALUES (-1)");
execute("INSERT INTO %s (k) VALUES ( 0)");
execute("INSERT INTO %s (k) VALUES ( 1)");
assertRows(execute("SELECT * FROM %s"),
row(0),
row(1),
row(-1));
assertInvalid("SELECT * FROM %s WHERE k >= -1 AND k < 1");
}
}

View File

@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.operations;
import java.util.Arrays;
@ -24,7 +24,9 @@ import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
public class SingleColumnRelationTest extends CQLTester
import org.apache.cassandra.cql3.CQLTester;
public class SelectSingleColumnRelationTest extends CQLTester
{
@Test
public void testInvalidCollectionEqualityRelation() throws Throwable

File diff suppressed because it is too large Load Diff

View File

@ -15,16 +15,48 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.operations;
import org.junit.Test;
/**
* Type-casting is mostly using for functions and their use with functions is
* tested in UFTest. This is a few additional "sanity" tests.
*/
public class TypeCastTest extends CQLTester
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.utils.ByteBufferUtil;
public class UpdateTest extends CQLTester
{
/**
* Test altering the type of a column, including the one in the primary key (#4041)
* migrated from cql_tests.py:TestCQL.update_type_test()
*/
@Test
public void testUpdateColumnType() throws Throwable
{
createTable("CREATE TABLE %s (k text, c text, s set <text>, v text, PRIMARY KEY(k, c))");
// using utf8 character so that we can see the transition to BytesType
execute("INSERT INTO %s (k, c, v, s) VALUES ('ɸ', 'ɸ', 'ɸ', {'ɸ'})");
assertRows(execute("SELECT * FROM %s"),
row("ɸ", "ɸ", set("ɸ"), "ɸ"));
execute("ALTER TABLE %s ALTER v TYPE blob");
assertRows(execute("SELECT * FROM %s"),
row("ɸ", "ɸ", set("ɸ"), ByteBufferUtil.bytes("ɸ")));
execute("ALTER TABLE %s ALTER k TYPE blob");
assertRows(execute("SELECT * FROM %s"),
row(ByteBufferUtil.bytes("ɸ"), "ɸ", set("ɸ"), ByteBufferUtil.bytes("ɸ")));
execute("ALTER TABLE %s ALTER c TYPE blob");
assertRows(execute("SELECT * FROM %s"),
row(ByteBufferUtil.bytes("ɸ"), ByteBufferUtil.bytes("ɸ"), set("ɸ"), ByteBufferUtil.bytes("ɸ")));
execute("ALTER TABLE %s ALTER s TYPE set<blob>");
assertRows(execute("SELECT * FROM %s"),
row(ByteBufferUtil.bytes("ɸ"), ByteBufferUtil.bytes("ɸ"), set(ByteBufferUtil.bytes("ɸ")), ByteBufferUtil.bytes("ɸ")));
}
@Test
public void testTypeCasts() throws Throwable
{

View File

@ -15,11 +15,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
package org.apache.cassandra.cql3.validation.operations;
import org.junit.Test;
public class UseStatementTest extends CQLTester
import org.apache.cassandra.cql3.CQLTester;
public class UseTest extends CQLTester
{
@Test
public void testUseStatementWithBindVariable() throws Throwable

View File

@ -22,8 +22,9 @@ import org.junit.BeforeClass;
import org.junit.Test;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.cql3.QueryOptions;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.dht.ByteOrderedPartitioner;
import org.apache.cassandra.transport.Message;
import org.apache.cassandra.transport.Server;
import org.apache.cassandra.transport.SimpleClient;
@ -37,6 +38,8 @@ public class ClientWarningsTest extends CQLTester
@BeforeClass
public static void setUp()
{
DatabaseDescriptor.setPartitioner(ByteOrderedPartitioner.instance);
requireNetwork();
DatabaseDescriptor.setBatchSizeWarnThresholdInKB(1);
}

View File

@ -29,14 +29,16 @@ import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.cql3.BatchQueryOptions;
import org.apache.cassandra.cql3.CQLStatement;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.cql3.QueryHandler;
import org.apache.cassandra.cql3.QueryOptions;
import org.apache.cassandra.cql3.QueryProcessor;
import org.apache.cassandra.cql3.statements.BatchStatement;
import org.apache.cassandra.cql3.statements.ParsedStatement;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.dht.ByteOrderedPartitioner;
import org.apache.cassandra.exceptions.RequestExecutionException;
import org.apache.cassandra.exceptions.RequestValidationException;
import org.apache.cassandra.service.ClientState;
@ -63,6 +65,8 @@ public class MessagePayloadTest extends CQLTester
{
try
{
DatabaseDescriptor.setPartitioner(ByteOrderedPartitioner.instance);
cqlQueryHandlerField = ClientState.class.getDeclaredField("cqlQueryHandler");
cqlQueryHandlerField.setAccessible(true);

View File

@ -46,6 +46,6 @@ public class TimeUUIDs extends Generator<UUID>
@Override
public UUID generate()
{
return UUIDGen.getTimeUUID(dateGen.generate().getTime(), clockSeqAndNode);
return UUIDGen.getTimeUUID(dateGen.generate().getTime(), 0L, clockSeqAndNode);
}
}