Skip to content

Commit 6a5fc09

Browse files
committed
Invalidate statement cache even if the statement is not reprepared.
This helps with cache hygiene. Also, reduce allocations. [#382] Signed-off-by: Mark Paluch <[email protected]>
1 parent 7f57957 commit 6a5fc09

File tree

1 file changed

+22
-20
lines changed

1 file changed

+22
-20
lines changed

src/main/java/io/r2dbc/postgresql/ExtendedFlowDelegate.java

+22-20
Original file line numberDiff line numberDiff line change
@@ -253,28 +253,31 @@ private static Flux<BackendMessage> fetchCursoredWithFlush(ExtendedFlowOperator
253253
}
254254

255255
private static BiConsumer<BackendMessage, SynchronousSink<BackendMessage>> handleReprepare(Sinks.Many<FrontendMessage> requests, ExtendedFlowOperator operator, MessageFactory messageFactory) {
256-
257256
AtomicBoolean reprepared = new AtomicBoolean();
258257

259258
return (message, sink) -> {
260259

261-
if (message instanceof ErrorResponse && requiresReprepare((ErrorResponse) message) && reprepared.compareAndSet(false, true)) {
260+
if (message instanceof ErrorResponse && requiresReprepare((ErrorResponse) message)) {
262261

263262
operator.evictCachedStatement();
264263

265-
List<FrontendMessage.DirectEncoder> messages = messageFactory.createMessages();
266-
if (!messages.contains(Sync.INSTANCE)) {
267-
messages.add(0, Sync.INSTANCE);
264+
if (reprepared.compareAndSet(false, true)) {
265+
266+
List<FrontendMessage.DirectEncoder> messages = messageFactory.createMessages();
267+
if (!messages.contains(Sync.INSTANCE)) {
268+
messages.add(0, Sync.INSTANCE);
269+
}
270+
requests.emitNext(new CompositeFrontendMessage(messages), Sinks.EmitFailureHandler.FAIL_FAST);
271+
272+
return;
268273
}
269-
requests.emitNext(new CompositeFrontendMessage(messages), Sinks.EmitFailureHandler.FAIL_FAST);
270-
} else {
271-
sink.next(message);
272274
}
275+
276+
sink.next(message);
273277
};
274278
}
275279

276280
private static boolean requiresReprepare(ErrorResponse errorResponse) {
277-
278281
ErrorDetails details = new ErrorDetails(errorResponse.getFields());
279282
String code = details.getCode();
280283

@@ -304,7 +307,7 @@ interface MessageFactory {
304307
/**
305308
* Operator to encapsulate common activity around the extended flow. Subclasses {@link AtomicInteger} to capture the number of ReadyForQuery frames.
306309
*/
307-
static class ExtendedFlowOperator extends AtomicInteger {
310+
static class ExtendedFlowOperator extends AtomicInteger implements Predicate<BackendMessage> {
308311

309312
private final String sql;
310313

@@ -328,7 +331,6 @@ public ExtendedFlowOperator(String sql, Binding binding, StatementCache cache, L
328331
this.values = values;
329332
this.portal = portal;
330333
this.forceBinary = forceBinary;
331-
set(1);
332334
}
333335

334336
public void close(Sinks.Many<FrontendMessage> requests) {
@@ -337,9 +339,6 @@ public void close(Sinks.Many<FrontendMessage> requests) {
337339
}
338340

339341
public void evictCachedStatement() {
340-
341-
incrementAndGet();
342-
343342
synchronized (this) {
344343
this.name = null;
345344
}
@@ -351,14 +350,16 @@ public void hydrateStatementCache() {
351350
}
352351

353352
public Predicate<BackendMessage> takeUntil() {
354-
return m -> {
353+
return this;
354+
}
355355

356-
if (m instanceof ReadyForQuery) {
357-
return decrementAndGet() <= 0;
358-
}
356+
@Override
357+
public boolean test(BackendMessage backendMessage) {
358+
if (backendMessage instanceof ReadyForQuery) {
359+
return decrementAndGet() <= 0;
360+
}
359361

360-
return false;
361-
};
362+
return false;
362363
}
363364

364365
private boolean isPrepareRequired() {
@@ -376,6 +377,7 @@ public String getStatementName() {
376377
}
377378

378379
public List<FrontendMessage.DirectEncoder> getMessages(Collection<FrontendMessage.DirectEncoder> append) {
380+
incrementAndGet();
379381
List<FrontendMessage.DirectEncoder> messagesToSend = new ArrayList<>(6);
380382

381383
if (isPrepareRequired()) {

0 commit comments

Comments
 (0)