Skip to content

Commit f582003

Browse files
committed
Handle postgres error code 42P08 among the lazyly rewritten prepared statements with parameters. Also similar tests have been refactored to use the eventually close and ensure the connection is closed on a test failure as well.
fixes #1103
1 parent a6c5068 commit f582003

File tree

2 files changed

+104
-85
lines changed

2 files changed

+104
-85
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ protected <R> void doSchedule(CommandBase<R> cmd, Handler<AsyncResult<R>> handle
167167
public boolean isIndeterminatePreparedStatementError(Throwable error) {
168168
if (error instanceof PgException) {
169169
String code = ((PgException) error).getCode();
170-
return "42P18".equals(code) || "42804".equals(code);
170+
return "42P18".equals(code) || "42804".equals(code) || "42P08".equals(code);
171171
}
172172
return false;
173173
}

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

Lines changed: 103 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -343,197 +343,216 @@ public void testCloseStatement(TestContext ctx) {
343343
}
344344

345345
@Test
346-
public void testInferDataTypeString(TestContext ctx) {
347-
testInferDataType(ctx, String.class, "WORLD", "WORLD");
346+
public void testInferDataTypeString42P18(TestContext ctx) {
347+
testInferDataType42P18(ctx, String.class, "WORLD", "WORLD");
348348
}
349349

350350
@Test
351-
public void testInferDataTypeBoolean(TestContext ctx) {
352-
testInferDataType(ctx, Boolean.class, true, "t");
351+
public void testInferDataTypeBoolean42P18(TestContext ctx) {
352+
testInferDataType42P18(ctx, Boolean.class, true, "t");
353353
}
354354

355355
@Test
356-
public void testInferDataTypeShort(TestContext ctx) {
357-
testInferDataType(ctx, Short.class, (short)2, "2");
356+
public void testInferDataTypeShort42P18(TestContext ctx) {
357+
testInferDataType42P18(ctx, Short.class, (short)2, "2");
358358
}
359359

360360
@Test
361-
public void testInferDataTypeInteger(TestContext ctx) {
362-
testInferDataType(ctx, Integer.class, Integer.MAX_VALUE, "" + Integer.MAX_VALUE);
361+
public void testInferDataTypeInteger42P18(TestContext ctx) {
362+
testInferDataType42P18(ctx, Integer.class, Integer.MAX_VALUE, "" + Integer.MAX_VALUE);
363363
}
364364

365365
@Test
366-
public void testInferDataTypeLong(TestContext ctx) {
367-
testInferDataType(ctx, Long.class, Long.MAX_VALUE, "" + Long.MAX_VALUE);
366+
public void testInferDataTypeLong42P18(TestContext ctx) {
367+
testInferDataType42P18(ctx, Long.class, Long.MAX_VALUE, "" + Long.MAX_VALUE);
368368
}
369369

370370
@Test
371-
public void testInferDataTypeFloat(TestContext ctx) {
372-
testInferDataType(ctx, Float.class, 0F, "0");
371+
public void testInferDataTypeFloat42P18(TestContext ctx) {
372+
testInferDataType42P18(ctx, Float.class, 0F, "0");
373373
}
374374

375375
@Test
376-
public void testInferDataTypeDouble(TestContext ctx) {
377-
testInferDataType(ctx, Double.class, 0D, "0");
376+
public void testInferDataTypeDouble42P18(TestContext ctx) {
377+
testInferDataType42P18(ctx, Double.class, 0D, "0");
378378
}
379379

380380
@Test
381-
public void testInferDataTypeLocalDate(TestContext ctx) {
381+
public void testInferDataTypeLocalDate42P18(TestContext ctx) {
382382
LocalDate value = LocalDate.now();
383-
testInferDataType(ctx, LocalDate.class, value, value.toString());
383+
testInferDataType42P18(ctx, LocalDate.class, value, value.toString());
384384
}
385385

386386
@Test
387-
public void testInferDataTypeLocalDateTime(TestContext ctx) {
387+
public void testInferDataTypeLocalDateTime42P18(TestContext ctx) {
388388
LocalDateTime value = LocalDateTime.of(LocalDate.now(), LocalTime.NOON);
389389
String suffix = value.toLocalDate() + " " + value.toLocalTime().format(DateTimeFormatter.ISO_LOCAL_TIME);
390-
testInferDataType(ctx, LocalDateTime.class, value, suffix, "{\"" + suffix + "\"}");
390+
testInferDataType42P18(ctx, LocalDateTime.class, value, suffix, "{\"" + suffix + "\"}");
391391
}
392392

393393
@Test
394-
public void testInferDataTypeOffsetDateTime(TestContext ctx) {
394+
public void testInferDataTypeOffsetDateTime42P18(TestContext ctx) {
395395
OffsetDateTime value = OffsetDateTime.of(LocalDateTime.of(LocalDate.now(), LocalTime.NOON), ZoneOffset.UTC);
396396
String suffix = value.toLocalDate() + " " + value.toLocalTime().format(DateTimeFormatter.ISO_LOCAL_TIME) + "+00";
397-
testInferDataType(ctx, OffsetDateTime.class, value, suffix, "{\"" + suffix + "\"}");
397+
testInferDataType42P18(ctx, OffsetDateTime.class, value, suffix, "{\"" + suffix + "\"}");
398398
}
399399

400400
@Test
401-
public void testInferDataTypeOffsetInterval(TestContext ctx) {
401+
public void testInferDataTypeOffsetInterval42P18(TestContext ctx) {
402402
Interval value = Interval.of(1);
403-
testInferDataType(ctx, Interval.class, value, "1 year", "{\"1 year\"}");
403+
testInferDataType42P18(ctx, Interval.class, value, "1 year", "{\"1 year\"}");
404404
}
405405

406406
@Test
407-
public void testInferDataTypeBuffer(TestContext ctx) {
408-
testInferDataType(ctx, Buffer.class, Buffer.buffer("WORLD"), "\\x574f524c44", "{\"\\\\x574f524c44\"}");
407+
public void testInferDataTypeBuffer42P18(TestContext ctx) {
408+
testInferDataType42P18(ctx, Buffer.class, Buffer.buffer("WORLD"), "\\x574f524c44", "{\"\\\\x574f524c44\"}");
409409
}
410410

411411
@Test
412-
public void testInferDataTypeUUID(TestContext ctx) {
412+
public void testInferDataTypeUUID42P18(TestContext ctx) {
413413
UUID value = UUID.randomUUID();
414-
testInferDataType(ctx, UUID.class, value, "" + value);
414+
testInferDataType42P18(ctx, UUID.class, value, "" + value);
415415
}
416416

417417
@Test
418-
public void testInferDataTypeJsonObject(TestContext ctx) {
418+
public void testInferDataTypeJsonObject42P18(TestContext ctx) {
419419
JsonObject value = new JsonObject().put("foo", "bar");
420-
testInferDataType(ctx, JsonObject.class, value, "" + value, "{\"{\\\"foo\\\":\\\"bar\\\"}\"}");
420+
testInferDataType42P18(ctx, JsonObject.class, value, "" + value, "{\"{\\\"foo\\\":\\\"bar\\\"}\"}");
421421
}
422422

423423
@Test
424-
public void testInferDataTypeJsonArray(TestContext ctx) {
424+
public void testInferDataTypeJsonArray42P18(TestContext ctx) {
425425
JsonArray value = new JsonArray().add(1).add("foo").add(true);
426-
testInferDataType(ctx, JsonArray.class, value, "" + value, "{\"[1,\\\"foo\\\",true]\"}");
426+
testInferDataType42P18(ctx, JsonArray.class, value, "" + value, "{\"[1,\\\"foo\\\",true]\"}");
427427
}
428428

429429
@Test
430-
public void testInferDataTypePoint(TestContext ctx) {
430+
public void testInferDataTypePoint42P18(TestContext ctx) {
431431
Point value = new Point();
432-
testInferDataType(ctx, Point.class, value, "(0,0)", "{\"(0,0)\"}");
432+
testInferDataType42P18(ctx, Point.class, value, "(0,0)", "{\"(0,0)\"}");
433433
}
434434

435435
@Test
436-
public void testInferDataTypeLine(TestContext ctx) {
436+
public void testInferDataTypeLine42P18(TestContext ctx) {
437437
Line value = new Line(1.0, 0.0, 0.0);
438-
testInferDataType(ctx, Line.class, value, "{1,0,0}", "{\"{1,0,0}\"}");
438+
testInferDataType42P18(ctx, Line.class, value, "{1,0,0}", "{\"{1,0,0}\"}");
439439
}
440440

441441
@Test
442-
public void testInferDataTypeLineSegment(TestContext ctx) {
442+
public void testInferDataTypeLineSegment42P18(TestContext ctx) {
443443
LineSegment value = new LineSegment();
444-
testInferDataType(ctx, LineSegment.class, value, "[(0,0),(0,0)]", "{\"[(0,0),(0,0)]\"}");
444+
testInferDataType42P18(ctx, LineSegment.class, value, "[(0,0),(0,0)]", "{\"[(0,0),(0,0)]\"}");
445445
}
446446

447447
@Test
448-
public void testInferDataTypeBox(TestContext ctx) {
448+
public void testInferDataTypeBox42P18(TestContext ctx) {
449449
Box value = new Box();
450-
testInferDataType(ctx, Box.class, value, "(0,0),(0,0)");
450+
testInferDataType42P18(ctx, Box.class, value, "(0,0),(0,0)");
451451
}
452452

453453
@Test
454-
public void testInferDataTypePath(TestContext ctx) {
454+
public void testInferDataTypePath42P18(TestContext ctx) {
455455
Path value = new Path().addPoint(new Point());
456-
testInferDataType(ctx, Path.class, value, "((0,0))", "{\"((0,0))\"}");
456+
testInferDataType42P18(ctx, Path.class, value, "((0,0))", "{\"((0,0))\"}");
457457
}
458458

459459
@Test
460-
public void testInferDataTypePolygon(TestContext ctx) {
460+
public void testInferDataTypePolygon42P18(TestContext ctx) {
461461
Polygon value = new Polygon().addPoint(new Point()).addPoint(new Point()).addPoint(new Point());
462-
testInferDataType(ctx, Polygon.class, value, "((0,0),(0,0),(0,0))", "{\"((0,0),(0,0),(0,0))\"}");
462+
testInferDataType42P18(ctx, Polygon.class, value, "((0,0),(0,0),(0,0))", "{\"((0,0),(0,0),(0,0))\"}");
463463
}
464464

465465
@Test
466-
public void testInferDataTypeCircle(TestContext ctx) {
466+
public void testInferDataTypeCircle42P18(TestContext ctx) {
467467
Circle value = new Circle();
468-
testInferDataType(ctx, Circle.class, value, "<(0,0),0>", "{\"<(0,0),0>\"}");
468+
testInferDataType42P18(ctx, Circle.class, value, "<(0,0),0>", "{\"<(0,0),0>\"}");
469469
}
470470

471-
private <T> void testInferDataType(TestContext ctx, Class<T> type, T value, String suffix) {
472-
testInferDataType(ctx, type, value, suffix, "{" + suffix + "}");
471+
private <T> void testInferDataType42P18(TestContext ctx, Class<T> type, T value, String suffix) {
472+
testInferDataType42P18(ctx, type, value, suffix, "{" + suffix + "}");
473473
}
474474

475-
private <T> void testInferDataType(TestContext ctx, Class<T> type, T value, String suffix1, String suffix2) {
475+
private <T> void testInferDataType42P18(TestContext ctx, Class<T> type, T value, String suffix1, String suffix2) {
476+
Object array = Array.newInstance(type, 1);
477+
Array.set(array, 0, value);
476478
PgConnection.connect(vertx, options(), ctx.asyncAssertSuccess(conn -> {
477-
conn.preparedQuery("SELECT CONCAT('HELLO ', $1)")
478-
.execute(Tuple.of(value), ctx.asyncAssertSuccess(result1 -> {
479+
conn
480+
.preparedQuery("SELECT CONCAT('HELLO ', $1)").execute(Tuple.of(value))
481+
.map(result1 -> {
479482
Row row1 = result1.iterator().next();
480483
ctx.assertEquals("HELLO " + suffix1, row1.getString(0));
481-
Object array = Array.newInstance(type, 1);
482-
Array.set(array, 0, value);
483-
conn.preparedQuery("SELECT CONCAT('HELLO ', $1)")
484-
.execute(Tuple.of(array), ctx.asyncAssertSuccess(result2 -> {
485-
Row row2 = result2.iterator().next();
486-
String v = row2.getString(0);
487-
ctx.assertEquals("HELLO " + suffix2, row2.getString(0));
488-
conn.close();
489-
}));
490-
}));
484+
return "";
485+
})
486+
.compose(v -> conn.preparedQuery("SELECT CONCAT('HELLO ', $1)").execute(Tuple.of(array)))
487+
.map(result2 -> {
488+
Row row2 = result2.iterator().next();
489+
String v = row2.getString(0);
490+
ctx.assertEquals("HELLO " + suffix2, row2.getString(0));
491+
return "";
492+
})
493+
.eventually(v -> conn.close());
491494
}));
492495
}
493496

494497
@Test
495-
public void testInferDataTypeFailure(TestContext ctx) {
498+
public void testInferDataTypeLazy42P18(TestContext ctx) {
496499
PgConnection.connect(vertx, options(), ctx.asyncAssertSuccess(conn -> {
497-
conn.preparedQuery("SELECT CONCAT('HELLO', $1)")
498-
.execute(Tuple.of(null), ctx.asyncAssertFailure(result -> {
499-
conn.close();
500-
}));
500+
conn
501+
.prepare("SELECT CONCAT('HELLO', $1)")
502+
.compose(ps -> ps.query().execute(Tuple.of("__")))
503+
.map(result -> {
504+
Row row = result.iterator().next();
505+
ctx.assertEquals("HELLO__", row.getString(0));
506+
return "";
507+
})
508+
.eventually(v -> conn.close());
501509
}));
502510
}
503511

504512
@Test
505-
public void testInferDataTypeLazy(TestContext ctx) {
513+
public void testInferDataTypeFailure42P18(TestContext ctx) {
506514
PgConnection.connect(vertx, options(), ctx.asyncAssertSuccess(conn -> {
507-
conn.prepare("SELECT CONCAT('HELLO', $1)", ctx.asyncAssertSuccess(ps -> {
508-
ps.query().execute(Tuple.of("__"), ctx.asyncAssertSuccess(result -> {
509-
Row row = result.iterator().next();
510-
ctx.assertEquals("HELLO__", row.getString(0));
511-
conn.close();
512-
}));
513-
}));
515+
conn.preparedQuery("SELECT CONCAT('HELLO', $1)")
516+
.execute(Tuple.of(null))
517+
.eventually(v -> conn.close())
518+
.onComplete(ctx.asyncAssertFailure());
514519
}));
515520
}
516521

517522
@Test
518-
public void testInferDataTypeLazyFailure(TestContext ctx) {
523+
public void testInferDataTypeLazyFailure42P18(TestContext ctx) {
519524
PgConnection.connect(vertx, options(), ctx.asyncAssertSuccess(conn -> {
520-
conn.prepare("SELECT CONCAT('HELLO', $1)", ctx.asyncAssertSuccess(ps -> {
521-
ps.query().execute(Tuple.of(null), ctx.asyncAssertFailure(result -> {
522-
conn.close();
523-
}));
524-
}));
525+
conn
526+
.prepare("SELECT CONCAT('HELLO', $1)")
527+
.compose(ps -> ps.query().execute(Tuple.of(null)))
528+
.eventually(v -> conn.close())
529+
.onComplete(ctx.asyncAssertFailure());
525530
}));
526531
}
527532

528533
@Test
529-
public void testInferDataTypeLazyPolymorphic(TestContext ctx) {
534+
public void testInferDataTypeLazy42804(TestContext ctx) {
530535
PgConnection.connect(vertx, options(), ctx.asyncAssertSuccess(conn -> {
531-
conn.prepare("SELECT to_jsonb($1)", ctx.asyncAssertSuccess(ps -> {
532-
ps.query().execute(Tuple.of("foo"), ctx.asyncAssertSuccess(result -> {
536+
conn
537+
.prepare("SELECT to_jsonb($1)")
538+
.compose(ps -> ps.query().execute(Tuple.of("foo")))
539+
.map(result -> {
533540
ctx.assertEquals("foo", result.iterator().next().getString(0));
534-
conn.close();
535-
}));
536-
}));
541+
return "";
542+
})
543+
.eventually(v -> conn.close())
544+
.onComplete(ctx.asyncAssertSuccess());
545+
}));
546+
}
547+
548+
@Test
549+
public void testInferDataTypeLazy42P08(TestContext ctx) {
550+
PgConnection.connect(vertx, options(), ctx.asyncAssertSuccess(conn -> {
551+
conn
552+
.prepare("UPDATE Fortune SET message=$2 WHERE id=$1 AND (Fortune.*) IS DISTINCT FROM ($1, $2)")
553+
.compose(ps -> ps.query().execute(Tuple.of(9, "Feature: A bug with seniority.")))
554+
.eventually(v -> conn.close())
555+
.onComplete(ctx.asyncAssertSuccess());
537556
}));
538557
}
539558
}

0 commit comments

Comments
 (0)