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
This commit is contained in:
Jonathan Ellis 2011-04-10 04:44:31 +00:00
parent 5b9c402457
commit de2ae8f91d
10 changed files with 120 additions and 63 deletions

View File

@ -33,10 +33,10 @@ CREATE COLUMNFAMILY <COLUMN FAMILY> (KEY <type> PRIMARY KEY [, name1
[WITH keyword1 = arg1 [AND keyword2 = arg2 [AND ...]]];
</code></pre><p><code>CREATE COLUMNFAMILY</code> 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.</p><h3 id="keytypes">Specifying Key Type</h3><pre><code>CREATE ... (KEY &lt;type&gt; PRIMARY KEY) ...
</code></pre><p>When creating a new column family, you must specify key type. The list of possible key types is identical to column comparators/validators, (see <a href="columntypes">Specifying Column Type</a>). It&#8217;s important to note that the key type must be compatible with the partitioner in use, for example <code>OrderPreservingPartitioner</code> and <code>CollatingOrderPreservingPartitioner</code> both require UTF-8 keys.</p><h3 id="columntypes">Specifying Column Type (optional)</h3><pre><code>CREATE ... (KEY &lt;type&gt; PRIMARY KEY, name1 type, name2 type) ...
</code></pre><p>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:</p><table><tr><th>type</th><th>description</th></tr><tr><td>bytes</td><td>Arbitrary bytes (no validation)</td></tr><tr><td>ascii</td><td>ASCII character string</td></tr><tr><td>utf8</td><td>UTF8 encoded string</td></tr><tr><td>timeuuid</td><td>Type 1 UUID</td></tr><tr><td>uuid</td><td>Type 4 UUID</td></tr><tr><td>int</td><td>4-byte integer</td></tr><tr><td>long</td><td>8-byte long</td></tr></table><p><em>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 <code>AbstractType</code>), either fully qualified, or relative to the <code>org.apache.cassandra.db.marshal</code> package.</em></p><h3 id="ColumnFamilyOptionsoptional">Column Family Options (optional)</h3><pre><code>CREATE COLUMNFAMILY ... WITH keyword1 = arg1 AND keyword2 = arg2;
</code></pre><p>A number of optional keyword arguments can be supplied to control the configuration of a new column family.</p><table><tr><th>keyword</th><th>default</th><th>description</th></tr><tr><td>comparator</td><td>utf8</td><td>Determines sorting and validation of column names. Valid values are identical to the types listed in <a href="#columntypes">Specifying Column Type</a> above.</td></tr><tr><td>comment</td><td>none</td><td>A free-form, human-readable comment.</td></tr><tr><td>row_cache_size</td><td>0</td><td>Number of rows whose entire contents to cache in memory.</td></tr><tr><td>key_cache_size</td><td>200000</td><td>Number of keys per SSTable whose locations are kept in memory in &#8220;mostly LRU&#8221; order.</td></tr><tr><td>read_repair_chance</td><td>1.0</td><td>The probability with which read repairs should be invoked on non-quorum reads.</td></tr><tr><td>gc_grace_seconds</td><td>864000</td><td>Time to wait before garbage collecting tombstones (deletion markers).</td></tr><tr><td>default_validation</td><td>utf8</td><td>Determines validation of column values. Valid values are identical to the types listed in <a href="#columntypes">Specifying Column Type</a> above.</td></tr><tr><td>min_compaction_threshold</td><td>4</td><td>Minimum number of SSTables needed to start a minor compaction.</td></tr><tr><td>max_compaction_threshold</td><td>32</td><td>Maximum number of SSTables allowed before a minor compaction is forced.</td></tr><tr><td>row_cache_save_period_in_seconds</td><td>0</td><td>Number of seconds between saving row caches.</td></tr><tr><td>key_cache_save_period_in_seconds</td><td>14400</td><td>Number of seconds between saving key caches.</td></tr><tr><td>memtable_flush_after_mins</td><td>60</td><td>Maximum time to leave a dirty table unflushed.</td></tr><tr><td>memtable_throughput_in_mb</td><td>dynamic</td><td>Maximum size of the memtable before it is flushed.</td></tr><tr><td>memtable_operations_in_millions</td><td>dynamic</td><td>Number of operations in millions before the memtable is flushed.</td></tr><tr><td>replicate_on_write</td><td>false</td><td></td></tr></table><h2 id="CREATEINDEX">CREATE INDEX</h2><p><em>Synopsis:</em></p><pre><code>CREATE INDEX [index_name] ON &lt;column_family&gt; (column_name);
</code></pre><p>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:</p><table><tr><th>type</th><th>description</th></tr><tr><td>bytea</td><td>Arbitrary bytes (no validation)</td></tr><tr><td>ascii</td><td>ASCII character string</td></tr><tr><td>text</td><td>UTF8 encoded string</td></tr><tr><td>varchar</td><td>UTF8 encoded string</td></tr><tr><td>uuid</td><td>Type 1, or type 4 UUID</td></tr><tr><td>varint</td><td>4-byte integer</td></tr><tr><td>bigint</td><td>8-byte long</td></tr></table><p><em>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 <code>AbstractType</code>), either fully qualified, or relative to the <code>org.apache.cassandra.db.marshal</code> package.</em></p><h3 id="ColumnFamilyOptionsoptional">Column Family Options (optional)</h3><pre><code>CREATE COLUMNFAMILY ... WITH keyword1 = arg1 AND keyword2 = arg2;
</code></pre><p>A number of optional keyword arguments can be supplied to control the configuration of a new column family.</p><table><tr><th>keyword</th><th>default</th><th>description</th></tr><tr><td>comparator</td><td>text</td><td>Determines sorting and validation of column names. Valid values are identical to the types listed in <a href="#columntypes">Specifying Column Type</a> above.</td></tr><tr><td>comment</td><td>none</td><td>A free-form, human-readable comment.</td></tr><tr><td>row_cache_size</td><td>0</td><td>Number of rows whose entire contents to cache in memory.</td></tr><tr><td>key_cache_size</td><td>200000</td><td>Number of keys per SSTable whose locations are kept in memory in &#8220;mostly LRU&#8221; order.</td></tr><tr><td>read_repair_chance</td><td>1.0</td><td>The probability with which read repairs should be invoked on non-quorum reads.</td></tr><tr><td>gc_grace_seconds</td><td>864000</td><td>Time to wait before garbage collecting tombstones (deletion markers).</td></tr><tr><td>default_validation</td><td>text</td><td>Determines validation of column values. Valid values are identical to the types listed in <a href="#columntypes">Specifying Column Type</a> above.</td></tr><tr><td>min_compaction_threshold</td><td>4</td><td>Minimum number of SSTables needed to start a minor compaction.</td></tr><tr><td>max_compaction_threshold</td><td>32</td><td>Maximum number of SSTables allowed before a minor compaction is forced.</td></tr><tr><td>row_cache_save_period_in_seconds</td><td>0</td><td>Number of seconds between saving row caches.</td></tr><tr><td>key_cache_save_period_in_seconds</td><td>14400</td><td>Number of seconds between saving key caches.</td></tr><tr><td>memtable_flush_after_mins</td><td>60</td><td>Maximum time to leave a dirty table unflushed.</td></tr><tr><td>memtable_throughput_in_mb</td><td>dynamic</td><td>Maximum size of the memtable before it is flushed.</td></tr><tr><td>memtable_operations_in_millions</td><td>dynamic</td><td>Number of operations in millions before the memtable is flushed.</td></tr><tr><td>replicate_on_write</td><td>false</td><td></td></tr></table><h2 id="CREATEINDEX">CREATE INDEX</h2><p><em>Synopsis:</em></p><pre><code>CREATE INDEX [index_name] ON &lt;column_family&gt; (column_name);
</code></pre><p>A <code>CREATE INDEX</code> statement is used to create a new, automatic secondary index for the named column.</p><h2 id="DROP">DROP</h2><p><em>Synopsis:</em></p><pre><code>DROP &lt;KEYSPACE|COLUMNFAMILY&gt; namespace;
</code></pre><p><code>DROP</code> statements result in the immediate, irreversible removal of keyspace and column family namespaces.</p><h2 id="CommonIdioms">Common Idioms</h2><h3 id="consistency">Specifying Consistency</h3><pre><code>... USING &lt;CONSISTENCY&gt; ...
</code></pre><p>Consistency level specifications are made up the keyword <code>USING</code>, followed by a consistency level identifier. Valid consistency levels are as follows:</p><ul><li><code>CONSISTENCY ZERO</code></li><li><code>CONSISTENCY ONE</code> (default)</li><li><code>CONSISTENCY QUORUM</code></li><li><code>CONSISTENCY ALL</code></li><li><code>CONSISTENCY DCQUORUM</code></li><li><code>CONSISTENCY DCQUORUMSYNC</code></li></ul><h3 id="terms">Term specification</h3><p>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:</p><ul><li>Any single quoted string literal (example: <code>'apple'</code>).</li><li>Unquoted alpha-numeric strings that begin with a letter (example: <code>carrot</code>).</li><li>Unquoted numeric literals (example: <code>100</code>).</li><li>UUID strings in hyphen-delimited hex notation (example: <code>1438fc5c-4ff6-11e0-b97f-0026c650d722</code>). </li></ul><p>Terms which do not conform to these rules result in an exception.</p><p>How column name/value terms are interpreted is determined by the configured type.</p><table><tr><th>type</th><th>term</th></tr><tr><td>ascii</td><td>Any string which can be decoded using ASCII charset</td></tr><tr><td>utf8</td><td>Any string which can be decoded using UTF8 charset</td></tr><tr><td>uuid</td><td>Standard UUID string format (hyphen-delimited hex notation)</td></tr><tr><td>timeuuid</td><td>Standard UUID string format (hyphen-delimited hex notation)</td></tr><tr><td>timeuuid</td><td>The string <code>now</code>, to represent a type-1 (time-based) UUID with a date-time component based on the current time</td></tr><tr><td>timeuuid</td><td>Numeric value representing milliseconds since epoch</td></tr><tr><td>timeuuid</td><td>An <a href="http://en.wikipedia.org/wiki/8601">iso8601 timestamp</a></td></tr><tr><td>long</td><td>Numeric value capable of fitting in 8 bytes</td></tr><tr><td>int</td><td>Numeric value of arbitrary size</td></tr><tr><td>bytes</td><td>Hex-encoded strings (converted directly to the corresponding bytes)</td></tr></table><h1 id="Versioning">Versioning</h1><p>Versioning of the CQL language adheres to the <a href="http://semver.org">Semantic Versioning</a> 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.</p><table><tr><th>version</th><th>description</th></tr><tr><td>Patch</td><td>The patch version is incremented when bugs are fixed.</td></tr><tr><td>Minor</td><td>Minor version increments occur when new, but backward compatible, functionality is introduced.</td></tr><tr><td>Major</td><td>The major version <em>must</em> be bumped when backward incompatible changes are introduced. This should rarely (if ever) occur.</td></tr></table><h1 id="Changes">Changes</h1><pre>Tue, 22 Mar 2011 18:10:28 -0700 - Eric Evans &lt;eevans@rackspace.com&gt;
</code></pre><p>Consistency level specifications are made up the keyword <code>USING</code>, followed by a consistency level identifier. Valid consistency levels are as follows:</p><ul><li><code>CONSISTENCY ZERO</code></li><li><code>CONSISTENCY ONE</code> (default)</li><li><code>CONSISTENCY QUORUM</code></li><li><code>CONSISTENCY ALL</code></li><li><code>CONSISTENCY DCQUORUM</code></li><li><code>CONSISTENCY DCQUORUMSYNC</code></li></ul><h3 id="terms">Term specification</h3><p>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:</p><ul><li>Any single quoted string literal (example: <code>'apple'</code>).</li><li>Unquoted alpha-numeric strings that begin with a letter (example: <code>carrot</code>).</li><li>Unquoted numeric literals (example: <code>100</code>).</li><li>UUID strings in hyphen-delimited hex notation (example: <code>1438fc5c-4ff6-11e0-b97f-0026c650d722</code>). </li></ul><p>Terms which do not conform to these rules result in an exception.</p><p>How column name/value terms are interpreted is determined by the configured type.</p><table><tr><th>type</th><th>term</th></tr><tr><td>ascii</td><td>Any string which can be decoded using ASCII charset</td></tr><tr><td>text / varchar</td><td>Any string which can be decoded using UTF8 charset</td></tr><tr><td>uuid</td><td>Standard UUID string format (hyphen-delimited hex notation)</td></tr><tr><td>uuid</td><td>Standard UUID string format (hyphen-delimited hex notation)</td></tr><tr><td>uuid</td><td>The string <code>now</code>, to represent a type-1 (time-based) UUID with a date-time component based on the current time</td></tr><tr><td>uuid</td><td>Numeric value representing milliseconds since epoch</td></tr><tr><td>uuid</td><td>An <a href="http://en.wikipedia.org/wiki/8601">iso8601 timestamp</a></td></tr><tr><td>bigint</td><td>Numeric value capable of fitting in 8 bytes</td></tr><tr><td>varint</td><td>Numeric value of arbitrary size</td></tr><tr><td>bytea</td><td>Hex-encoded strings (converted directly to the corresponding bytes)</td></tr></table><h1 id="Versioning">Versioning</h1><p>Versioning of the CQL language adheres to the <a href="http://semver.org">Semantic Versioning</a> 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.</p><table><tr><th>version</th><th>description</th></tr><tr><td>Patch</td><td>The patch version is incremented when bugs are fixed.</td></tr><tr><td>Minor</td><td>Minor version increments occur when new, but backward compatible, functionality is introduced.</td></tr><tr><td>Major</td><td>The major version <em>must</em> be bumped when backward incompatible changes are introduced. This should rarely (if ever) occur.</td></tr></table><h1 id="Changes">Changes</h1><pre>Tue, 22 Mar 2011 18:10:28 -0700 - Eric Evans &lt;eevans@rackspace.com&gt;
* Initial version, 1.0.0
</pre></body></html>

View File

@ -201,13 +201,13 @@ 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:
|_. 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

View File

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

View File

@ -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":

View File

@ -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]

View File

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

View File

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

View File

@ -35,8 +35,8 @@ public class TimeUUIDType extends AbstractType<UUID>
{
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",

View File

@ -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:<br>
* - if count of supplied bytes is less than 16, compare counts<br>
@ -200,6 +207,56 @@ public class UUIDType extends AbstractType<UUID>
@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;
}
}

View File

@ -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