Skip to content

Commit ab4e9d8

Browse files
committed
Pg Client might convert a query param to NULL if it has the wrong type (eclipse-vertx#1464)
Fixes eclipse-vertx#1463 With this change, a DataType always has a param extractor. The default extractor signals the failure to convert to PgParamDesc. Signed-off-by: Thomas Segismont <[email protected]>
1 parent 3b29a6a commit ab4e9d8

File tree

3 files changed

+51
-19
lines changed

3 files changed

+51
-19
lines changed

vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/DataType.java

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,22 @@
1818

1919
import io.netty.util.collection.IntObjectHashMap;
2020
import io.netty.util.collection.IntObjectMap;
21+
import io.vertx.core.VertxException;
22+
import io.vertx.core.buffer.Buffer;
2123
import io.vertx.core.internal.logging.Logger;
2224
import io.vertx.core.internal.logging.LoggerFactory;
2325
import io.vertx.core.json.JsonArray;
2426
import io.vertx.core.json.JsonObject;
25-
import io.vertx.pgclient.data.Box;
26-
import io.vertx.pgclient.data.Circle;
27-
import io.vertx.pgclient.data.Inet;
28-
import io.vertx.pgclient.data.Line;
29-
import io.vertx.pgclient.data.LineSegment;
30-
import io.vertx.pgclient.data.Money;
31-
import io.vertx.pgclient.data.Cidr;
27+
import io.vertx.pgclient.data.*;
3228
import io.vertx.sqlclient.Tuple;
3329
import io.vertx.sqlclient.data.Numeric;
34-
import io.vertx.pgclient.data.Interval;
35-
import io.vertx.pgclient.data.Path;
36-
import io.vertx.pgclient.data.Point;
37-
import io.vertx.pgclient.data.Polygon;
38-
import io.vertx.core.buffer.Buffer;
30+
import io.vertx.sqlclient.internal.TupleInternal;
3931

4032
import java.sql.JDBCType;
4133
import java.time.*;
4234
import java.util.HashMap;
4335
import java.util.Map;
36+
import java.util.Objects;
4437
import java.util.UUID;
4538

4639
/**
@@ -155,11 +148,11 @@ <T> DataType(int id, boolean supportsBinary, Class<T> type, JDBCType jdbcType) {
155148
<T> DataType(int id, boolean supportsBinary, Class<T> encodingType, Class<?> decodingType, JDBCType jdbcType, ParamExtractor<T> paramExtractor) {
156149
this.id = id;
157150
this.supportsBinary = supportsBinary;
158-
this.encodingType = encodingType;
151+
this.encodingType = Objects.requireNonNull(encodingType);
159152
this.decodingType = decodingType;
160153
this.jdbcType = jdbcType;
161154
this.array = decodingType.isArray();
162-
this.paramExtractor = paramExtractor;
155+
this.paramExtractor = paramExtractor != null ? paramExtractor : new DefaultParamExtractor<>(encodingType);
163156
}
164157

165158
static DataType valueOf(int oid) {
@@ -231,4 +224,23 @@ static DataType lookup(Class<?> type) {
231224
encodingTypeToDataType.put(Circle.class, CIRCLE);
232225
encodingTypeToDataType.put(Circle[].class, CIRCLE_ARRAY);
233226
}
227+
228+
private static class DefaultParamExtractor<T> implements ParamExtractor<T> {
229+
static final RuntimeException FAILURE = new VertxException("ignored", true);
230+
231+
final Class<T> encodingType;
232+
233+
DefaultParamExtractor(Class<T> encodingType) {
234+
this.encodingType = encodingType;
235+
}
236+
237+
@Override
238+
public T get(TupleInternal tuple, int idx) {
239+
Object value = tuple.getValue(idx);
240+
if (value != null && encodingType.isAssignableFrom(value.getClass())) {
241+
return encodingType.cast(value);
242+
}
243+
throw FAILURE;
244+
}
245+
}
234246
}

vertx-pg-client/src/main/java/io/vertx/pgclient/impl/codec/PgParamDesc.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,7 @@ public String prepare(TupleInternal values) {
5252
ParamExtractor<?> extractor = paramDataType.paramExtractor;
5353
Object val;
5454
try {
55-
if (extractor != null) {
56-
val = extractor.get(values, i);
57-
} else {
58-
val = values.get(paramDataType.encodingType, i);
59-
}
55+
val = extractor.get(values, i);
6056
} catch (Exception e) {
6157
return ErrorMessageFactory.buildWhenArgumentsTypeNotMatched(paramDataType.decodingType, i, values.getValue(i));
6258
}

vertx-pg-client/src/test/java/io/vertx/pgclient/PreparedStatementTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,34 @@
1717

1818
package io.vertx.pgclient;
1919

20+
import io.vertx.ext.unit.TestContext;
21+
import io.vertx.sqlclient.Tuple;
22+
import org.junit.Test;
23+
24+
import java.time.Duration;
25+
2026
public class PreparedStatementTest extends PreparedStatementTestBase {
2127

2228
@Override
2329
protected PgConnectOptions options() {
2430
return new PgConnectOptions(options).setCachePreparedStatements(false);
2531
}
32+
33+
@Test
34+
public void testPrepareExecuteValidationErrorDefaultExtractor(TestContext ctx) {
35+
PgConnection.connect(vertx, options()).onComplete(ctx.asyncAssertSuccess(conn -> {
36+
conn.prepare("SELECT $1 :: INTERVAL \"Interval\"").onComplete(ctx.asyncAssertSuccess(ps -> {
37+
ps.query().execute(Tuple.of(Duration.ofHours(3))).onComplete(ctx.asyncAssertFailure());
38+
}));
39+
}));
40+
}
41+
42+
@Test
43+
public void testPrepareExecuteValidationErrorDefaultExtractor_(TestContext ctx) {
44+
PgConnection.connect(vertx, options()).onComplete(ctx.asyncAssertSuccess(conn -> {
45+
conn
46+
.preparedQuery("SELECT $1 :: INTERVAL \"Interval\"")
47+
.execute(Tuple.of(Duration.ofHours(3))).onComplete(ctx.asyncAssertFailure());
48+
}));
49+
}
2650
}

0 commit comments

Comments
 (0)