Author: jbellis Date: Wed Aug 25 20:25:49 2010 New Revision: 989344 URL: http://svn.apache.org/viewvc?rev=989344&view=rev Log: Add CfDef.default_validation_class. patch by jhermes; reviewed by jbellis for CASSANDRA-891
Modified: cassandra/trunk/CHANGES.txt cassandra/trunk/conf/cassandra.yaml cassandra/trunk/interface/cassandra.genavro 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/avro/CassandraServer.java cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java cassandra/trunk/src/java/org/apache/cassandra/config/RawColumnFamily.java cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java cassandra/trunk/test/system/test_thrift_server.py cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java Modified: cassandra/trunk/CHANGES.txt URL: http://svn.apache.org/viewvc/cassandra/trunk/CHANGES.txt?rev=989344&r1=989343&r2=989344&view=diff ============================================================================== --- cassandra/trunk/CHANGES.txt (original) +++ cassandra/trunk/CHANGES.txt Wed Aug 25 20:25:49 2010 @@ -34,6 +34,7 @@ dev * added CMSInitiatingOccupancyFraction=80 to default GC options * fix using DynamicEndpointSnitch with NetworkTopologyStrategy (CASSANDRA-1429) + * Add CfDef.default_validation_class (CASSANDRA-891) 0.7-beta1 Modified: cassandra/trunk/conf/cassandra.yaml URL: http://svn.apache.org/viewvc/cassandra/trunk/conf/cassandra.yaml?rev=989344&r1=989343&r2=989344&view=diff ============================================================================== --- cassandra/trunk/conf/cassandra.yaml (original) +++ cassandra/trunk/conf/cassandra.yaml Wed Aug 25 20:25:49 2010 @@ -297,6 +297,7 @@ keyspaces: comment: 'A column family with supercolumns, whose column names are Longs (8 bytes)' - name: Indexed1 + default_validation_class: LongType column_metadata: - name: birthdate validator_class: LongType Modified: cassandra/trunk/interface/cassandra.genavro URL: http://svn.apache.org/viewvc/cassandra/trunk/interface/cassandra.genavro?rev=989344&r1=989343&r2=989344&view=diff ============================================================================== --- cassandra/trunk/interface/cassandra.genavro (original) +++ cassandra/trunk/interface/cassandra.genavro Wed Aug 25 20:25:49 2010 @@ -82,13 +82,13 @@ protocol Cassandra { union { Deletion, null } deletion; } - /* NB: Until AVRO-495: must be kept sync'd with private fields. */ + /* NB: Until AVRO-495: must be kept sync'd with src/avro/internode.genavro. */ enum IndexType { KEYS } /* describes a column in a column family. */ - /* NB: Until AVRO-495: must be kept sync'd with private fields. */ + /* NB: Until AVRO-495: must be kept sync'd with src/avro/internode.genavro. */ record ColumnDef { bytes name; string validation_class; @@ -100,7 +100,7 @@ protocol Cassandra { * describes a keyspace: * NB: the id field is ignored during column family creation: the server will choose an appropriate value. */ - /* NB: Until AVRO-495: must be kept sync'd with private fields. */ + /* NB: Until AVRO-495: must be kept sync'd with src/avro/internode.genavro. */ record CfDef { string keyspace; string name; @@ -115,12 +115,13 @@ protocol Cassandra { union { double, null } key_cache_size; union { double, null } read_repair_chance; union { int, null } gc_grace_seconds; - union { array<ColumnDef>, null } column_metadata; + union { string, null } default_validation_class; union { int, null } id; + union { array<ColumnDef>, null } column_metadata; } /* describes a keyspace. */ - /* NB: Until AVRO-495: must be kept sync'd with private fields. */ + /* NB: Until AVRO-495: must be kept sync'd with src/avro/internode.genavro. */ record KsDef { string name; string strategy_class; Modified: cassandra/trunk/interface/cassandra.thrift URL: http://svn.apache.org/viewvc/cassandra/trunk/interface/cassandra.thrift?rev=989344&r1=989343&r2=989344&view=diff ============================================================================== --- cassandra/trunk/interface/cassandra.thrift (original) +++ cassandra/trunk/interface/cassandra.thrift Wed Aug 25 20:25:49 2010 @@ -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 = "12.0.0" +const string VERSION = "12.1.0" # @@ -364,9 +364,10 @@ struct CfDef { 9: optional double row_cache_size=0, 10: optional bool preload_row_cache=0, 11: optional double key_cache_size=200000, - 12: optional double read_repair_chance=1.0 - 13: optional list<ColumnDef> column_metadata - 14: optional i32 gc_grace_seconds + 12: optional double read_repair_chance=1.0, + 13: optional list<ColumnDef> column_metadata, + 14: optional i32 gc_grace_seconds, + 15: optional string default_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=989344&r1=989343&r2=989344&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 Wed Aug 25 20:25:49 2010 @@ -63,6 +63,7 @@ public class CfDef implements TBase<CfDe private static final TField READ_REPAIR_CHANCE_FIELD_DESC = new TField("read_repair_chance", TType.DOUBLE, (short)12); private static final TField COLUMN_METADATA_FIELD_DESC = new TField("column_metadata", TType.LIST, (short)13); private static final TField GC_GRACE_SECONDS_FIELD_DESC = new TField("gc_grace_seconds", TType.I32, (short)14); + private static final TField DEFAULT_VALIDATION_CLASS_FIELD_DESC = new TField("default_validation_class", TType.STRING, (short)15); public String keyspace; public String name; @@ -78,6 +79,7 @@ public class CfDef implements TBase<CfDe public double read_repair_chance; public List<ColumnDef> column_metadata; public int gc_grace_seconds; + public String default_validation_class; /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ public enum _Fields implements TFieldIdEnum { @@ -94,7 +96,8 @@ public class CfDef implements TBase<CfDe KEY_CACHE_SIZE((short)11, "key_cache_size"), READ_REPAIR_CHANCE((short)12, "read_repair_chance"), COLUMN_METADATA((short)13, "column_metadata"), - GC_GRACE_SECONDS((short)14, "gc_grace_seconds"); + GC_GRACE_SECONDS((short)14, "gc_grace_seconds"), + DEFAULT_VALIDATION_CLASS((short)15, "default_validation_class"); private static final Map<String, _Fields> byName = new HashMap<String, _Fields>(); @@ -137,6 +140,8 @@ public class CfDef implements TBase<CfDe return COLUMN_METADATA; case 14: // GC_GRACE_SECONDS return GC_GRACE_SECONDS; + case 15: // DEFAULT_VALIDATION_CLASS + return DEFAULT_VALIDATION_CLASS; default: return null; } @@ -216,6 +221,8 @@ public class CfDef implements TBase<CfDe new StructMetaData(TType.STRUCT, ColumnDef.class)))); tmpMap.put(_Fields.GC_GRACE_SECONDS, new FieldMetaData("gc_grace_seconds", TFieldRequirementType.OPTIONAL, new FieldValueMetaData(TType.I32))); + tmpMap.put(_Fields.DEFAULT_VALIDATION_CLASS, new FieldMetaData("default_validation_class", TFieldRequirementType.OPTIONAL, + new FieldValueMetaData(TType.STRING))); metaDataMap = Collections.unmodifiableMap(tmpMap); FieldMetaData.addStructMetaDataMap(CfDef.class, metaDataMap); } @@ -294,6 +301,9 @@ public class CfDef implements TBase<CfDe this.column_metadata = __this__column_metadata; } this.gc_grace_seconds = other.gc_grace_seconds; + if (other.isSetDefault_validation_class()) { + this.default_validation_class = other.default_validation_class; + } } public CfDef deepCopy() { @@ -651,6 +661,30 @@ public class CfDef implements TBase<CfDe __isset_bit_vector.set(__GC_GRACE_SECONDS_ISSET_ID, value); } + public String getDefault_validation_class() { + return this.default_validation_class; + } + + public CfDef setDefault_validation_class(String default_validation_class) { + this.default_validation_class = default_validation_class; + return this; + } + + public void unsetDefault_validation_class() { + this.default_validation_class = null; + } + + /** Returns true if field default_validation_class is set (has been asigned a value) and false otherwise */ + public boolean isSetDefault_validation_class() { + return this.default_validation_class != null; + } + + public void setDefault_validation_classIsSet(boolean value) { + if (!value) { + this.default_validation_class = null; + } + } + public void setFieldValue(_Fields field, Object value) { switch (field) { case KEYSPACE: @@ -765,6 +799,14 @@ public class CfDef implements TBase<CfDe } break; + case DEFAULT_VALIDATION_CLASS: + if (value == null) { + unsetDefault_validation_class(); + } else { + setDefault_validation_class((String)value); + } + break; + } } @@ -816,6 +858,9 @@ public class CfDef implements TBase<CfDe case GC_GRACE_SECONDS: return new Integer(getGc_grace_seconds()); + case DEFAULT_VALIDATION_CLASS: + return getDefault_validation_class(); + } throw new IllegalStateException(); } @@ -855,6 +900,8 @@ public class CfDef implements TBase<CfDe return isSetColumn_metadata(); case GC_GRACE_SECONDS: return isSetGc_grace_seconds(); + case DEFAULT_VALIDATION_CLASS: + return isSetDefault_validation_class(); } throw new IllegalStateException(); } @@ -1002,6 +1049,15 @@ public class CfDef implements TBase<CfDe return false; } + boolean this_present_default_validation_class = true && this.isSetDefault_validation_class(); + boolean that_present_default_validation_class = true && that.isSetDefault_validation_class(); + if (this_present_default_validation_class || that_present_default_validation_class) { + if (!(this_present_default_validation_class && that_present_default_validation_class)) + return false; + if (!this.default_validation_class.equals(that.default_validation_class)) + return false; + } + return true; } @@ -1144,6 +1200,15 @@ public class CfDef implements TBase<CfDe return lastComparison; } } + lastComparison = Boolean.valueOf(isSetDefault_validation_class()).compareTo(typedOther.isSetDefault_validation_class()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetDefault_validation_class()) { lastComparison = TBaseHelper.compareTo(this.default_validation_class, typedOther.default_validation_class); + if (lastComparison != 0) { + return lastComparison; + } + } return 0; } @@ -1271,6 +1336,13 @@ public class CfDef implements TBase<CfDe TProtocolUtil.skip(iprot, field.type); } break; + case 15: // DEFAULT_VALIDATION_CLASS + if (field.type == TType.STRING) { + this.default_validation_class = iprot.readString(); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; default: TProtocolUtil.skip(iprot, field.type); } @@ -1377,6 +1449,13 @@ public class CfDef implements TBase<CfDe oprot.writeI32(this.gc_grace_seconds); oprot.writeFieldEnd(); } + if (this.default_validation_class != null) { + if (isSetDefault_validation_class()) { + oprot.writeFieldBegin(DEFAULT_VALIDATION_CLASS_FIELD_DESC); + oprot.writeString(this.default_validation_class); + oprot.writeFieldEnd(); + } + } oprot.writeFieldStop(); oprot.writeStructEnd(); } @@ -1501,6 +1580,16 @@ public class CfDef implements TBase<CfDe sb.append(this.gc_grace_seconds); first = false; } + if (isSetDefault_validation_class()) { + if (!first) sb.append(", "); + sb.append("default_validation_class:"); + if (this.default_validation_class == null) { + sb.append("null"); + } else { + sb.append(this.default_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=989344&r1=989343&r2=989344&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 Wed Aug 25 20:25:49 2010 @@ -42,6 +42,6 @@ import org.slf4j.LoggerFactory; public class Constants { - public static final String VERSION = "12.0.0"; + public static final String VERSION = "12.1.0"; } Modified: cassandra/trunk/src/avro/internode.genavro URL: http://svn.apache.org/viewvc/cassandra/trunk/src/avro/internode.genavro?rev=989344&r1=989343&r2=989344&view=diff ============================================================================== --- cassandra/trunk/src/avro/internode.genavro (original) +++ cassandra/trunk/src/avro/internode.genavro Wed Aug 25 20:25:49 2010 @@ -56,8 +56,9 @@ protocol InterNode { union { double, null } key_cache_size; union { double, null } read_repair_chance; union { int, null } gc_grace_seconds; - union { array<ColumnDef>, null } column_metadata; + union { string, null } default_validation_class; union { int, null } id; + union { array<ColumnDef>, null } column_metadata; } /* NB: Until AVRO-495: must be kept sync'd with KSMetaData and the public KsDef. */ Modified: cassandra/trunk/src/java/org/apache/cassandra/avro/CassandraServer.java URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/avro/CassandraServer.java?rev=989344&r1=989343&r2=989344&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/avro/CassandraServer.java (original) +++ cassandra/trunk/src/java/org/apache/cassandra/avro/CassandraServer.java Wed Aug 25 20:25:49 2010 @@ -648,10 +648,11 @@ public class CassandraServer implements Collection<CFMetaData> cfDefs = new ArrayList<CFMetaData>((int)ksDef.cf_defs.size()); for (CfDef cfDef : ksDef.cf_defs) { - String cfType, compare, subCompare, reconcilerName; + String cfType, compare, subCompare, reconcilerName, validate; cfType = cfDef.column_type == null ? D_CF_CFTYPE : cfDef.column_type.toString(); ClockType clockType = ClockType.create(cfDef.clock_type == null ? D_CF_CFCLOCKTYPE : cfDef.clock_type.toString()); compare = cfDef.comparator_type == null ? D_CF_COMPTYPE : cfDef.comparator_type.toString(); + validate = cfDef.default_validation_class == null ? D_CF_COMPTYPE : cfDef.default_validation_class.toString(); subCompare = cfDef.subcomparator_type == null ? D_CF_SUBCOMPTYPE : cfDef.subcomparator_type.toString(); reconcilerName = cfDef.reconciler == null ? D_CF_RECONCILER : cfDef.reconciler.toString(); @@ -681,6 +682,7 @@ public class CassandraServer implements cfDef.key_cache_size == null ? CFMetaData.DEFAULT_KEY_CACHE_SIZE : cfDef.key_cache_size, cfDef.read_repair_chance == null ? CFMetaData.DEFAULT_READ_REPAIR_CHANCE : cfDef.read_repair_chance, cfDef.gc_grace_seconds == null ? CFMetaData.DEFAULT_GC_GRACE_SECONDS : cfDef.gc_grace_seconds, + DatabaseDescriptor.getComparator(validate), Collections.<byte[], ColumnDefinition>emptyMap()); cfDefs.add(cfmeta); } @@ -820,6 +822,7 @@ public class CassandraServer implements String cfType = cf_def.column_type == null ? D_CF_CFTYPE : cf_def.column_type.toString(); ClockType clockType = ClockType.create(cf_def.clock_type == null ? D_CF_CFCLOCKTYPE : cf_def.clock_type.toString()); String compare = cf_def.comparator_type == null ? D_CF_COMPTYPE : cf_def.comparator_type.toString(); + String validate = cf_def.default_validation_class == null ? D_CF_COMPTYPE : cf_def.default_validation_class.toString(); String subCompare = cf_def.subcomparator_type == null ? D_CF_SUBCOMPTYPE : cf_def.subcomparator_type.toString(); String reconcilerName = cf_def.reconciler == null ? D_CF_RECONCILER : cf_def.reconciler.toString(); @@ -845,6 +848,7 @@ public class CassandraServer implements cf_def.key_cache_size == null ? CFMetaData.DEFAULT_KEY_CACHE_SIZE : cf_def.key_cache_size, cf_def.read_repair_chance == null ? CFMetaData.DEFAULT_READ_REPAIR_CHANCE : cf_def.read_repair_chance, cf_def.gc_grace_seconds != null ? cf_def.gc_grace_seconds : CFMetaData.DEFAULT_GC_GRACE_SECONDS, + DatabaseDescriptor.getComparator(validate), ColumnDefinition.fromColumnDefs((Iterable<ColumnDef>) cf_def.column_metadata)); } 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=989344&r1=989343&r2=989344&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java (original) +++ cassandra/trunk/src/java/org/apache/cassandra/config/CFMetaData.java Wed Aug 25 20:25:49 2010 @@ -79,6 +79,7 @@ public final class CFMetaData 0.01, 0, 0, + BytesType.instance, cfId, Collections.<byte[], ColumnDefinition>emptyMap()); } @@ -136,6 +137,7 @@ public final class CFMetaData public final Integer cfId; public boolean preloadRowCache; public final int gcGraceSeconds; // default 864000 (ten days) + public final AbstractType defaultValidator; // values are longs, strings, bytes (no-op)... public final Map<byte[], ColumnDefinition> column_metadata; @@ -152,6 +154,7 @@ public final class CFMetaData double keyCacheSize, double readRepairChance, int gcGraceSeconds, + AbstractType defaultValidator, Integer cfId, Map<byte[], ColumnDefinition> column_metadata) { @@ -171,6 +174,7 @@ public final class CFMetaData this.keyCacheSize = keyCacheSize; this.readRepairChance = readRepairChance; this.gcGraceSeconds = gcGraceSeconds; + this.defaultValidator = defaultValidator; this.cfId = cfId; this.column_metadata = Collections.unmodifiableMap(column_metadata); } @@ -187,22 +191,22 @@ public final class CFMetaData } } - public CFMetaData(String tableName, String cfName, ColumnFamilyType cfType, ClockType clockType, AbstractType comparator, AbstractType subcolumnComparator, AbstractReconciler reconciler, String comment, double rowCacheSize, boolean preloadRowCache, double keyCacheSize, double readRepairChance, int gcGraceSeconds, Map<byte[], ColumnDefinition> column_metadata) + public CFMetaData(String tableName, String cfName, ColumnFamilyType cfType, ClockType clockType, AbstractType comparator, AbstractType subcolumnComparator, AbstractReconciler reconciler, String comment, double rowCacheSize, boolean preloadRowCache, double keyCacheSize, double readRepairChance, int gcGraceSeconds, AbstractType defaultvalidator, Map<byte[], ColumnDefinition> column_metadata) { - this(tableName, cfName, cfType, clockType, comparator, subcolumnComparator, reconciler, comment, rowCacheSize, preloadRowCache, keyCacheSize, readRepairChance, gcGraceSeconds, nextId(), column_metadata); + this(tableName, cfName, cfType, clockType, comparator, subcolumnComparator, reconciler, comment, rowCacheSize, preloadRowCache, keyCacheSize, readRepairChance, gcGraceSeconds, defaultvalidator, nextId(), column_metadata); } /** clones an existing CFMetaData using the same id. */ public static CFMetaData rename(CFMetaData cfm, String newName) { - CFMetaData newCfm = new CFMetaData(cfm.tableName, newName, cfm.cfType, cfm.clockType, cfm.comparator, cfm.subcolumnComparator, cfm.reconciler, cfm.comment, cfm.rowCacheSize, cfm.preloadRowCache, cfm.keyCacheSize, cfm.readRepairChance, cfm.gcGraceSeconds, cfm.cfId, cfm.column_metadata); + CFMetaData newCfm = new CFMetaData(cfm.tableName, newName, cfm.cfType, cfm.clockType, cfm.comparator, cfm.subcolumnComparator, cfm.reconciler, cfm.comment, cfm.rowCacheSize, cfm.preloadRowCache, cfm.keyCacheSize, cfm.readRepairChance, cfm.gcGraceSeconds, cfm.defaultValidator, cfm.cfId, cfm.column_metadata); return newCfm; } /** clones existing CFMetaData. keeps the id but changes the table name.*/ public static CFMetaData renameTable(CFMetaData cfm, String tableName) { - return new CFMetaData(tableName, cfm.cfName, cfm.cfType, cfm.clockType, cfm.comparator, cfm.subcolumnComparator, cfm.reconciler, cfm.comment, cfm.rowCacheSize, cfm.preloadRowCache, cfm.keyCacheSize, cfm.readRepairChance, cfm.gcGraceSeconds, cfm.cfId, cfm.column_metadata); + return new CFMetaData(tableName, cfm.cfName, cfm.cfType, cfm.clockType, cfm.comparator, cfm.subcolumnComparator, cfm.reconciler, cfm.comment, cfm.rowCacheSize, cfm.preloadRowCache, cfm.keyCacheSize, cfm.readRepairChance, cfm.gcGraceSeconds, cfm.defaultValidator, cfm.cfId, cfm.column_metadata); } /** used for evicting cf data out of static tracking collections. */ @@ -238,6 +242,7 @@ public final class CFMetaData cf.preload_row_cache = preloadRowCache; cf.read_repair_chance = readRepairChance; cf.gc_grace_seconds = gcGraceSeconds; + cf.default_validation_class = new Utf8(defaultValidator.getClass().getName()); cf.column_metadata = SerDeUtils.createArray(column_metadata.size(), org.apache.cassandra.config.avro.ColumnDef.SCHEMA$); for (ColumnDefinition cd : column_metadata.values()) @@ -250,12 +255,14 @@ public final class CFMetaData AbstractType comparator; AbstractType subcolumnComparator = null; AbstractReconciler reconciler; + AbstractType validator; try { comparator = DatabaseDescriptor.getComparator(cf.comparator_type.toString()); if (cf.subcomparator_type != null) subcolumnComparator = DatabaseDescriptor.getComparator(cf.subcomparator_type.toString()); reconciler = DatabaseDescriptor.getReconciler(cf.reconciler.toString()); + validator = DatabaseDescriptor.getComparator(cf.default_validation_class.toString()); } catch (Exception ex) { @@ -268,7 +275,7 @@ public final class CFMetaData ColumnDefinition cd = ColumnDefinition.inflate(cditer.next()); column_metadata.put(cd.name, cd); } - return new CFMetaData(cf.keyspace.toString(), cf.name.toString(), ColumnFamilyType.create(cf.column_type.toString()), ClockType.create(cf.clock_type.toString()), comparator, subcolumnComparator, reconciler, cf.comment.toString(), cf.row_cache_size, cf.preload_row_cache, cf.key_cache_size, cf.read_repair_chance, cf.gc_grace_seconds, cf.id, column_metadata); + return new CFMetaData(cf.keyspace.toString(), cf.name.toString(), ColumnFamilyType.create(cf.column_type.toString()), ClockType.create(cf.clock_type.toString()), comparator, subcolumnComparator, reconciler, cf.comment.toString(), cf.row_cache_size, cf.preload_row_cache, cf.key_cache_size, cf.read_repair_chance, cf.gc_grace_seconds, validator, cf.id, column_metadata); } public boolean equals(Object obj) @@ -328,9 +335,10 @@ public final class CFMetaData public AbstractType getValueValidator(byte[] column) { + AbstractType validator = defaultValidator; ColumnDefinition columnDefinition = column_metadata.get(column); - if (columnDefinition == null) - return null; - return columnDefinition.validator; + if (columnDefinition != null) + validator = columnDefinition.validator; + return validator; } } Modified: cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java?rev=989344&r1=989343&r2=989344&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java (original) +++ cassandra/trunk/src/java/org/apache/cassandra/config/DatabaseDescriptor.java Wed Aug 25 20:25:49 2010 @@ -583,9 +583,11 @@ public class DatabaseDescriptor throw new ConfigurationException("ColumnFamily name contains invalid characters."); } - // Parse out the column comparator + // Parse out the column comparators and validators AbstractType comparator = getComparator(cf.compare_with); AbstractType subcolumnComparator = null; + AbstractType default_validator = getComparator(cf.default_validation_class); + ColumnFamilyType cfType = cf.column_type == null ? ColumnFamilyType.Standard : cf.column_type; if (cfType == ColumnFamilyType.Super) { @@ -639,6 +641,7 @@ public class DatabaseDescriptor cf.keys_cached, cf.read_repair_chance, cf.gc_grace_seconds, + default_validator, metadata); } defs.add(new KSMetaData(keyspace.name, Modified: cassandra/trunk/src/java/org/apache/cassandra/config/RawColumnFamily.java URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/config/RawColumnFamily.java?rev=989344&r1=989343&r2=989344&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/config/RawColumnFamily.java (original) +++ cassandra/trunk/src/java/org/apache/cassandra/config/RawColumnFamily.java Wed Aug 25 20:25:49 2010 @@ -44,5 +44,6 @@ public class RawColumnFamily public double read_repair_chance = CFMetaData.DEFAULT_READ_REPAIR_CHANCE; public boolean preload_row_cache = CFMetaData.DEFAULT_PRELOAD_ROW_CACHE; public int gc_grace_seconds = CFMetaData.DEFAULT_GC_GRACE_SECONDS; + public String default_validation_class; public RawColumnDefinition[] column_metadata = new RawColumnDefinition[0]; } Modified: cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java?rev=989344&r1=989343&r2=989344&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java (original) +++ cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java Wed Aug 25 20:25:49 2010 @@ -215,6 +215,7 @@ public class ColumnFamilyStore implement 0, 0, CFMetaData.DEFAULT_GC_GRACE_SECONDS, + BytesType.instance, Collections.<byte[], ColumnDefinition>emptyMap()); ColumnFamilyStore indexedCfs = ColumnFamilyStore.createColumnFamilyStore(table, indexedCfName, 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=989344&r1=989343&r2=989344&view=diff ============================================================================== --- cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java (original) +++ cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java Wed Aug 25 20:25:49 2010 @@ -968,6 +968,7 @@ public class CassandraServer implements cf_def.key_cache_size, cf_def.read_repair_chance, cf_def.isSetGc_grace_seconds() ? cf_def.gc_grace_seconds : CFMetaData.DEFAULT_GC_GRACE_SECONDS, + DatabaseDescriptor.getComparator(cf_def.default_validation_class), ColumnDefinition.fromColumnDef(cf_def.column_metadata)); } Modified: cassandra/trunk/test/system/test_thrift_server.py URL: http://svn.apache.org/viewvc/cassandra/trunk/test/system/test_thrift_server.py?rev=989344&r1=989343&r2=989344&view=diff ============================================================================== --- cassandra/trunk/test/system/test_thrift_server.py (original) +++ cassandra/trunk/test/system/test_thrift_server.py Wed Aug 25 20:25:49 2010 @@ -1191,7 +1191,7 @@ class TestMutations(ThriftTester): client.system_drop_keyspace(keyspace.name) def test_column_validators(self): - # regular CF + # columndef validation for regular CF ks = 'Keyspace1' _set_keyspace(ks) cd = ColumnDef('col', 'LongType', None, None) @@ -1207,7 +1207,7 @@ class TestMutations(ThriftTester): e = _expect_exception(lambda: client.insert('key1', cp, col1, ConsistencyLevel.ONE), InvalidRequestException) assert e.why.find("failed validation") >= 0 - # super CF + # columndef validation for super CF scf = CfDef('Keyspace1', 'ValidatorSuperColumnFamily', column_type='Super', column_metadata=[cd]) client.system_add_column_family(scf) ks_def = client.describe_keyspace(ks) @@ -1217,7 +1217,27 @@ class TestMutations(ThriftTester): client.insert('key0', scp, col0, ConsistencyLevel.ONE) e = _expect_exception(lambda: client.insert('key1', scp, col1, ConsistencyLevel.ONE), InvalidRequestException) assert e.why.find("failed validation") >= 0 - + + # columndef and cfdef default validation + cf = CfDef('Keyspace1', 'DefaultValidatorColumnFamily', column_metadata=[cd], default_validation_class='UTF8Type') + client.system_add_column_family(cf) + ks_def = client.describe_keyspace(ks) + assert 'DefaultValidatorColumnFamily' in [x.name for x in ks_def.cf_defs] + + dcp = ColumnParent('DefaultValidatorColumnFamily') + # inserting a longtype into column 'col' is valid at the columndef level + client.insert('key0', dcp, col0, ConsistencyLevel.ONE) + # inserting a UTF8type into column 'col' fails at the columndef level + e = _expect_exception(lambda: client.insert('key1', dcp, col1, ConsistencyLevel.ONE), InvalidRequestException) + assert e.why.find("failed validation") >= 0 + + # insert a longtype into column 'fcol' should fail at the cfdef level + col2 = Column('fcol', _i64(4224), Clock(0)) + e = _expect_exception(lambda: client.insert('key1', dcp, col2, ConsistencyLevel.ONE), InvalidRequestException) + assert e.why.find("failed validation") >= 0 + # insert a UTF8type into column 'fcol' is valid at the cfdef level + col3 = Column('fcol', "Stringin' it up in the Stringtel Stringifornia", Clock(0)) + client.insert('key0', dcp, col3, ConsistencyLevel.ONE) def test_system_column_family_operations(self): _set_keyspace('Keyspace1') Modified: cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java URL: http://svn.apache.org/viewvc/cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java?rev=989344&r1=989343&r2=989344&view=diff ============================================================================== --- cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java (original) +++ cassandra/trunk/test/unit/org/apache/cassandra/db/DefsTest.java Wed Aug 25 20:25:49 2010 @@ -81,7 +81,7 @@ public class DefsTest extends CleanupHel @Test public void addNewCfToBogusTable() throws InterruptedException { - CFMetaData newCf = new CFMetaData("MadeUpKeyspace", "NewCF", ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, TimestampReconciler.instance, "new cf", 0, false, 1.0, 0, 864000, Collections.<byte[], ColumnDefinition>emptyMap()); + CFMetaData newCf = new CFMetaData("MadeUpKeyspace", "NewCF", ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, TimestampReconciler.instance, "new cf", 0, false, 1.0, 0, 864000, BytesType.instance, Collections.<byte[], ColumnDefinition>emptyMap()); try { new AddColumnFamily(newCf).apply(); @@ -106,7 +106,7 @@ public class DefsTest extends CleanupHel assert DatabaseDescriptor.getDefsVersion().equals(prior); // add a cf. - CFMetaData newCf1 = new CFMetaData("Keyspace1", "MigrationCf_1", ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, TimestampReconciler.instance, "Migration CF ", 0, false, 1.0, 0, 864000, Collections.<byte[], ColumnDefinition>emptyMap()); + CFMetaData newCf1 = new CFMetaData("Keyspace1", "MigrationCf_1", ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, TimestampReconciler.instance, "Migration CF ", 0, false, 1.0, 0, 864000, BytesType.instance, Collections.<byte[], ColumnDefinition>emptyMap()); Migration m1 = new AddColumnFamily(newCf1); m1.apply(); UUID ver1 = m1.getVersion(); @@ -156,7 +156,7 @@ public class DefsTest extends CleanupHel final String cf = "BrandNewCf"; KSMetaData original = DatabaseDescriptor.getTableDefinition(ks); - CFMetaData newCf = new CFMetaData(original.name, cf, ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, TimestampReconciler.instance, "A New Column Family", 0, false, 1.0, 0, 864000, Collections.<byte[], ColumnDefinition>emptyMap()); + CFMetaData newCf = new CFMetaData(original.name, cf, ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, TimestampReconciler.instance, "A New Column Family", 0, false, 1.0, 0, 864000, BytesType.instance, Collections.<byte[], ColumnDefinition>emptyMap()); assert !DatabaseDescriptor.getTableDefinition(ks).cfMetaData().containsKey(newCf.cfName); new AddColumnFamily(newCf).apply(); @@ -271,7 +271,7 @@ public class DefsTest extends CleanupHel public void addNewKS() throws ConfigurationException, IOException, ExecutionException, InterruptedException { DecoratedKey dk = Util.dk("key0"); - CFMetaData newCf = new CFMetaData("NewKeyspace1", "AddedStandard1", ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, TimestampReconciler.instance, "A new cf for a new ks", 0, false, 1.0, 0, 864000, Collections.<byte[], ColumnDefinition>emptyMap()); + CFMetaData newCf = new CFMetaData("NewKeyspace1", "AddedStandard1", ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, TimestampReconciler.instance, "A new cf for a new ks", 0, false, 1.0, 0, 864000, BytesType.instance, Collections.<byte[], ColumnDefinition>emptyMap()); KSMetaData newKs = new KSMetaData(newCf.tableName, SimpleStrategy.class, null, 5, newCf); new AddKeyspace(newKs).apply(); @@ -429,7 +429,7 @@ public class DefsTest extends CleanupHel new AddKeyspace(newKs).apply(); assert DatabaseDescriptor.getTableDefinition("EmptyKeyspace") != null; - CFMetaData newCf = new CFMetaData("EmptyKeyspace", "AddedLater", ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, TimestampReconciler.instance, "A new CF to add to an empty KS", 0, false, 1.0, 0, 864000, Collections.<byte[], ColumnDefinition>emptyMap()); + CFMetaData newCf = new CFMetaData("EmptyKeyspace", "AddedLater", ColumnFamilyType.Standard, ClockType.Timestamp, UTF8Type.instance, null, TimestampReconciler.instance, "A new CF to add to an empty KS", 0, false, 1.0, 0, 864000, BytesType.instance, Collections.<byte[], ColumnDefinition>emptyMap()); //should not exist until apply assert !DatabaseDescriptor.getTableDefinition(newKs.name).cfMetaData().containsKey(newCf.cfName);