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]

Reply via email to