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。
我一直在研究用户定义的类型,发现您可以这样做:
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。