Skip to content

Commit 888e203

Browse files
stamhankar999olim7t
authored andcommitted
JAVA-1891: Allow null items when setting values in bulk
In tuple values, UDT values and bound statements.
1 parent 055a29a commit 888e203

5 files changed

Lines changed: 51 additions & 2 deletions

File tree

changelog/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
### 4.0.0-alpha4 (in progress)
66

7+
- [bug] JAVA-1891: Allow null items when setting values in bulk
78
- [improvement] JAVA-1767: Improve message when column not in result set
89
- [improvement] JAVA-1624: Expose ExecutionInfo on exceptions where applicable
910
- [improvement] JAVA-1766: Revisit nullability

core/src/main/java/com/datastax/oss/driver/internal/core/data/ValuesHelper.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ public static ByteBuffer[] encodeValues(
6161
throw new IllegalArgumentException("Unsupported token type " + value.getClass());
6262
}
6363
} else {
64-
TypeCodec<Object> codec = codecRegistry.codecFor(fieldTypes.get(i), value);
64+
TypeCodec<Object> codec =
65+
(value == null)
66+
? codecRegistry.codecFor(fieldTypes.get(i))
67+
: codecRegistry.codecFor(fieldTypes.get(i), value);
6568
encodedValue = codec.encode(value, protocolVersion);
6669
}
6770
encodedValues[i] = encodedValue;
@@ -104,7 +107,9 @@ public static ByteBuffer[] encodePreparedValues(
104107
}
105108
} else {
106109
TypeCodec<Object> codec =
107-
codecRegistry.codecFor(variableDefinitions.get(i).getType(), value);
110+
(value == null)
111+
? codecRegistry.codecFor(variableDefinitions.get(i).getType())
112+
: codecRegistry.codecFor(variableDefinitions.get(i).getType(), value);
108113
encodedValue = codec.encode(value, protocolVersion);
109114
}
110115
encodedValues[i] = encodedValue;

core/src/test/java/com/datastax/oss/driver/internal/core/data/DefaultTupleValueTest.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,15 @@
2222
import com.datastax.oss.driver.api.core.type.DataType;
2323
import com.datastax.oss.driver.api.core.type.DataTypes;
2424
import com.datastax.oss.driver.api.core.type.TupleType;
25+
import com.datastax.oss.driver.api.core.type.codec.TypeCodecs;
2526
import com.datastax.oss.driver.internal.SerializationHelper;
2627
import com.datastax.oss.driver.internal.core.type.DefaultTupleType;
2728
import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList;
2829
import com.datastax.oss.protocol.internal.util.Bytes;
30+
import java.io.UnsupportedEncodingException;
2931
import java.util.List;
3032
import org.junit.Test;
33+
import org.mockito.Mockito;
3134

3235
public class DefaultTupleValueTest extends AccessibleByIndexTestBase<TupleValue> {
3336

@@ -60,6 +63,18 @@ public void should_serialize_and_deserialize() {
6063
assertThat(Bytes.toHexString(out.getBytesUnsafe(1))).isEqualTo("0x61");
6164
}
6265

66+
@Test
67+
public void should_support_null_items_when_setting_in_bulk() throws UnsupportedEncodingException {
68+
DefaultTupleType type =
69+
new DefaultTupleType(ImmutableList.of(DataTypes.INT, DataTypes.TEXT), attachmentPoint);
70+
Mockito.when(codecRegistry.<Integer>codecFor(DataTypes.INT)).thenReturn(TypeCodecs.INT);
71+
Mockito.when(codecRegistry.codecFor(DataTypes.TEXT, "foo")).thenReturn(TypeCodecs.TEXT);
72+
TupleValue value = type.newValue(null, "foo");
73+
74+
assertThat(value.isNull(0)).isTrue();
75+
assertThat(value.getString(1)).isEqualTo("foo");
76+
}
77+
6378
@Test
6479
public void should_equate_instances_with_same_values_but_different_binary_representations() {
6580
TupleType tupleType = DataTypes.tupleOf(DataTypes.VARINT);

core/src/test/java/com/datastax/oss/driver/internal/core/data/DefaultUdtValueTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,14 @@
2323
import com.datastax.oss.driver.api.core.type.DataType;
2424
import com.datastax.oss.driver.api.core.type.DataTypes;
2525
import com.datastax.oss.driver.api.core.type.UserDefinedType;
26+
import com.datastax.oss.driver.api.core.type.codec.TypeCodecs;
2627
import com.datastax.oss.driver.internal.SerializationHelper;
2728
import com.datastax.oss.driver.internal.core.type.UserDefinedTypeBuilder;
2829
import com.datastax.oss.protocol.internal.util.Bytes;
30+
import java.io.UnsupportedEncodingException;
2931
import java.util.List;
3032
import org.junit.Test;
33+
import org.mockito.Mockito;
3134

3235
public class DefaultUdtValueTest extends AccessibleByIdTestBase<UdtValue> {
3336

@@ -78,6 +81,22 @@ public void should_serialize_and_deserialize() {
7881
assertThat(Bytes.toHexString(out.getBytesUnsafe(1))).isEqualTo("0x61");
7982
}
8083

84+
@Test
85+
public void should_support_null_items_when_setting_in_bulk() throws UnsupportedEncodingException {
86+
UserDefinedType type =
87+
new UserDefinedTypeBuilder(
88+
CqlIdentifier.fromInternal("ks"), CqlIdentifier.fromInternal("type"))
89+
.withField(CqlIdentifier.fromInternal("field1"), DataTypes.INT)
90+
.withField(CqlIdentifier.fromInternal("field2"), DataTypes.TEXT)
91+
.build();
92+
Mockito.when(codecRegistry.<Integer>codecFor(DataTypes.INT)).thenReturn(TypeCodecs.INT);
93+
Mockito.when(codecRegistry.codecFor(DataTypes.TEXT, "foo")).thenReturn(TypeCodecs.TEXT);
94+
UdtValue value = type.newValue(null, "foo");
95+
96+
assertThat(value.isNull(0)).isTrue();
97+
assertThat(value.getString(1)).isEqualTo("foo");
98+
}
99+
81100
@Test
82101
public void should_equate_instances_with_same_values_but_different_binary_representations() {
83102
UserDefinedType type =

integration-tests/src/test/java/com/datastax/oss/driver/api/core/cql/BoundStatementIT.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static org.assertj.core.api.Assertions.assertThat;
1919

2020
import com.datastax.oss.driver.api.core.CqlSession;
21+
import com.datastax.oss.driver.api.core.type.codec.TypeCodecs;
2122
import com.datastax.oss.driver.api.testinfra.CassandraRequirement;
2223
import com.datastax.oss.driver.api.testinfra.ccm.CcmRule;
2324
import com.datastax.oss.driver.api.testinfra.session.SessionRule;
@@ -130,6 +131,14 @@ public void should_have_empty_result_definitions_for_update_query() {
130131
assertThat(rs.getColumnDefinitions()).hasSize(0);
131132
}
132133

134+
@Test
135+
public void should_bind_null_value_when_setting_values_in_bulk() {
136+
PreparedStatement prepared =
137+
sessionRule.session().prepare("INSERT INTO test2 (k, v0) values (?, ?)");
138+
BoundStatement boundStatement = prepared.bind(name.getMethodName(), null);
139+
assertThat(boundStatement.get(1, TypeCodecs.INT)).isNull();
140+
}
141+
133142
@Test
134143
public void should_allow_custom_codecs_when_setting_values_in_bulk() {
135144
// v0 is an int column, but we'll bind a String to it

0 commit comments

Comments
 (0)