Cassandra 2.1:通过嵌套 UDT 进行递归

Cassandra 2.1: Recursion by nesting UDT's

我一直在研究用户定义的类型,发现您可以这样做:

cqlsh:test> CREATE TYPE ping(time timestamp);
cqlsh:test> CREATE TYPE pong(time timestamp, ping frozen <ping>);
cqlsh:test> ALTER TYPE ping ADD pong frozen <pong>;


cqlsh:test> DESC TYPE ping ;

CREATE TYPE test.ping (
    time timestamp,
    pong frozen<pong>
);

cqlsh:test> DESC TYPE pong ;

CREATE TYPE test.pong (
    time timestamp,
    ping frozen<ping>
);

这与任何用例相关吗?

好吧,我没有 seen/heard 这些用例中的任何一个,但是您可以使用这样的结构来存储树或链表(尽管 Cassandra 已经支持列表,所以我不确定好处是)。

刚刚在处理密切相关的 Java driver ticket 时遇到这个问题。

该模式似乎是递归的,但当您实际尝试插入数据时它不起作用:

// (using int instead of time for the sake of clarity)
cqlsh:test> create type ping(pingid int);
cqlsh:test> create type pong(pongid int, ping frozen<ping>);
cqlsh:test> alter type ping ADD pong frozen<pong>;
cqlsh:test> create table foo(ping frozen<ping> primary key);

// These are OK:

cqlsh:test> insert into foo(ping) values( {pingid:1} );

cqlsh:test> insert into foo(ping) values(
    { pingid:1, 
      pong: { pongid:2, 
              ping: {pingid: 3}}} );

// But notice what happens when you nest one more level:

cqlsh:test> insert into foo(ping) values(
    { pingid:1, 
      pong: { pongid:2, 
              ping: {pingid: 3, 
                     pong: {pongid: 4}}}} );
InvalidRequest: code=2200 [Invalid query] message="Unknown field 'pong' in value of user
defined type ping"

看起来在 pong 定义时使用的 ping 是一个 "copy",没有看到 ALTER 语句的效果。所以我的猜测是不允许递归并且缺少检查。当我得到 Cassandra 开发人员的确认后,我会更新我的答案。

一个有趣的副作用是您之后既不能删除 ping 也不能删除 pong :-)


编辑: 这确实是 ALTER TYPE 不应该允许的事情。参见 CASSANDRA-10339