David Capwell created CASSANDRA-20479:
-----------------------------------------

             Summary: Inconsistent semantic when CAS condition is on a UDT 
column
                 Key: CASSANDRA-20479
                 URL: https://issues.apache.org/jira/browse/CASSANDRA-20479
             Project: Apache Cassandra
          Issue Type: Bug
          Components: Feature/Lightweight Transactions
            Reporter: David Capwell


{code}
@Test
public void test() throws IOException
{
    try (Cluster cluster = Cluster.build(1).start())
    {
        var inst = cluster.get(1);
        init(cluster);
        cluster.schemaChange(withKeyspace("CREATE TYPE %s.foo(f1 int)"));
        cluster.schemaChange(withKeyspace("CREATE TABLE %s.tbl(pk int, v0 foo, 
v1 int, PRIMARY KEY(pk))"));

        inst.executeInternal(withKeyspace("INSERT INTO %s.tbl(pk, v1) VALUES 
(?, ?)"), 0, 0);

        AssertUtils.assertRows(inst.executeInternal(withKeyspace("SELECT * FROM 
%s.tbl WHERE v0=? ALLOW FILTERING"), ByteBufferUtil.EMPTY_BYTE_BUFFER),
                               rows());
    }
}
{code}

This fails with 

{code}
org.apache.cassandra.exceptions.InvalidRequestException: Non-frozen UDT column 
'v0' (foo) cannot be restricted by any relation

        at 
org.apache.cassandra.cql3.statements.RequestValidations.invalidRequest(RequestValidations.java:370)
        at 
org.apache.cassandra.cql3.statements.RequestValidations.checkTrue(RequestValidations.java:97)
        at 
org.apache.cassandra.cql3.statements.RequestValidations.checkFalse(RequestValidations.java:223)
        at org.apache.cassandra.cql3.Operator.validateFor(Operator.java:964)
{code}

But we allow this in a CAS condition

{code}
@Test
public void test2() throws IOException
{
    try (Cluster cluster = Cluster.build(1).start())
    {
        var coord = cluster.coordinator(1);
        init(cluster);
        cluster.schemaChange(withKeyspace("CREATE TYPE %s.foo(f1 int)"));
        cluster.schemaChange(withKeyspace("CREATE TABLE %s.tbl(pk int, v0 foo, 
v1 int, PRIMARY KEY(pk))"));

        coord.execute(withKeyspace("UPDATE %s.tbl SET v1=? WHERE pk=? IF 
v0=?"), ConsistencyLevel.QUORUM, 0, 0, ByteBufferUtil.EMPTY_BYTE_BUFFER);

        AssertUtils.assertRows(coord.execute(withKeyspace("SELECT * FROM 
%s.tbl"), ConsistencyLevel.SERIAL),
                               rows());
    }
}
{code}

This test fails differently, it fails because the condition actually applied!

{code}
java.lang.AssertionError: Expected: []
Actual: [[0, null, 0]]
{code}

The reason this happens is we don’t seem to validate the operations like we do 
in the WHERE clause, and 
org.apache.cassandra.cql3.Operator#isSatisfiedBy(org.apache.cassandra.db.marshal.MultiElementType<?>,
 org.apache.cassandra.db.rows.ComplexColumnData, java.nio.ByteBuffer) defines 
the following

{code}
if (elements.isEmpty())
    return leftOperand == null;
{code}

Since the row doesn’t exist, leftOperand is null, and elements is empty (tuple 
of null values != null logically).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org
For additional commands, e-mail: commits-h...@cassandra.apache.org

Reply via email to