Nadav Har'El created CASSANDRA-21747:
----------------------------------------
Summary: CREATE AGGREGATE fails when INITCOND is a UDT value with
a field name that needs quoting
Key: CASSANDRA-21747
URL: https://issues.apache.org/jira/browse/CASSANDRA-21747
Project: Apache Cassandra
Issue Type: Bug
Reporter: Nadav Har'El
Tested on Cassandra 5.0.9 and 6.0-alpha2.
An aggregate whose state type is a user-defined type with a field name that
needs quoting (e.g., a case-sensitive name) can't be created with an INITCOND,
even though the INITCOND literal correctly quotes the field name:
{code:sql}
CREATE TYPE ks.t ("A" int);
CREATE FUNCTION ks.sf(s ks.t, x int) RETURNS NULL ON NULL INPUT RETURNS ks.t
LANGUAGE java AS 'return s;';
CREATE AGGREGATE ks.agg(int) SFUNC sf STYPE ks.t INITCOND {"A": 10};
{code}
fails with:
{noformat}
InvalidRequest: Error from server: code=2200 [Invalid query] message="Unknown
field 'a' in value of user defined type t"
{noformat}
With a field name containing a space, the cause is visible in the error message:
{code:sql}
CREATE TYPE ks.t2 ("my field" int);
CREATE FUNCTION ks.sf2(s ks.t2, x int) RETURNS NULL ON NULL INPUT RETURNS ks.t2
LANGUAGE java AS 'return s;';
CREATE AGGREGATE ks.agg2(int) SFUNC sf2 STYPE ks.t2 INITCOND {"my field": 10};
{code}
fails with:
{noformat}
SyntaxException: Error from server: code=2000 [Syntax error in CQL query]
message="Failed parsing CQL term: [{my field: 10}] reason: SyntaxException line
1:4 no viable alternative at input 'field' ...
{noformat}
A field name which doesn't need quoting works, with or without quotes in the
INITCOND (e.g., INITCOND \{"a": 10} for a field a).
The cause: CreateAggregateStatement doesn't use the already-parsed INITCOND
term, but converts it back to a string and parses that string again -
Terms.asBytes(keyspaceName, rawInitialValue.toString(), stateType) in 5.0, and
Term.asBytes(keyspaceName, rawInitialValue.toString(), stateType) in 6.0. For a
UDT literal, UserTypes.Literal's string form is built by
UserTypes.userTypeToString(), which prints each field name with
FieldIdentifier.toString(), i.e., the bare name without quotes. So
{"A": 10}
becomes
{A: 10}
, which is parsed as a value for the field a, and
{"my field": 10}
becomes
{my field: 10}
which isn't valid CQL.
Note that the form in which INITCOND is saved in the schema and printed by
DESCRIBE AGGREGATE - CQL3Type.UserDefined.toCQLLiteral() - does quote field
names when needed (ColumnIdentifier.maybeQuote()), so only the CREATE AGGREGATE
path is affected. A possible fix is to quote field names in
UserTypes.userTypeToString() when needed, or to avoid converting the parsed
INITCOND term back to a string.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]