Author: xedin
Date: Tue Aug 30 16:54:23 2011
New Revision: 1163289
URL: http://svn.apache.org/viewvc?rev=1163289&view=rev
Log:
Add validation that Keyspace names are case-insensitively unique
patch by Jonathan Ellis; reviewed by Pavel Yaskevich for CASSANDRA-3066
Modified:
cassandra/branches/cassandra-0.8/CHANGES.txt
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/QueryProcessor.java
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/service/ClientState.java
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/CassandraServer.java
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java
Modified: cassandra/branches/cassandra-0.8/CHANGES.txt
URL:
http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/CHANGES.txt?rev=1163289&r1=1163288&r2=1163289&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.8/CHANGES.txt (original)
+++ cassandra/branches/cassandra-0.8/CHANGES.txt Tue Aug 30 16:54:23 2011
@@ -43,7 +43,7 @@
* fix ip address String representation in the ring cache (CASSANDRA-3044)
* fix ring cache compatibility when mixing pre-0.8.4 nodes with post-
in the same cluster (CASSANDRA-3023)
-
+ * Add validation that Keyspace names are case-insensitively unique
(CASSANDRA-3066)
0.8.4
* include files-to-be-streamed in StreamInSession.getSources (CASSANDRA-2972)
Modified:
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/QueryProcessor.java
URL:
http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/QueryProcessor.java?rev=1163289&r1=1163288&r2=1163289&view=diff
==============================================================================
---
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/QueryProcessor.java
(original)
+++
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/cql/QueryProcessor.java
Tue Aug 30 16:54:23 2011
@@ -662,7 +662,7 @@ public class QueryProcessor
case CREATE_KEYSPACE:
CreateKeyspaceStatement create =
(CreateKeyspaceStatement)statement.statement;
create.validate();
- clientState.hasKeyspaceListAccess(Permission.WRITE);
+ clientState.hasKeyspaceSchemaAccess(Permission.WRITE);
validateSchemaAgreement();
try
@@ -672,6 +672,7 @@ public class QueryProcessor
Collections.<CfDef>emptyList())
.setStrategy_options(create.getStrategyOptions());
ThriftValidation.validateKsDef(ksd);
+
ThriftValidation.validateKeyspaceNotYetExisting(create.getName());
applyMigrationOnStage(new
AddKeyspace(KSMetaData.fromThrift(ksd)));
}
catch (ConfigurationException e)
@@ -692,7 +693,7 @@ public class QueryProcessor
case CREATE_COLUMNFAMILY:
CreateColumnFamilyStatement createCf =
(CreateColumnFamilyStatement)statement.statement;
- clientState.hasColumnFamilyListAccess(Permission.WRITE);
+ clientState.hasColumnFamilySchemaAccess(Permission.WRITE);
validateSchemaAgreement();
try
@@ -717,7 +718,7 @@ public class QueryProcessor
case CREATE_INDEX:
CreateIndexStatement createIdx =
(CreateIndexStatement)statement.statement;
- clientState.hasColumnFamilyListAccess(Permission.WRITE);
+ clientState.hasColumnFamilySchemaAccess(Permission.WRITE);
validateSchemaAgreement();
CFMetaData oldCfm =
DatabaseDescriptor.getCFMetaData(CFMetaData.getId(keyspace,
createIdx.getColumnFamily()));
@@ -769,7 +770,7 @@ public class QueryProcessor
case DROP_INDEX:
DropIndexStatement dropIdx =
(DropIndexStatement)statement.statement;
- clientState.hasColumnFamilyListAccess(Permission.WRITE);
+ clientState.hasColumnFamilySchemaAccess(Permission.WRITE);
validateSchemaAgreement();
try
@@ -794,7 +795,7 @@ public class QueryProcessor
case DROP_KEYSPACE:
String deleteKeyspace = (String)statement.statement;
- clientState.hasKeyspaceListAccess(Permission.WRITE);
+ clientState.hasKeyspaceSchemaAccess(Permission.WRITE);
validateSchemaAgreement();
try
@@ -819,7 +820,7 @@ public class QueryProcessor
case DROP_COLUMNFAMILY:
String deleteColumnFamily = (String)statement.statement;
- clientState.hasColumnFamilyListAccess(Permission.WRITE);
+ clientState.hasColumnFamilySchemaAccess(Permission.WRITE);
validateSchemaAgreement();
try
Modified:
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/service/ClientState.java
URL:
http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/service/ClientState.java?rev=1163289&r1=1163288&r2=1163289&view=diff
==============================================================================
---
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/service/ClientState.java
(original)
+++
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/service/ClientState.java
Tue Aug 30 16:54:23 2011
@@ -30,6 +30,7 @@ import org.apache.cassandra.auth.Authent
import org.apache.cassandra.auth.Permission;
import org.apache.cassandra.auth.Resources;
import org.apache.cassandra.config.DatabaseDescriptor;
+import org.apache.cassandra.db.Table;
import org.apache.cassandra.thrift.AuthenticationException;
import org.apache.cassandra.thrift.InvalidRequestException;
@@ -111,7 +112,7 @@ public class ClientState
/**
* Confirms that the client thread has the given Permission for the
Keyspace list.
*/
- public void hasKeyspaceListAccess(Permission perm) throws
InvalidRequestException
+ public void hasKeyspaceSchemaAccess(Permission perm) throws
InvalidRequestException
{
validateLogin();
@@ -125,13 +126,13 @@ public class ClientState
* Confirms that the client thread has the given Permission for the
ColumnFamily list of
* the current keyspace.
*/
- public void hasColumnFamilyListAccess(Permission perm) throws
InvalidRequestException
+ public void hasColumnFamilySchemaAccess(Permission perm) throws
InvalidRequestException
{
validateLogin();
validateKeyspace();
// hardcode disallowing messing with system keyspace
- if (keyspace.equalsIgnoreCase("system"))
+ if (keyspace.equalsIgnoreCase(Table.SYSTEM_TABLE) && perm ==
Permission.WRITE)
throw new InvalidRequestException("system keyspace is not
user-modifiable");
resourceClear();
Modified:
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/CassandraServer.java
URL:
http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/CassandraServer.java?rev=1163289&r1=1163288&r2=1163289&view=diff
==============================================================================
---
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/CassandraServer.java
(original)
+++
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/CassandraServer.java
Tue Aug 30 16:54:23 2011
@@ -589,7 +589,7 @@ public class CassandraServer implements
public KsDef describe_keyspace(String table) throws NotFoundException,
InvalidRequestException
{
- state().hasKeyspaceListAccess(Permission.READ);
+ state().hasKeyspaceSchemaAccess(Permission.READ);
KSMetaData ksm = DatabaseDescriptor.getTableDefinition(table);
if (ksm == null)
@@ -694,7 +694,7 @@ public class CassandraServer implements
public List<KsDef> describe_keyspaces() throws TException,
InvalidRequestException
{
- state().hasKeyspaceListAccess(Permission.READ);
+ state().hasKeyspaceSchemaAccess(Permission.READ);
Set<String> keyspaces = DatabaseDescriptor.getTables();
List<KsDef> ksset = new ArrayList<KsDef>();
@@ -815,7 +815,7 @@ public class CassandraServer implements
throws InvalidRequestException, SchemaDisagreementException, TException
{
logger.debug("add_column_family");
- state().hasColumnFamilyListAccess(Permission.WRITE);
+ state().hasColumnFamilySchemaAccess(Permission.WRITE);
CFMetaData.addDefaultIndexNames(cf_def);
ThriftValidation.validateCfDef(cf_def, null);
validateSchemaAgreement();
@@ -843,7 +843,7 @@ public class CassandraServer implements
throws InvalidRequestException, SchemaDisagreementException, TException
{
logger.debug("drop_column_family");
- state().hasColumnFamilyListAccess(Permission.WRITE);
+ state().hasColumnFamilySchemaAccess(Permission.WRITE);
validateSchemaAgreement();
try
@@ -869,9 +869,10 @@ public class CassandraServer implements
throws InvalidRequestException, SchemaDisagreementException, TException
{
logger.debug("add_keyspace");
- state().hasKeyspaceListAccess(Permission.WRITE);
+ state().hasKeyspaceSchemaAccess(Permission.WRITE);
validateSchemaAgreement();
-
+ ThriftValidation.validateKeyspaceNotYetExisting(ks_def.name);
+
// generate a meaningful error if the user setup keyspace and/or
column definition incorrectly
for (CfDef cf : ks_def.cf_defs)
{
@@ -913,7 +914,7 @@ public class CassandraServer implements
throws InvalidRequestException, SchemaDisagreementException, TException
{
logger.debug("drop_keyspace");
- state().hasKeyspaceListAccess(Permission.WRITE);
+ state().hasKeyspaceSchemaAccess(Permission.WRITE);
validateSchemaAgreement();
try
@@ -941,7 +942,7 @@ public class CassandraServer implements
throws InvalidRequestException, SchemaDisagreementException, TException
{
logger.debug("update_keyspace");
- state().hasKeyspaceListAccess(Permission.WRITE);
+ state().hasKeyspaceSchemaAccess(Permission.WRITE);
ThriftValidation.validateTable(ks_def.name);
if (ks_def.getCf_defs() != null && ks_def.getCf_defs().size() > 0)
throw new InvalidRequestException("Keyspace update must not
contain any column family definitions.");
@@ -971,7 +972,7 @@ public class CassandraServer implements
throws InvalidRequestException, SchemaDisagreementException, TException
{
logger.debug("update_column_family");
- state().hasColumnFamilyListAccess(Permission.WRITE);
+ state().hasColumnFamilySchemaAccess(Permission.WRITE);
if (cf_def.keyspace == null || cf_def.name == null)
throw new InvalidRequestException("Keyspace and CF name must be
set.");
CFMetaData oldCfm =
DatabaseDescriptor.getCFMetaData(CFMetaData.getId(cf_def.keyspace,
cf_def.name));
Modified:
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java
URL:
http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java?rev=1163289&r1=1163288&r2=1163289&view=diff
==============================================================================
---
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java
(original)
+++
cassandra/branches/cassandra-0.8/src/java/org/apache/cassandra/thrift/ThriftValidation.java
Tue Aug 30 16:54:23 2011
@@ -713,4 +713,16 @@ public class ThriftValidation
if (cf_def.isSetMemtable_operations_in_millions())
DatabaseDescriptor.validateMemtableOperations(cf_def.memtable_operations_in_millions);
}
+
+ public static void validateKeyspaceNotYetExisting(String newKsName) throws
InvalidRequestException
+ {
+ // keyspace names must be unique case-insensitively because the
keyspace name becomes the directory
+ // where we store CF sstables. Names that differ only in case would
thus cause problems on
+ // case-insensitive filesystems (NTFS, most installations of HFS+).
+ for (String ksName : DatabaseDescriptor.getTables())
+ {
+ if (ksName.equalsIgnoreCase(newKsName))
+ throw new InvalidRequestException("Keyspace names must be
case-insensitively unique");
+ }
+ }
}