May a Cassandra (CQL 3) map
hold null values? I thought null values were permitted, but failure of my program suggests otherwise. Or is there a bug in the driver I am using?
The official documentation for CQL map
s says:
A map is a typed set of key-value pairs, where keys are unique. Furthermore, note that the map are internally sorted by their keys and will thus always be returned in that order.
So the keys may not be null (otherwise sorting would be impossible), but there is no mention of a requirement that map values are not null.
I have a field that is a map<timestamp,uuid>
, which I am trying to write to using values in a Java Map< Date, UUID >
. One of the map values (UUID
s) is null. This seems to cause a NPE in the Cassandra client code (Cassandra version 1.2.6, called from DataStax Java driver 1.0.1) when marshalling the UUID of the map:
java.lang.NullPointerException
at org.apache.cassandra.utils.UUIDGen.decompose(UUIDGen.java:82)
at org.apache.cassandra.cql.jdbc.JdbcUUID.decompose(JdbcUUID.java:55)
at org.apache.cassandra.db.marshal.UUIDType.decompose(UUIDType.java:187)
at org.apache.cassandra.db.marshal.UUIDType.decompose(UUIDType.java:43)
at org.apache.cassandra.db.marshal.MapType.decompose(MapType.java:122)
at org.apache.cassandra.db.marshal.MapType.decompose(MapType.java:29)
at com.datastax.driver.core.BoundStatement.bind(BoundStatement.java:188)
at [my method]
The UUIDGen.decompose(UUID)
method has no special handling of a null UUID
, hence the NPE. Contrast with JdbcBoolean.decompose(Boolean)
, which decomposes a null Boolean
to an empty byte-buffer. Similarly, JdbcDate.decompose(Date)
decomposes a null Date
to an empty byte-buffer.
I can produce a similar problem if I have a map holding null integers (using a Java Map< Date, Integer >
with a null value, for a Cassandra map<timestamp,int>
), so this problem is not restricted to uuid
values.
Cassandra requires all fields in the WHERE clause to be part of the primary key. Cassandra will not allow a part of a primary key to hold a null value. While Cassandra will allow you to create a secondary index on a column containing null values, it still won't allow you to query for those null values.
To complete a distributed DELETE operation, Cassandra replaces it with a special value called a tombstone which can be propagated to replicas. When inserting or updating a field, you can set a certain field to null as a way to clear the value of a field, and it is considered a DELETE operation.
A map is a name and a pair of typed values. Using the map type, you can store timestamp-related information in user profiles. Each element of the map is internally stored as one Cassandra column that you can modify, replace, delete, and query.
You are right, null values are not (yet?) supported inside Maps. I faced this thing before and like you couldn't find relative documentation -- In similar situation I help myself with cqlsh
A small test give you the answer
CREATE TABLE map_example (
id text,
m map<text, text>,
PRIMARY KEY ((id))
)
try
insert into map_example (id, m ) VALUES ( 'a', {'key':null});
> Bad Request: null is not supported inside collections
HTH, Carlo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With