[
https://issues.apache.org/jira/browse/CASSANDRA-11064?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15134351#comment-15134351
]
Sylvain Lebresne commented on CASSANDRA-11064:
----------------------------------------------
I did push the previous patch too quickly and there was actually 3 reasons why
the unit tests weren't passing:
# I had mis-handled {{null}} in the assertion of {{CreateAggregateStatement}}
so I've switch to {{Objects.equals}}.
# {{asCQLLiteral}} was indeed destructive of it's input which we clearly want
to avoid. That said, I think the {{duplicate()}} should be pushed where the
destruction is (in the Collection, UDT and Tuple cases) so that 1)
{{toCQLLitera}}, which is public after all, is also non-destructive, 2) it's
immediatly clear why duplication is needed and 3) we save duplication in the
common case of simple types which don't require it (not that performance
matters too much here...)
# {{Terms.asByte(type.asCQLLiteral(x))}} was not equal to {{x}} for {{x ==
null}} and {{type}} being a collection type because {{toCQLLiteral}} for
collections was converting {{null}} to an empty collection. I'm not sure what
was the rational behind this but it's a problem and it's not immediately clear
to me why we would want that in the first place. There was btw a bug in
{{CQL3TypeLiteralTest.testCollectionNullAndEmpty}} which was using an empty
{{ByteBuffer}} as an empty collection value but that's incorrect: an empty
collection is a collection with size 0, and an empty {{ByteBuffer}} is actually
invalid for a collection.
I fixed those on my branch above and restarted CI (hopefully it's clear now). I
did push another commit that is more of a nit, but I wasn't fan of using
{{StringBuilder}} all over the place in {{toCQLLiteral}} so the commit push the
use of them only for more complex literals (collections, UDT and tuples), which
imo is slightly cleaner code wise. It could be argued that it's a little bit
less efficient for nested complex values since we'll end up creating more
{{StringBuilder}} instances, but none of this is terribly performance
sensistive (and very complex value proobably not all that common in
{{INITCOND}}) so I prefer sticking to cleaner code until we can prove we need
to optimize. Anyway, if that change is contentious, I'm not gonna insist on it.
> Failed aggregate creation breaks server permanently
> ---------------------------------------------------
>
> Key: CASSANDRA-11064
> URL: https://issues.apache.org/jira/browse/CASSANDRA-11064
> Project: Cassandra
> Issue Type: Bug
> Reporter: Olivier Michallat
> Assignee: Robert Stupp
> Fix For: 3.0.x
>
>
> While testing edge cases around aggregates, I tried the following to see if
> custom types were supported:
> {code}
> ccm create v321 -v3.2.1 -n3
> ccm updateconf enable_user_defined_functions:true
> ccm start
> ccm node1 cqlsh
> CREATE FUNCTION id(i 'DynamicCompositeType(s => UTF8Type, i => Int32Type)')
> RETURNS NULL ON NULL INPUT
> RETURNS 'DynamicCompositeType(s => UTF8Type, i => Int32Type)'
> LANGUAGE java
> AS 'return i;';
> // function created successfully
> CREATE AGGREGATE ag()
> SFUNC id
> STYPE 'DynamicCompositeType(s => UTF8Type, i => Int32Type)'
> INITCOND 's@foo:i@32';
> ServerError: <ErrorMessage code=0000 [Server error]
> message="java.lang.RuntimeException: java.util.concurrent.ExecutionException:
> org.apache.cassandra.exceptions.SyntaxException: Failed parsing CQL term:
> [s@foo:i@32] reason: SyntaxException line 1:1 no viable alternative at
> character '@'">{code}
> Despite the error, the aggregate appears in system tables:
> {code}
> select * from system_schema.aggregates;
> keyspace_name | aggregate_name | ...
> ---------------+----------------+ ...
> test | ag | ...
> {code}
> But you can't drop it, and trying to drop its function produces the server
> error again:
> {code}
> DROP AGGREGATE ag;
> InvalidRequest: code=2200 [Invalid query] message="Cannot drop non existing
> aggregate 'test.ag'"
> DROP FUNCTION id;
> ServerError: <ErrorMessage code=0000 [Server error]
> message="java.lang.RuntimeException: java.util.concurrent.ExecutionException:
> org.apache.cassandra.exceptions.SyntaxException: Failed parsing CQL term:
> [s@foo:i@32] reason: SyntaxException line 1:1 no viable alternative at
> character '@'">
> {code}
> What's worse, it's now impossible to restart the server:
> {code}
> ccm stop; ccm start
> org.apache.cassandra.exceptions.SyntaxException: Failed parsing CQL term:
> [s@foo:i@32] reason: SyntaxException line 1:1 no viable alternative at
> character '@'
> at
> org.apache.cassandra.cql3.CQLFragmentParser.parseAny(CQLFragmentParser.java:48)
> at org.apache.cassandra.cql3.Terms.asBytes(Terms.java:51)
> at
> org.apache.cassandra.schema.SchemaKeyspace.createUDAFromRow(SchemaKeyspace.java:1225)
> at
> org.apache.cassandra.schema.SchemaKeyspace.fetchUDAs(SchemaKeyspace.java:1204)
> at
> org.apache.cassandra.schema.SchemaKeyspace.fetchFunctions(SchemaKeyspace.java:1129)
> at
> org.apache.cassandra.schema.SchemaKeyspace.fetchKeyspace(SchemaKeyspace.java:897)
> at
> org.apache.cassandra.schema.SchemaKeyspace.fetchKeyspacesWithout(SchemaKeyspace.java:872)
> at
> org.apache.cassandra.schema.SchemaKeyspace.fetchNonSystemKeyspaces(SchemaKeyspace.java:860)
> at org.apache.cassandra.config.Schema.loadFromDisk(Schema.java:125)
> at org.apache.cassandra.config.Schema.loadFromDisk(Schema.java:115)
> at
> org.apache.cassandra.service.CassandraDaemon.setup(CassandraDaemon.java:229)
> at
> org.apache.cassandra.service.CassandraDaemon.activate(CassandraDaemon.java:551)
> at
> org.apache.cassandra.service.CassandraDaemon.main(CassandraDaemon.java:680)
> {code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)