You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by ee...@apache.org on 2011/03/28 21:08:35 UTC
svn commit: r1086345 - in /cassandra/trunk: interface/
interface/thrift/gen-java/org/apache/cassandra/thrift/ src/avro/
src/java/org/apache/cassandra/config/ src/java/org/apache/cassandra/cql/
src/java/org/apache/cassandra/thrift/
Author: eevans
Date: Mon Mar 28 19:08:34 2011
New Revision: 1086345
URL: http://svn.apache.org/viewvc?rev=1086345&view=rev
Log:
type validated row keys
Patch by Jon Hermes (w/ minor changes); reviewed by eevans for CASSANDRA-2311
Modified:
cassandra/trunk/interface/cassandra.thrift
cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/CfDef.java
cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/Constants.java
cassandra/trunk/src/avro/internode.genavro
cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java
cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java
cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java
cassandra/trunk/src/java/org/apache/cassandra/thrift/ThriftValidation.java
Modified: cassandra/trunk/interface/cassandra.thrift
URL: http://svn.apache.org/viewvc/cassandra/trunk/interface/cassandra.thrift?rev=1086345&r1=1086344&r2=1086345&view=diff
==============================================================================
--- cassandra/trunk/interface/cassandra.thrift (original)
+++ cassandra/trunk/interface/cassandra.thrift Mon Mar 28 19:08:34 2011
@@ -46,7 +46,7 @@ namespace rb CassandraThrift
# for every edit that doesn't result in a change to major/minor.
#
# See the Semantic Versioning Specification (SemVer) http://semver.org.
-const string VERSION = "19.4.0"
+const string VERSION = "19.5.0"
#
@@ -402,6 +402,7 @@ struct CfDef {
23: optional double memtable_operations_in_millions,
24: optional bool replicate_on_write=0,
25: optional double merge_shards_chance,
+ 26: optional string key_validation_class,
}
/* describes a keyspace. */
Modified: cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/CfDef.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/CfDef.java?rev=1086345&r1=1086344&r2=1086345&view=diff
==============================================================================
--- cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/CfDef.java (original)
+++ cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/CfDef.java Mon Mar 28 19:08:34 2011
@@ -73,6 +73,7 @@ public class CfDef implements TBase<CfDe
private static final TField MEMTABLE_OPERATIONS_IN_MILLIONS_FIELD_DESC = new TField("memtable_operations_in_millions", TType.DOUBLE, (short)23);
private static final TField REPLICATE_ON_WRITE_FIELD_DESC = new TField("replicate_on_write", TType.BOOL, (short)24);
private static final TField MERGE_SHARDS_CHANCE_FIELD_DESC = new TField("merge_shards_chance", TType.DOUBLE, (short)25);
+ private static final TField KEY_VALIDATION_CLASS_FIELD_DESC = new TField("key_validation_class", TType.STRING, (short)26);
public String keyspace;
public String name;
@@ -96,6 +97,7 @@ public class CfDef implements TBase<CfDe
public double memtable_operations_in_millions;
public boolean replicate_on_write;
public double merge_shards_chance;
+ public String key_validation_class;
/** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
public enum _Fields implements TFieldIdEnum {
@@ -120,7 +122,8 @@ public class CfDef implements TBase<CfDe
MEMTABLE_THROUGHPUT_IN_MB((short)22, "memtable_throughput_in_mb"),
MEMTABLE_OPERATIONS_IN_MILLIONS((short)23, "memtable_operations_in_millions"),
REPLICATE_ON_WRITE((short)24, "replicate_on_write"),
- MERGE_SHARDS_CHANCE((short)25, "merge_shards_chance");
+ MERGE_SHARDS_CHANCE((short)25, "merge_shards_chance"),
+ KEY_VALIDATION_CLASS((short)26, "key_validation_class");
private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
@@ -179,6 +182,8 @@ public class CfDef implements TBase<CfDe
return REPLICATE_ON_WRITE;
case 25: // MERGE_SHARDS_CHANCE
return MERGE_SHARDS_CHANCE;
+ case 26: // KEY_VALIDATION_CLASS
+ return KEY_VALIDATION_CLASS;
default:
return null;
}
@@ -283,6 +288,8 @@ public class CfDef implements TBase<CfDe
new FieldValueMetaData(TType.BOOL)));
tmpMap.put(_Fields.MERGE_SHARDS_CHANCE, new FieldMetaData("merge_shards_chance", TFieldRequirementType.OPTIONAL,
new FieldValueMetaData(TType.DOUBLE)));
+ tmpMap.put(_Fields.KEY_VALIDATION_CLASS, new FieldMetaData("key_validation_class", TFieldRequirementType.OPTIONAL,
+ new FieldValueMetaData(TType.STRING)));
metaDataMap = Collections.unmodifiableMap(tmpMap);
FieldMetaData.addStructMetaDataMap(CfDef.class, metaDataMap);
}
@@ -359,6 +366,9 @@ public class CfDef implements TBase<CfDe
this.memtable_operations_in_millions = other.memtable_operations_in_millions;
this.replicate_on_write = other.replicate_on_write;
this.merge_shards_chance = other.merge_shards_chance;
+ if (other.isSetKey_validation_class()) {
+ this.key_validation_class = other.key_validation_class;
+ }
}
public CfDef deepCopy() {
@@ -405,6 +415,7 @@ public class CfDef implements TBase<CfDe
setMerge_shards_chanceIsSet(false);
this.merge_shards_chance = 0.0;
+ this.key_validation_class = null;
}
public String getKeyspace() {
@@ -936,6 +947,30 @@ public class CfDef implements TBase<CfDe
__isset_bit_vector.set(__MERGE_SHARDS_CHANCE_ISSET_ID, value);
}
+ public String getKey_validation_class() {
+ return this.key_validation_class;
+ }
+
+ public CfDef setKey_validation_class(String key_validation_class) {
+ this.key_validation_class = key_validation_class;
+ return this;
+ }
+
+ public void unsetKey_validation_class() {
+ this.key_validation_class = null;
+ }
+
+ /** Returns true if field key_validation_class is set (has been asigned a value) and false otherwise */
+ public boolean isSetKey_validation_class() {
+ return this.key_validation_class != null;
+ }
+
+ public void setKey_validation_classIsSet(boolean value) {
+ if (!value) {
+ this.key_validation_class = null;
+ }
+ }
+
public void setFieldValue(_Fields field, Object value) {
switch (field) {
case KEYSPACE:
@@ -1114,6 +1149,14 @@ public class CfDef implements TBase<CfDe
}
break;
+ case KEY_VALIDATION_CLASS:
+ if (value == null) {
+ unsetKey_validation_class();
+ } else {
+ setKey_validation_class((String)value);
+ }
+ break;
+
}
}
@@ -1185,6 +1228,9 @@ public class CfDef implements TBase<CfDe
case MERGE_SHARDS_CHANCE:
return new Double(getMerge_shards_chance());
+ case KEY_VALIDATION_CLASS:
+ return getKey_validation_class();
+
}
throw new IllegalStateException();
}
@@ -1240,6 +1286,8 @@ public class CfDef implements TBase<CfDe
return isSetReplicate_on_write();
case MERGE_SHARDS_CHANCE:
return isSetMerge_shards_chance();
+ case KEY_VALIDATION_CLASS:
+ return isSetKey_validation_class();
}
throw new IllegalStateException();
}
@@ -1455,6 +1503,15 @@ public class CfDef implements TBase<CfDe
return false;
}
+ boolean this_present_key_validation_class = true && this.isSetKey_validation_class();
+ boolean that_present_key_validation_class = true && that.isSetKey_validation_class();
+ if (this_present_key_validation_class || that_present_key_validation_class) {
+ if (!(this_present_key_validation_class && that_present_key_validation_class))
+ return false;
+ if (!this.key_validation_class.equals(that.key_validation_class))
+ return false;
+ }
+
return true;
}
@@ -1572,6 +1629,11 @@ public class CfDef implements TBase<CfDe
if (present_merge_shards_chance)
builder.append(merge_shards_chance);
+ boolean present_key_validation_class = true && (isSetKey_validation_class());
+ builder.append(present_key_validation_class);
+ if (present_key_validation_class)
+ builder.append(key_validation_class);
+
return builder.toHashCode();
}
@@ -1803,6 +1865,16 @@ public class CfDef implements TBase<CfDe
return lastComparison;
}
}
+ lastComparison = Boolean.valueOf(isSetKey_validation_class()).compareTo(typedOther.isSetKey_validation_class());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetKey_validation_class()) {
+ lastComparison = TBaseHelper.compareTo(this.key_validation_class, typedOther.key_validation_class);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
return 0;
}
@@ -1999,6 +2071,13 @@ public class CfDef implements TBase<CfDe
TProtocolUtil.skip(iprot, field.type);
}
break;
+ case 26: // KEY_VALIDATION_CLASS
+ if (field.type == TType.STRING) {
+ this.key_validation_class = iprot.readString();
+ } else {
+ TProtocolUtil.skip(iprot, field.type);
+ }
+ break;
default:
TProtocolUtil.skip(iprot, field.type);
}
@@ -2143,6 +2222,13 @@ public class CfDef implements TBase<CfDe
oprot.writeDouble(this.merge_shards_chance);
oprot.writeFieldEnd();
}
+ if (this.key_validation_class != null) {
+ if (isSetKey_validation_class()) {
+ oprot.writeFieldBegin(KEY_VALIDATION_CLASS_FIELD_DESC);
+ oprot.writeString(this.key_validation_class);
+ oprot.writeFieldEnd();
+ }
+ }
oprot.writeFieldStop();
oprot.writeStructEnd();
}
@@ -2311,6 +2397,16 @@ public class CfDef implements TBase<CfDe
sb.append(this.merge_shards_chance);
first = false;
}
+ if (isSetKey_validation_class()) {
+ if (!first) sb.append(", ");
+ sb.append("key_validation_class:");
+ if (this.key_validation_class == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.key_validation_class);
+ }
+ first = false;
+ }
sb.append(")");
return sb.toString();
}
Modified: cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/Constants.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/Constants.java?rev=1086345&r1=1086344&r2=1086345&view=diff
==============================================================================
--- cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/Constants.java (original)
+++ cassandra/trunk/interface/thrift/gen-java/org/apache/cassandra/thrift/Constants.java Mon Mar 28 19:08:34 2011
@@ -44,6 +44,6 @@ import org.slf4j.LoggerFactory;
public class Constants {
- public static final String VERSION = "19.4.0";
+ public static final String VERSION = "19.5.0";
}
Modified: cassandra/trunk/src/avro/internode.genavro
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/avro/internode.genavro?rev=1086345&r1=1086344&r2=1086345&view=diff
==============================================================================
--- cassandra/trunk/src/avro/internode.genavro (original)
+++ cassandra/trunk/src/avro/internode.genavro Mon Mar 28 19:08:34 2011
@@ -52,6 +52,7 @@ protocol InterNode {
boolean replicate_on_write = false;
union { int, null } gc_grace_seconds;
union { null, string } default_validation_class = null;
+ union { null, string } key_validation_class = null;
union { null, int } min_compaction_threshold = null;
union { null, int } max_compaction_threshold = null;
union { int, null } row_cache_save_period_in_seconds = 0;
Modified: cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java?rev=1086345&r1=1086344&r2=1086345&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java Mon Mar 28 19:08:34 2011
@@ -140,6 +140,7 @@ public final class CFMetaData
private boolean replicateOnWrite; // default false
private int gcGraceSeconds; // default 864000 (ten days)
private AbstractType defaultValidator; // default BytesType (no-op), use comparator types
+ private AbstractType keyValidator; // default BytesType (no-op), use comparator types
private int minCompactionThreshold; // default 4
private int maxCompactionThreshold; // default 32
private int rowCacheSavePeriodInSeconds; // default 0 (off)
@@ -159,6 +160,7 @@ public final class CFMetaData
public CFMetaData replicateOnWrite(boolean prop) {replicateOnWrite = prop; return this;}
public CFMetaData gcGraceSeconds(int prop) {gcGraceSeconds = prop; return this;}
public CFMetaData defaultValidator(AbstractType prop) {defaultValidator = prop; return this;}
+ public CFMetaData keyValidator(AbstractType prop) {keyValidator = prop; return this;}
public CFMetaData minCompactionThreshold(int prop) {minCompactionThreshold = prop; return this;}
public CFMetaData maxCompactionThreshold(int prop) {maxCompactionThreshold = prop; return this;}
public CFMetaData rowCacheSavePeriod(int prop) {rowCacheSavePeriodInSeconds = prop; return this;}
@@ -217,6 +219,7 @@ public final class CFMetaData
// Defaults strange or simple enough to not need a DEFAULT_T for
defaultValidator = BytesType.instance;
+ keyValidator = BytesType.instance;
comment = "";
column_metadata = new HashMap<ByteBuffer,ColumnDefinition>();
}
@@ -308,6 +311,7 @@ public final class CFMetaData
cf.replicate_on_write = replicateOnWrite;
cf.gc_grace_seconds = gcGraceSeconds;
cf.default_validation_class = new Utf8(defaultValidator.getClass().getName());
+ cf.key_validation_class = new Utf8(keyValidator.getClass().getName());
cf.min_compaction_threshold = minCompactionThreshold;
cf.max_compaction_threshold = maxCompactionThreshold;
cf.row_cache_save_period_in_seconds = rowCacheSavePeriodInSeconds;
@@ -328,14 +332,15 @@ public final class CFMetaData
AbstractType comparator;
AbstractType subcolumnComparator = null;
AbstractType validator;
+ AbstractType keyValidator;
+
try
{
comparator = DatabaseDescriptor.getComparator(cf.comparator_type.toString());
if (cf.subcomparator_type != null)
subcolumnComparator = DatabaseDescriptor.getComparator(cf.subcomparator_type.toString());
- validator = cf.default_validation_class == null
- ? BytesType.instance
- : DatabaseDescriptor.getComparator(cf.default_validation_class.toString());
+ validator = DatabaseDescriptor.getComparator(cf.default_validation_class.toString());
+ keyValidator = DatabaseDescriptor.getComparator(cf.key_validation_class.toString());
}
catch (Exception ex)
{
@@ -375,6 +380,7 @@ public final class CFMetaData
.replicateOnWrite(cf.replicate_on_write)
.gcGraceSeconds(cf.gc_grace_seconds)
.defaultValidator(validator)
+ .keyValidator(keyValidator)
.columnMetadata(column_metadata);
}
@@ -418,6 +424,11 @@ public final class CFMetaData
return defaultValidator;
}
+ public AbstractType getKeyValidator()
+ {
+ return keyValidator;
+ }
+
public Integer getMinCompactionThreshold()
{
return minCompactionThreshold;
@@ -482,6 +493,8 @@ public final class CFMetaData
.append(readRepairChance, rhs.readRepairChance)
.append(replicateOnWrite, rhs.replicateOnWrite)
.append(gcGraceSeconds, rhs.gcGraceSeconds)
+ .append(defaultValidator, rhs.defaultValidator)
+ .append(keyValidator, rhs.keyValidator)
.append(minCompactionThreshold, rhs.minCompactionThreshold)
.append(maxCompactionThreshold, rhs.maxCompactionThreshold)
.append(cfId.intValue(), rhs.cfId.intValue())
@@ -510,6 +523,7 @@ public final class CFMetaData
.append(replicateOnWrite)
.append(gcGraceSeconds)
.append(defaultValidator)
+ .append(keyValidator)
.append(minCompactionThreshold)
.append(maxCompactionThreshold)
.append(cfId)
@@ -593,6 +607,7 @@ public final class CFMetaData
replicateOnWrite = cf_def.replicate_on_write;
gcGraceSeconds = cf_def.gc_grace_seconds;
defaultValidator = DatabaseDescriptor.getComparator(cf_def.default_validation_class);
+ keyValidator = DatabaseDescriptor.getComparator(cf_def.key_validation_class);
minCompactionThreshold = cf_def.min_compaction_threshold;
maxCompactionThreshold = cf_def.max_compaction_threshold;
rowCacheSavePeriodInSeconds = cf_def.row_cache_save_period_in_seconds;
@@ -658,6 +673,7 @@ public final class CFMetaData
def.setReplicate_on_write(cfm.replicateOnWrite);
def.setGc_grace_seconds(cfm.gcGraceSeconds);
def.setDefault_validation_class(cfm.defaultValidator.getClass().getName());
+ def.setKey_validation_class(cfm.keyValidator.getClass().getName());
def.setMin_compaction_threshold(cfm.minCompactionThreshold);
def.setMax_compaction_threshold(cfm.maxCompactionThreshold);
def.setRow_cache_save_period_in_seconds(cfm.rowCacheSavePeriodInSeconds);
@@ -732,6 +748,7 @@ public final class CFMetaData
newDef.comment = def.getComment();
newDef.comparator_type = def.getComparator_type();
newDef.default_validation_class = def.getDefault_validation_class();
+ newDef.key_validation_class = def.getKey_validation_class();
newDef.gc_grace_seconds = def.getGc_grace_seconds();
newDef.id = def.getId();
newDef.key_cache_save_period_in_seconds = def.getKey_cache_save_period_in_seconds();
@@ -862,6 +879,7 @@ public final class CFMetaData
.append("replicateOnWrite", replicateOnWrite)
.append("gcGraceSeconds", gcGraceSeconds)
.append("defaultValidator", defaultValidator)
+ .append("keyValidator", keyValidator)
.append("minCompactionThreshold", minCompactionThreshold)
.append("maxCompactionThreshold", maxCompactionThreshold)
.append("rowCacheSavePeriodInSeconds", rowCacheSavePeriodInSeconds)
Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java?rev=1086345&r1=1086344&r2=1086345&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java Mon Mar 28 19:08:34 2011
@@ -69,6 +69,7 @@ import com.google.common.collect.Maps;
import static org.apache.cassandra.thrift.ThriftValidation.validateKey;
import static org.apache.cassandra.thrift.ThriftValidation.validateColumnFamily;
+import static org.apache.cassandra.thrift.ThriftValidation.validateKeyType;
public class QueryProcessor
{
@@ -224,6 +225,7 @@ public class QueryProcessor
for (UpdateStatement update : updateStatements)
{
+ String cfname = update.getColumnFamily();
// Avoid unnecessary authorizations.
if (!(cfamsSeen.contains(update.getColumnFamily())))
{
@@ -234,7 +236,8 @@ public class QueryProcessor
// FIXME: keys as ascii is not a Real Solution
ByteBuffer key = update.getKey().getByteBuffer(AsciiType.instance);
validateKey(key);
- validateColumnFamily(keyspace, update.getColumnFamily());
+ validateColumnFamily(keyspace, cfname);
+ validateKeyType(key, keyspace, cfname);
AbstractType<?> comparator = update.getComparator(keyspace);
RowMutation rm = new RowMutation(keyspace, key);
Modified: cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java?rev=1086345&r1=1086344&r2=1086345&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java Mon Mar 28 19:08:34 2011
@@ -349,6 +349,7 @@ public class CassandraServer implements
ThriftValidation.validateKey(key);
ThriftValidation.validateColumnParent(state().getKeyspace(), column_parent);
+ ThriftValidation.validateKeyType(key, state().getKeyspace(), column_parent.column_family);
ThriftValidation.validateColumnNames(state().getKeyspace(), column_parent, Arrays.asList(column.name));
ThriftValidation.validateColumnData(state().getKeyspace(), column_parent.column_family, column);
@@ -387,7 +388,8 @@ public class CassandraServer implements
for (Map.Entry<String, List<Mutation>> columnFamilyMutations : columnFamilyToMutations.entrySet())
{
String cfName = columnFamilyMutations.getKey();
-
+ ThriftValidation.validateKeyType(key, state().getKeyspace(), cfName);
+
// Avoid unneeded authorizations
if (!(cfamsSeen.contains(cfName)))
{
@@ -423,6 +425,7 @@ public class CassandraServer implements
ThriftValidation.validateKey(key);
ThriftValidation.validateColumnPathOrParent(state().getKeyspace(), column_path);
+ ThriftValidation.validateKeyType(key, state().getKeyspace(), column_path.column_family);
RowMutation rm = new RowMutation(state().getKeyspace(), key);
rm.delete(new QueryPath(column_path), timestamp);
Modified: cassandra/trunk/src/java/org/apache/cassandra/thrift/ThriftValidation.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/thrift/ThriftValidation.java?rev=1086345&r1=1086344&r2=1086345&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/thrift/ThriftValidation.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/thrift/ThriftValidation.java Mon Mar 28 19:08:34 2011
@@ -23,9 +23,6 @@ package org.apache.cassandra.thrift;
import java.nio.ByteBuffer;
import java.util.*;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.config.ConfigurationException;
import org.apache.cassandra.config.DatabaseDescriptor;
@@ -50,8 +47,6 @@ import org.apache.cassandra.utils.FBUtil
*/
public class ThriftValidation
{
- private static final Logger logger = LoggerFactory.getLogger(ThriftValidation.class);
-
public static void validateKey(ByteBuffer key) throws InvalidRequestException
{
if (key == null || key.remaining() == 0)
@@ -66,6 +61,19 @@ public class ThriftValidation
}
}
+ public static void validateKeyType(ByteBuffer key, String ksname, String cfname) throws InvalidRequestException
+ {
+ try
+ {
+ AbstractType<?> keyValidator = DatabaseDescriptor.getCFMetaData(ksname, cfname).getKeyValidator();
+ keyValidator.validate(key);
+ }
+ catch (MarshalException e)
+ {
+ throw new InvalidRequestException(e.toString());
+ }
+ }
+
public static void validateTable(String tablename) throws KeyspaceNotDefinedException
{
if (!DatabaseDescriptor.getTables().contains(tablename))