Exception on UDT => CLR mapping of collection property which has null value
CSHARP-801
Some graph related classes depend on the current culture
CSHARP-832
Refine connection errors for connecting to cloud instance that may have been parked
CSHARP-829
Include test with node changing address
CSHARP-828
Policies.NewDefaultLoadBalancingPolicy and Policies.DefaultLoadBalancingPolicy return the default OSS default
CSHARP-821
Support using the same POCO and mappings in multiple keyspaces
CSHARP-820
Add option to keep contact points unresolved and always re-resolve when there's total connectivity loss
CSHARP-819
Reduce integration tests execution time
CSHARP-818
"Local datacenter is not specified" message is logged if user specifies it with the default execution profile
CSHARP-816
Add documentation about batch support for LINQ and Mapper
CSHARP-812
Add Mapper and Linq2Cql example projects
CSHARP-811
Consider retrying on the next host immediately if Unsent is true
CSHARP-809
Drop support for .NET Standard 1.5
CSHARP-806
Handle prepared id mismatch when repreparing on the fly
CSHARP-798
Change Thread.Sleep to assert retries in ReconnectionTests
CSHARP-785
Consider replacing DateTimeOffset with long for timestamp related methods
CSHARP-773
Use collection with fast reads for prepared queries
CSHARP-768
Consider resetting heartbeat only on client reads
CSHARP-767
Provide a way to help users integrate the driver with DI
CSHARP-753
Implement support for Cassandra 4.0 in the C# driver
CSHARP-751
Small API breaking changes that do not fit into any other epic
CSHARP-749
Implement new DseLoadBalancingPolicy and set it as the default
CSHARP-748
Implement idempotency awareness in the C# driver
CSHARP-747
Create and expose metrics in the C# Driver
CSHARP-746
Set idempotency property in statements generated by Mapper and LINQ components
CSHARP-743
Retry logic should be skipped when statement is not idempotent
CSHARP-742
Add jitter to driver reconnection delay calculation
CSHARP-724
Cache prepared statements by query string
CSHARP-723
Remove usedHostsPerRemoteDc from DCAwareRoundRobinPolicy
CSHARP-722
Use fixed size connection pool
CSHARP-721
Consider using K4os.Compression.LZ4 for LZ4 compression on .NET Core
CSHARP-719
Consider changing OperationState to be asynchronous
CSHARP-718
Provide Serializer without open connection to Cassandra
CSHARP-712
Mapper cannot deserialize IList properties
CSHARP-710
Support reconnection when initializing
CSHARP-698
When socket.ConnectAsync() throws an error synchronously, SocketAsyncEventArgs is not disposed
CSHARP-697
Provide a means of sending query to a specific node to facilitate virtual table queries
CSHARP-694
Parse Virtual Keyspace Metadata
CSHARP-693
Make RowSet iteration and pagination not thread-safe
CSHARP-689
Expose IRow and IRowSet and hide implementations
CSHARP-688
Bump frame coalescing threshold to 64KB
CSHARP-683
Merge Cluster and Session into a single interface
CSHARP-682
Slow Query Logger / Request Tracker
CSHARP-674
Remove deprecated interfaces and methods
CSHARP-665
Use prepared statement result_metadata for execute row responses
CSHARP-664
Add .NET Core support for the DSE Auth Provider
CSHARP-654
Provide optional alternate type and serializer for decimals
CSHARP-651
Test responses with warnings and/or custom payloads are incorrectly parsed for non-results
CSHARP-647
Analyze impact of Spectre/Meltdown patches for Windows on the driver performance
CSHARP-645
Add DSE to jenkins build
CSHARP-644
issue 1 of 114

Exception on UDT => CLR mapping of collection property which has null value

Description

Exception on mapping collection in UDT to CLR collection, if value in DB is null

Example:
DB
CREATE TYPE IF NOT EXISTS settings (
ids frozen<list<int>>
);

CREATE TABLE IF NOT EXISTS test_users (
user_id int,
settings frozen<settings>,
PRIMARY KEY (user_id)
);

INSERT INTO test_users (user_id, settings) VALUES (1, { "ids": null });
SELECT * FROM test_users;

user_id | languages
--------+------------
1 | {ids: null}

C# Code to reproduce the bug:

using System;
using System.Collections.Generic;
using System.Linq;
using Cassandra;

namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
var cluster = Cluster.Builder()
.WithConnectionString("Contact Points=127.0.0.1;Port=9042")
.Build();

var connection = cluster.ConnectAsync().GetAwaiter().GetResult();
connection.UserDefinedTypes.Define(UdtMap.For<Settings>("settings", "users").Map(clr => clr.Ids, "ids"));
var rowSet = connection.Execute("SELECT settings FROM users.test_users WHERE user_id=1");
var user = rowSet.First();
var settings = user.GetValue<Settings>("settings");

Console.WriteLine($"Settings: {settings.Ids}");
Console.ReadLine();
}
}

public class Settings
{
public IList<int> Ids { get; set; }
}
}

--------------------------------------
An unhandled exception has occurred while executing the request.
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentNullException: Value cannot be null.
Parameter name: collection
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at Cassandra.Mapping.TypeConversion.TypeConverter.ConvertToList[T](IEnumerable`1 list)
— End of inner exception stack trace —
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Delegate.DynamicInvokeImpl(Object[] args)
at Cassandra.Mapping.TypeConversion.TypeConverter.ConvertToUdtFieldFromDbValue(Type dbType, Type valueType, Object value)
at Cassandra.UdtMap.ToObject(Object[] values)
at Cassandra.Serialization.UdtSerializer.Deserialize(UInt16 protocolVersion, Byte[] buffer, Int32 offset, Int32 length, IColumnInfo typeInfo)
at Cassandra.Serialization.Serializer.Deserialize(Byte[] buffer, Int32 offset, Int32 length, ColumnTypeCode typeCode, IColumnInfo typeInfo)
at Cassandra.Serialization.CollectionSerializer.Deserialize(UInt16 protocolVersion, Byte[] buffer, Int32 offset, Int32 length, IColumnInfo typeInfo)
at Cassandra.Serialization.Serializer.Deserialize(Byte[] buffer, Int32 offset, Int32 length, ColumnTypeCode typeCode, IColumnInfo typeInfo)
at Cassandra.FrameReader.ReadFromBytes(Byte[] buffer, Int32 offset, Int32 length, ColumnTypeCode typeCode, IColumnInfo typeInfo)
at Cassandra.OutputRows.ProcessRowItem(FrameReader reader)
at Cassandra.OutputRows.ProcessRows(RowSet rs, FrameReader reader)
at Cassandra.OutputRows..ctor(FrameReader reader, Nullable`1 traceId)
at Cassandra.Responses.ResultResponse..ctor(Frame frame)
at Cassandra.Responses.ResultResponse.Create(Frame frame)
at Cassandra.FrameParser.Parse(Frame frame)

int[] failures like the IList but with a bit different exception
{System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentNullException: Value cannot be null.
Parameter name: source
at System.Linq.Enumerable.Select[TSource,TResult](IEnumerable`1 source, Func`2 selector)
at Cassandra.Mapping.TypeConversion.TypeConverter.ConvertToArrayFromDb[TSource,TResult](IEnumerable`1 listFromDatabase)

IEnumerable<int> does not fail in case of null, but does not map in case of value, but it's a different story.

Why, I believe, the issue is blocker:
1. The same driver enables writing null in collection inside UDT;
2. Once null has been written, it cannot be read again. Besides, system failures on an attempt of reading such data. That's critical. Fortunately, I noticed such behavior before going into production. If it had been revealed in prod, it would be a catastrophe.
3. I haven't found a workaround: no hooks in mapping pipeline to inject some fixes into; no alternatives.

Environment

None

Pull Requests

None

Status

Assignee

Unassigned

Reporter

Andrey Braynin

Labels

Reproduced in

3.11.0

PM Priority

None

Fix versions

None

External issue ID

None

External issue ID

None

External issue ID

None

External issue ID

None

External issue ID

None

External issue ID

None

Doc Impact

None

Reviewer

None

Pull Request

None

Epic Link

None

Sprint

Size

None

Components

Affects versions

Priority

Blocker
Configure