Skip to content

Commit a761a1c

Browse files
author
Dmitry Konstantinov
committed
Make UdtCodec logic tolerant to extra unknown fields at the tail of UDT to support live schema upgrades
Patch by Dmitry Konstantinov; reviewed by TBD for CASSANDRA-19814
1 parent d0a1e44 commit a761a1c

File tree

2 files changed

+19
-17
lines changed
  • core/src

2 files changed

+19
-17
lines changed

core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/UdtCodec.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,17 +100,14 @@ public UdtValue decode(@Nullable ByteBuffer bytes, @NonNull ProtocolVersion prot
100100
if (bytes == null) {
101101
return null;
102102
}
103-
// empty byte buffers will result in empty values
104103
try {
105104
ByteBuffer input = bytes.duplicate();
106105
UdtValue value = cqlType.newValue();
107106
int i = 0;
108107
while (input.hasRemaining()) {
109108
if (i == cqlType.getFieldTypes().size()) {
110-
throw new IllegalArgumentException(
111-
String.format(
112-
"Too many fields in encoded UDT value, expected %d",
113-
cqlType.getFieldTypes().size()));
109+
// ignores all unknown fields at the tail during a decoding
110+
break;
114111
}
115112
int elementSize = input.getInt();
116113
ByteBuffer element;

core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/UdtCodecTest.java

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -136,18 +136,23 @@ public void should_decode_udt() {
136136
}
137137

138138
@Test
139-
public void should_fail_to_decode_udt_when_too_many_fields() {
140-
assertThatThrownBy(
141-
() ->
142-
decode(
143-
"0x"
144-
+ ("00000004" + "00000001")
145-
+ "ffffffff"
146-
+ ("00000001" + "61")
147-
// extra contents
148-
+ "ffffffff"))
149-
.isInstanceOf(IllegalArgumentException.class)
150-
.hasMessage("Too many fields in encoded UDT value, expected 3");
139+
public void should_decode_udt_when_too_many_fields() {
140+
UdtValue udt = decode("0x"
141+
+ ("00000004" + "00000001") // size and contents of int field 0
142+
+ "ffffffff" // null field 1
143+
+ ("00000001" + "61") // size and contents of String field 2
144+
+ ("00000004" + "00000002") // size and contents of int field 3, unknown for UDT version used to create the codec
145+
);
146+
147+
assertThat(udt.getInt(0)).isEqualTo(1);
148+
assertThat(udt.isNull(1)).isTrue();
149+
assertThat(udt.getString(2)).isEqualTo("a");
150+
assertThat(udt.size()).isEqualTo(3); // unknown field is not decoded
151+
152+
153+
verify(intCodec).decodePrimitive(Bytes.fromHexString("0x00000001"), ProtocolVersion.DEFAULT);
154+
verifyZeroInteractions(doubleCodec);
155+
verify(textCodec).decode(Bytes.fromHexString("0x61"), ProtocolVersion.DEFAULT);
151156
}
152157

153158
/** Test for JAVA-2557. Ensures that the codec can decode null fields with any negative length. */

0 commit comments

Comments
 (0)