Cassandra 2.1:通过嵌套UDT的递归 [英] Cassandra 2.1: Recursion by nesting UDT's
问题描述
我在玩用户定义的类型,发现你可以这样做:
cqlsh:test> ; CREATE TYPE ping(时间时间戳);
cqlsh:test> CREATE TYPE pong(时间时间戳,ping冷冻< ping>);
cqlsh:test> ALTER TYPE ping ADD pong frozen< pong> ;;
cqlsh:test> DESC类型ping;
CREATE TYPE test.ping(
time timestamp,
pong frozen< pong>
);
cqlsh:test> DESC类型pong;
CREATE TYPE test.pong(
time timestamp,
ping frozen< ping>
);
这是否与任何用例相关?
该模式似乎是递归的,但是当你实际尝试插入数据时不起作用:
//(为了清楚起见,使用int而不是时间)
cqlsh:test>创建类型ping(pingid int);
cqlsh:test>创建类型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);
//这些都可以:
cqlsh:test> insert into foo(ping)values({pingid:1});
cqlsh:test>插入到foo(ping)值(
{pingid:1,
pong:{pongid:2,
ping:{pingid:3}}});
//但是请注意,当你嵌套一个级别时会发生什么:
cqlsh:test>插入到foo(ping)值(
{pingid:1,
pong:{pongid:2,
ping:{pingid:3,
pong:{pongid:4} }}});
InvalidRequest:code = 2200 [无效的查询] message =未知的字段'pong'在用户的值
定义类型ping
看起来像 pong
时使用的 ping
defined是一个副本,没有看到ALTER语句的效果。所以我的猜测是递归是不允许的,有一个缺失的检查。
一个有趣的副作用是你既不能删除 ping
pong
之后: - ) EDIT:这确实是 ALTER TYPE
不允许的。请参阅 CASSANDRA-10339 。
I was playing around with the user-defined types and found out you can do something like this:
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>
);
Is this relevant for any use case?
Just came across this while working on a closely related Java driver ticket.
The schema appears to be recursive, but that doesn't work when you actually try to insert data:
// (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"
Looks like the ping
that was used at the time pong
was defined is a "copy" that didn't see the effect of the ALTER statement. So my guess is that recursivity is not allowed and there is a missing check. I'll update my answer when I get confirmation from the Cassandra developers.
One interesting side-effect is that you can delete neither ping
nor pong
after that :-)
EDIT: this is indeed something that ALTER TYPE
should not allow. See CASSANDRA-10339.
这篇关于Cassandra 2.1:通过嵌套UDT的递归的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!