From de2ae8f91d58b92de5629131b904966fa58d801e Mon Sep 17 00:00:00 2001 From: Jonathan Ellis Date: Sun, 10 Apr 2011 04:44:31 +0000 Subject: [PATCH] use SQL-ish data types patch by jbellis and Eric Evans for CASSANDRA-2445 git-svn-id: https://svn.apache.org/repos/asf/cassandra/trunk@1090738 13f79535-47bb-0310-9956-ffa450edef68 --- doc/cql/CQL.html | 6 +- doc/cql/CQL.textile | 32 +++++----- .../cql/jdbc/CassandraPreparedStatement.java | 10 +--- drivers/py/cql/marshal.py | 2 + src/java/org/apache/cassandra/cql/Cql.g | 2 +- .../cql/CreateColumnFamilyStatement.java | 13 ++-- src/java/org/apache/cassandra/cql/Term.java | 2 + .../cassandra/db/marshal/TimeUUIDType.java | 4 +- .../apache/cassandra/db/marshal/UUIDType.java | 59 ++++++++++++++++++- test/system/test_cql.py | 53 +++++++++-------- 10 files changed, 120 insertions(+), 63 deletions(-) diff --git a/doc/cql/CQL.html b/doc/cql/CQL.html index 1f24af803a..21a808181b 100644 --- a/doc/cql/CQL.html +++ b/doc/cql/CQL.html @@ -33,10 +33,10 @@ CREATE COLUMNFAMILY <COLUMN FAMILY> (KEY <type> PRIMARY KEY [, name1 [WITH keyword1 = arg1 [AND keyword2 = arg2 [AND ...]]];

CREATE COLUMNFAMILY statements create new column family namespaces under the current keyspace. Valid column family names are strings of alphanumeric characters and underscores, which begin with a letter.

Specifying Key Type

CREATE ... (KEY <type> PRIMARY KEY) ...
 

When creating a new column family, you must specify key type. The list of possible key types is identical to column comparators/validators, (see Specifying Column Type). It’s important to note that the key type must be compatible with the partitioner in use, for example OrderPreservingPartitioner and CollatingOrderPreservingPartitioner both require UTF-8 keys.

Specifying Column Type (optional)

CREATE ... (KEY <type> PRIMARY KEY, name1 type, name2 type) ...
-

It is possible to assign columns a type during column family creation. Columns configured with a type are validated accordingly when a write occurs. Column types are specified as a parenthesized, comma-separated list of column term and type pairs. The list of recognized types are:

typedescription
bytesArbitrary bytes (no validation)
asciiASCII character string
utf8UTF8 encoded string
timeuuidType 1 UUID
uuidType 4 UUID
int4-byte integer
long8-byte long

Note: In addition to the recognized types listed above, it is also possible to supply a string containing the name of a class (a sub-class of AbstractType), either fully qualified, or relative to the org.apache.cassandra.db.marshal package.

Column Family Options (optional)

CREATE COLUMNFAMILY ... WITH keyword1 = arg1 AND keyword2 = arg2;
-

A number of optional keyword arguments can be supplied to control the configuration of a new column family.

keyworddefaultdescription
comparatorutf8Determines sorting and validation of column names. Valid values are identical to the types listed in Specifying Column Type above.
commentnoneA free-form, human-readable comment.
row_cache_size0Number of rows whose entire contents to cache in memory.
key_cache_size200000Number of keys per SSTable whose locations are kept in memory in “mostly LRU” order.
read_repair_chance1.0The probability with which read repairs should be invoked on non-quorum reads.
gc_grace_seconds864000Time to wait before garbage collecting tombstones (deletion markers).
default_validationutf8Determines validation of column values. Valid values are identical to the types listed in Specifying Column Type above.
min_compaction_threshold4Minimum number of SSTables needed to start a minor compaction.
max_compaction_threshold32Maximum number of SSTables allowed before a minor compaction is forced.
row_cache_save_period_in_seconds0Number of seconds between saving row caches.
key_cache_save_period_in_seconds14400Number of seconds between saving key caches.
memtable_flush_after_mins60Maximum time to leave a dirty table unflushed.
memtable_throughput_in_mbdynamicMaximum size of the memtable before it is flushed.
memtable_operations_in_millionsdynamicNumber of operations in millions before the memtable is flushed.
replicate_on_writefalse

CREATE INDEX

Synopsis:

CREATE INDEX [index_name] ON <column_family> (column_name);
+

It is possible to assign columns a type during column family creation. Columns configured with a type are validated accordingly when a write occurs. Column types are specified as a parenthesized, comma-separated list of column term and type pairs. The list of recognized types are:

typedescription
byteaArbitrary bytes (no validation)
asciiASCII character string
textUTF8 encoded string
varcharUTF8 encoded string
uuidType 1, or type 4 UUID
varint4-byte integer
bigint8-byte long

Note: In addition to the recognized types listed above, it is also possible to supply a string containing the name of a class (a sub-class of AbstractType), either fully qualified, or relative to the org.apache.cassandra.db.marshal package.

Column Family Options (optional)

CREATE COLUMNFAMILY ... WITH keyword1 = arg1 AND keyword2 = arg2;
+

A number of optional keyword arguments can be supplied to control the configuration of a new column family.

keyworddefaultdescription
comparatortextDetermines sorting and validation of column names. Valid values are identical to the types listed in Specifying Column Type above.
commentnoneA free-form, human-readable comment.
row_cache_size0Number of rows whose entire contents to cache in memory.
key_cache_size200000Number of keys per SSTable whose locations are kept in memory in “mostly LRU” order.
read_repair_chance1.0The probability with which read repairs should be invoked on non-quorum reads.
gc_grace_seconds864000Time to wait before garbage collecting tombstones (deletion markers).
default_validationtextDetermines validation of column values. Valid values are identical to the types listed in Specifying Column Type above.
min_compaction_threshold4Minimum number of SSTables needed to start a minor compaction.
max_compaction_threshold32Maximum number of SSTables allowed before a minor compaction is forced.
row_cache_save_period_in_seconds0Number of seconds between saving row caches.
key_cache_save_period_in_seconds14400Number of seconds between saving key caches.
memtable_flush_after_mins60Maximum time to leave a dirty table unflushed.
memtable_throughput_in_mbdynamicMaximum size of the memtable before it is flushed.
memtable_operations_in_millionsdynamicNumber of operations in millions before the memtable is flushed.
replicate_on_writefalse

CREATE INDEX

Synopsis:

CREATE INDEX [index_name] ON <column_family> (column_name);
 

A CREATE INDEX statement is used to create a new, automatic secondary index for the named column.

DROP

Synopsis:

DROP <KEYSPACE|COLUMNFAMILY> namespace;
 

DROP statements result in the immediate, irreversible removal of keyspace and column family namespaces.

Common Idioms

Specifying Consistency

... USING <CONSISTENCY> ...
-

Consistency level specifications are made up the keyword USING, followed by a consistency level identifier. Valid consistency levels are as follows:

Term specification

Terms are used in statements to specify things such as keyspaces, column families, indexes, column names and values, and keyword arguments. The rules governing term specification are as follows:

Terms which do not conform to these rules result in an exception.

How column name/value terms are interpreted is determined by the configured type.

typeterm
asciiAny string which can be decoded using ASCII charset
utf8Any string which can be decoded using UTF8 charset
uuidStandard UUID string format (hyphen-delimited hex notation)
timeuuidStandard UUID string format (hyphen-delimited hex notation)
timeuuidThe string now, to represent a type-1 (time-based) UUID with a date-time component based on the current time
timeuuidNumeric value representing milliseconds since epoch
timeuuidAn iso8601 timestamp
longNumeric value capable of fitting in 8 bytes
intNumeric value of arbitrary size
bytesHex-encoded strings (converted directly to the corresponding bytes)

Versioning

Versioning of the CQL language adheres to the Semantic Versioning guidelines. Versions take the form X.Y.Z where X, Y, and Z are integer values representing major, minor, and patch level respectively. There is no correlation between Cassandra release versions and the CQL language version.

versiondescription
PatchThe patch version is incremented when bugs are fixed.
MinorMinor version increments occur when new, but backward compatible, functionality is introduced.
MajorThe major version must be bumped when backward incompatible changes are introduced. This should rarely (if ever) occur.

Changes

Tue, 22 Mar 2011 18:10:28 -0700 - Eric Evans <eevans@rackspace.com>
+

Consistency level specifications are made up the keyword USING, followed by a consistency level identifier. Valid consistency levels are as follows:

Term specification

Terms are used in statements to specify things such as keyspaces, column families, indexes, column names and values, and keyword arguments. The rules governing term specification are as follows:

Terms which do not conform to these rules result in an exception.

How column name/value terms are interpreted is determined by the configured type.

typeterm
asciiAny string which can be decoded using ASCII charset
text / varcharAny string which can be decoded using UTF8 charset
uuidStandard UUID string format (hyphen-delimited hex notation)
uuidStandard UUID string format (hyphen-delimited hex notation)
uuidThe string now, to represent a type-1 (time-based) UUID with a date-time component based on the current time
uuidNumeric value representing milliseconds since epoch
uuidAn iso8601 timestamp
bigintNumeric value capable of fitting in 8 bytes
varintNumeric value of arbitrary size
byteaHex-encoded strings (converted directly to the corresponding bytes)

Versioning

Versioning of the CQL language adheres to the Semantic Versioning guidelines. Versions take the form X.Y.Z where X, Y, and Z are integer values representing major, minor, and patch level respectively. There is no correlation between Cassandra release versions and the CQL language version.

versiondescription
PatchThe patch version is incremented when bugs are fixed.
MinorMinor version increments occur when new, but backward compatible, functionality is introduced.
MajorThe major version must be bumped when backward incompatible changes are introduced. This should rarely (if ever) occur.

Changes

Tue, 22 Mar 2011 18:10:28 -0700 - Eric Evans <eevans@rackspace.com>
  * Initial version, 1.0.0
 
\ No newline at end of file diff --git a/doc/cql/CQL.textile b/doc/cql/CQL.textile index 4c31ddac4a..06fa3ad9a1 100644 --- a/doc/cql/CQL.textile +++ b/doc/cql/CQL.textile @@ -201,13 +201,13 @@ CREATE ... (KEY PRIMARY KEY, name1 type, name2 type) ... It is possible to assign columns a type during column family creation. Columns configured with a type are validated accordingly when a write occurs. Column types are specified as a parenthesized, comma-separated list of column term and type pairs. The list of recognized types are: |_. type|_. description| -|bytes|Arbitrary bytes (no validation)| +|bytea|Arbitrary bytes (no validation)| |ascii|ASCII character string| -|utf8|UTF8 encoded string| -|timeuuid|Type 1 UUID| -|uuid|Type 4 UUID| -|int|4-byte integer| -|long|8-byte long| +|text|UTF8 encoded string| +|varchar|UTF8 encoded string| +|uuid|Type 1, or type 4 UUID| +|varint|Arbitrary-precision integer| +|bigint|8-byte long| _Note: In addition to the recognized types listed above, it is also possible to supply a string containing the name of a class (a sub-class of @AbstractType@), either fully qualified, or relative to the @org.apache.cassandra.db.marshal@ package._ @@ -219,13 +219,13 @@ CREATE COLUMNFAMILY ... WITH keyword1 = arg1 AND keyword2 = arg2; A number of optional keyword arguments can be supplied to control the configuration of a new column family. |_. keyword|_. default|_. description| -|comparator|utf8|Determines sorting and validation of column names. Valid values are identical to the types listed in "Specifying Column Type":#columntypes above.| +|comparator|text|Determines sorting and validation of column names. Valid values are identical to the types listed in "Specifying Column Type":#columntypes above.| |comment|none|A free-form, human-readable comment.| |row_cache_size|0|Number of rows whose entire contents to cache in memory.| |key_cache_size|200000|Number of keys per SSTable whose locations are kept in memory in "mostly LRU" order.| |read_repair_chance|1.0|The probability with which read repairs should be invoked on non-quorum reads.| |gc_grace_seconds|864000|Time to wait before garbage collecting tombstones (deletion markers).| -|default_validation|utf8|Determines validation of column values. Valid values are identical to the types listed in "Specifying Column Type":#columntypes above.| +|default_validation|text|Determines validation of column values. Valid values are identical to the types listed in "Specifying Column Type":#columntypes above.| |min_compaction_threshold|4|Minimum number of SSTables needed to start a minor compaction.| |max_compaction_threshold|32|Maximum number of SSTables allowed before a minor compaction is forced.| |row_cache_save_period_in_seconds|0|Number of seconds between saving row caches.| @@ -282,15 +282,15 @@ How column name/value terms are interpreted is determined by the configured type |_. type|_. term| |ascii|Any string which can be decoded using ASCII charset| -|utf8|Any string which can be decoded using UTF8 charset| +|text / varchar|Any string which can be decoded using UTF8 charset| |uuid|Standard UUID string format (hyphen-delimited hex notation)| -|timeuuid|Standard UUID string format (hyphen-delimited hex notation)| -|timeuuid|The string @now@, to represent a type-1 (time-based) UUID with a date-time component based on the current time| -|timeuuid|Numeric value representing milliseconds since epoch| -|timeuuid|An "iso8601 timestamp":http://en.wikipedia.org/wiki/8601| -|long|Numeric value capable of fitting in 8 bytes| -|int|Numeric value of arbitrary size| -|bytes|Hex-encoded strings (converted directly to the corresponding bytes)| +|uuid|Standard UUID string format (hyphen-delimited hex notation)| +|uuid|The string @now@, to represent a type-1 (time-based) UUID with a date-time component based on the current time| +|uuid|Numeric value representing milliseconds since epoch| +|uuid|An "iso8601 timestamp":http://en.wikipedia.org/wiki/8601| +|bigint|Integer value capable of fitting in 8 bytes| +|varint|Integer value of arbitrary size| +|bytea|Hex-encoded strings (converted directly to the corresponding bytes)| h1. Versioning diff --git a/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java b/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java index 013f2ebc4e..04be1ee99c 100644 --- a/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java +++ b/drivers/java/src/org/apache/cassandra/cql/jdbc/CassandraPreparedStatement.java @@ -1,11 +1,6 @@ package org.apache.cassandra.cql.jdbc; -import org.apache.cassandra.db.marshal.AbstractType; -import org.apache.cassandra.db.marshal.AsciiType; -import org.apache.cassandra.db.marshal.BytesType; -import org.apache.cassandra.db.marshal.LexicalUUIDType; -import org.apache.cassandra.db.marshal.TimeUUIDType; -import org.apache.cassandra.db.marshal.UTF8Type; +import org.apache.cassandra.db.marshal.*; import java.io.InputStream; import java.io.Reader; @@ -67,7 +62,8 @@ public class CassandraPreparedStatement extends CassandraStatement implements Pr type == AsciiType.instance || type == UTF8Type.instance || type == LexicalUUIDType.instance || - type == TimeUUIDType.instance; + type == TimeUUIDType.instance || + type == UUIDType.instance; } // double quotes strings (in parameters) diff --git a/drivers/py/cql/marshal.py b/drivers/py/cql/marshal.py index 720bae62d7..641d56ffbd 100644 --- a/drivers/py/cql/marshal.py +++ b/drivers/py/cql/marshal.py @@ -68,6 +68,8 @@ def unmarshal(bytestr, typestr): return decode_bigint(bytestr) elif typestr == "org.apache.cassandra.db.marshal.LongType": return unpack(">q", bytestr)[0] + elif typestr == "org.apache.cassandra.db.marshal.UUIDType": + return UUID(bytes=bytestr) elif typestr == "org.apache.cassandra.db.marshal.LexicalUUIDType": return UUID(bytes=bytestr) elif typestr == "org.apache.cassandra.db.marshal.TimeUUIDType": diff --git a/src/java/org/apache/cassandra/cql/Cql.g b/src/java/org/apache/cassandra/cql/Cql.g index f4bc876397..e89c1b789d 100644 --- a/src/java/org/apache/cassandra/cql/Cql.g +++ b/src/java/org/apache/cassandra/cql/Cql.g @@ -342,7 +342,7 @@ dropColumnFamilyStatement returns [String cfam] ; comparatorType - : 'bytes' | 'ascii' | 'utf8' | 'int' | 'long' | 'uuid' | 'timeuuid' + : 'bytea' | 'ascii' | 'text' | 'varchar' | 'varint' | 'bigint' | 'uuid' ; term returns [Term item] diff --git a/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java b/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java index 934defcffd..cd76abf187 100644 --- a/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java +++ b/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java @@ -63,14 +63,13 @@ public class CreateColumnFamilyStatement static { - comparators.put("bytes", "BytesType"); + comparators.put("bytea", "BytesType"); comparators.put("ascii", "AsciiType"); - comparators.put("utf8", "UTF8Type"); - comparators.put("int", "IntegerType"); - comparators.put("long", "LongType"); - comparators.put("uuid", "LexicalUUIDType"); - comparators.put("timeuuid", "TimeUUIDType"); - + comparators.put("text", "UTF8Type"); + comparators.put("varchar", "UTF8Type"); + comparators.put("varint", "IntegerType"); + comparators.put("bigint", "LongType"); + comparators.put("uuid", "UUIDType"); keywords.add(KW_COMPARATOR); keywords.add(KW_COMMENT); keywords.add(KW_ROWCACHESIZE); diff --git a/src/java/org/apache/cassandra/cql/Term.java b/src/java/org/apache/cassandra/cql/Term.java index 61a58cca37..5df293601c 100644 --- a/src/java/org/apache/cassandra/cql/Term.java +++ b/src/java/org/apache/cassandra/cql/Term.java @@ -104,6 +104,8 @@ public class Term case INTEGER: return IntegerType.instance.fromString(text); case UUID: + // we specifically want the Lexical class here, not "UUIDType," because we're supposed to have + // a uuid-shaped string here, and UUIDType also accepts integer or date strings (and turns them into version 1 uuids). return LexicalUUIDType.instance.fromString(text); } diff --git a/src/java/org/apache/cassandra/db/marshal/TimeUUIDType.java b/src/java/org/apache/cassandra/db/marshal/TimeUUIDType.java index d00f24fd17..c63914e532 100644 --- a/src/java/org/apache/cassandra/db/marshal/TimeUUIDType.java +++ b/src/java/org/apache/cassandra/db/marshal/TimeUUIDType.java @@ -35,8 +35,8 @@ public class TimeUUIDType extends AbstractType { public static final TimeUUIDType instance = new TimeUUIDType(); - private Pattern regexPattern = Pattern.compile("[A-Fa-f0-9]{8}\\-[A-Fa-f0-9]{4}\\-[A-Fa-f0-9]{4}\\-[A-Fa-f0-9]{4}\\-[A-Fa-f0-9]{12}"); - private static String[] iso8601Patterns = new String[] { + static final Pattern regexPattern = Pattern.compile("[A-Fa-f0-9]{8}\\-[A-Fa-f0-9]{4}\\-[A-Fa-f0-9]{4}\\-[A-Fa-f0-9]{4}\\-[A-Fa-f0-9]{12}"); + static final String[] iso8601Patterns = new String[] { "yyyy-MM-dd HH:mm", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mmZ", diff --git a/src/java/org/apache/cassandra/db/marshal/UUIDType.java b/src/java/org/apache/cassandra/db/marshal/UUIDType.java index 81e8144ee0..89cc6589f2 100644 --- a/src/java/org/apache/cassandra/db/marshal/UUIDType.java +++ b/src/java/org/apache/cassandra/db/marshal/UUIDType.java @@ -22,8 +22,15 @@ package org.apache.cassandra.db.marshal; */ import java.nio.ByteBuffer; +import java.text.ParseException; import java.util.UUID; +import org.apache.commons.lang.time.DateUtils; + +import org.apache.cassandra.utils.ByteBufferUtil; +import org.apache.cassandra.utils.FBUtilities; +import org.apache.cassandra.utils.UUIDGen; + /** * Compares UUIDs using the following criteria:
* - if count of supplied bytes is less than 16, compare counts
@@ -200,6 +207,56 @@ public class UUIDType extends AbstractType @Override public ByteBuffer fromString(String source) throws MarshalException { - return LexicalUUIDType.instance.fromString(source); + // Return an empty ByteBuffer for an empty string. + if (source.isEmpty()) + return ByteBufferUtil.EMPTY_BYTE_BUFFER; + + ByteBuffer idBytes = null; + + // ffffffff-ffff-ffff-ffff-ffffffffff + if (TimeUUIDType.regexPattern.matcher(source).matches()) + { + UUID uuid; + try + { + uuid = UUID.fromString(source); + idBytes = ByteBuffer.wrap(UUIDGen.decompose(uuid)); + } + catch (IllegalArgumentException e) + { + throw new MarshalException(String.format("unable to make UUID from '%s'", source), e); + } + } + else if (source.toLowerCase().equals("now")) + { + idBytes = ByteBuffer.wrap(UUIDGen.decompose(UUIDGen.makeType1UUIDFromHost(FBUtilities.getLocalAddress()))); + } + // Milliseconds since epoch? + else if (source.matches("^\\d+$")) + { + try + { + idBytes = ByteBuffer.wrap(UUIDGen.getTimeUUIDBytes(Long.parseLong(source))); + } + catch (NumberFormatException e) + { + throw new MarshalException(String.format("unable to make version 1 UUID from '%s'", source), e); + } + } + // Last chance, attempt to parse as date-time string + else + { + try + { + long timestamp = DateUtils.parseDate(source, TimeUUIDType.iso8601Patterns).getTime(); + idBytes = ByteBuffer.wrap(UUIDGen.getTimeUUIDBytes(timestamp)); + } + catch (ParseException e1) + { + throw new MarshalException(String.format("unable to coerce '%s' to version 1 UUID", source), e1); + } + } + + return idBytes; } } diff --git a/test/system/test_cql.py b/test/system/test_cql.py index 8e676a29f6..38cefe1b93 100644 --- a/test/system/test_cql.py +++ b/test/system/test_cql.py @@ -40,35 +40,35 @@ def uuid1bytes_to_millis(uuidbytes): def load_sample(dbconn): dbconn.execute(""" - CREATE COLUMNFAMILY StandardString1 (KEY utf8 PRIMARY KEY) + CREATE COLUMNFAMILY StandardString1 (KEY text PRIMARY KEY) WITH comparator = ascii AND default_validation = ascii; """) dbconn.execute(""" - CREATE COLUMNFAMILY StandardUtf82 (KEY utf8 PRIMARY KEY) - WITH comparator = utf8 AND default_validation = ascii; + CREATE COLUMNFAMILY StandardUtf82 (KEY text PRIMARY KEY) + WITH comparator = text AND default_validation = ascii; """) dbconn.execute(""" - CREATE COLUMNFAMILY StandardLongA (KEY utf8 PRIMARY KEY) - WITH comparator = long AND default_validation = ascii; + CREATE COLUMNFAMILY StandardLongA (KEY text PRIMARY KEY) + WITH comparator = bigint AND default_validation = ascii; """) dbconn.execute(""" - CREATE COLUMNFAMILY StandardIntegerA (KEY utf8 PRIMARY KEY) - WITH comparator = int AND default_validation = ascii; + CREATE COLUMNFAMILY StandardIntegerA (KEY text PRIMARY KEY) + WITH comparator = varint AND default_validation = ascii; """) dbconn.execute(""" - CREATE COLUMNFAMILY StandardUUID (KEY utf8 PRIMARY KEY) + CREATE COLUMNFAMILY StandardUUID (KEY text PRIMARY KEY) WITH comparator = uuid AND default_validation = ascii; """) dbconn.execute(""" - CREATE COLUMNFAMILY StandardTimeUUID (KEY utf8 PRIMARY KEY) - WITH comparator = timeuuid AND default_validation = ascii; + CREATE COLUMNFAMILY StandardTimeUUID (KEY text PRIMARY KEY) + WITH comparator = uuid AND default_validation = ascii; """) dbconn.execute(""" - CREATE COLUMNFAMILY StandardTimeUUIDValues (KEY utf8 PRIMARY KEY) - WITH comparator = ascii AND default_validation = timeuuid; + CREATE COLUMNFAMILY StandardTimeUUIDValues (KEY text PRIMARY KEY) + WITH comparator = ascii AND default_validation = uuid; """) dbconn.execute(""" - CREATE COLUMNFAMILY IndexedA (KEY utf8 PRIMARY KEY, birthdate long) + CREATE COLUMNFAMILY IndexedA (KEY text PRIMARY KEY, birthdate bigint) WITH comparator = ascii AND default_validation = ascii; """) dbconn.execute("CREATE INDEX ON IndexedA (birthdate)") @@ -365,12 +365,12 @@ class TestCql(ThriftTester): conn.execute(""" CREATE COLUMNFAMILY NewCf1 ( - KEY int PRIMARY KEY, - 'username' utf8, - 'age' int, - 'birthdate' long, + KEY varint PRIMARY KEY, + 'username' text, + 'age' varint, + 'birthdate' bigint, 'id' uuid - ) WITH comparator = utf8 AND comment = 'shiny, new, cf' AND + ) WITH comparator = text AND comment = 'shiny, new, cf' AND default_validation = ascii; """) @@ -393,11 +393,11 @@ class TestCql(ThriftTester): assert_raises(CQLException, conn.execute, """CREATE COLUMNFAMILY NewCf2 - (KEY int PRIMARY KEY, KEY utf8 PRIMARY KEY)""") + (KEY varint PRIMARY KEY, KEY text PRIMARY KEY)""") # No column defs conn.execute("""CREATE COLUMNFAMILY NewCf3 - (KEY int PRIMARY KEY) WITH comparator = long""") + (KEY varint PRIMARY KEY) WITH comparator = bigint""") ksdef = thrift_client.describe_keyspace("CreateCFKeyspace") assert len(ksdef.cf_defs) == 2, \ "expected 3 column families total, found %d" % len(ksdef.cf_defs) @@ -406,7 +406,8 @@ class TestCql(ThriftTester): # Column defs, defaults otherwise conn.execute("""CREATE COLUMNFAMILY NewCf4 - (KEY int PRIMARY KEY, 'a' int, 'b' int);""") + (KEY varint PRIMARY KEY, 'a' varint, 'b' varint) + WITH comparator = text;""") ksdef = thrift_client.describe_keyspace("CreateCFKeyspace") assert len(ksdef.cf_defs) == 3, \ "expected 4 column families total, found %d" % len(ksdef.cf_defs) @@ -414,7 +415,7 @@ class TestCql(ThriftTester): assert len(cfam.column_metadata) == 2, \ "expected 2 columns, found %d" % len(cfam.column_metadata) for coldef in cfam.column_metadata: - assert coldef.name in ("a", "b"), "Unknown column name" + assert coldef.name in ("a", "b"), "Unknown column name " + coldef.name assert coldef.validation_class.endswith("marshal.IntegerType") def test_drop_columnfamily(self): @@ -425,7 +426,7 @@ class TestCql(ThriftTester): AND strategy_class = 'SimpleStrategy'; """) conn.execute('USE Keyspace4CFDrop;') - conn.execute('CREATE COLUMNFAMILY CF4Drop (KEY int PRIMARY KEY);') + conn.execute('CREATE COLUMNFAMILY CF4Drop (KEY varint PRIMARY KEY);') # TODO: temporary (until this can be done with CQL). ksdef = thrift_client.describe_keyspace("Keyspace4CFDrop") @@ -440,7 +441,7 @@ class TestCql(ThriftTester): "creating column indexes" conn = init() conn.execute("USE Keyspace1") - conn.execute("CREATE COLUMNFAMILY CreateIndex1 (KEY utf8 PRIMARY KEY)") + conn.execute("CREATE COLUMNFAMILY CreateIndex1 (KEY text PRIMARY KEY)") conn.execute("CREATE INDEX namedIndex ON CreateIndex1 (items)") conn.execute("CREATE INDEX ON CreateIndex1 (stuff)") @@ -475,7 +476,7 @@ class TestCql(ThriftTester): """ % str(timeuuid)) assert r[0].columns[0].name == timeuuid - # Tests a node-side conversion from long to UUID. + # Tests a node-side conversion from bigint to UUID. ms = uuid1bytes_to_millis(uuid.uuid1().bytes) conn.execute(""" UPDATE StandardTimeUUIDValues SET 'id' = %d WHERE KEY = 'uuidtest' @@ -536,7 +537,7 @@ class TestCql(ThriftTester): r = conn.execute("SELECT ? FROM StandardUUID WHERE KEY = 'uuidtest'", uid) - assert r[0].columns[0].name == uid + assert r[0].columns[0].name == uid, r[0].columns[0].name # TODO: slices of uuids from cf w/ LexicalUUIDType comparator