How to insert a custom type with map<text, boolean> field using cqlsh in Cassandra?

1.3k views Asked by At

I am getting an error like this:

field is not of type frozen<map<text, boolean>>

Any example for inserting a custom type object in which a filed is of type frozen<map<text, boolean>>?

Any idea how to do this with nodejs cassandra-driver?

UPDATE

Tried as @Olivier Michallat mentioned. But my answer is as below. Any idea why it comes like this instead of a josn?

cqlsh:test> create type t(m map<text, boolean>);
cqlsh:test> create table foo(k int primary key, v frozen<t>);
cqlsh:test> insert into foo(k,v) values (1, {m: {'foo': true}});
cqlsh:test> select * from foo;

 k | v
---+-------------------------------------------------------------------------
 1 | \x00\x00\x00\x10\x00\x00\x00\x01\x00\x00\x00\x03foo\x00\x00\x00\x01\x01

(1 rows)

UPDATE 2

Thanks @Olivier Michallat, the latest cqlsh gave me the expected results.


amt@amt-db:~$ docker run -it --rm --link cass1:cass poklet/cassandra cqlsh cass
Connected to Test Cluster at cass:9042.
[cqlsh 5.0.1 | Cassandra 2.1.5 | CQL spec 3.2.0 | Native protocol v3]
Use HELP for help.
cqlsh> use test;
cqlsh:test> create type setting(timeout timestamp, capabilities map<text, boolean>);
cqlsh:test> create table app(id uuid primary key, name text, defaultSetting frozen<setting>);
cqlsh:test> insert into app(id, name, defaultSetting) values (7031d49e-70cf-450d-90d8-178fa97c5e67, 'Test Cassandra', {timeout: 30, capabilities: {'read': true, 'write': false, 'delete': false}});
cqlsh:test> select * from app;

 id                                   | defaultsetting                                                                                       | name
--------------------------------------+------------------------------------------------------------------------------------------------------+----------------
 7031d49e-70cf-450d-90d8-178fa97c5e67 | {timeout: '1970-01-01 00:00:00+0000', capabilities: {'delete': False, 'read': True, 'write': False}} | Test Cassandra

(1 rows)
cqlsh:test> 

I updated my node version to "v0.12.4". But the nodejs cassandra-driver does not give me expected response.

//filename: udt.js
var cassandra = require('cassandra-driver');

var options = {
    contactPoints: ["192.168.2.203"],
    keyspace: "test",
    encoding: {
        map: Map,
        set: Set
    }
};
var client = new cassandra.Client(options);

client.connect(function (err) {
    if(err){
        console.info("connect err", err);
        return;
    }
    var query = 'select * from app';
    client.execute(query, function(err, result){
        if (err) {
            console.info("query err", err);
            return;
        }
        console.info(result.rows);
    });
});

See the result


manu@kochi:~/app/test$ node udt.js 
[ { id: Uuid: 7031d49e-70cf-450d-90d8-178fa97c5e67,
    defaultsetting: 
     { timeout: Thu Jan 01 1970 05:30:00 GMT+0530 (IST),
       capabilities: {} },
    name: 'Test Cassandra' } ]

@BryceAtNetwork23 any idea why 'capabilities' are not shown using node cassandra-driver?

2

There are 2 answers

3
Olivier Michallat On

Here's an example in cqlsh. The column holding the user type must be marked frozen (which indicates that Cassandra serializes it as a single value):

cqlsh:test> create type t(m map<text, boolean>);
cqlsh:test> create table foo(k int primary key, v frozen<t>);
cqlsh:test> insert into foo(k,v) values (1, {m: {'foo': true}});
cqlsh:test> select * from foo;

 k | v
---+--------------------
 1 | {m: {'foo': True}}

(1 rows)
2
Aaron On

I'll take the second part of your question.

Any idea how to do this with nodejs cassandra-driver?

Based on what I'm seeing in the DataStax node.js driver documentation on collections, you should use Javascript objects as a map value (using similar naming conventions to what Oliver has indicated):

var key = 1;
var m = {
   foo: true
};
var query = 'UPDATE foo SET v = ? WHERE k = ?';
client.execute(query, [m, key], { prepare: true}, callback);