Description
This issue exists also in the Datastax driver, so it should probably be fixed in both but I'm reporting it here for now.
Normally, passing the Python value None
as a bind value for a prepared statement passes the CQL null value - i.e., a value with length=-1.
However, it seems that when we bind a collection type, and it includes a None as one of the elements, e.g., the list ['hello', None]
, the driver mistakenly converts the None
not to null but to an empty value (value with length=0) which is probably not what we want.
For example, consider that we have a table with schema p int primary key, v list<text>
, and do:
stmt = cql.prepare(f"INSERT INTO {table} (p,v) VALUES ({p}, ?)")
cql.execute(stmt, [['hello',None]])
What we'd expect this to do is to attempt to to insert null
into the list, basically the same thing as the unprepared statement INSERT INTO {table} (p,v) VALUES ({p}, ['hi', null])
. This attempt should be refused by the server, because nulls elements not allowed in collections. But what the driver does instead is to send the empty value for this None
. In the case of the string this is nothing else than an empty string - so basically Scylla is told to write an empty string... Instead of the write failing, it succeeds and if we now do cql.execute(f"SELECT * FROM {table} WHERE p={p}"))
the result is the silly [(p, ['hello',''])]
.
scylladb/scylladb#12425 contains two tests for this in Scylla's test framework which uses the Python driver to make requests. It demonstrates the situation described above for the string type (causing an empty string to be written instead of reporting an error) and also for integer type (in this case, Cassandra gets confused by the empty integer and returns some strange internal error).