Uploaded image for project: 'Cassandra'
  1. Cassandra
  2. CASSANDRA-10954

[Regression] Error when removing list element with UPDATE statement

    XMLWordPrintableJSON

Details

    • Normal

    Description

      Steps to reproduce:

      CREATE TABLE simple(
        id int PRIMARY KEY,
        int_list list<int>
      );
      
      INSERT INTO simple(id, int_list) VALUES(10, [1,2,3]);
      SELECT * FROM simple;
      
       id | int_list
      ----+-----------
       10 | [1, 2, 3]
      
      UPDATE simple SET int_list[0]=null WHERE id=10;
      ServerError: <ErrorMessage code=0000 [Server error] message="java.lang.AssertionError">
      

      Per CQL semantics, setting a column to NULL == deleting it.

      When using debugger, below is the Java stack trace on server side:

       ERROR o.apache.cassandra.transport.Message - Unexpected exception during request; channel = [id: 0x6dbc33bd, /192.168.51.1:57723 => /192.168.51.1:9473]
      java.lang.AssertionError: null
      	at org.apache.cassandra.db.rows.BufferCell.<init>(BufferCell.java:49) ~[cassandra-all-3.1.1.jar:3.1.1]
      	at org.apache.cassandra.db.rows.BufferCell.tombstone(BufferCell.java:88) ~[cassandra-all-3.1.1.jar:3.1.1]
      	at org.apache.cassandra.cql3.UpdateParameters.addTombstone(UpdateParameters.java:141) ~[cassandra-all-3.1.1.jar:3.1.1]
      	at org.apache.cassandra.cql3.UpdateParameters.addTombstone(UpdateParameters.java:136) ~[cassandra-all-3.1.1.jar:3.1.1]
      	at org.apache.cassandra.cql3.Lists$SetterByIndex.execute(Lists.java:362) ~[cassandra-all-3.1.1.jar:3.1.1]
      	at org.apache.cassandra.cql3.statements.UpdateStatement.addUpdateForKey(UpdateStatement.java:94) ~[cassandra-all-3.1.1.jar:3.1.1]
      	at org.apache.cassandra.cql3.statements.ModificationStatement.addUpdates(ModificationStatement.java:666) ~[cassandra-all-3.1.1.jar:3.1.1]
      	at org.apache.cassandra.cql3.statements.ModificationStatement.getMutations(ModificationStatement.java:606) ~[cassandra-all-3.1.1.jar:3.1.1]
      	at org.apache.cassandra.cql3.statements.ModificationStatement.executeWithoutCondition(ModificationStatement.java:413) ~[cassandra-all-3.1.1.jar:3.1.1]
      	at org.apache.cassandra.cql3.statements.ModificationStatement.execute(ModificationStatement.java:401) ~[cassandra-all-3.1.1.jar:3.1.1]
      	at org.apache.cassandra.cql3.QueryProcessor.processStatement(QueryProcessor.java:206) ~[cassandra-all-3.1.1.jar:3.1.1]
      	at org.apache.cassandra.cql3.QueryProcessor.processPrepared(QueryProcessor.java:472) ~[cassandra-all-3.1.1.jar:3.1.1]
      	at org.apache.cassandra.cql3.QueryProcessor.processPrepared(QueryProcessor.java:449) ~[cassandra-all-3.1.1.jar:3.1.1]
      	at org.apache.cassandra.transport.messages.ExecuteMessage.execute(ExecuteMessage.java:130) ~[cassandra-all-3.1.1.jar:3.1.1]
      	at org.apache.cassandra.transport.Message$Dispatcher.channelRead0(Message.java:507) [cassandra-all-3.1.1.jar:3.1.1]
      	at org.apache.cassandra.transport.Message$Dispatcher.channelRead0(Message.java:401) [cassandra-all-3.1.1.jar:3.1.1]
      	at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) [netty-all-4.0.23.Final.jar:4.0.23.Final]
      	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333) [netty-all-4.0.23.Final.jar:4.0.23.Final]
      	at io.netty.channel.AbstractChannelHandlerContext.access$700(AbstractChannelHandlerContext.java:32) [netty-all-4.0.23.Final.jar:4.0.23.Final]
      	at io.netty.channel.AbstractChannelHandlerContext$8.run(AbstractChannelHandlerContext.java:324) [netty-all-4.0.23.Final.jar:4.0.23.Final]
      	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_60-ea]
      	at org.apache.cassandra.concurrent.AbstractTracingAwareExecutorService$FutureTask.run(AbstractTracingAwareExecutorService.java:164) [cassandra-all-3.1.1.jar:3.1.1]
      	at org.apache.cassandra.concurrent.SEPWorker.run(SEPWorker.java:105) [cassandra-all-3.1.1.jar:3.1.1]
      	at java.lang.Thread.run(Thread.java:745) [na:1.8.0_60-ea]
      

      The root cause seems to be located at org.apache.cassandra.cql3.Lists:362 :

                  CellPath elementPath = existingRow.getComplexColumnData(column).getCellByIndex(idx).path();
                  if (value == null)
                  {
                      params.addTombstone(column);
                  }
                  else if (value != ByteBufferUtil.UNSET_BYTE_BUFFER)
                  {
                      params.addCell(column, elementPath, value);
                  }
      

      In the if block, it seems we do not pass the CellPath as it should be and it makes the asertion assert column.isComplex() == (path != null); fails at
      org.apache.cassandra.db.rows:49

          public BufferCell(ColumnDefinition column, long timestamp, int ttl, int localDeletionTime, ByteBuffer value, CellPath path)
          {
              super(column);
              assert column.isComplex() == (path != null);
              ....
         }
      

      Another remark about the code block in org.apache.cassandra.cql3.Lists:362, there is an if/else if but there is no final else block to catch all other alternatives, is it intended or just an oversight ?

      Attachments

        Activity

          People

            slebresne Sylvain Lebresne
            doanduyhai DuyHai Doan
            Sylvain Lebresne
            Benjamin Lerer
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: