Support IN ? bindings

Description

I tried to use the following CQL query:
DELETE FROM table WHERE id IN ?

using Java driver like this:
prepStatement.setList("id", idsAsList);

but got the following exception:

java.lang.IllegalArgumentException: id is not a column defined in this metadata at com.datastax.driver.core.ColumnDefinitions.getAllIdx(ColumnDefinitions.java:273) at com.datastax.driver.core.BoundStatement.setList(BoundStatement.java:840)

Debugger shows that Cassandra sends "in(id)" in metadata but driver tries to bind "id".

See mail thread for more details: https://groups.google.com/a/lists.datastax.com/forum/#!topic/java-driver-user/U7mlKcoDL5o
Cassandra bugreport: CASSANDRA-6393

Environment

None

Pull Requests

None

Attachments

1

Activity

Show:

Mikhail Mazursky 
November 27, 2013 at 3:07 AM

Sylvain, thanks for explaining all that stuff! Now, when I finally understand what is going on, I completely agree with you. I will just continue to use "in(id)" binding.
Also I wasn't aware about aliases e.g. SELECT a AS X FROM.... syntax.

Sylvain Lebresne 
November 26, 2013 at 6:16 PM

I agree that more documentation would be needed and that a bunch of examples would help there.

But as for adding a new method, I'd really rather not. We now have named bind variables and it's a good idea to just use them all the time and not care about this. And in fact, because of named bind variables, we can't really add a setIn() method cleanly, because if the use has name it's variable that name will be used in the metadata and we don't really have a way to know it driver side.

Also, there is a somewhat situation with functions calls, if you do WHERE token(foo) = ?, the metadata will also have 'token(foo)', not 'foo'. So we would need a setToken() method too? And if we do that, what about SELECT blobAsInt(foo) FROM ... which will yield 'blobAsInt(foo)' in the metadata? Should we also have getter for it? In all cases the user can easily force the name in the metadata through CQL (using either named bind variables or aliases for the select case), so I don't think adding more API functions to the driver really adds anything except a bigger API.

Mikhail Mazursky 
November 26, 2013 at 5:31 PM

Ok. Maybe a new method should be added to set such bindings? Something like boundStatement.setIn(String, Collection<T>)? IMO current API is great but it is a bit unfriendly for that particular usecase. How should someone find out that it should be used that way? slightly smiling face There are no examples in documentation.

Sylvain Lebresne 
November 26, 2013 at 5:21 PM

There isn't anything to do here really. I'm sorry I read the initial email too quickly but there wasn't any bug here. Cassandra doesn't name the column 'id' in the metadata because that would be incorrect as 'id' is a uuid (I'm using you example names and types) but what's expected in this position is a list<uuid> because it's a "list of values for 'id'". To indicate that, cassandra uses 'in(id)' instead. And that's fine. If you want to set the value, the name is 'in(id)' so either use that, or, if you prefer, use a named bind variables in the first place. But there is not bug, the exception you get is correct in particular.

Not a Problem

Details

Assignee

Reporter

Labels

Affects versions

Components

Priority

Created November 26, 2013 at 11:05 AM
Updated December 12, 2013 at 9:54 PM
Resolved November 26, 2013 at 5:21 PM

Flag notifications