Skip to content

Commit ed518bb

Browse files
committed
feat(unknownType): add support for Bolt Unknown Type
1 parent ee9a0e5 commit ed518bb

File tree

15 files changed

+246
-5
lines changed

15 files changed

+246
-5
lines changed

driver/clirr-ignored-differences.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,4 +935,10 @@
935935
<differenceType>8001</differenceType>
936936
</difference>
937937

938+
<difference>
939+
<className>org/neo4j/driver/types/TypeSystem</className>
940+
<differenceType>7012</differenceType>
941+
<method>org.neo4j.driver.types.Type UNSUPPORTED()</method>
942+
</difference>
943+
938944
</differences>

driver/src/main/java/org/neo4j/driver/Value.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.neo4j.driver.types.Relationship;
4343
import org.neo4j.driver.types.Type;
4444
import org.neo4j.driver.types.TypeSystem;
45+
import org.neo4j.driver.types.UnsupportedTypeData;
4546
import org.neo4j.driver.types.Vector;
4647
import org.neo4j.driver.util.Immutable;
4748
import org.neo4j.driver.util.Preview;
@@ -684,6 +685,10 @@ public interface Value extends MapAccessor, MapAccessorWithDefaultValue {
684685
* <td>{@link TypeSystem#VECTOR}</td>
685686
* <td>{@link Vector}</td>
686687
* </tr>
688+
* <tr>
689+
* <td>{@link TypeSystem#UNSUPPORTED}</td>
690+
* <td>{@link UnsupportedTypeData}</td>
691+
* </tr>
687692
* </tbody>
688693
* </table>
689694
*

driver/src/main/java/org/neo4j/driver/Values.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
import org.neo4j.driver.internal.value.PointValue;
6868
import org.neo4j.driver.internal.value.StringValue;
6969
import org.neo4j.driver.internal.value.TimeValue;
70+
import org.neo4j.driver.internal.value.UnsupportedValue;
7071
import org.neo4j.driver.internal.value.VectorValue;
7172
import org.neo4j.driver.mapping.Property;
7273
import org.neo4j.driver.types.Entity;
@@ -77,6 +78,7 @@
7778
import org.neo4j.driver.types.Point;
7879
import org.neo4j.driver.types.Relationship;
7980
import org.neo4j.driver.types.TypeSystem;
81+
import org.neo4j.driver.types.UnsupportedTypeData;
8082
import org.neo4j.driver.types.Vector;
8183
import org.neo4j.driver.util.Preview;
8284

@@ -182,6 +184,9 @@ public static Value value(Object value) {
182184
if (value instanceof Vector vector) {
183185
return value(vector);
184186
}
187+
if (value instanceof UnsupportedTypeData) {
188+
return value((UnsupportedTypeData) value);
189+
}
185190

186191
if (value instanceof List<?>) {
187192
return value((List<Object>) value);
@@ -1149,4 +1154,8 @@ private static Value vector(Object array) {
11491154
"Unsupported vector element type: " + array.getClass().getName());
11501155
}
11511156
}
1157+
1158+
private static Value value(UnsupportedTypeData unsupportedTypeData) {
1159+
return new UnsupportedValue(unsupportedTypeData);
1160+
}
11521161
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [https://neo4j.com]
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.neo4j.driver.internal;
18+
19+
import java.util.Optional;
20+
import org.neo4j.driver.types.UnsupportedTypeData;
21+
22+
public record InternalUnsupportedTypeData(String name, String minProtocolVersion, String messageValue)
23+
implements UnsupportedTypeData {
24+
@Override
25+
public Optional<String> message() {
26+
return Optional.ofNullable(messageValue);
27+
}
28+
}

driver/src/main/java/org/neo4j/driver/internal/types/InternalTypeSystem.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import static org.neo4j.driver.internal.types.TypeConstructor.RELATIONSHIP;
3737
import static org.neo4j.driver.internal.types.TypeConstructor.STRING;
3838
import static org.neo4j.driver.internal.types.TypeConstructor.TIME;
39+
import static org.neo4j.driver.internal.types.TypeConstructor.UNSUPPORTED;
3940
import static org.neo4j.driver.internal.types.TypeConstructor.VECTOR;
4041

4142
import org.neo4j.driver.Value;
@@ -72,6 +73,7 @@ public class InternalTypeSystem implements TypeSystem {
7273
private final TypeRepresentation durationType = constructType(DURATION);
7374
private final TypeRepresentation nullType = constructType(NULL);
7475
private final TypeRepresentation vectorType = constructType(VECTOR);
76+
private final TypeRepresentation unsupportedType = constructType(UNSUPPORTED);
7577

7678
private InternalTypeSystem() {}
7779

@@ -180,6 +182,11 @@ public Type VECTOR() {
180182
return vectorType;
181183
}
182184

185+
@Override
186+
public Type UNSUPPORTED() {
187+
return unsupportedType;
188+
}
189+
183190
private TypeRepresentation constructType(TypeConstructor tyCon) {
184191
return new TypeRepresentation(tyCon);
185192
}

driver/src/main/java/org/neo4j/driver/internal/types/TypeConstructor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ public boolean covers(Value value) {
5757
DATE_TIME,
5858
DURATION,
5959
NULL,
60-
VECTOR;
60+
VECTOR,
61+
UNSUPPORTED;
6162

6263
private static TypeConstructor typeConstructorOf(Value value) {
6364
return ((InternalValue) value).typeConstructor();

driver/src/main/java/org/neo4j/driver/internal/value/BoltValueFactory.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,19 @@
2929
import java.util.Collections;
3030
import java.util.List;
3131
import java.util.Map;
32+
import org.neo4j.bolt.connection.BoltProtocolVersion;
3233
import org.neo4j.bolt.connection.values.Node;
3334
import org.neo4j.bolt.connection.values.Path;
3435
import org.neo4j.bolt.connection.values.Relationship;
3536
import org.neo4j.bolt.connection.values.Segment;
37+
import org.neo4j.bolt.connection.values.Type;
3638
import org.neo4j.bolt.connection.values.Value;
3739
import org.neo4j.bolt.connection.values.ValueFactory;
3840
import org.neo4j.driver.Values;
3941
import org.neo4j.driver.internal.InternalNode;
4042
import org.neo4j.driver.internal.InternalPath;
4143
import org.neo4j.driver.internal.InternalRelationship;
44+
import org.neo4j.driver.internal.InternalUnsupportedTypeData;
4245

4346
public class BoltValueFactory implements ValueFactory {
4447
private static final BoltValueFactory INSTANCE = new BoltValueFactory();
@@ -265,6 +268,15 @@ public Value vector(Class<?> elementType, Object elements) {
265268
return value;
266269
}
267270

271+
@Override
272+
public Value unsupportedTypeData(String name, BoltProtocolVersion minBoltVersion, Map<String, Value> extra) {
273+
var message = extra.get("message");
274+
var messageString =
275+
message != null ? message.boltValueType().equals(Type.STRING) ? message.asString() : null : null;
276+
return (InternalValue)
277+
Values.value((Object) new InternalUnsupportedTypeData(name, minBoltVersion.toString(), messageString));
278+
}
279+
268280
@Override
269281
public Value unsupportedDateTimeValue(DateTimeException e) {
270282
return new UnsupportedDateTimeValue(e);
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [https://neo4j.com]
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.neo4j.driver.internal.value;
18+
19+
import org.neo4j.driver.internal.types.InternalTypeSystem;
20+
import org.neo4j.driver.types.UnsupportedTypeData;
21+
22+
public final class UnsupportedValue extends ObjectValueAdapter<UnsupportedTypeData> {
23+
public UnsupportedValue(UnsupportedTypeData adapted) {
24+
super(adapted);
25+
}
26+
27+
@Override
28+
public org.neo4j.bolt.connection.values.Type boltValueType() {
29+
return org.neo4j.bolt.connection.values.Type.UNSUPPORTED;
30+
}
31+
32+
@Override
33+
public org.neo4j.driver.types.Type type() {
34+
return InternalTypeSystem.TYPE_SYSTEM.UNSUPPORTED();
35+
}
36+
37+
@Override
38+
public <T> T as(Class<T> targetClass) {
39+
if (targetClass.isAssignableFrom(UnsupportedTypeData.class)) {
40+
return targetClass.cast(asObject());
41+
}
42+
return asMapped(targetClass);
43+
}
44+
}

driver/src/main/java/org/neo4j/driver/types/TypeSystem.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,20 @@ static TypeSystem getDefault() {
164164
*/
165165
@Preview(name = "Neo4j Vector")
166166
Type VECTOR();
167+
168+
/**
169+
* Returns a {@link Type} instance representing an unknown type.
170+
* <p>
171+
* An unknown type may occur when a new type is introduced in the Neo4j server and the driver is connected over an
172+
* older Bolt Protocol version that does not support this type. The {@link UnsupportedTypeData} object provides information
173+
* about the unknown type and the {@link UnsupportedTypeData#minProtocolVersion()} needed to transmit it. However, the
174+
* {@link UnsupportedTypeData} object itself requires at least Bolt Protocol 6.0.
175+
* <p>
176+
* Note that the unknown type MUST NOT be sent to the server.
177+
*
178+
* @return the type instance
179+
* @since 6.0.0
180+
* @see UnsupportedTypeData
181+
*/
182+
Type UNSUPPORTED();
167183
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [https://neo4j.com]
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.neo4j.driver.types;
18+
19+
import java.util.Optional;
20+
21+
/**
22+
* An object instance of {@link TypeSystem#UNSUPPORTED()} type.
23+
* <p>
24+
* This object contains information about the unknown type and the {@link #minProtocolVersion()} needed to transmit it.
25+
* <p>
26+
* Note that this object MUST NOT be sent to the server.
27+
*
28+
* @since 6.0.0
29+
*/
30+
public interface UnsupportedTypeData {
31+
/**
32+
* Returns the type name.
33+
* @return the type name
34+
*/
35+
String name();
36+
37+
/**
38+
* The minimum Bolt Protocol version needed to transmit this type.
39+
* @return the minimum Bolt Protocol version
40+
*/
41+
String minProtocolVersion();
42+
43+
/**
44+
* An optional message.
45+
* @return the message
46+
*/
47+
Optional<String> message();
48+
}

0 commit comments

Comments
 (0)