mirror of https://github.com/apache/cassandra
Merge branch 'cassandra-2.2' into trunk
This commit is contained in:
commit
bc9b0be321
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ public abstract class UntypedResultSet implements Iterable<UntypedResultSet.Row>
|
|||
|
||||
public List<ColumnSpecification> metadata()
|
||||
{
|
||||
return cqlRows.metadata.names;
|
||||
return cqlRows.metadata.requestNames();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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")));
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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, '\"');
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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>");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -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')");
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
@ -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)");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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'
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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)");
|
||||
}
|
||||
}
|
||||
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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)
|
||||
|
|
@ -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);
|
||||
|
|
@ -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'}})");
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
@ -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 })
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
||||
{
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue