mirror of https://github.com/apache/cassandra
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:
parent
5b9c402457
commit
de2ae8f91d
|
|
@ -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 <type> 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’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 <type> 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 “mostly LRU” 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 <column_family> (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 “mostly LRU” 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 <column_family> (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 <KEYSPACE|COLUMNFAMILY> 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 <CONSISTENCY> ...
|
||||
</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 <eevans@rackspace.com>
|
||||
</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 <eevans@rackspace.com>
|
||||
* Initial version, 1.0.0
|
||||
</pre></body></html>
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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":
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue