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;