Merge branch cassandra-3.11 into trunk

This commit is contained in:
Benjamin Lerer 2017-01-18 16:09:36 +01:00
commit 369e7aa4c1
17 changed files with 44 additions and 547 deletions

View File

@ -31,6 +31,7 @@
* Tables in system_distributed should not use gcgs of 0 (CASSANDRA-12954)
3.10
* Remove ALTER TYPE support (CASSANDRA-12443)
* Fix TestHintedHandoff.hintedhandoff_decom_test (CASSANDRA-13058)
* Fixed query monitoring for range queries (CASSANDRA-13050)
* Remove outboundBindAny configuration property (CASSANDRA-12673)

View File

@ -36,21 +36,6 @@ Upgrading
will continue to operate, but CREATE and ALTER will validate that all
datacenters specified exist in the cluster.
3.11
====
Upgrading
---------
- Specifying the default_time_to_live option when creating or altering a
materialized view was erroneously accepted (and ignored). It is now
properly rejected.
- Only Java and JavaScript are now supported UDF languages.
The sandbox in 3.0 already prevented the use of script languages except Java
and JavaScript.
- Compaction now correctly drops sstables out of CompactionTask when there
isn't enough disk space to perform the full compaction. This should reduce
pending compaction tasks on systems with little remaining disk space.
3.10
====
@ -111,6 +96,18 @@ New features
Upgrading
---------
- Support for alter types of already defined tables and of UDTs fields has been disabled.
If it is necessary to return a different type, please use casting instead. See
CASSANDRA-12443 for more details.
- Specifying the default_time_to_live option when creating or altering a
materialized view was erroneously accepted (and ignored). It is now
properly rejected.
- Only Java and JavaScript are now supported UDF languages.
The sandbox in 3.0 already prevented the use of script languages except Java
and JavaScript.
- Compaction now correctly drops sstables out of CompactionTask when there
isn't enough disk space to perform the full compaction. This should reduce
pending compaction tasks on systems with little remaining disk space.
- Request timeouts in cassandra.yaml (read_request_timeout_in_ms, etc) now apply to the
"full" request time on the coordinator. Previously, they only covered the time from
when the coordinator sent a message to a replica until the time that the replica

View File

@ -396,8 +396,7 @@ __Syntax:__
bc(syntax)..
<alter-table-stmt> ::= ALTER (TABLE | COLUMNFAMILY) <tablename> <instruction>
<instruction> ::= ALTER <identifier> TYPE <type>
| ADD <identifier> <type>
<instruction> ::= ADD <identifier> <type>
| ADD ( <identifier> <type> ( , <identifier> <type> )* )
| DROP <identifier>
| DROP ( <identifier> ( , <identifier> )* )
@ -407,7 +406,6 @@ __Sample:__
bc(sample)..
ALTER TABLE addamsFamily
ALTER lastKnownLocation TYPE uuid;
ALTER TABLE addamsFamily
ADD gravesite varchar;
@ -416,10 +414,9 @@ ALTER TABLE addamsFamily
WITH comment = 'A most excellent and useful column family'
AND read_repair_chance = 0.2;
p.
The @ALTER@ statement is used to manipulate table definitions. It allows for adding new columns, dropping existing ones, changing the type of existing columns, or updating the table options. As with table creation, @ALTER COLUMNFAMILY@ is allowed as an alias for @ALTER TABLE@.
The @ALTER@ statement is used to manipulate table definitions. It allows for adding new columns, dropping existing ones, or updating the table options. As with table creation, @ALTER COLUMNFAMILY@ is allowed as an alias for @ALTER TABLE@.
The @<tablename>@ is the table name optionally preceded by the keyspace name. The @<instruction>@ defines the alteration to perform:
* @ALTER@: Update the type of a given defined column. Note that the type of the "clustering columns":#createTablepartitionClustering can be modified only in very limited cases, as it induces the on-disk ordering of rows. Columns on which a "secondary index":#createIndexStmt is defined have the same restriction. To change the type of any other column, the column must already exist in type definition and its type should be compatible with the new type. No validation of existing data is performed. The compatibility table is available below.
* @ADD@: Adds a new column to the table. The @<identifier>@ for the new column must not conflict with an existing column. Moreover, columns cannot be added to tables defined with the @COMPACT STORAGE@ option.
* @DROP@: Removes a column from the table. Dropped columns will immediately become unavailable in the queries and will not be included in compacted sstables in the future. If a column is readded, queries won't return values written before the column was last dropped. It is assumed that timestamps represent actual time, so if this is not your case, you should NOT readd previously dropped columns. Columns can't be dropped from tables defined with the @COMPACT STORAGE@ option.
* @WITH@: Allows to update the options of the table. The "supported @<option>@":#createTableOptions (and syntax) are the same as for the @CREATE TABLE@ statement except that @COMPACT STORAGE@ is not supported. Note that setting any @compaction@ sub-options has the effect of erasing all previous @compaction@ options, so you need to re-specify all the sub-options if you want to keep them. The same note applies to the set of @compression@ sub-options.
@ -621,23 +618,18 @@ __Syntax:__
bc(syntax)..
<alter-type-stmt> ::= ALTER TYPE <typename> <instruction>
<instruction> ::= ALTER <field-name> TYPE <type>
| ADD <field-name> <type>
<instruction> ::= ADD <field-name> <type>
| RENAME <field-name> TO <field-name> ( AND <field-name> TO <field-name> )*
p.
__Sample:__
bc(sample)..
ALTER TYPE address ALTER zip TYPE varint
ALTER TYPE address ADD country text
ALTER TYPE address RENAME zip TO zipcode AND street_name TO street
p.
The @ALTER TYPE@ statement is used to manipulate type definitions. It allows for adding new fields, renaming existing fields, or changing the type of existing fields.
When altering the type of a column, the new type must be compatible with the previous type.
h3(#dropTypeStmt). DROP TYPE
__Syntax:__

View File

@ -21,6 +21,12 @@ Changes
The following describes the changes in each version of CQL.
3.4.4
^^^^^
- ``ALTER TABLE`` ``ALTER`` has been removed; a column's type may not be changed after creation (:jira:`12443`).
- ``ALTER TYPE`` ``ALTER`` has been removed; a field's type may not be changed after creation (:jira:`12443`).
3.4.3
^^^^^

View File

@ -558,15 +558,12 @@ Altering an existing table uses the ``ALTER TABLE`` statement:
.. productionlist::
alter_table_statement: ALTER TABLE `table_name` `alter_table_instruction`
alter_table_instruction: ALTER `column_name` TYPE `cql_type`
: | ADD `column_name` `cql_type` ( ',' `column_name` `cql_type` )*
alter_table_instruction: ADD `column_name` `cql_type` ( ',' `column_name` `cql_type` )*
: | DROP `column_name` ( `column_name` )*
: | WITH `options`
For instance::
ALTER TABLE addamsFamily ALTER lastKnownLocation TYPE uuid;
ALTER TABLE addamsFamily ADD gravesite varchar;
ALTER TABLE addamsFamily
@ -575,11 +572,6 @@ For instance::
The ``ALTER TABLE`` statement can:
- Change the type of one of the column in the table (through the ``ALTER`` instruction). Note that the type of a column
cannot be changed arbitrarily. The change of type should be such that any value of the previous type should be a valid
value of the new type. Further, for :ref:`clustering columns <clustering-columns>` and columns on which a secondary
index is defined, the new type must sort values in the same way the previous type does. See the :ref:`type
compatibility table <alter-table-type-compatibility>` below for detail on which type changes are accepted.
- Add new column(s) to the table (through the ``ADD`` instruction). Note that the primary key of a table cannot be
changed and thus newly added column will, by extension, never be part of the primary key. Also note that :ref:`compact
tables <compact-tables>` have restrictions regarding column addition. Note that this is constant (in the amount of
@ -602,48 +594,6 @@ The ``ALTER TABLE`` statement can:
.. warning:: Once a column is dropped, it is allowed to re-add a column with the same name than the dropped one
**unless** the type of the dropped column was a (non-frozen) column (due to an internal technical limitation).
.. _alter-table-type-compatibility:
CQL type compatibility:
~~~~~~~~~~~~~~~~~~~~~~~
CQL data types may be converted only as the following table.
+-------------------------------------------------------+--------------------+
| Existing type | Can be altered to: |
+=======================================================+====================+
| timestamp | bigint |
+-------------------------------------------------------+--------------------+
| ascii, bigint, boolean, date, decimal, double, float, | blob |
| inet, int, smallint, text, time, timestamp, timeuuid, | |
| tinyint, uuid, varchar, varint | |
+-------------------------------------------------------+--------------------+
| int | date |
+-------------------------------------------------------+--------------------+
| ascii, varchar | text |
+-------------------------------------------------------+--------------------+
| bigint | time |
+-------------------------------------------------------+--------------------+
| bigint | timestamp |
+-------------------------------------------------------+--------------------+
| timeuuid | uuid |
+-------------------------------------------------------+--------------------+
| ascii, text | varchar |
+-------------------------------------------------------+--------------------+
| bigint, int, timestamp | varint |
+-------------------------------------------------------+--------------------+
Clustering columns have stricter requirements, only the following conversions are allowed:
+------------------------+----------------------+
| Existing type | Can be altered to |
+========================+======================+
| ascii, text, varchar | blob |
+------------------------+----------------------+
| ascii, varchar | text |
+------------------------+----------------------+
| ascii, text | varchar |
+------------------------+----------------------+
.. _drop-table-statement:

View File

@ -487,14 +487,11 @@ An existing user-defined type can be modified using an ``ALTER TYPE`` statement:
.. productionlist::
alter_type_statement: ALTER TYPE `udt_name` `alter_type_modification`
alter_type_modification: ALTER `identifier` TYPE `cql_type`
: | ADD `field_definition`
alter_type_modification: ADD `field_definition`
: | RENAME `identifier` TO `identifier` ( `identifier` TO `identifier` )*
You can:
- modify the type of particular field (``ALTER TYPE address ALTER zip TYPE bigint``). The restrictions for such change
are the same than when :ref:`altering the type of column <alter-table-statement>`.
- add a new field to the type (``ALTER TYPE address ADD country text``). That new field will be ``null`` for any values
of the type created before the addition.
- rename the fields of the type (``ALTER TYPE address RENAME zip TO zipcode``).

View File

@ -1376,8 +1376,7 @@ syntax_rules += r'''
<alterTableStatement> ::= "ALTER" wat=( "COLUMNFAMILY" | "TABLE" ) cf=<columnFamilyName>
<alterInstructions>
;
<alterInstructions> ::= "ALTER" existcol=<cident> "TYPE" <storageType>
| "ADD" newcol=<cident> <storageType> ("static")?
<alterInstructions> ::= "ADD" newcol=<cident> <storageType> ("static")?
| "DROP" existcol=<cident>
| "WITH" <cfamProperty> ( "AND" <cfamProperty> )*
| "RENAME" existcol=<cident> "TO" newcol=<cident>
@ -1387,8 +1386,7 @@ syntax_rules += r'''
<alterUserTypeStatement> ::= "ALTER" "TYPE" ut=<userTypeName>
<alterTypeInstructions>
;
<alterTypeInstructions> ::= "ALTER" existcol=<cident> "TYPE" <storageType>
| "ADD" newcol=<cident> <storageType>
<alterTypeInstructions> ::= "ADD" newcol=<cident> <storageType>
| "RENAME" existcol=<cident> "TO" newcol=<cident>
( "AND" existcol=<cident> "TO" newcol=<cident> )*
;

View File

@ -47,7 +47,6 @@ import org.apache.cassandra.cql3.statements.CFStatement;
import org.apache.cassandra.cql3.statements.CreateTableStatement;
import org.apache.cassandra.db.*;
import org.apache.cassandra.db.compaction.AbstractCompactionStrategy;
import org.apache.cassandra.db.filter.ColumnFilter;
import org.apache.cassandra.db.marshal.*;
import org.apache.cassandra.dht.IPartitioner;
import org.apache.cassandra.exceptions.ConfigurationException;
@ -88,16 +87,15 @@ public final class CFMetaData
private final boolean isSuper;
private final boolean isCounter;
private final boolean isView;
private final boolean isIndex;
public volatile ClusteringComparator comparator; // bytes, long, timeuuid, utf8, etc. This is built directly from clusteringColumns
public final ClusteringComparator comparator; // bytes, long, timeuuid, utf8, etc. This is built directly from clusteringColumns
public final IPartitioner partitioner; // partitioner the table uses
private final AbstractType<?> keyValidator;
// non-final, for now
public volatile TableParams params = TableParams.DEFAULT;
private volatile AbstractType<?> keyValidator = BytesType.instance;
private volatile Map<ByteBuffer, DroppedColumn> droppedColumns = new HashMap<>();
private volatile Triggers triggers = Triggers.none();
private volatile Indexes indexes = Indexes.none();
@ -293,8 +291,10 @@ public final class CFMetaData
this.clusteringColumns = clusteringColumns;
this.partitionColumns = partitionColumns;
//This needs to happen before serializers are set
//because they use comparator.subtypes()
this.comparator = new ClusteringComparator(extractTypes(clusteringColumns));
List<AbstractType<?>> keyTypes = extractTypes(partitionKeyColumns);
this.keyValidator = keyTypes.size() == 1 ? keyTypes.get(0) : CompositeType.getInstance(keyTypes);
rebuild();
this.resource = DataResource.table(ksName, cfName);
@ -304,24 +304,17 @@ public final class CFMetaData
// are kept because they are often useful in a different format.
private void rebuild()
{
this.comparator = new ClusteringComparator(extractTypes(clusteringColumns));
Map<ByteBuffer, ColumnDefinition> newColumnMetadata = Maps.newHashMapWithExpectedSize(partitionKeyColumns.size() + clusteringColumns.size() + partitionColumns.size());
for (ColumnDefinition def : partitionKeyColumns)
newColumnMetadata.put(def.name.bytes, def);
for (ColumnDefinition def : clusteringColumns)
{
newColumnMetadata.put(def.name.bytes, def);
def.type.checkComparable();
}
for (ColumnDefinition def : partitionColumns)
newColumnMetadata.put(def.name.bytes, def);
this.columnMetadata = newColumnMetadata;
List<AbstractType<?>> keyTypes = extractTypes(partitionKeyColumns);
this.keyValidator = keyTypes.size() == 1 ? keyTypes.get(0) : CompositeType.getInstance(keyTypes);
if (isCompactTable())
this.compactValueColumn = CompactTables.getCompactValueColumn(partitionColumns, isSuper());
}
@ -762,8 +755,6 @@ public final class CFMetaData
params = cfm.params;
keyValidator = cfm.keyValidator;
if (!cfm.droppedColumns.isEmpty())
droppedColumns = cfm.droppedColumns;
@ -791,9 +782,6 @@ public final class CFMetaData
cfm.cfId, cfId));
if (!cfm.flags.equals(flags))
throw new ConfigurationException(String.format("Column family type mismatch (found %s; expected %s)", cfm.flags, flags));
if (!cfm.comparator.isCompatibleWith(comparator))
throw new ConfigurationException(String.format("Column family comparators do not match or are not compatible (found %s; expected %s).", cfm.comparator.toString(), comparator.toString()));
}
@ -938,12 +926,9 @@ public final class CFMetaData
{
case PARTITION_KEY:
partitionKeyColumns.set(def.position(), def);
List<AbstractType<?>> keyTypes = extractTypes(partitionKeyColumns);
keyValidator = keyTypes.size() == 1 ? keyTypes.get(0) : CompositeType.getInstance(keyTypes);
break;
case CLUSTERING:
clusteringColumns.set(def.position(), def);
comparator = new ClusteringComparator(extractTypes(clusteringColumns));
break;
case REGULAR:
case STATIC:

View File

@ -62,7 +62,7 @@ import static org.apache.cassandra.cql3.statements.RequestValidations.checkTrue;
public class QueryProcessor implements QueryHandler
{
public static final CassandraVersion CQL_VERSION = new CassandraVersion("3.4.3");
public static final CassandraVersion CQL_VERSION = new CassandraVersion("3.4.4");
public static final QueryProcessor instance = new QueryProcessor();

View File

@ -29,8 +29,6 @@ import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.db.Keyspace;
import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.db.marshal.CollectionType;
import org.apache.cassandra.db.marshal.CounterColumnType;
import org.apache.cassandra.db.marshal.ReversedType;
import org.apache.cassandra.db.view.View;
import org.apache.cassandra.exceptions.*;
import org.apache.cassandra.schema.IndexMetadata;
@ -97,6 +95,8 @@ public class AlterTableStatement extends SchemaAlteringStatement
switch (oType)
{
case ALTER:
throw new InvalidRequestException("Altering of types is not allowed");
case ADD:
if (cfm.isDense())
throw new InvalidRequestException("Cannot add new column to a COMPACT STORAGE table");
@ -182,42 +182,6 @@ public class AlterTableStatement extends SchemaAlteringStatement
}
break;
case ALTER:
columnName = colNameList.get(0).getColumnName().getIdentifier(cfm);
def = cfm.getColumnDefinition(columnName);
dataType = colNameList.get(0).getColumnType();
assert dataType != null;
validator = dataType.prepare(keyspace());
if (def == null)
throw new InvalidRequestException(String.format("Column %s was not found in table %s", columnName, columnFamily()));
AbstractType<?> validatorType = def.isReversedType() && !validator.getType().isReversed()
? ReversedType.getInstance(validator.getType())
: validator.getType();
validateAlter(cfm, def, validatorType);
// In any case, we update the column definition
cfm.addOrReplaceColumnDefinition(def.withNewType(validatorType));
// We also have to validate the view types here. If we have a view which includes a column as part of
// the clustering key, we need to make sure that it is indeed compatible.
for (ViewDefinition view : views)
{
if (!view.includes(columnName)) continue;
ViewDefinition viewCopy = view.copy();
ColumnDefinition viewDef = view.metadata.getColumnDefinition(columnName);
AbstractType viewType = viewDef.isReversedType() && !validator.getType().isReversed()
? ReversedType.getInstance(validator.getType())
: validator.getType();
validateAlter(view.metadata, viewDef, viewType);
viewCopy.metadata.addOrReplaceColumnDefinition(viewDef.withNewType(viewType));
if (viewUpdates == null)
viewUpdates = new ArrayList<>();
viewUpdates.add(viewCopy);
}
break;
case DROP:
if (!cfm.isCQLTable())
throw new InvalidRequestException("Cannot drop columns from a non-CQL3 table");
@ -343,52 +307,6 @@ public class AlterTableStatement extends SchemaAlteringStatement
return new Event.SchemaChange(Event.SchemaChange.Change.UPDATED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
}
private static void validateAlter(CFMetaData cfm, ColumnDefinition def, AbstractType<?> validatorType)
{
switch (def.kind)
{
case PARTITION_KEY:
if (validatorType instanceof CounterColumnType)
throw new InvalidRequestException(String.format("counter type is not supported for PRIMARY KEY part %s", def.name));
AbstractType<?> currentType = cfm.getKeyValidatorAsClusteringComparator().subtype(def.position());
if (!validatorType.isValueCompatibleWith(currentType))
throw new ConfigurationException(String.format("Cannot change %s from type %s to type %s: types are incompatible.",
def.name,
currentType.asCQL3Type(),
validatorType.asCQL3Type()));
break;
case CLUSTERING:
if (!cfm.isCQLTable())
throw new InvalidRequestException(String.format("Cannot alter clustering column %s in a non-CQL3 table", def.name));
AbstractType<?> oldType = cfm.comparator.subtype(def.position());
// Note that CFMetaData.validateCompatibility already validate the change we're about to do. However, the error message it
// sends is a bit cryptic for a CQL3 user, so validating here for a sake of returning a better error message
// Do note that we need isCompatibleWith here, not just isValueCompatibleWith.
if (!validatorType.isCompatibleWith(oldType))
{
throw new ConfigurationException(String.format("Cannot change %s from type %s to type %s: types are not order-compatible.",
def.name,
oldType.asCQL3Type(),
validatorType.asCQL3Type()));
}
break;
case REGULAR:
case STATIC:
// As above, we want a clear error message, but in this case it happens that CFMetaData.validateCompatibility *does not*
// validate this for historical reasons so it's doubtly important. Note that we only care about value compatibility
// though since we won't compare values (except when there is an index, but that is validated by ColumnDefinition already).
// TODO: we could clear out where validation is done and do it only once.
if (!validatorType.isValueCompatibleWith(def.type))
throw new ConfigurationException(String.format("Cannot change %s from type %s to type %s: types are incompatible.",
def.name,
def.type.asCQL3Type(),
validatorType.asCQL3Type()));
break;
}
}
@Override
public String toString()
{

View File

@ -54,12 +54,12 @@ public abstract class AlterTypeStatement extends SchemaAlteringStatement
public static AlterTypeStatement addition(UTName name, FieldIdentifier fieldName, CQL3Type.Raw type)
{
return new AddOrAlter(name, true, fieldName, type);
return new Add(name, fieldName, type);
}
public static AlterTypeStatement alter(UTName name, FieldIdentifier fieldName, CQL3Type.Raw type)
{
return new AddOrAlter(name, false, fieldName, type);
throw new InvalidRequestException("Altering of types is not allowed");
}
public static AlterTypeStatement renames(UTName name, Map<FieldIdentifier, FieldIdentifier> renames)
@ -237,21 +237,19 @@ public abstract class AlterTypeStatement extends SchemaAlteringStatement
});
}
private static class AddOrAlter extends AlterTypeStatement
private static class Add extends AlterTypeStatement
{
private final boolean isAdd;
private final FieldIdentifier fieldName;
private final CQL3Type.Raw type;
public AddOrAlter(UTName name, boolean isAdd, FieldIdentifier fieldName, CQL3Type.Raw type)
public Add(UTName name, FieldIdentifier fieldName, CQL3Type.Raw type)
{
super(name);
this.isAdd = isAdd;
this.fieldName = fieldName;
this.type = type;
}
private UserType doAdd(UserType toUpdate) throws InvalidRequestException
protected UserType makeUpdatedType(UserType toUpdate, KeyspaceMetadata ksm) throws InvalidRequestException
{
if (toUpdate.fieldPosition(fieldName) >= 0)
throw new InvalidRequestException(String.format("Cannot add new field %s to type %s: a field of the same name already exists", fieldName, name));
@ -270,30 +268,6 @@ public abstract class AlterTypeStatement extends SchemaAlteringStatement
return new UserType(toUpdate.keyspace, toUpdate.name, newNames, newTypes, toUpdate.isMultiCell());
}
private UserType doAlter(UserType toUpdate, KeyspaceMetadata ksm) throws InvalidRequestException
{
checkTypeNotUsedByAggregate(ksm);
int idx = toUpdate.fieldPosition(fieldName);
if (idx < 0)
throw new InvalidRequestException(String.format("Unknown field %s in type %s", fieldName, name));
AbstractType<?> previous = toUpdate.fieldType(idx);
if (!type.prepare(keyspace()).getType().isCompatibleWith(previous))
throw new InvalidRequestException(String.format("Type %s is incompatible with previous type %s of field %s in user type %s", type, previous.asCQL3Type(), fieldName, name));
List<FieldIdentifier> newNames = new ArrayList<>(toUpdate.fieldNames());
List<AbstractType<?>> newTypes = new ArrayList<>(toUpdate.fieldTypes());
newTypes.set(idx, type.prepare(keyspace()).getType());
return new UserType(toUpdate.keyspace, toUpdate.name, newNames, newTypes, toUpdate.isMultiCell());
}
protected UserType makeUpdatedType(UserType toUpdate, KeyspaceMetadata ksm) throws InvalidRequestException
{
return isAdd ? doAdd(toUpdate) : doAlter(toUpdate, ksm);
}
}
private static class Renames extends AlterTypeStatement

View File

@ -684,80 +684,4 @@ public class ViewSchemaTest extends CQLTester
Assert.assertEquals("Cannot use DROP TABLE on Materialized View", e.getMessage());
}
}
@Test
public void testAlterTable() throws Throwable
{
createTable("CREATE TABLE %s (" +
"a int," +
"b text," +
"PRIMARY KEY (a, b))");
executeNet(protocolVersion, "USE " + keyspace());
createView("mv1", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE a IS NOT NULL AND b IS NOT NULL PRIMARY KEY (b, a)");
alterTable("ALTER TABLE %s ALTER b TYPE blob");
}
@Test
public void testAlterReversedTypeBaseTable() throws Throwable
{
createTable("CREATE TABLE %s (" +
"a int," +
"b text," +
"PRIMARY KEY (a, b))" +
"WITH CLUSTERING ORDER BY (b DESC)");
executeNet(protocolVersion, "USE " + keyspace());
createView("mv1", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE a IS NOT NULL AND b IS NOT NULL PRIMARY KEY (a, b) WITH CLUSTERING ORDER BY (b ASC)");
alterTable("ALTER TABLE %s ALTER b TYPE blob");
}
@Test
public void testAlterReversedTypeViewTable() throws Throwable
{
createTable("CREATE TABLE %s (" +
"a int," +
"b text," +
"PRIMARY KEY (a, b))");
executeNet(protocolVersion, "USE " + keyspace());
createView("mv1", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE a IS NOT NULL AND b IS NOT NULL PRIMARY KEY (a, b) WITH CLUSTERING ORDER BY (b DESC)");
alterTable("ALTER TABLE %s ALTER b TYPE blob");
}
@Test
public void testAlterClusteringViewTable() throws Throwable
{
createTable("CREATE TABLE %s (" +
"a int," +
"b text," +
"PRIMARY KEY (a))");
executeNet(protocolVersion, "USE " + keyspace());
createView("mv1", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE a IS NOT NULL AND b IS NOT NULL PRIMARY KEY (a, b) WITH CLUSTERING ORDER BY (b DESC)");
alterTable("ALTER TABLE %s ALTER b TYPE blob");
}
@Test
public void testAlterViewTableValue() throws Throwable
{
createTable("CREATE TABLE %s (" +
"a int," +
"b int," +
"PRIMARY KEY (a))");
executeNet(protocolVersion, "USE " + keyspace());
createView("mv1", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE a IS NOT NULL AND b IS NOT NULL PRIMARY KEY (a, b) WITH CLUSTERING ORDER BY (b DESC)");
assertInvalid("ALTER TABLE %s ALTER b TYPE blob");
}
}

View File

@ -511,20 +511,6 @@ public class FrozenCollectionsTest extends CQLTester
}
}
private void assertInvalidAlterWithMessage(String createTableStatement, String errorMessage) throws Throwable
{
try
{
alterTableMayThrow(createTableStatement);
Assert.fail("Expected CREATE TABLE statement to error: " + createTableStatement);
}
catch (InvalidRequestException | ConfigurationException ex)
{
Assert.assertTrue("Expected error message to contain '" + errorMessage + "', but got '" + ex.getMessage() + "'",
ex.getMessage().contains(errorMessage));
}
}
@Test
public void testInvalidOperations() throws Throwable
{
@ -557,34 +543,6 @@ public class FrozenCollectionsTest extends CQLTester
"frozen<> is only allowed on collections, tuples, and user-defined types");
}
@Test
public void testAltering() throws Throwable
{
createTable("CREATE TABLE %s (a int, b frozen<list<int>>, c frozen<list<int>>, PRIMARY KEY (a, b))");
alterTable("ALTER TABLE %s ALTER c TYPE frozen<list<blob>>");
assertInvalidAlterWithMessage("ALTER TABLE %s ALTER b TYPE frozen<list<blob>>",
"types are not order-compatible");
assertInvalidAlterWithMessage("ALTER TABLE %s ALTER b TYPE list<int>",
"types are not order-compatible");
assertInvalidAlterWithMessage("ALTER TABLE %s ALTER c TYPE list<blob>",
"types are incompatible");
alterTable("ALTER TABLE %s DROP c");
alterTable("ALTER TABLE %s ADD c frozen<set<int>>");
assertInvalidAlterWithMessage("ALTER TABLE %s ALTER c TYPE frozen<set<blob>>",
"types are incompatible");
alterTable("ALTER TABLE %s DROP c");
alterTable("ALTER TABLE %s ADD c frozen<map<int, int>>");
assertInvalidAlterWithMessage("ALTER TABLE %s ALTER c TYPE frozen<map<blob, int>>",
"types are incompatible");
alterTable("ALTER TABLE %s ALTER c TYPE frozen<map<int, blob>>");
}
private void assertInvalidIndexCreationWithMessage(String statement, String errorMessage) throws Throwable
{
try

View File

@ -67,36 +67,4 @@ public class TypeTest extends CQLTester
UntypedResultSet results = execute("SELECT * FROM %s WHERE a=0 AND b < now()");
assertEquals(1, results.size());
}
@Test
// tests CASSANDRA-7797
public void testAlterReversedColumn() throws Throwable
{
createTable("CREATE TABLE IF NOT EXISTS %s (a int, b 'org.apache.cassandra.db.marshal.DateType', PRIMARY KEY (a, b)) WITH CLUSTERING ORDER BY (b DESC)");
alterTable("ALTER TABLE %s ALTER b TYPE 'org.apache.cassandra.db.marshal.ReversedType(org.apache.cassandra.db.marshal.TimestampType)'");
}
@Test
public void testIncompatibleReversedTypes() throws Throwable
{
createTable("CREATE TABLE IF NOT EXISTS %s (a int, b 'org.apache.cassandra.db.marshal.DateType', PRIMARY KEY (a, b)) WITH CLUSTERING ORDER BY (b DESC)");
try
{
alterTable("ALTER TABLE %s ALTER b TYPE 'org.apache.cassandra.db.marshal.ReversedType(org.apache.cassandra.db.marshal.TimeUUIDType)'");
fail("Expected error for ALTER statement");
}
catch (RuntimeException e) { }
}
@Test
public void testReversedAndNonReversed() throws Throwable
{
createTable("CREATE TABLE IF NOT EXISTS %s (a int, b 'org.apache.cassandra.db.marshal.DateType', PRIMARY KEY (a, b))");
try
{
alterTable("ALTER TABLE %s ALTER b TYPE 'org.apache.cassandra.db.marshal.ReversedType(org.apache.cassandra.db.marshal.DateType)'");
fail("Expected error for ALTER statement");
}
catch (RuntimeException e) { }
}
}

View File

@ -611,7 +611,6 @@ public class UserTypesTest extends CQLTester
private void assertInvalidAlterDropStatements(String t) throws Throwable
{
assertInvalidMessage("Cannot alter user type " + typeWithKs(t), "ALTER TYPE " + typeWithKs(t) + " RENAME foo TO bar;");
assertInvalidMessage("Cannot alter user type " + typeWithKs(t), "ALTER TYPE " + typeWithKs(t) + " ALTER foo TYPE text;");
assertInvalidMessage("Cannot drop user type " + typeWithKs(t), "DROP TYPE " + typeWithKs(t) + ';');
}

View File

@ -17,19 +17,16 @@
*/
package org.apache.cassandra.cql3.validation.operations;
import org.junit.Assert;
import org.junit.Test;
import org.apache.cassandra.config.SchemaConstants;
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.InvalidRequestException;
import org.apache.cassandra.exceptions.SyntaxException;
import org.apache.cassandra.schema.SchemaKeyspace;
import org.apache.cassandra.transport.ProtocolVersion;
import org.apache.cassandra.utils.ByteBufferUtil;
import org.junit.Assert;
import org.junit.Test;
import static java.lang.String.format;
import static org.junit.Assert.assertEquals;
@ -386,37 +383,6 @@ public class AlterTest extends CQLTester
"ALTER TABLE %s WITH compression = { 'class' : 'SnappyCompressor', 'chunk_length_kb' : 32 , 'chunk_length_in_kb' : 32 };");
}
@Test
public void testAlterType() throws Throwable
{
createTable("CREATE TABLE %s (id text PRIMARY KEY, content text);");
alterTable("ALTER TABLE %s ALTER content TYPE blob");
createTable("CREATE TABLE %s (pk int, ck text, value blob, PRIMARY KEY (pk, ck)) WITH CLUSTERING ORDER BY (ck DESC)");
alterTable("ALTER TABLE %s ALTER ck TYPE blob");
createTable("CREATE TABLE %s (pk int, ck int, value blob, PRIMARY KEY (pk, ck))");
assertThrowsConfigurationException("Cannot change value from type blob to type text: types are incompatible.",
"ALTER TABLE %s ALTER value TYPE TEXT;");
}
/**
* tests CASSANDRA-10027
*/
@Test
public void testAlterColumnTypeToDate() throws Throwable
{
createTable("CREATE TABLE %s (key int PRIMARY KEY, c1 int);");
execute("INSERT INTO %s (key, c1) VALUES (1,1);");
execute("ALTER TABLE %s ALTER c1 TYPE date;");
assertRows(execute("SELECT * FROM %s"), row(1, 1));
createTable("CREATE TABLE %s (key int PRIMARY KEY, c1 varint);");
execute("INSERT INTO %s (key, c1) VALUES (1,1);");
assertInvalidMessage("Cannot change c1 from type varint to type date: types are incompatible.",
"ALTER TABLE %s ALTER c1 TYPE date;");
}
private void assertThrowsConfigurationException(String errorMsg, String alterStmt) throws Throwable
{
try
@ -429,108 +395,4 @@ public class AlterTest extends CQLTester
assertEquals(errorMsg, e.getMessage());
}
}
@Test // tests CASSANDRA-8879
public void testAlterClusteringColumnTypeInCompactTable() throws Throwable
{
createTable("CREATE TABLE %s (key blob, column1 blob, value blob, PRIMARY KEY ((key), column1)) WITH COMPACT STORAGE");
assertInvalidThrow(InvalidRequestException.class, "ALTER TABLE %s ALTER column1 TYPE ascii");
}
/*
* Test case to check addition of one column
*/
@Test
public void testAlterAddOneColumn() throws Throwable
{
createTable("CREATE TABLE IF NOT EXISTS %s (id int, name text, PRIMARY KEY (id))");
alterTable("ALTER TABLE %s add mail text;");
assertColumnNames(execute("SELECT * FROM %s"), "id", "mail", "name");
}
/*
* Test case to check addition of more than one column
*/
@Test
public void testAlterAddMultiColumn() throws Throwable
{
createTable("CREATE TABLE IF NOT EXISTS %s (id int, yearofbirth int, PRIMARY KEY (id))");
alterTable("ALTER TABLE %s add (firstname text, password blob, lastname text, \"SOME escaped col\" bigint)");
assertColumnNames(execute("SELECT * FROM %s"), "id", "SOME escaped col", "firstname", "lastname", "password", "yearofbirth");
}
/*
* Should throw SyntaxException if multiple columns are added using wrong syntax.
* Expected Syntax : Alter table T1 add (C1 datatype,C2 datatype,C3 datatype)
*/
@Test(expected = SyntaxException.class)
public void testAlterAddMultiColumnWithoutBraces() throws Throwable
{
execute("ALTER TABLE %s.users add lastname text, password blob, yearofbirth int;");
}
/*
* Test case to check deletion of one column
*/
@Test
public void testAlterDropOneColumn() throws Throwable
{
createTable("CREATE TABLE IF NOT EXISTS %s (id text, telephone int, yearofbirth int, PRIMARY KEY (id))");
alterTable("ALTER TABLE %s drop telephone");
assertColumnNames(execute("SELECT * FROM %s"), "id", "yearofbirth");
}
@Test
/*
* Test case to check deletion of more than one column
*/
public void testAlterDropMultiColumn() throws Throwable
{
createTable("CREATE TABLE IF NOT EXISTS %s (id text, address text, telephone int, yearofbirth int, \"SOME escaped col\" bigint, PRIMARY KEY (id))");
alterTable("ALTER TABLE %s drop (address, telephone, \"SOME escaped col\");");
assertColumnNames(execute("SELECT * FROM %s"), "id", "yearofbirth");
}
/*
* Should throw SyntaxException if multiple columns are dropped using wrong syntax.
*/
@Test(expected = SyntaxException.class)
public void testAlterDeletionColumnWithoutBraces() throws Throwable
{
execute("ALTER TABLE %s.users drop name,address;");
}
@Test(expected = InvalidRequestException.class)
public void testAlterAddDuplicateColumn() throws Throwable
{
createTable("CREATE TABLE IF NOT EXISTS %s (id text, address text, telephone int, yearofbirth int, PRIMARY KEY (id))");
execute("ALTER TABLE %s add (salary int, salary int);");
}
@Test(expected = InvalidRequestException.class)
public void testAlterDropDuplicateColumn() throws Throwable
{
createTable("CREATE TABLE IF NOT EXISTS %s (id text, address text, telephone int, yearofbirth int, PRIMARY KEY (id))");
execute("ALTER TABLE %s drop (address, address);");
}
@Test
public void testAlterToBlob() throws Throwable
{
// This tests for the bug from #11820 in particular
createTable("CREATE TABLE %s (a int PRIMARY KEY, b int)");
execute("INSERT INTO %s (a, b) VALUES (1, 1)");
executeNet(ProtocolVersion.CURRENT, "ALTER TABLE %s ALTER b TYPE BLOB");
assertRowsNet(ProtocolVersion.CURRENT, executeNet(ProtocolVersion.CURRENT, "SELECT * FROM %s WHERE a = 1"),
row(1, ByteBufferUtil.bytes(1))
);
}
}

View File

@ -33,38 +33,6 @@ 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
{