UPDATE/INSERT with null values irregular behavior from Java driver

780 views
Skip to first unread message

sopsaare@gmail.com

<sopsaare@gmail.com>
unread,
Oct 7, 2015, 5:25:01 AM10/7/15
to ScyllaDB users
Hi again!

I have continued testing with Scylla but now I run into an issue that is blocker for me.

The issue is best described as a problem setting some fields as "null" values in UPDATE or INSERT statement via Java Driver.
I'm not really sure if this is know problem or not but I was not able to find this exact problem anywhere else. 

My Scylla version is:

Installed Packages
Name        : scylla-server
Arch        : x86_64
Version     : 0.9
Release     : 20150924.4de5875.el7.centos



For Java Driver I tried 2.0.0 and 2.1.7. My JDK is Oracle 1.7.something.

Here created keyspace and columnfamily and tested the partial null UPDATE from cqlsh:

cqlsh> CREATE KEYSPACE test WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};
cqlsh> USE test ;
cqlsh:test> CREATE TABLE foobar ( key text PRIMARY KEY , val1 text , val2 float );
cqlsh:test> UPDATE foobar SET val1 = 'aaa', val2 = null WHERE key = 'bbb' ;
cqlsh:test> UPDATE foobar SET val1 = null, val2 = 1 WHERE key = 'ccc' ;
cqlsh:test> SELECT * FROM foobar ;

 key | val1 | val2
-----+------+------
 bbb |  aaa | null
 ccc | null |    1

(2 rows)

As can be seen this obviously worked.
Then I run this Java application:


package com.documill.discovery.db.test;

import com.datastax.driver.core.Cluster;
import com.datastax.driver.core.PreparedStatement;
import com.datastax.driver.core.Session;

public class Test
{
  public static void main(String... argh) throws Throwable
  {
    Cluster c = Cluster.builder().addContactPoint("scylladb").build();
    Session s = c.connect();
    s.execute("USE test;");
    System.out.println("using test");

    PreparedStatement ps = s.prepare("UPDATE foobar SET val1 = ?, val2 = ? WHERE key = ?;");

    s.execute(ps.bind("ccc", Float.valueOf(1f), "java1"));
    System.out.println("java1 done");

    s.execute(ps.bind(null, Float.valueOf(1f), "java2"));
    System.out.println("java2 done");

    s.execute(ps.bind(null, null, "java3"));
    System.out.println("java3 done");

    s.execute(ps.bind("ddd", null, "java4"));
    System.out.println("java4 done");
  }
}

And got Exception like this:

15/10/07 12:23:15 INFO core.NettyUtil: Found Netty's native epoll transport in the classpath, using it
15/10/07 12:23:15 INFO policies.DCAwareRoundRobinPolicy: Using data-center name 'datacenter1' for DCAwareRoundRobinPolicy (if this is incorrect, please provide the correct datacenter name with DCAwareRoundRobinPolicy constructor)
15/10/07 12:23:15 INFO core.Cluster: New Cassandra host scylladb/192.168.0.194:9042 added
using test
java1 done
java2 done
java3 done
Exception in thread "main" com.datastax.driver.core.exceptions.InvalidQueryException: marshaling error: Conversion failed
at com.datastax.driver.core.exceptions.InvalidQueryException.copy(InvalidQueryException.java:35)
at com.datastax.driver.core.DefaultResultSetFuture.extractCauseFromExecutionException(DefaultResultSetFuture.java:269)
at com.datastax.driver.core.DefaultResultSetFuture.getUninterruptibly(DefaultResultSetFuture.java:183)
at com.datastax.driver.core.AbstractSession.execute(AbstractSession.java:52)
at com.documill.discovery.archive.implementation.cql.ScyllaTester.main(ScyllaTester.java:28)
Caused by: com.datastax.driver.core.exceptions.InvalidQueryException: marshaling error: Conversion failed
at com.datastax.driver.core.Responses$Error.asException(Responses.java:102)
at com.datastax.driver.core.DefaultResultSetFuture.onSet(DefaultResultSetFuture.java:118)
at com.datastax.driver.core.RequestHandler.setFinalResult(RequestHandler.java:183)
at com.datastax.driver.core.RequestHandler.access$2300(RequestHandler.java:45)
at com.datastax.driver.core.RequestHandler$SpeculativeExecution.setFinalResult(RequestHandler.java:748)
at com.datastax.driver.core.RequestHandler$SpeculativeExecution.onSet(RequestHandler.java:573)
at com.datastax.driver.core.Connection$Dispatcher.channelRead0(Connection.java:991)
at com.datastax.driver.core.Connection$Dispatcher.channelRead0(Connection.java:913)
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)
at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:266)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:846)
at io.netty.channel.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:805)
at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:346)
at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:254)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112)
at java.lang.Thread.run(Thread.java:745)


After this I checked what happened in Scylla via cqlsh:

cqlsh:test> SELECT * FROM foobar ;

 key   | val1 | val2
-------+------+------
 java2 | null |    1
   bbb |  aaa | null
   ccc | null |    1
 java1 |  ccc |    1

(4 rows)


So it seems that the 4th statement was the problem where I tried to set val1 to "ddd" and val2 to null. That is obviously not the most elegant case but in my application I happen to have some wide column families which I update from long Object arrays which may contain some null fields. So creating new statement for 40 - cell wide column family every single time I have null somewhere in the array is not an option. 

Also this behavior cannot be replicated on standard Cassandra, this is the output when connecting to Cassandra 2.1.9. (I also tried with 2.0.X)

15/10/07 12:17:51 INFO core.NettyUtil: Found Netty's native epoll transport in the classpath, using it
15/10/07 12:17:52 INFO policies.DCAwareRoundRobinPolicy: Using data-center name 'datacenter1' for DCAwareRoundRobinPolicy (if this is incorrect, please provide the correct datacenter name with DCAwareRoundRobinPolicy constructor)
15/10/07 12:17:52 INFO core.Cluster: New Cassandra host localhost/127.0.0.1:9042 added
using test
java1 done
java2 done
java3 done
java4 done

And this is the view from cqlsh:

cqlsh:test> SELECT * FROM foobar ;

 key   | val1 | val2
-------+------+------
 java2 | null |    1
   bbb |  aaa | null
   ccc | null |    1
 java4 |  ddd | null
 java1 |  ccc |    1

(5 rows)




I played around and was able to replicate this behavior in pretty many ways but usually it consisted of some non text value set to null. Also using UPDATE or INSERT did not seem to matter. 

To me this does not seem to be correct behavior. Hope someone can clarify if I made some bad assumption or did not read something carefully enough. 


Brgs,
Sampo

Avi Kivity

<avi@scylladb.com>
unread,
Oct 7, 2015, 5:41:07 AM10/7/15
to scylladb-users@googlegroups.com
I think I see the problem.  Let me see if I can compile you application and test it out (my Java skills are very rusty).


--
You received this message because you are subscribed to the Google Groups "ScyllaDB users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scylladb-user...@googlegroups.com.
To post to this group, send email to scyllad...@googlegroups.com.
Visit this group at http://groups.google.com/group/scylladb-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/scylladb-users/4bd183c1-1ca6-4082-a516-5907e16f80b5%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Pekka Enberg

<penberg@scylladb.com>
unread,
Oct 7, 2015, 5:44:35 AM10/7/15
to ScyllaDB users, Sampo Saarela, Paweł Dziepak, Tomasz Grabiec
On Wed, Oct 7, 2015 at 12:25 PM, <sops...@gmail.com> wrote:
> Exception in thread "main"
> com.datastax.driver.core.exceptions.InvalidQueryException: marshaling error:
> Conversion failed
> at
> com.datastax.driver.core.exceptions.InvalidQueryException.copy(InvalidQueryException.java:35)

That "marshaling error" comes from ScyllaDB. Looks like we have a
issue with "null" handling for float types. Pawel, Tomek, comments?

- Pekka

Avi Kivity

<avi@scylladb.com>
unread,
Oct 7, 2015, 5:45:42 AM10/7/15
to scylladb-users@googlegroups.com, Sampo Saarela, Paweł Dziepak, Tomasz Grabiec
It's actually a text conversion ("Conversion error" comes from utf8
conversion). I think I see the source.

Tomasz Grabiec

<tgrabiec@scylladb.com>
unread,
Oct 7, 2015, 5:46:29 AM10/7/15
to Avi Kivity, scylladb-users@googlegroups.com, Sampo Saarela, Paweł Dziepak
Looks like string_type_impl::validate() doesn't tolerate nulls. 

Avi Kivity

<avi@scylladb.com>
unread,
Oct 7, 2015, 5:47:33 AM10/7/15
to scylladb-users@googlegroups.com, Sampo Saarela, Paweł Dziepak
It's a larger problem - it expects a NUL terminated value, but doesn't get one.  The fix is simple.

Shlomi Livne

<shlomi@scylladb.com>
unread,
Oct 7, 2015, 6:14:21 AM10/7/15
to ScyllaDB users, Sampo Saarela, Paweł Dziepak
I have replicated the issue using a python test - will add it to regression

from dtest import Tester, debug

class CQLAdditionalTests(Tester):

    def prepare(self):
        """
        Sets up cluster to test against.
        """
        cluster = self.cluster
        cluster.populate(1).start()
        return cluster


    def simple_null_value_tests(self):
        cluster = self.prepare()
        node1 = cluster.nodelist()[0]
        session = self.patient_cql_connection(node1)
        self.create_ks(session, 'ks', 1)
 
        session.execute("""

             CREATE TABLE foobar ( key text PRIMARY KEY , val1 text , val2 float );
        """)
 
        update = session.prepare("UPDATE foobar SET val1 = ?, val2 = ? WHERE key = ?;")
        session.execute(update.bind(("ccc", 1.0, "java1")))
        session.execute(update.bind((None, 1.0, "java2")))
        session.execute(update.bind((None, None, "java3")))
        session.execute(update.bind(("ddd", None, "java4")))
 
        res = session.execute("""
                SELECT * FROM foobar
        """)
        assert len(res) == 4, res
 

Avi/Sampo can you please file a bug so we can track it.


--
You received this message because you are subscribed to the Google Groups "ScyllaDB users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scylladb-user...@googlegroups.com.
To post to this group, send email to scyllad...@googlegroups.com.
Visit this group at http://groups.google.com/group/scylladb-users.

Avi Kivity

<avi@scylladb.com>
unread,
Oct 7, 2015, 6:21:56 AM10/7/15
to scylladb-users@googlegroups.com
Patch posted, if you are building from source, you can apply and test it.
--
You received this message because you are subscribed to the Google Groups "ScyllaDB users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scylladb-user...@googlegroups.com.
To post to this group, send email to scyllad...@googlegroups.com.
Visit this group at http://groups.google.com/group/scylladb-users.

Sampo Saarela

<sopsaare@gmail.com>
unread,
Oct 7, 2015, 6:37:26 AM10/7/15
to scylladb-users@googlegroups.com
Hi,

So this is repaired already? Fantastic! Any idea when I could be seeing update in the yum repository?

Brgs,
Sampo

You received this message because you are subscribed to a topic in the Google Groups "ScyllaDB users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/scylladb-users/NDotmFN7tRY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to scylladb-user...@googlegroups.com.

To post to this group, send email to scyllad...@googlegroups.com.
Visit this group at http://groups.google.com/group/scylladb-users.

Pekka Enberg

<penberg@scylladb.com>
unread,
Oct 7, 2015, 8:07:49 AM10/7/15
to ScyllaDB users, Shlomi Livne, Sampo Saarela
Hi,

On Wed, Oct 7, 2015 at 1:37 PM, Sampo Saarela <sops...@gmail.com> wrote:
> So this is repaired already? Fantastic! Any idea when I could be seeing
> update in the yum repository?

We are in the process of pushing 0.10 out. If things go well, you'll
have a shiny new RPM early next week.

- Pekka
Reply all
Reply to author
Forward
0 new messages