Skip to content

Commit a8830e7

Browse files
committed
Introduce ObjectCodec to support bindNull(Object.class)
[resolves #664]
1 parent 8cc55a3 commit a8830e7

File tree

3 files changed

+123
-1
lines changed

3 files changed

+123
-1
lines changed

src/main/java/io/r2dbc/postgresql/codec/DefaultCodecs.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ EncodedParameter encodeParameterValue(Object value, @Nullable PostgresTypeIdenti
268268
if (dataType == null) {
269269

270270
if (parameterValue == null) {
271-
throw new IllegalArgumentException(String.format("Cannot encode null value %s using type inference", value));
271+
return ObjectCodec.INSTANCE.encodeNull();
272272
}
273273

274274
Codec<?> codec = this.codecLookup.findEncodeCodec(parameterValue);
@@ -294,6 +294,10 @@ EncodedParameter encodeParameterValue(Object value, @Nullable PostgresTypeIdenti
294294
public EncodedParameter encodeNull(Class<?> type) {
295295
Assert.requireNonNull(type, "type must not be null");
296296

297+
if (type == Object.class) {
298+
return ObjectCodec.INSTANCE.encodeNull();
299+
}
300+
297301
Codec<?> codec = this.codecLookup.findEncodeNullCodec(type);
298302
if (codec != null) {
299303
return codec.encodeNull();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright 2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.r2dbc.postgresql.codec;
18+
19+
import io.netty.buffer.ByteBuf;
20+
import io.r2dbc.postgresql.client.EncodedParameter;
21+
import io.r2dbc.postgresql.message.Format;
22+
23+
import static io.r2dbc.postgresql.codec.PostgresqlObjectId.UNSPECIFIED;
24+
import static io.r2dbc.postgresql.message.Format.FORMAT_TEXT;
25+
26+
final class ObjectCodec implements Codec<Object> {
27+
28+
static final ObjectCodec INSTANCE = new ObjectCodec();
29+
30+
private ObjectCodec() {
31+
}
32+
33+
@Override
34+
public EncodedParameter encodeNull() {
35+
return AbstractCodec.createNull(FORMAT_TEXT, UNSPECIFIED);
36+
}
37+
38+
public EncodedParameter encodeNull(int dataType) {
39+
return new EncodedParameter(FORMAT_TEXT, dataType, EncodedParameter.NULL_VALUE);
40+
}
41+
42+
@Override
43+
public boolean canDecode(int dataType, Format format, Class<?> type) {
44+
return false;
45+
}
46+
47+
@Override
48+
public boolean canEncode(Object value) {
49+
return false;
50+
}
51+
52+
@Override
53+
public boolean canEncodeNull(Class<?> type) {
54+
return Object.class.equals(type);
55+
}
56+
57+
@Override
58+
public Object decode(ByteBuf buffer, int dataType, Format format, Class<?> type) {
59+
throw new UnsupportedOperationException();
60+
}
61+
62+
@Override
63+
public EncodedParameter encode(Object value) {
64+
throw new UnsupportedOperationException();
65+
}
66+
67+
@Override
68+
public EncodedParameter encode(Object value, int dataType) {
69+
throw new UnsupportedOperationException();
70+
}
71+
72+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright 2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.r2dbc.postgresql.codec;
18+
19+
import io.r2dbc.postgresql.AbstractIntegrationTests;
20+
import org.junit.jupiter.api.Test;
21+
import reactor.test.StepVerifier;
22+
23+
/**
24+
* Integration tests for {@link ObjectCodec} usage.
25+
*/
26+
class ObjectCodecIntegrationTests extends AbstractIntegrationTests {
27+
28+
@Test
29+
void shouldEncodeNull() {
30+
31+
SERVER.getJdbcOperations().execute("DROP TABLE IF EXISTS test");
32+
SERVER.getJdbcOperations().execute("CREATE TABLE test (ci INT4, cs VARCHAR)");
33+
34+
this.connection.createStatement("INSERT INTO test VALUES($1, $2)")
35+
.bindNull("$1", Object.class)
36+
.bindNull("$2", Object.class)
37+
.execute()
38+
.flatMap(it -> it.getRowsUpdated())
39+
.as(StepVerifier::create)
40+
.expectNext(1L)
41+
.verifyComplete();
42+
43+
SERVER.getJdbcOperations().execute("DROP TABLE test");
44+
}
45+
46+
}

0 commit comments

Comments
 (0)