You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by ee...@apache.org on 2011/03/09 23:00:26 UTC
svn commit: r1080023 - in /cassandra/trunk/src/java/org/apache/cassandra/cql:
CreateColumnFamilyStatement.java QueryProcessor.java SelectStatement.java
Term.java UpdateStatement.java
Author: eevans
Date: Wed Mar 9 22:00:25 2011
New Revision: 1080023
URL: http://svn.apache.org/viewvc?rev=1080023&view=rev
Log:
use AbstractType.fromString methods to marshal to BB
Patch by eevans for CASSANDRA-2027
Modified:
cassandra/trunk/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java
cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java
cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java
cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java
cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java
Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java?rev=1080023&r1=1080022&r2=1080023&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java Wed Mar 9 22:00:25 2011
@@ -31,6 +31,7 @@ import org.apache.cassandra.config.Colum
import org.apache.cassandra.config.ConfigurationException;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.db.ColumnFamilyType;
+import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.thrift.InvalidRequestException;
/** A <code>CREATE COLUMNFAMILY</code> parsed from a CQL query statement. */
@@ -165,7 +166,7 @@ public class CreateColumnFamilyStatement
}
// Column definitions
- private Map<ByteBuffer, ColumnDefinition> getColumns() throws InvalidRequestException
+ private Map<ByteBuffer, ColumnDefinition> getColumns(AbstractType<?> comparator) throws InvalidRequestException
{
Map<ByteBuffer, ColumnDefinition> columnDefs = new HashMap<ByteBuffer, ColumnDefinition>();
@@ -173,7 +174,7 @@ public class CreateColumnFamilyStatement
{
try
{
- ByteBuffer columnName = col.getKey().getByteBuffer();
+ ByteBuffer columnName = col.getKey().getByteBuffer(comparator);
String validator = comparators.containsKey(col.getValue()) ? comparators.get(col.getValue()) : col.getValue();
columnDefs.put(columnName, new ColumnDefinition(columnName, validator, null, null));
}
@@ -202,10 +203,14 @@ public class CreateColumnFamilyStatement
try
{
+ // RPC uses BytesType as the default validator/comparator but BytesType expects hex for string terms, (not convenient).
+ AbstractType<?> comparator = DatabaseDescriptor.getComparator(comparators.get(getPropertyString(KW_COMPARATOR, "ascii")));
+ String validator = getPropertyString(KW_DEFAULTVALIDATION, "ascii");
+
return new CFMetaData(keyspace,
name,
ColumnFamilyType.create("Standard"),
- DatabaseDescriptor.getComparator(comparators.get(properties.get(KW_COMPARATOR))),
+ comparator,
null,
properties.get(KW_COMMENT),
getPropertyDouble(KW_ROWCACHESIZE, CFMetaData.DEFAULT_ROW_CACHE_SIZE),
@@ -213,7 +218,7 @@ public class CreateColumnFamilyStatement
getPropertyDouble(KW_READREPAIRCHANCE, CFMetaData.DEFAULT_READ_REPAIR_CHANCE),
getPropertyBoolean(KW_REPLICATEONWRITE, false),
getPropertyInt(KW_GCGRACESECONDS, CFMetaData.DEFAULT_GC_GRACE_SECONDS),
- DatabaseDescriptor.getComparator(comparators.get(properties.get(KW_DEFAULTVALIDATION))),
+ DatabaseDescriptor.getComparator(comparators.get(validator)),
getPropertyInt(KW_MINCOMPACTIONTHRESHOLD, CFMetaData.DEFAULT_MIN_COMPACTION_THRESHOLD),
getPropertyInt(KW_MAXCOMPACTIONTHRESHOLD, CFMetaData.DEFAULT_MAX_COMPACTION_THRESHOLD),
getPropertyInt(KW_ROWCACHESAVEPERIODSECS, CFMetaData.DEFAULT_ROW_CACHE_SAVE_PERIOD_IN_SECONDS),
@@ -221,7 +226,7 @@ public class CreateColumnFamilyStatement
getPropertyInt(KW_MEMTABLEFLUSHINMINS, CFMetaData.DEFAULT_MEMTABLE_LIFETIME_IN_MINS),
getPropertyInt(KW_MEMTABLESIZEINMB, CFMetaData.DEFAULT_MEMTABLE_THROUGHPUT_IN_MB),
getPropertyDouble(KW_MEMTABLEOPSINMILLIONS, CFMetaData.DEFAULT_MEMTABLE_OPERATIONS_IN_MILLIONS),
- getColumns());
+ getColumns(comparator));
}
catch (ConfigurationException e)
{
@@ -229,6 +234,12 @@ public class CreateColumnFamilyStatement
}
}
+ private String getPropertyString(String key, String defaultValue)
+ {
+ String value = properties.get(key);
+ return value != null ? value : defaultValue;
+ }
+
// Return a property value, typed as a Boolean
private Boolean getPropertyBoolean(String key, Boolean defaultValue) throws InvalidRequestException
{
Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java?rev=1080023&r1=1080022&r2=1080023&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java Wed Mar 9 22:00:25 2011
@@ -51,6 +51,7 @@ import org.apache.cassandra.db.migration
import org.apache.cassandra.db.migration.UpdateColumnFamily;
import org.apache.cassandra.db.migration.avro.CfDef;
import org.apache.cassandra.db.marshal.AbstractType;
+import org.apache.cassandra.db.marshal.AsciiType;
import org.apache.cassandra.db.marshal.MarshalException;
import org.apache.cassandra.dht.AbstractBounds;
import org.apache.cassandra.dht.Bounds;
@@ -78,11 +79,12 @@ public class QueryProcessor
{
List<org.apache.cassandra.db.Row> rows = null;
QueryPath queryPath = new QueryPath(select.getColumnFamily());
+ AbstractType<?> comparator = select.getComparator(keyspace);
List<ReadCommand> commands = new ArrayList<ReadCommand>();
assert select.getKeys().size() == 1;
- ByteBuffer key = select.getKeys().get(0).getByteBuffer();
+ ByteBuffer key = select.getKeys().get(0).getByteBuffer(AsciiType.instance);
validateKey(key);
// ...of a list of column names
@@ -90,7 +92,7 @@ public class QueryProcessor
{
Collection<ByteBuffer> columnNames = new ArrayList<ByteBuffer>();
for (Term column : select.getColumnNames())
- columnNames.add(column.getByteBuffer());
+ columnNames.add(column.getByteBuffer(comparator));
validateColumnNames(keyspace, select.getColumnFamily(), columnNames);
commands.add(new SliceByNamesReadCommand(keyspace, key, queryPath, columnNames));
@@ -100,13 +102,13 @@ public class QueryProcessor
{
validateColumnNames(keyspace,
select.getColumnFamily(),
- select.getColumnStart().getByteBuffer(),
- select.getColumnFinish().getByteBuffer());
+ select.getColumnStart().getByteBuffer(comparator),
+ select.getColumnFinish().getByteBuffer(comparator));
commands.add(new SliceFromReadCommand(keyspace,
key,
queryPath,
- select.getColumnStart().getByteBuffer(),
- select.getColumnFinish().getByteBuffer(),
+ select.getColumnStart().getByteBuffer(comparator),
+ select.getColumnFinish().getByteBuffer(comparator),
select.isColumnsReversed(),
select.getColumnsLimit()));
}
@@ -132,13 +134,14 @@ public class QueryProcessor
{
List<org.apache.cassandra.db.Row> rows = null;
- ByteBuffer startKey = (select.getKeyStart() != null) ? select.getKeyStart().getByteBuffer() : (new Term()).getByteBuffer();
- ByteBuffer finishKey = (select.getKeyFinish() != null) ? select.getKeyFinish().getByteBuffer() : (new Term()).getByteBuffer();
+ ByteBuffer startKey = (select.getKeyStart() != null) ? select.getKeyStart().getByteBuffer(AsciiType.instance) : (new Term()).getByteBuffer();
+ ByteBuffer finishKey = (select.getKeyFinish() != null) ? select.getKeyFinish().getByteBuffer(AsciiType.instance) : (new Term()).getByteBuffer();
IPartitioner<?> p = StorageService.getPartitioner();
AbstractBounds bounds = new Bounds(p.getToken(startKey), p.getToken(finishKey));
+ AbstractType<?> comparator = select.getComparator(keyspace);
// XXX: Our use of Thrift structs internally makes me Sad. :(
- SlicePredicate thriftSlicePredicate = slicePredicateFromSelect(select);
+ SlicePredicate thriftSlicePredicate = slicePredicateFromSelect(select, comparator);
validateSlicePredicate(keyspace, select.getColumnFamily(), thriftSlicePredicate);
try
@@ -170,19 +173,25 @@ public class QueryProcessor
private static List<org.apache.cassandra.db.Row> getIndexedSlices(String keyspace, SelectStatement select)
throws TimedOutException, UnavailableException, InvalidRequestException
{
+ AbstractType<?> comparator = select.getComparator(keyspace);
// XXX: Our use of Thrift structs internally (still) makes me Sad. :~(
- SlicePredicate thriftSlicePredicate = slicePredicateFromSelect(select);
+ SlicePredicate thriftSlicePredicate = slicePredicateFromSelect(select, comparator);
validateSlicePredicate(keyspace, select.getColumnFamily(), thriftSlicePredicate);
List<IndexExpression> expressions = new ArrayList<IndexExpression>();
for (Relation columnRelation : select.getColumnRelations())
{
- expressions.add(new IndexExpression(columnRelation.getEntity().getByteBuffer(),
+ // Left and right side of relational expression encoded according to comparator/validator.
+ ByteBuffer entity = columnRelation.getEntity().getByteBuffer(comparator);
+ ByteBuffer value = columnRelation.getValue().getByteBuffer(select.getValueValidator(keyspace, entity));
+
+ expressions.add(new IndexExpression(entity,
IndexOperator.valueOf(columnRelation.operator().toString()),
- columnRelation.getValue().getByteBuffer()));
+ value));
}
- ByteBuffer startKey = (!select.isKeyRange()) ? (new Term()).getByteBuffer() : select.getKeyStart().getByteBuffer();
+ // FIXME: keys as ascii is not a Real Solution
+ ByteBuffer startKey = (!select.isKeyRange()) ? (new Term()).getByteBuffer() : select.getKeyStart().getByteBuffer(AsciiType.instance);
IndexClause thriftIndexClause = new IndexClause(expressions, startKey, select.getNumRecords());
List<org.apache.cassandra.db.Row> rows;
@@ -222,20 +231,20 @@ public class QueryProcessor
cfamsSeen.add(update.getColumnFamily());
}
- ByteBuffer key = update.getKey().getByteBuffer();
+ // FIXME: keys as ascii is not a Real Solution
+ ByteBuffer key = update.getKey().getByteBuffer(AsciiType.instance);
validateKey(key);
validateColumnFamily(keyspace, update.getColumnFamily());
+ AbstractType<?> comparator = update.getComparator(keyspace);
RowMutation rm = new RowMutation(keyspace, key);
for (Map.Entry<Term, Term> column : update.getColumns().entrySet())
{
- validateColumn(keyspace,
- update.getColumnFamily(),
- column.getKey().getByteBuffer(),
- column.getValue().getByteBuffer());
- rm.add(new QueryPath(update.getColumnFamily(), null, column.getKey().getByteBuffer()),
- column.getValue().getByteBuffer(),
- System.currentTimeMillis());
+ ByteBuffer colName = column.getKey().getByteBuffer(comparator);
+ ByteBuffer colValue = column.getValue().getByteBuffer(update.getValueValidator(keyspace, colName));
+
+ validateColumn(keyspace, update.getColumnFamily(), colName, colValue);
+ rm.add(new QueryPath(update.getColumnFamily(), null, colName), colValue, System.currentTimeMillis());
}
rowMutations.add(rm);
@@ -255,15 +264,16 @@ public class QueryProcessor
}
}
- private static SlicePredicate slicePredicateFromSelect(SelectStatement select) throws InvalidRequestException
+ private static SlicePredicate slicePredicateFromSelect(SelectStatement select, AbstractType<?> comparator)
+ throws InvalidRequestException
{
SlicePredicate thriftSlicePredicate = new SlicePredicate();
if (select.isColumnRange() || select.getColumnNames().size() == 0)
{
SliceRange sliceRange = new SliceRange();
- sliceRange.start = select.getColumnStart().getByteBuffer();
- sliceRange.finish = select.getColumnFinish().getByteBuffer();
+ sliceRange.start = select.getColumnStart().getByteBuffer(comparator);
+ sliceRange.finish = select.getColumnFinish().getByteBuffer(comparator);
sliceRange.reversed = select.isColumnsReversed();
sliceRange.count = select.getColumnsLimit();
thriftSlicePredicate.slice_range = sliceRange;
@@ -272,7 +282,7 @@ public class QueryProcessor
{
List<ByteBuffer> columnNames = new ArrayList<ByteBuffer>();
for (Term column : select.getColumnNames())
- columnNames.add(column.getByteBuffer());
+ columnNames.add(column.getByteBuffer(comparator));
thriftSlicePredicate.column_names = columnNames;
}
@@ -301,12 +311,14 @@ public class QueryProcessor
if (select.getKeys().size() > 1)
throw new InvalidRequestException("SELECTs can contain only by by-key clause");
+ AbstractType<?> comparator = select.getComparator(keyspace);
+
if (select.getColumnRelations().size() > 0)
{
Set<ByteBuffer> indexed = Table.open(keyspace).getColumnFamilyStore(select.getColumnFamily()).getIndexedColumns();
for (Relation relation : select.getColumnRelations())
{
- if ((relation.operator().equals(RelationType.EQ)) && indexed.contains(relation.getEntity().getByteBuffer()))
+ if ((relation.operator().equals(RelationType.EQ)) && indexed.contains(relation.getEntity().getByteBuffer(comparator)))
return;
}
throw new InvalidRequestException("No indexed columns present in by-columns clause with \"equals\" operator");
@@ -354,7 +366,7 @@ public class QueryProcessor
private static void validateColumnNames(String keyspace, String columnFamily, Iterable<ByteBuffer> columns)
throws InvalidRequestException
{
- AbstractType comparator = ColumnFamily.getComparatorFor(keyspace, columnFamily, null);
+ AbstractType<?> comparator = ColumnFamily.getComparatorFor(keyspace, columnFamily, null);
for (ByteBuffer name : columns)
{
if (name.remaining() > IColumn.MAX_NAME_LENGTH)
@@ -388,7 +400,7 @@ public class QueryProcessor
throws InvalidRequestException
{
validateColumnName(keyspace, columnFamily, name);
- AbstractType validator = DatabaseDescriptor.getValueValidator(keyspace, columnFamily, name);
+ AbstractType<?> validator = DatabaseDescriptor.getValueValidator(keyspace, columnFamily, name);
try
{
@@ -562,19 +574,20 @@ public class QueryProcessor
case DELETE:
DeleteStatement delete = (DeleteStatement)statement.statement;
clientState.hasColumnFamilyAccess(delete.getColumnFamily(), Permission.WRITE);
+ AbstractType<?> comparator = DatabaseDescriptor.getComparator(keyspace, delete.getColumnFamily());
List<RowMutation> rowMutations = new ArrayList<RowMutation>();
for (Term key : delete.getKeys())
{
- RowMutation rm = new RowMutation(keyspace, key.getByteBuffer());
+ RowMutation rm = new RowMutation(keyspace, key.getByteBuffer(AsciiType.instance));
if (delete.getColumns().size() < 1) // No columns, delete the row
rm.delete(new QueryPath(delete.getColumnFamily()), System.currentTimeMillis());
else // Delete specific columns
{
for (Term column : delete.getColumns())
{
- validateColumnName(keyspace, delete.getColumnFamily(), column.getByteBuffer());
- rm.delete(new QueryPath(delete.getColumnFamily(), null, column.getByteBuffer()),
+ validateColumnName(keyspace, delete.getColumnFamily(), column.getByteBuffer(comparator));
+ rm.delete(new QueryPath(delete.getColumnFamily(), null, column.getByteBuffer(comparator)),
System.currentTimeMillis());
}
}
Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java?rev=1080023&r1=1080022&r2=1080023&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/SelectStatement.java Wed Mar 9 22:00:25 2011
@@ -20,8 +20,11 @@
*/
package org.apache.cassandra.cql;
+import java.nio.ByteBuffer;
import java.util.List;
+import org.apache.cassandra.config.DatabaseDescriptor;
+import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.thrift.ConsistencyLevel;
/**
@@ -123,4 +126,14 @@ public class SelectStatement
{
return isCountOper;
}
+
+ public AbstractType getComparator(String keyspace)
+ {
+ return DatabaseDescriptor.getComparator(keyspace, columnFamily);
+ }
+
+ public AbstractType getValueValidator(String keyspace, ByteBuffer column)
+ {
+ return DatabaseDescriptor.getValueValidator(keyspace, columnFamily, column);
+ }
}
Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java?rev=1080023&r1=1080022&r2=1080023&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java Wed Mar 9 22:00:25 2011
@@ -24,8 +24,13 @@ import java.io.UnsupportedEncodingExcept
import java.nio.ByteBuffer;
import java.text.ParseException;
+import org.apache.cassandra.db.marshal.AbstractType;
+import org.apache.cassandra.db.marshal.AsciiType;
+import org.apache.cassandra.db.marshal.IntegerType;
import org.apache.cassandra.db.marshal.LexicalUUIDType;
+import org.apache.cassandra.db.marshal.MarshalException;
import org.apache.cassandra.db.marshal.TimeUUIDType;
+import org.apache.cassandra.db.marshal.UTF8Type;
import org.apache.cassandra.thrift.InvalidRequestException;
import org.apache.cassandra.utils.ByteBufferUtil;
import org.apache.cassandra.utils.FBUtilities;
@@ -87,6 +92,25 @@ public class Term
}
/**
+ * Returns the typed value, serialized to a ByteBuffer according to a
+ * comparator/validator.
+ *
+ * @return a ByteBuffer of the value.
+ * @throws InvalidRequestException if unable to coerce the string to its type.
+ */
+ public ByteBuffer getByteBuffer(AbstractType<?> validator) throws InvalidRequestException
+ {
+ try
+ {
+ return validator.fromString(text);
+ }
+ catch (MarshalException e)
+ {
+ throw new InvalidRequestException(e.getMessage());
+ }
+ }
+
+ /**
* Returns the typed value, serialized to a ByteBuffer.
*
* @return a ByteBuffer of the value.
@@ -97,72 +121,15 @@ public class Term
switch (type)
{
case STRING:
- return ByteBuffer.wrap(text.getBytes());
+ return AsciiType.instance.fromString(text);
case INTEGER:
- try
- {
- return ByteBufferUtil.bytes(Integer.parseInt(text));
- }
- catch (NumberFormatException e)
- {
- throw new InvalidRequestException(text + " is not valid for type int");
- }
+ return IntegerType.instance.fromString(text);
case UNICODE:
- try
- {
- return ByteBuffer.wrap(text.getBytes("UTF-8"));
- }
- catch (UnsupportedEncodingException e)
- {
- throw new RuntimeException(e);
- }
+ return UTF8Type.instance.fromString(text);
case UUID:
- try
- {
- return LexicalUUIDType.instance.fromString(text);
- }
- catch (IllegalArgumentException e)
- {
- throw new InvalidRequestException(text + " is not valid for type uuid");
- }
+ return LexicalUUIDType.instance.fromString(text);
case TIMEUUID:
- if (text.equals("") || text.toLowerCase().equals("now"))
- {
- return ByteBuffer.wrap(UUIDGen.decompose(UUIDGen.makeType1UUIDFromHost(FBUtilities.getLocalAddress())));
- }
-
- // Milliseconds since epoch?
- if (text.matches("^\\d+$"))
- {
- try
- {
- return ByteBuffer.wrap(UUIDGen.getTimeUUIDBytes(Long.parseLong(text)));
- }
- catch (NumberFormatException e)
- {
- throw new InvalidRequestException(text + " is not valid for type timeuuid");
- }
- }
-
- try
- {
- long timestamp = DateUtils.parseDate(text, iso8601Patterns).getTime();
- return ByteBuffer.wrap(UUIDGen.getTimeUUIDBytes(timestamp));
- }
- catch (ParseException e1)
- {
- // Ignore failures; we'll move onto the Next Thing.
- }
-
- // Last chance, a UUID string (i.e. f79326be-2d7b-11e0-b074-0026c650d722)
- try
- {
- return TimeUUIDType.instance.fromString(text);
- }
- catch (IllegalArgumentException e)
- {
- throw new InvalidRequestException(text + " is not valid for type timeuuid");
- }
+ return TimeUUIDType.instance.fromString(text);
}
// FIXME: handle scenario that should never happen
Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java?rev=1080023&r1=1080022&r2=1080023&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/UpdateStatement.java Wed Mar 9 22:00:25 2011
@@ -20,8 +20,11 @@
*/
package org.apache.cassandra.cql;
+import java.nio.ByteBuffer;
import java.util.Map;
+import org.apache.cassandra.config.DatabaseDescriptor;
+import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.thrift.ConsistencyLevel;
/**
@@ -110,4 +113,14 @@ public class UpdateStatement
columns,
cLevel);
}
+
+ public AbstractType getComparator(String keyspace)
+ {
+ return DatabaseDescriptor.getComparator(keyspace, columnFamily);
+ }
+
+ public AbstractType getValueValidator(String keyspace, ByteBuffer column)
+ {
+ return DatabaseDescriptor.getValueValidator(keyspace, columnFamily, column);
+ }
}