Skip to content

Commit

Permalink
Apply best-effort conversion for numeric and boolean types when the r…
Browse files Browse the repository at this point in the history
…eturned script return type does not match #2200

We now attempt a best-effort conversion for return values for which the intended CommandOutput does not match. Specifically, Boolean and Integer outputs attempt return value parsing.
  • Loading branch information
mp911de committed Sep 26, 2022
1 parent 82e67b3 commit 76c995e
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 7 deletions.
3 changes: 2 additions & 1 deletion src/main/java/io/lettuce/core/output/BooleanOutput.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package io.lettuce.core.output;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;

import io.lettuce.core.codec.RedisCodec;

Expand All @@ -41,7 +42,7 @@ public void set(long integer) {

@Override
public void set(ByteBuffer bytes) {
output = (bytes != null) ? Boolean.TRUE : Boolean.FALSE;
output = (bytes != null) ? Boolean.parseBoolean(StandardCharsets.UTF_8.decode(bytes).toString()) : Boolean.FALSE;
}

@Override
Expand Down
8 changes: 7 additions & 1 deletion src/main/java/io/lettuce/core/output/IntegerOutput.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package io.lettuce.core.output;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;

import io.lettuce.core.codec.RedisCodec;

Expand All @@ -40,7 +41,12 @@ public void set(long integer) {

@Override
public void set(ByteBuffer bytes) {
output = null;
if (bytes == null) {
output = null;
} else {
// fallback for long as ByteBuffer
output = Long.parseLong(StandardCharsets.UTF_8.decode(bytes).toString());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
import io.lettuce.test.condition.EnabledOnCommand;

/**
* Integration tests for scripting commands.
*
* @author Will Glozer
* @author Mark Paluch
* @author dengliming
Expand All @@ -53,6 +55,7 @@
public class ScriptingCommandIntegrationTests extends TestSupport {

private final RedisClient client;

private final RedisCommands<String, String> redis;

@Inject
Expand All @@ -77,13 +80,21 @@ void tearDown() {
}
redis.ping();
}).waitOrTimeout();

}

@Test
void eval() {

redis.set(key, "true");
assertThat((Boolean) redis.eval("return 1 + 1 == 4", BOOLEAN)).isEqualTo(false);
assertThat((Boolean) redis.eval("return redis.call('GET', KEYS[1])", BOOLEAN, key)).isEqualTo(true);

redis.set(key, "1");

assertThat((Boolean) redis.eval("return 1 + 1 == 4", BOOLEAN)).isEqualTo(false);
assertThat((Number) redis.eval("return 1 + 1", INTEGER)).isEqualTo(2L);
assertThat((String) redis.eval("return redis.call('GET', KEYS[1])", VALUE, key)).isEqualTo("1");
assertThat((Long) redis.eval("return redis.call('GET', KEYS[1])", INTEGER, key)).isEqualTo(1L);
assertThat((String) redis.eval("return {ok='status'}", STATUS)).isEqualTo("status");
assertThat((String) redis.eval("return 'one'", VALUE)).isEqualTo("one");
assertThat((List<?>) redis.eval("return {1, 'one', {2}}", MULTI)).isEqualTo(list(1L, "one", list(2L)));
Expand Down Expand Up @@ -132,17 +143,18 @@ void evalsha() {
assertThat((Number) redis.eval(script, INTEGER)).isEqualTo(2L);
assertThat((Number) redis.evalsha(digest, INTEGER)).isEqualTo(2L);

assertThatThrownBy(() -> redis.evalsha(redis.digest("return 1 + 1 == 4"), INTEGER)).isInstanceOf(
RedisNoScriptException.class).hasMessageContaining("NOSCRIPT No matching script. Please use EVAL.");
assertThatThrownBy(() -> redis.evalsha(redis.digest("return 1 + 1 == 4"), INTEGER))
.isInstanceOf(RedisNoScriptException.class)
.hasMessageContaining("NOSCRIPT No matching script. Please use EVAL.");
}

@Test
void evalshaWithMulti() {
redis.scriptFlush();
String digest = redis.digest("return {1234, 5678}");

assertThatThrownBy(() -> redis.evalsha(digest, MULTI)).isInstanceOf(RedisNoScriptException.class).hasMessageContaining(
"NOSCRIPT No matching script. Please use EVAL.");
assertThatThrownBy(() -> redis.evalsha(digest, MULTI)).isInstanceOf(RedisNoScriptException.class)
.hasMessageContaining("NOSCRIPT No matching script. Please use EVAL.");
}

@Test
Expand Down Expand Up @@ -227,4 +239,5 @@ void scriptFlushSync() {
assertThat(redis.scriptFlush(FlushMode.SYNC)).isEqualTo("OK");
assertThat(redis.scriptExists(digest1)).isEqualTo(list(false));
}

}

0 comments on commit 76c995e

Please sign in to comment.