Re: is this correct, thrift unportable to CQL3Š.

2013-09-25 Thread Sylvain Lebresne
On Tue, Sep 24, 2013 at 7:24 PM, Hiller, Dean dean.hil...@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

--
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 sylv...@datastax.commailto:sylv...@datastax.com
 Reply-To: user@cassandra.apache.orgmailto:user@cassandra.apache.org 
 user@cassandra.apache.orgmailto:user@cassandra.apache.org
 Date: Tuesday, September 24, 2013 10:58 AM
 To: user@cassandra.apache.orgmailto:user@cassandra.apache.org 
 user@cassandra.apache.orgmailto:user@cassandra.apache.org
 Subject: Re: is this correct, thrift unportable to CQL3Š.

 On Tue, Sep 24, 2013 at 6:17 PM, Vikas Goyal vi...@easility.commailto:
 vi...@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 sylv...@datastax.com
 mailto:sylv...@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

Re: is this correct, thrift unportable to CQL3Š.

2013-09-25 Thread Alex Popescu
On Wed, Sep 25, 2013 at 12:22 AM, Sylvain Lebresne sylv...@datastax.comwrote:

 On Tue, Sep 24, 2013 at 7:24 PM, Hiller, Dean dean.hil...@nrel.govwrote:

 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 sylv...@datastax.commailto:sylv...@datastax.com
 
 Reply-To: user@cassandra.apache.orgmailto:user@cassandra.apache.org 
 user@cassandra.apache.orgmailto:user@cassandra.apache.org
 Date: Tuesday, September 24, 2013 10:58 AM
 To: user@cassandra.apache.orgmailto:user@cassandra.apache.org 
 user@cassandra.apache.orgmailto:user@cassandra.apache.org
 Subject: Re: is this correct, thrift unportable to CQL3Š.

 On Tue, Sep 24, 2013 at 6:17 PM, Vikas Goyal vi...@easility.commailto:
 vi...@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 sylv...@datastax.com
 mailto:sylv...@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

Re: is this correct, thrift unportable to CQL3Š.

2013-09-25 Thread Sylvain Lebresne
 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?


As said previously, debating this is outside the scope of this mailing
list, but to make it short, using empty values for types that don't
naturally support them like Integer is going to be painful (inserting is
one thing, handling them on the read side is another) and confusing no
matter what. So you should avoid it in the first place (and there is *tons*
of way to do that) and consequently adding an helper to do something you
should avoid is a bad idea.

--
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 sylv...@datastax.commailto:sylv...@datastax.com
 
 Reply-To: user@cassandra.apache.orgmailto:user@cassandra.apache.org
 user@cassandra.apache.orgmailto:user@cassandra.apache.org
 Date: Tuesday, September 24, 2013 10:58 AM
 To: user@cassandra.apache.orgmailto:user@cassandra.apache.org 
 user@cassandra.apache.orgmailto:user@cassandra.apache.org
 Subject: Re: is this correct, thrift unportable to CQL3Š.

 On Tue, Sep 24, 2013 at 6:17 PM, Vikas Goyal vi...@easility.commailto:
 vi...@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 sylv...@datastax.com
 mailto:sylv...@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 sylv...@datastax.com
 mailto:sylv...@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

Re: is this correct, thrift unportable to CQL3Š.

2013-09-24 Thread Vikas Goyal
Thanks Sylvain,

However,we tried missing the value but it didn't work :(

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 sylv...@datastax.comwrote:

 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.hil...@nrel.govwrote:

 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






Re: is this correct, thrift unportable to CQL3Š.

2013-09-24 Thread Sylvain Lebresne
 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 sylv...@datastax.comwrote:

 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.hil...@nrel.govwrote:

 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







Re: is this correct, thrift unportable to CQL3Š.

2013-09-24 Thread Vikas Goyal
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..

Thanks a ton,
Vikas Goyal


On Tue, Sep 24, 2013 at 9:05 PM, Sylvain Lebresne sylv...@datastax.comwrote:


 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 
 sylv...@datastax.comwrote:

 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.hil...@nrel.govwrote:

 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