Skip to content

Commit 2ca180b

Browse files
robfrankclaude
andcommitted
#3588 fix: address code review feedback
- Guard streamPaged against non-SQL languages (falls back to CURSOR mode) - Use langOrDefault() in client query/queryStream to prevent NPE on null language - Extract langOrDefault() helper on server side to deduplicate language defaulting - Add streaming query e2e tests for SQL and OpenCypher Co-Authored-By: Claude Opus 4.6 <[email protected]>
1 parent 9ab1d79 commit 2ca180b

File tree

3 files changed

+28
-7
lines changed

3 files changed

+28
-7
lines changed

e2e/src/test/java/com/arcadedb/e2e/RemoteGrpcDatabaseTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,16 @@ void simpleOpenCypherQuery() {
7575
}, false, 10);
7676
}
7777

78+
@Test
79+
void streamQueryWithSQL() {
80+
final ResultSet result = database.queryStream("sql", "select * from Beer limit 10");
81+
assertThat(CollectionUtils.countEntries(result)).isEqualTo(10);
82+
}
83+
84+
@Test
85+
void streamQueryWithOpenCypher() {
86+
final ResultSet result = database.queryStream("opencypher", "MATCH(p:Beer) RETURN p LIMIT 10");
87+
assertThat(CollectionUtils.countEntries(result)).isEqualTo(10);
88+
}
89+
7890
}

grpc-client/src/main/java/com/arcadedb/remote/grpc/RemoteGrpcDatabase.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ public ResultSet query(final String language, final String query, RemoteGrpcConf
556556
ExecuteQueryRequest.Builder requestBuilder = ExecuteQueryRequest.newBuilder()
557557
.setDatabase(getName())
558558
.setQuery(query)
559-
.setLanguage(language)
559+
.setLanguage(langOrDefault(language))
560560
.setCredentials(buildCredentials());
561561

562562
if (transactionId != null) {
@@ -779,7 +779,7 @@ public ResultSet queryStream(final String language, final String query, final Re
779779
stats.queries.incrementAndGet();
780780

781781
StreamQueryRequest.Builder b = StreamQueryRequest.newBuilder().setDatabase(getName()).setQuery(query)
782-
.setLanguage(language)
782+
.setLanguage(langOrDefault(language))
783783
.setCredentials(buildCredentials())
784784
.setBatchSize(batchSize > 0 ? batchSize : 100).setRetrievalMode(mode);
785785

grpcw/src/main/java/com/arcadedb/server/grpc/ArcadeDbGrpcService.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,7 @@ private ExecuteCommandResponse executeCommandInternal(ExecuteCommandRequest req,
252252
try {
253253
final Map<String, Object> params = GrpcTypeConverter.convertParameters(req.getParametersMap());
254254

255-
// Language defaults to "sql" when empty
256-
final String language = (req.getLanguage() == null || req.getLanguage().isEmpty()) ? "sql" : req.getLanguage();
255+
final String language = langOrDefault(req.getLanguage());
257256

258257
// Transaction: begin if requested
259258
final boolean hasTx = req.hasTransaction();
@@ -818,7 +817,7 @@ public void executeQuery(ExecuteQueryRequest request, StreamObserver<ExecuteQuer
818817
// Execute the query
819818
long startTime = System.currentTimeMillis();
820819

821-
final String language = (request.getLanguage() == null || request.getLanguage().isEmpty()) ? "sql" : request.getLanguage();
820+
final String language = langOrDefault(request.getLanguage());
822821

823822
LogManager.instance().log(this, Level.FINE, "executeQuery(): language = %s query = %s", language, request.getQuery());
824823

@@ -1107,12 +1106,18 @@ public void streamQuery(StreamQueryRequest request, StreamObserver<QueryResult>
11071106
beganHere = true;
11081107
}
11091108

1110-
final String language = (request.getLanguage() == null || request.getLanguage().isEmpty()) ? "sql" : request.getLanguage();
1109+
final String language = langOrDefault(request.getLanguage());
11111110

11121111
// --- Dispatch on mode (helpers do NOT manage transactions) ---
1112+
// PAGED mode uses SQL-specific SKIP/LIMIT wrapping, so fall back to CURSOR for non-SQL languages
11131113
switch (request.getRetrievalMode()) {
11141114
case MATERIALIZE_ALL -> streamMaterialized(db, request, batchSize, scso, cancelled, projectionConfig, language);
1115-
case PAGED -> streamPaged(db, request, batchSize, scso, cancelled, projectionConfig, language);
1115+
case PAGED -> {
1116+
if (!"sql".equalsIgnoreCase(language))
1117+
streamCursor(db, request, batchSize, scso, cancelled, projectionConfig, language);
1118+
else
1119+
streamPaged(db, request, batchSize, scso, cancelled, projectionConfig, language);
1120+
}
11161121
case CURSOR -> streamCursor(db, request, batchSize, scso, cancelled, projectionConfig, language);
11171122
default -> streamCursor(db, request, batchSize, scso, cancelled, projectionConfig, language);
11181123
}
@@ -3067,6 +3072,10 @@ private String generateTransactionId() {
30673072
return "tx_" + System.nanoTime();
30683073
}
30693074

3075+
private static String langOrDefault(String language) {
3076+
return (language == null || language.isEmpty()) ? "sql" : language;
3077+
}
3078+
30703079
// ---- Debug helpers ----
30713080
private static String summarizeJava(Object o) {
30723081
if (o == null)

0 commit comments

Comments
 (0)