incubator-cassandra-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alex Popescu <al...@datastax.com>
Subject Re: is this correct, thrift unportable to CQL3Š.
Date Wed, 25 Sep 2013 08:15:09 GMT
On Wed, Sep 25, 2013 at 12:22 AM, Sylvain Lebresne <sylvain@datastax.com>wrote:

> On Tue, Sep 24, 2013 at 7:24 PM, Hiller, Dean <Dean.Hiller@nrel.gov>wrote:
>
>> Java has Integer as opposed to int which is what I represent "golf
>> scores" with so to speak in my example.  In this case, Integer can be null
>> but of course maps to "empty" just fine.  What about querying for all golf
>> scores that are "empty" then?
>>
>
> The DataStax java driver already "maps" a null Integer to a null CQL3
> column, and so it *cannot* also map it to an empty value. And even though
> you cannot have null CQL3 columns in the primary key, mapping a null
> Integer to an empty value would be highly confusing/inconsistent (from the
> point of view of the java driver) because:
> 1) having a null Integer map differently depending on whether the
> receiving column is in the PK or not would be messy/surprising.
> 2) it's not really technically possible because internally the driver does
> not always have the information of whether the receiving column is in the
> PK or not
> 3) what about strings? Should we also map a null String to an empty value
> when the column is in the PK? Because that would mean mapping a null java
> String to an empty CQL3 string value and that just feel wrong. And if we
> don't do it, then it means we treat Integer and String differently with
> respect to null and that's too would be pretty confusing.
>
> But anyway, all of that is pretty specific to the java driver, so maybe if
> you guys want to debate that further we should move to the driver mailing
> list:
> https://groups.google.com/a/lists.datastax.com/forum/#!forum/java-driver-user
>
>
Nulls should definitely stay null (that's an old DB debate), but  if this
is a generic case, we might consider adding an emptyValue() helper method.
Would that be possible Sylvain?


> --
> Sylvain
>
>
>>
>> Ie. This sounds like this solution would be perfect if we can get rid of
>> the exception piece.
>>
>> Thanks much!!!
>> Dean
>>
>> From: Sylvain Lebresne <sylvain@datastax.com<mailto:sylvain@datastax.com
>> >>
>> Reply-To: "user@cassandra.apache.org<mailto:user@cassandra.apache.org>" <
>> user@cassandra.apache.org<mailto:user@cassandra.apache.org>>
>> Date: Tuesday, September 24, 2013 10:58 AM
>> To: "user@cassandra.apache.org<mailto:user@cassandra.apache.org>" <
>> user@cassandra.apache.org<mailto:user@cassandra.apache.org>>
>> Subject: Re: is this correct, thrift unportable to CQL3Š.
>>
>> On Tue, Sep 24, 2013 at 6:17 PM, Vikas Goyal <vikas@easility.com<mailto:
>> vikas@easility.com>> wrote:
>> Ok. Great. It works for String and Decimal/Float but not for integer data
>> type..
>> i.e,, if I am passing "" to the composite key column which is either text
>> or float, it works..
>>
>> session.execute(boundStatement.bind(rowkey, "", ByteBuffer.wrap(value)));
>>
>> But not working with bigint, int or varint..and getting following
>> exception;
>>
>> Exception:Invalid type for value 1 of CQL type varint, expecting class
>> java.math.BigInteger but class java.lang.String provided
>>
>> ..I am exploring more though..
>>
>> We're getting into details of the java driver at this point. For int,
>> what you can do is:
>>   boundStatement.setString("id", rowkey);
>>   boundStatement.setBytesUnsafe("columnname", ByteBuffer.wrap(new
>> byte[0]));
>>   boundStatement.setBytes("columnvalue", ByteBuffer.wrap(value));
>>
>> In other words, the shorthand BoundStatement.bind() won't let you insert
>> an empty value for types
>> that don't naturally have an empty value (like int; keep in mind that an
>> empty value is not the same
>> than null). But you can circumvent that using setBytesUnsafe if you
>> really want.
>>
>> Long story short, my advice would be to avoid using empty values for type
>> that don't naturally have
>> one (anything else than text and blob really). If you do, that's going to
>> be painful (but possible) to
>> work with, at least with the java driver (but for good reasons, java just
>> doesn't have a good to
>> represent an empty int value (again, you can have a null Integer but
>> that's different)).
>>
>> --
>> Sylvain
>>
>>
>> Thanks a ton,
>> Vikas Goyal
>>
>>
>> On Tue, Sep 24, 2013 at 9:05 PM, Sylvain Lebresne <sylvain@datastax.com
>> <mailto:sylvain@datastax.com>> wrote:
>>
>> However,we tried missing the value but it didn't work :(
>>
>> Right, because not providing a value is akin to having a null value (in
>> the CQL3 sense of the term, which is different from what Dean asked about)
>> and null values are not allowed for primary key columns.
>> You could however insert an *empty* value if you wanted, which in you
>> case is just inserting an empty string since colname is a string. Thrift
>> doesn't allow more or less in that case.
>>
>> --
>> Sylvain
>>
>>
>>
>> So our code is like below where we are using 3 values if colname is not
>> null..else 2 values..
>>
>>             if (key != null) {
>>                 PreparedStatement statement = session.prepare("INSERT
>> INTO keys.StringIndice (id, colname, colvalue) VALUES (?, ?, ?)");
>>                 BoundStatement boundStatement = new
>> BoundStatement(statement);
>>
>> session.execute(boundStatement.bind(StandardConverters.convertFromBytes(String.class,
>> rowKey), key, ByteBuffer.wrap(value)));
>>             } else {
>>                 PreparedStatement statement = session.prepare("INSERT
>> INTO " + keys + "." + table + "(id, colvalue) VALUES (?, ?)");
>>                 BoundStatement boundStatement = new
>> BoundStatement(statement);
>>
>> session.execute(boundStatement.bind(StandardConverters.convertFromBytes(String.class,
>> rowKey), ByteBuffer.wrap(value)));
>>           }
>>
>> And, I did that and getting this exception:
>>
>> Exception:Missing PRIMARY KEY part colname since colvalue is set
>>
>> And just FYI. Our Column Family definition is below:
>>
>> CREATE TABLE keys.StringIndice (id text,
>> colname text,
>> colvalue blob,
>> PRIMARY KEY (id,colname, colvalue)) WITH COMPACT STORAGE)
>>
>> Thanks again,
>> Vikas Goyal
>>
>>
>>
>> On Tue, Sep 24, 2013 at 7:02 PM, Sylvain Lebresne <sylvain@datastax.com
>> <mailto:sylvain@datastax.com>> wrote:
>> Short answer: not, this is not correct.
>>
>> Longer answer: what you call "null" is actually an empty value (which is
>> *not* the same thing, unless you consider an empty string is the same thing
>> than a null string). As it happens, C* always an empty value as a valid
>> value for any type and that's true of both thrift and CQL3. What is true is
>> that CQL3 discourage the use of empty values for type for which it doesn't
>> particularly make sense (integers typically) by not having a particular
>> easy to use syntax to input them. But that's supported nonetheless. If you
>> use a prepared statement for instance (where you send values already
>> serialized), nothing will prevent you from sending an empty value. Even if
>> you don't want to use a prepared statement, CQL3 has conversion functions (
>> http://cassandra.apache.org/doc/cql3/CQL.html#blobFun) that allows to do
>> it (for instance, "blobAsInt(0x)" will be an empty int value).
>>
>> --
>> Sylvain
>>
>>
>>
>> On Tue, Sep 24, 2013 at 2:36 PM, Hiller, Dean <Dean.Hiller@nrel.gov
>> <mailto:Dean.Hiller@nrel.gov>> wrote:
>> Many applications in thrift use the wide row with composite column name
>> and as an example, let's say golf score for instance and we end up with
>> golf score : pk like so
>>
>> null : pk56
>> null : pk45
>> 89 : pk90
>> 89: pk87
>> 90: pk101
>> 95: pk17
>>
>> Notice that there are some who do not have a golf score(zero would not
>> quite make sense and would be interpreted as a golf score).  I am hearing
>> from this post if they are correct that this is not portable to CQL3???  Is
>> this true?
>> http://stackoverflow.com/questions/18963248/how-can-i-have-null-column-value-for-a-composite-key-column-in-cql3
>>
>> (This sounds like a major deficit to me as the wide row now can only be
>> used where actual values exist?????).  Is it possible to port this pattern
>> to CQL3?
>>
>> Thanks,
>> Dean
>>
>>
>>
>>
>>
>>
>>
>>
>


-- 

:- a)


Alex Popescu
Sen. Product Manager @ DataStax
@al3xandru

Mime
View raw message