You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2010/08/25 22:25:50 UTC

svn commit: r989344 - in /cassandra/trunk: ./ conf/ interface/ interface/thrift/gen-java/org/apache/cassandra/thrift/ src/avro/ src/java/org/apache/cassandra/avro/ src/java/org/apache/cassandra/config/ src/java/org/apache/cassandra/db/ src/java/org/apa...

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);