You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sl...@apache.org on 2013/10/21 10:17:05 UTC

[1/3] git commit: Fix altering column types

Updated Branches:
  refs/heads/trunk d1f8c6f7a -> 477191b27


Fix altering column types

patch by slebresne; reviewed by iamaleksey for CASSANDRA-6185


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/189a6072
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/189a6072
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/189a6072

Branch: refs/heads/trunk
Commit: 189a60728db1e01bfeaa664b41431701fd684f5f
Parents: df188cc
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Mon Oct 21 10:10:54 2013 +0200
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Mon Oct 21 10:10:54 2013 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cassandra/config/ColumnDefinition.java      |  3 +-
 .../cql3/statements/AlterTableStatement.java    | 35 ++++++++++++++++----
 .../cassandra/db/marshal/AbstractType.java      | 14 +++++++-
 .../apache/cassandra/db/marshal/BytesType.java  |  7 ++++
 .../cassandra/db/marshal/CompositeType.java     | 24 ++++++++++++++
 6 files changed, 76 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/189a6072/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 70bb919..117a200 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,5 +1,6 @@
 1.2.12
  * (Hadoop) Require CFRR batchSize to be at least 2 (CASSANDRA-6114)
+ * Fix altering column types (CASSANDRA-6185)
 
 
 1.2.11

http://git-wip-us.apache.org/repos/asf/cassandra/blob/189a6072/src/java/org/apache/cassandra/config/ColumnDefinition.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/ColumnDefinition.java b/src/java/org/apache/cassandra/config/ColumnDefinition.java
index db5f7ed..807f008 100644
--- a/src/java/org/apache/cassandra/config/ColumnDefinition.java
+++ b/src/java/org/apache/cassandra/config/ColumnDefinition.java
@@ -180,8 +180,9 @@ public class ColumnDefinition
         if (getIndexType() != null && def.getIndexType() != null)
         {
             // If an index is set (and not drop by this update), the validator shouldn't be change to a non-compatible one
+            // (and we want true comparator compatibility, not just value one, since the validator is used by LocalPartitioner to order index rows)
             if (!def.getValidator().isCompatibleWith(getValidator()))
-                throw new ConfigurationException(String.format("Cannot modify validator to a non-compatible one for column %s since an index is set", comparator.getString(name)));
+                throw new ConfigurationException(String.format("Cannot modify validator to a non-order-compatible one for column %s since an index is set", comparator.getString(name)));
 
             assert getIndexName() != null;
             if (!getIndexName().equals(def.getIndexName()))

http://git-wip-us.apache.org/repos/asf/cassandra/blob/189a6072/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java b/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
index a247a4d..36ec56d 100644
--- a/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
@@ -134,24 +134,45 @@ public class AlterTableStatement extends SchemaAlteringStatement
                             throw new InvalidRequestException(String.format("counter type is not supported for PRIMARY KEY part %s", columnName));
                         if (cfDef.hasCompositeKey)
                         {
-                            List<AbstractType<?>> newTypes = new ArrayList<AbstractType<?>>(((CompositeType) cfm.getKeyValidator()).types);
+                            List<AbstractType<?>> oldTypes = ((CompositeType) cfm.getKeyValidator()).types;
+                            if (!newType.isValueCompatibleWith(oldTypes.get(name.position)))
+                                throw new ConfigurationException(String.format("Cannot change %s from type %s to type %s: types are incompatible.",
+                                                                               columnName,
+                                                                               oldTypes.get(name.position).asCQL3Type(),
+                                                                               validator));
+
+                            List<AbstractType<?>> newTypes = new ArrayList<AbstractType<?>>(oldTypes);
                             newTypes.set(name.position, newType);
                             cfm.keyValidator(CompositeType.getInstance(newTypes));
                         }
                         else
                         {
+                            if (!newType.isValueCompatibleWith(cfm.getKeyValidator()))
+                                throw new ConfigurationException(String.format("Cannot change %s from type %s to type %s: types are incompatible.",
+                                                                               columnName,
+                                                                               cfm.getKeyValidator().asCQL3Type(),
+                                                                               validator));
                             cfm.keyValidator(newType);
                         }
                         break;
                     case COLUMN_ALIAS:
                         assert cfDef.isComposite;
-                        List<AbstractType<?>> newTypes = new ArrayList<AbstractType<?>>(((CompositeType) cfm.comparator).types);
+                        List<AbstractType<?>> oldTypes = ((CompositeType) cfm.comparator).types;
+                        // Note that CFMetaData.validateCompatibility already validate the change we're about to do. However, the error message it
+                        // sends is a bit cryptic for a CQL3 user, so validating here for a sake of returning a better error message
+                        // Do note that we need isCompatibleWith here, not just isValueCompatibleWith.
+                        if (!validator.getType().isCompatibleWith(oldTypes.get(name.position)))
+                            throw new ConfigurationException(String.format("Cannot change %s from type %s to type %s: types are not order-compatible.",
+                                                                           columnName,
+                                                                           oldTypes.get(name.position).asCQL3Type(),
+                                                                           validator));
+                        List<AbstractType<?>> newTypes = new ArrayList<AbstractType<?>>(oldTypes);
                         newTypes.set(name.position, validator.getType());
                         cfm.comparator = CompositeType.getInstance(newTypes);
                         break;
                     case VALUE_ALIAS:
                         // See below
-                        if (!validator.getType().isCompatibleWith(cfm.getDefaultValidator()))
+                        if (!validator.getType().isValueCompatibleWith(cfm.getDefaultValidator()))
                             throw new ConfigurationException(String.format("Cannot change %s from type %s to type %s: types are incompatible.",
                                                                            columnName,
                                                                            cfm.getDefaultValidator().asCQL3Type(),
@@ -160,10 +181,12 @@ public class AlterTableStatement extends SchemaAlteringStatement
                         break;
                     case COLUMN_METADATA:
                         ColumnDefinition column = cfm.getColumnDefinition(columnName.key);
-                        // Thrift allows to change a column validator so CFMetaData.validateCompatility will let it slide
+                        // Thrift allows to change a column validator so CFMetaData.validateCompatibility will let it slide
                         // if we change to an incompatible type (contrarily to the comparator case). But we don't want to
-                        // allow it for CQL3 (see #5882) so validating it explicitly here
-                        if (!validator.getType().isCompatibleWith(column.getValidator()))
+                        // allow it for CQL3 (see #5882) so validating it explicitly here. We only care about value compatibility
+                        // though since we won't compare values (except when there is an index, but that is validated by
+                        // ColumnDefinition already).
+                        if (!validator.getType().isValueCompatibleWith(column.getValidator()))
                             throw new ConfigurationException(String.format("Cannot change %s from type %s to type %s: types are incompatible.",
                                                                            columnName,
                                                                            column.getValidator().asCQL3Type(),

http://git-wip-us.apache.org/repos/asf/cassandra/blob/189a6072/src/java/org/apache/cassandra/db/marshal/AbstractType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/AbstractType.java b/src/java/org/apache/cassandra/db/marshal/AbstractType.java
index cbba89c..140ea7f 100644
--- a/src/java/org/apache/cassandra/db/marshal/AbstractType.java
+++ b/src/java/org/apache/cassandra/db/marshal/AbstractType.java
@@ -213,7 +213,19 @@ public abstract class AbstractType<T> implements Comparator<ByteBuffer>
      */
     public boolean isCompatibleWith(AbstractType<?> previous)
     {
-        return this == previous;
+        return this.equals(previous);
+    }
+
+    /**
+     * Returns true if values of the previous AbstracType can be read by the this
+     * AbsractType. Note that this is a weaker version of isCompatibleWith, as it
+     * does not require that both type compare values the same way.
+     *
+     * Note that a type should be compatible with at least itself.
+     */
+    public boolean isValueCompatibleWith(AbstractType<?> previous)
+    {
+        return isCompatibleWith(previous);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cassandra/blob/189a6072/src/java/org/apache/cassandra/db/marshal/BytesType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/BytesType.java b/src/java/org/apache/cassandra/db/marshal/BytesType.java
index 1bb2bd2..a9fee0a 100644
--- a/src/java/org/apache/cassandra/db/marshal/BytesType.java
+++ b/src/java/org/apache/cassandra/db/marshal/BytesType.java
@@ -83,6 +83,13 @@ public class BytesType extends AbstractType<ByteBuffer>
         return this == previous || previous == AsciiType.instance || previous == UTF8Type.instance;
     }
 
+    @Override
+    public boolean isValueCompatibleWith(AbstractType<?> previous)
+    {
+        // BytesType can read anything
+        return true;
+    }
+
     public CQL3Type asCQL3Type()
     {
         return CQL3Type.Native.BLOB;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/189a6072/src/java/org/apache/cassandra/db/marshal/CompositeType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/marshal/CompositeType.java b/src/java/org/apache/cassandra/db/marshal/CompositeType.java
index 2a27617..8cb1e34 100644
--- a/src/java/org/apache/cassandra/db/marshal/CompositeType.java
+++ b/src/java/org/apache/cassandra/db/marshal/CompositeType.java
@@ -172,6 +172,30 @@ public class CompositeType extends AbstractCompositeType
         return true;
     }
 
+    @Override
+    public boolean isValueCompatibleWith(AbstractType<?> previous)
+    {
+        if (this == previous)
+            return true;
+
+        if (!(previous instanceof CompositeType))
+            return false;
+
+        // Extending with new components is fine
+        CompositeType cp = (CompositeType)previous;
+        if (types.size() < cp.types.size())
+            return false;
+
+        for (int i = 0; i < cp.types.size(); i++)
+        {
+            AbstractType tprev = cp.types.get(i);
+            AbstractType tnew = types.get(i);
+            if (!tnew.isValueCompatibleWith(tprev))
+                return false;
+        }
+        return true;
+    }
+
     private static class StaticParsedComparator implements ParsedComparator
     {
         final AbstractType<?> type;


[3/3] git commit: Merge branch 'cassandra-2.0' into trunk

Posted by sl...@apache.org.
Merge branch 'cassandra-2.0' into trunk


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/477191b2
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/477191b2
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/477191b2

Branch: refs/heads/trunk
Commit: 477191b272942dba7f4a9e0fcd9fc835e6bef9b7
Parents: d1f8c6f 5c54262
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Mon Oct 21 10:16:48 2013 +0200
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Mon Oct 21 10:16:48 2013 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cassandra/config/ColumnDefinition.java      |  4 +--
 .../cql3/statements/AlterTableStatement.java    | 35 ++++++++++++++++----
 .../cassandra/db/marshal/AbstractType.java      | 14 +++++++-
 .../apache/cassandra/db/marshal/BytesType.java  |  7 ++++
 .../cassandra/db/marshal/CompositeType.java     | 24 ++++++++++++++
 6 files changed, 76 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/477191b2/CHANGES.txt
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/477191b2/src/java/org/apache/cassandra/config/ColumnDefinition.java
----------------------------------------------------------------------


[2/3] git commit: Merge branch 'cassandra-1.2' into cassandra-2.0

Posted by sl...@apache.org.
Merge branch 'cassandra-1.2' into cassandra-2.0

Conflicts:
	CHANGES.txt
	src/java/org/apache/cassandra/config/ColumnDefinition.java
	src/java/org/apache/cassandra/db/marshal/CompositeType.java


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/5c542623
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/5c542623
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/5c542623

Branch: refs/heads/trunk
Commit: 5c54262336430ee2fdca2eb5df6cdff525abf78b
Parents: edd1226 189a607
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Mon Oct 21 10:15:59 2013 +0200
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Mon Oct 21 10:15:59 2013 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cassandra/config/ColumnDefinition.java      |  4 +--
 .../cql3/statements/AlterTableStatement.java    | 35 ++++++++++++++++----
 .../cassandra/db/marshal/AbstractType.java      | 14 +++++++-
 .../apache/cassandra/db/marshal/BytesType.java  |  7 ++++
 .../cassandra/db/marshal/CompositeType.java     | 24 ++++++++++++++
 6 files changed, 76 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/5c542623/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index 351c625,117a200..02bbc1d
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -60,43 -36,9 +60,44 @@@ Merged from 1.2
   * Fix validation of empty column names for compact tables (CASSANDRA-6152)
   * Skip replaying mutations that pass CRC but fail to deserialize (CASSANDRA-6183)
   * Rework token replacement to use replace_address (CASSANDRA-5916)
++ * Fix altering column types (CASSANDRA-6185)
  
  
 -1.2.10
 +2.0.1
 + * Fix bug that could allow reading deleted data temporarily (CASSANDRA-6025)
 + * Improve memory use defaults (CASSANDRA-5069)
 + * Make ThriftServer more easlly extensible (CASSANDRA-6058)
 + * Remove Hadoop dependency from ITransportFactory (CASSANDRA-6062)
 + * add file_cache_size_in_mb setting (CASSANDRA-5661)
 + * Improve error message when yaml contains invalid properties (CASSANDRA-5958)
 + * Improve leveled compaction's ability to find non-overlapping L0 compactions
 +   to work on concurrently (CASSANDRA-5921)
 + * Notify indexer of columns shadowed by range tombstones (CASSANDRA-5614)
 + * Log Merkle tree stats (CASSANDRA-2698)
 + * Switch from crc32 to adler32 for compressed sstable checksums (CASSANDRA-5862)
 + * Improve offheap memcpy performance (CASSANDRA-5884)
 + * Use a range aware scanner for cleanup (CASSANDRA-2524)
 + * Cleanup doesn't need to inspect sstables that contain only local data
 +   (CASSANDRA-5722)
 + * Add ability for CQL3 to list partition keys (CASSANDRA-4536)
 + * Improve native protocol serialization (CASSANDRA-5664)
 + * Upgrade Thrift to 0.9.1 (CASSANDRA-5923)
 + * Require superuser status for adding triggers (CASSANDRA-5963)
 + * Make standalone scrubber handle old and new style leveled manifest
 +   (CASSANDRA-6005)
 + * Fix paxos bugs (CASSANDRA-6012, 6013, 6023)
 + * Fix paged ranges with multiple replicas (CASSANDRA-6004)
 + * Fix potential AssertionError during tracing (CASSANDRA-6041)
 + * Fix NPE in sstablesplit (CASSANDRA-6027)
 + * Migrate pre-2.0 key/value/column aliases to system.schema_columns
 +   (CASSANDRA-6009)
 + * Paging filter empty rows too agressively (CASSANDRA-6040)
 + * Support variadic parameters for IN clauses (CASSANDRA-4210)
 + * cqlsh: return the result of CAS writes (CASSANDRA-5796)
 + * Fix validation of IN clauses with 2ndary indexes (CASSANDRA-6050)
 + * Support named bind variables in CQL (CASSANDRA-6033)
 +Merged from 1.2:
 + * Allow cache-keys-to-save to be set at runtime (CASSANDRA-5980)
   * Avoid second-guessing out-of-space state (CASSANDRA-5605)
   * Tuning knobs for dealing with large blobs and many CFs (CASSANDRA-5982)
   * (Hadoop) Fix CQLRW for thrift tables (CASSANDRA-6002)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5c542623/src/java/org/apache/cassandra/config/ColumnDefinition.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5c542623/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5c542623/src/java/org/apache/cassandra/db/marshal/AbstractType.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5c542623/src/java/org/apache/cassandra/db/marshal/BytesType.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/5c542623/src/java/org/apache/cassandra/db/marshal/CompositeType.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/db/marshal/CompositeType.java
index 640fea7,8cb1e34..3110049
--- a/src/java/org/apache/cassandra/db/marshal/CompositeType.java
+++ b/src/java/org/apache/cassandra/db/marshal/CompositeType.java
@@@ -193,25 -173,29 +193,49 @@@ public class CompositeType extends Abst
      }
  
      @Override
+     public boolean isValueCompatibleWith(AbstractType<?> previous)
+     {
+         if (this == previous)
+             return true;
+ 
+         if (!(previous instanceof CompositeType))
+             return false;
+ 
+         // Extending with new components is fine
+         CompositeType cp = (CompositeType)previous;
+         if (types.size() < cp.types.size())
+             return false;
+ 
+         for (int i = 0; i < cp.types.size(); i++)
+         {
+             AbstractType tprev = cp.types.get(i);
+             AbstractType tnew = types.get(i);
+             if (!tnew.isValueCompatibleWith(tprev))
+                 return false;
+         }
+         return true;
+     }
+ 
++    @Override
 +    public boolean intersects(List<ByteBuffer> minColumnNames, List<ByteBuffer> maxColumnNames, SliceQueryFilter filter)
 +    {
 +        assert minColumnNames.size() == maxColumnNames.size();
 +        for (ColumnSlice slice : filter.slices)
 +        {
 +            ByteBuffer[] start = split(filter.isReversed() ? slice.finish : slice.start);
 +            ByteBuffer[] finish = split(filter.isReversed() ? slice.start : slice.finish);
 +            for (int i = 0; i < minColumnNames.size(); i++)
 +            {
 +                AbstractType<?> t = types.get(i);
 +                ByteBuffer s = i < start.length ? start[i] : ByteBufferUtil.EMPTY_BYTE_BUFFER;
 +                ByteBuffer f = i < finish.length ? finish[i] : ByteBufferUtil.EMPTY_BYTE_BUFFER;
 +                if (!t.intersects(minColumnNames.get(i), maxColumnNames.get(i), s, f))
 +                    return false;
 +            }
 +        }
 +        return true;
 +    }
 +
      private static class StaticParsedComparator implements ParsedComparator
      {
          final AbstractType<?> type;