Skip to content
This repository has been archived by the owner on Feb 22, 2019. It is now read-only.

CQL3 Map Collection type returning interesting value #113

Closed
somecallmemike opened this issue Aug 13, 2013 · 8 comments
Closed

CQL3 Map Collection type returning interesting value #113

somecallmemike opened this issue Aug 13, 2013 · 8 comments

Comments

@somecallmemike
Copy link

Edit: forgot to mention I am using version 0.6.2
Edit2: Cleaned up the formatting (missing special chars that were not escaped)

I have a CQL3 table that was created like this:

CREATE TABLE table (
usr text,
box text,
uidseq map<bigint, text>,
PRIMARY KEY (usr, box)
)

On the cqlsh command line I run the following query and get back my map:

select uidseq from table WHERE usr = 'usr' AND box = 'box';

uidseq
{1: 'a', 2: 'a'}

However when I run the same query through Helenus I am getting back a buffer as the value:

results.forEach(function(row){
row.forEach(function(name,value,ts,ttl){
if (Buffer.isBuffer(value)) {
console.log('its a buffer', value);
}
});
});

it's a buffer <Buffer 00 02 00 08 00 00 00 00 00 00 00 01 00 01 61 00 08 00 00 00 00 00 00 00 02 00 01 61>

Which when run through toString('utf-8') the buffer contains the letter 'a'. I have not been able to determine what object type the return value of the map collection type is, and pretty stuck as to how to approach the issue at this point.

@industral
Copy link

confirm. has the same issue

@daviddamen
Copy link

I have the same issue with a set column in the table. Also using version 0.6.2.

@devdazed
Copy link
Contributor

devdazed commented Sep 5, 2013

the issue here is that there isn't any decoder for the collection types. I'm not sure how we would go about it as it is difficult to tell if this is a collection type or if it is just a standard composite column.

@daviddamen
Copy link

In our own project, we can work around it. It's a set of strings, so we call toString('utf8') on the Buffer that's returned and then split it on the delimiter. Unfortunately, I'm not well versed enough (yet?) in these technologies to provide a meaningful general solution.

@jaredhirsch
Copy link

uggg, this is a bummer. Even just having a set of convenience functions like parseMap is better than handing off a raw buffer. +1 to give this bug some attention

@devdazed
Copy link
Contributor

devdazed commented Sep 6, 2013

So, basically this can only be done in CQL3. The reason why is that the Thrift API doesn't really expose enough info (specifically the type information) to be able to decode these columns properly and differentiate them from standard composite columns.

From the blog post: http://www.datastax.com/dev/blog/cql3_collections

The slightly longer, more nuanced answer is that internally each collection is implemented 
using one column per element, and with some composite comparator trick to make that work. 
So in theory you could access those columns from thrift, but you’d have to regroup the columns 
together, and the thrift API doesn’t expose enough metadata, so this will be hard to correctly.

Basically, the only way it can be easily decoded is roll your own parseMap methods because only you know the types that that you are using in your Collections.

I would love to give a method to parse these, but I just don't see a way using Thrift, I expose the raw buffer so that the user can parse the data themselves. For information of how to parse the composite types, you can check out the marshal portion of the driver.

Unless someone can be able to parse out the type information from the columns, I'm afraid I'm going to have to close this one.

@devdazed devdazed closed this as completed Sep 6, 2013
@leonardlabuneti
Copy link

I managed to decode the returned buffer and get the data for the field type SET, it can be done only if you have fixed length values and you know the length,

var elemLength = 10; //10 - nr of chars - lets suppose you store strings
allElems = new Array();

results.forEach(function(row){

var elems = row.get('field').value;
elems = elems.toString('utf-8');

//remove non-alphanumeric chars from the result
elems = elems.replace(/\W/g,'');

for(var i = 0;i<elems.length;i+=elemLength){
var elem = elem.substr(i,elemLength);
allElems.push(elem);
}

});
console.log(allElems);

@devdazed
Copy link
Contributor

This should be fixed in 0.6.8

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants