Skip to content

Commit 3e85168

Browse files
committed
fix: redis query result
Fixed issue #3470
1 parent d0b927f commit 3e85168

2 files changed

Lines changed: 52 additions & 12 deletions

File tree

redisw/src/main/java/com/arcadedb/redis/query/RedisQueryEngine.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,14 @@ private List<String> parseCommand(final String command) {
290290
}
291291

292292
private ResultSet createResultSet(final Object result) {
293+
if (result instanceof Record record) {
294+
// Return documents directly (consistent with SQL/OpenCypher result format)
295+
final ResultInternal resultInternal = new ResultInternal(record);
296+
return new IteratorResultSet(Collections.singleton((Result) resultInternal).iterator());
297+
}
298+
293299
final ResultInternal resultInternal = new ResultInternal();
294300
resultInternal.setProperty("value", result);
295-
296301
return new IteratorResultSet(Collections.singleton((Result) resultInternal).iterator());
297302
}
298303

@@ -447,8 +452,7 @@ private Object hGet(final List<String> parts) {
447452

448453
// Check if it's a RID
449454
if (firstArg.startsWith("#")) {
450-
final Record record = new RID(database, firstArg).asDocument();
451-
return record != null ? record.toJSON(true).toString() : null;
455+
return new RID(database, firstArg).asDocument();
452456
}
453457

454458
// It's an index lookup
@@ -459,8 +463,7 @@ private Object hGet(final List<String> parts) {
459463
final String indexName = firstArg;
460464
final String key = parts.get(2);
461465

462-
final Record record = getRecordByIndex(indexName, key);
463-
return record != null ? record.toJSON(true).toString() : null;
466+
return getRecordByIndex(indexName, key);
464467
}
465468

466469
/**
@@ -483,8 +486,7 @@ private List<Object> hMGet(final List<String> parts) {
483486
if (!rid.startsWith("#")) {
484487
throw new CommandParsingException("All arguments must be RIDs when first argument is a RID");
485488
}
486-
final Record record = new RID(database, rid).asDocument();
487-
results.add(record != null ? record.toJSON(true).toString() : null);
489+
results.add(new RID(database, rid).asDocument());
488490
}
489491
} else {
490492
// It's an index lookup
@@ -494,8 +496,7 @@ private List<Object> hMGet(final List<String> parts) {
494496

495497
final String indexName = firstArg;
496498
for (int i = 2; i < parts.size(); i++) {
497-
final Record record = getRecordByIndex(indexName, parts.get(i));
498-
results.add(record != null ? record.toJSON(true).toString() : null);
499+
results.add(getRecordByIndex(indexName, parts.get(i)));
499500
}
500501
}
501502

redisw/src/test/java/com/arcadedb/redis/RedisQueryLanguageTest.java

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,50 @@ void hSetAndHGetWithDatabase() throws Exception {
133133

134134
// Test HGET - retrieve by index (syntax: HGET <indexName> <key>)
135135
response = executeCommand(0, "redis", "HGET Person[id] 1");
136-
final String docJson = (String) getResultValue(response);
137-
final JSONObject doc = new JSONObject(docJson);
136+
final JSONArray results = response.getJSONArray("result");
137+
assertThat(results.length()).isEqualTo(1);
138+
final JSONObject doc = results.getJSONObject(0);
138139
assertThat(doc.getInt("id")).isEqualTo(1);
139140
assertThat(doc.getString("name")).isEqualTo("John");
140141
}
141142

143+
@Test
144+
void hGetReturnsConsistentFormatWithSQL() throws Exception {
145+
// Issue #3470: Redis HGET should return documents in the same format as SQL/OpenCypher
146+
// i.e. {"result": [{"@rid":"...","@type":"...","id":1}]}
147+
// NOT {"result": [{"value": "{\"@rid\":\"...\",\"id\":1}"}]}
148+
final Database database = getServerDatabase(0, getDatabaseName());
149+
150+
database.command("sql", "CREATE VERTEX TYPE doc");
151+
database.command("sql", "CREATE PROPERTY doc.id LONG");
152+
database.command("sql", "CREATE INDEX ON doc (id) UNIQUE");
153+
database.command("sql", "INSERT INTO doc SET id = 1");
154+
155+
// Query via SQL
156+
final JSONObject sqlResponse = executeQuery(0, "sql", "SELECT FROM doc WHERE id = 1");
157+
final JSONArray sqlResults = sqlResponse.getJSONArray("result");
158+
assertThat(sqlResults.length()).isEqualTo(1);
159+
final JSONObject sqlDoc = sqlResults.getJSONObject(0);
160+
161+
// Query via Redis HGET
162+
final JSONObject redisResponse = executeQuery(0, "redis", "HGET doc[id] 1");
163+
final JSONArray redisResults = redisResponse.getJSONArray("result");
164+
assertThat(redisResults.length()).isEqualTo(1);
165+
final JSONObject redisDoc = redisResults.getJSONObject(0);
166+
167+
// Both should have the same structure: document properties at the top level, not wrapped in "value"
168+
assertThat(redisDoc.has("@rid")).isTrue();
169+
assertThat(redisDoc.has("@type")).isTrue();
170+
assertThat(redisDoc.getLong("id")).isEqualTo(1L);
171+
172+
// Should NOT have a "value" wrapper
173+
assertThat(redisDoc.has("value")).isFalse();
174+
175+
// Should match SQL result structure
176+
assertThat(redisDoc.getString("@rid")).isEqualTo(sqlDoc.getString("@rid"));
177+
assertThat(redisDoc.getString("@type")).isEqualTo(sqlDoc.getString("@type"));
178+
}
179+
142180
@Test
143181
void hExistsCommand() throws Exception {
144182
final Database database = getServerDatabase(0, getDatabaseName());
@@ -409,7 +447,8 @@ void nonIdempotentCommandsRejectedOnQueryEndpoint() throws Exception {
409447
assertThat(getResultValue(response)).isEqualTo("PONG");
410448

411449
response = executeQuery(0, "redis", "HGET doc[id] 1");
412-
assertThat(getResultValue(response)).isNotNull();
450+
assertThat(response.getJSONArray("result").length()).isEqualTo(1);
451+
assertThat(response.getJSONArray("result").getJSONObject(0).has("@rid")).isTrue();
413452

414453
response = executeQuery(0, "redis", "HEXISTS doc[id] 1");
415454
assertThat(getResultValueAsInt(response)).isEqualTo(1);

0 commit comments

Comments
 (0)