Skip to content

Commit 87ae812

Browse files
daschlMichael Nitschinger
authored andcommitted
JCBC-1594: Retry query error 4040.
It has been discovered that this error is returned by a 6.5 or later cluster even if the client sends the prepared statement paylods (because it does not look at them anymore due to security reasons). If the client receives a 4040, it is expected to clear the cache entry for this specific prepared statement and reprepare transparently. Change-Id: I10fe886fa43e971b444b59b5f96149fce694b85c Reviewed-on: http://review.couchbase.org/122597 Reviewed-by: Graham Pople <grahampople@gmail.com> Tested-by: Michael Nitschinger <michael.nitschinger@couchbase.com>
1 parent a3efbe2 commit 87ae812

File tree

2 files changed

+23
-19
lines changed

2 files changed

+23
-19
lines changed

src/main/java/com/couchbase/client/java/query/core/N1qlQueryExecutor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ private static boolean shouldRetry(JsonObject errorJson) {
301301

302302
if (code == null || msg == null) return false;
303303

304-
if (code == 4050 || code == 4070 ||
304+
if (code == 4040 || code == 4050 || code == 4070 ||
305305
(code == 5000 && msg.contains(ERROR_5000_SPECIFIC_MESSAGE))) {
306306
return true;
307307
}

src/test/java/com/couchbase/client/java/query/core/N1qlQueryExecutorTest.java

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
import com.couchbase.client.java.query.Select;
5050
import com.couchbase.client.java.query.Statement;
5151
import com.couchbase.client.java.util.LRUCache;
52-
import org.junit.After;
5352
import org.junit.AfterClass;
5453
import org.junit.Test;
5554
import org.mockito.internal.stubbing.answers.ReturnsElementsOf;
@@ -71,8 +70,8 @@ public static void tearDown() {
7170
}
7271

7372
@Test
74-
public void testPreparedStatementInCacheBypassesPreparation() throws Exception {
75-
LRUCache<String, PreparedPayload> cache = new LRUCache<String, PreparedPayload>(3);
73+
public void testPreparedStatementInCacheBypassesPreparation() {
74+
LRUCache<String, PreparedPayload> cache = new LRUCache<>(3);
7675
CouchbaseCore mockFacade = mock(CouchbaseCore.class);
7776
N1qlQueryExecutor executor = spy(new N1qlQueryExecutor(mockFacade, "default", "", "", cache, true));
7877

@@ -100,8 +99,8 @@ public void testPreparedStatementInCacheBypassesPreparation() throws Exception {
10099
}
101100

102101
@Test
103-
public void testPreparedStatementNotInCacheTriggersPreparation() throws Exception {
104-
LRUCache<String, PreparedPayload> cache = new LRUCache<String, PreparedPayload>(3);
102+
public void testPreparedStatementNotInCacheTriggersPreparation() {
103+
LRUCache<String, PreparedPayload> cache = new LRUCache<>(3);
105104
CouchbaseCore mockFacade = mock(CouchbaseCore.class);
106105
N1qlQueryExecutor executor = spy(new N1qlQueryExecutor(mockFacade, "default", "", "", cache, true));
107106

@@ -135,7 +134,7 @@ public void testPreparedStatementNotInCacheTriggersPreparation() throws Exceptio
135134

136135
@Test
137136
public void testExtractionOfPayloadFromPrepareResponse() {
138-
LRUCache<String, PreparedPayload> cache = new LRUCache<String, PreparedPayload>(3);
137+
LRUCache<String, PreparedPayload> cache = new LRUCache<>(3);
139138
CouchbaseCore mockFacade = mock(CouchbaseCore.class);
140139
N1qlQueryExecutor executor = new N1qlQueryExecutor(mockFacade, "default", "", "", cache, true);
141140

@@ -155,8 +154,8 @@ public void testExtractionOfPayloadFromPrepareResponse() {
155154
}
156155

157156
@Test
158-
public void testCachedPlanExecutionErrorTriggersRetry() throws Exception {
159-
LRUCache<String, PreparedPayload> cache = new LRUCache<String, PreparedPayload>(3);
157+
public void testCachedPlanExecutionErrorTriggersRetry() {
158+
LRUCache<String, PreparedPayload> cache = new LRUCache<>(3);
160159
CouchbaseCore mockFacade = mock(CouchbaseCore.class);
161160
N1qlQueryExecutor executor = spy(new N1qlQueryExecutor(mockFacade, "default", "", "", cache, true));
162161

@@ -191,8 +190,8 @@ public void testCachedPlanExecutionErrorTriggersRetry() throws Exception {
191190
}
192191

193192
@Test
194-
public void testUncachedPlanExecutionErrorTriggersRetry() throws Exception {
195-
LRUCache<String, PreparedPayload> cache = new LRUCache<String, PreparedPayload>(3);
193+
public void testUncachedPlanExecutionErrorTriggersRetry() {
194+
LRUCache<String, PreparedPayload> cache = new LRUCache<>(3);
196195
CouchbaseCore mockFacade = mock(CouchbaseCore.class);
197196
N1qlQueryExecutor executor = spy(new N1qlQueryExecutor(mockFacade, "default", "", "", cache, true));
198197

@@ -243,8 +242,8 @@ public void testUncachedPlanExecutionErrorTriggersRetry() throws Exception {
243242

244243

245244
@Test
246-
public void testUncachedPlanExecutionDoubleErrorTriggersRetryThenFails() throws Exception {
247-
LRUCache<String, PreparedPayload> cache = new LRUCache<String, PreparedPayload>(3);
245+
public void testUncachedPlanExecutionDoubleErrorTriggersRetryThenFails() {
246+
LRUCache<String, PreparedPayload> cache = new LRUCache<>(3);
248247
CouchbaseCore mockFacade = mock(CouchbaseCore.class);
249248
N1qlQueryExecutor executor = spy(new N1qlQueryExecutor(mockFacade, "default", "", "", cache, true));
250249

@@ -299,8 +298,8 @@ public void testUncachedPlanExecutionDoubleErrorTriggersRetryThenFails() throws
299298
assertEquals(4050, errors.get(0).getInt("code").intValue());
300299
}
301300

302-
private void testRetryCondition(int code, String msg, boolean retryExpected) throws Exception {
303-
LRUCache<String, PreparedPayload> cache = new LRUCache<String, PreparedPayload>(3);
301+
private void testRetryCondition(int code, String msg, boolean retryExpected) {
302+
LRUCache<String, PreparedPayload> cache = new LRUCache<>(3);
304303
CouchbaseCore mockFacade = mock(CouchbaseCore.class);
305304
N1qlQueryExecutor executor = spy(new N1qlQueryExecutor(mockFacade, "default", "", "", cache, true));
306305

@@ -362,22 +361,27 @@ private void testRetryCondition(int code, String msg, boolean retryExpected) thr
362361
}
363362

364363
@Test
365-
public void testRetryOn4050() throws Exception {
364+
public void testRetryOn4040() {
365+
testRetryCondition(4040, "notRelevant", true);
366+
}
367+
368+
@Test
369+
public void testRetryOn4050() {
366370
testRetryCondition(4050, "notRelevant", true);
367371
}
368372

369373
@Test
370-
public void testRetryOn4070() throws Exception {
374+
public void testRetryOn4070() {
371375
testRetryCondition(4070, "notRelevant", true);
372376
}
373377

374378
@Test
375-
public void testRetryOn5000WithSpecificMessage() throws Exception {
379+
public void testRetryOn5000WithSpecificMessage() {
376380
testRetryCondition(5000, "toto" + N1qlQueryExecutor.ERROR_5000_SPECIFIC_MESSAGE, true);
377381
}
378382

379383
@Test
380-
public void testNoRetryOn5000WithRandomMessage() throws Exception {
384+
public void testNoRetryOn5000WithRandomMessage() {
381385
testRetryCondition(5000, "notRelevant", false);
382386
}
383387
}

0 commit comments

Comments
 (0)