Skip to content

Commit 8ad52fe

Browse files
author
Julien Ruaux
committed
fix: case insensitive names. Fixes #10
1 parent d14676e commit 8ad52fe

File tree

9 files changed

+89
-50
lines changed

9 files changed

+89
-50
lines changed

src/main/java/com/redis/trino/RediSearchSession.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import static java.lang.String.format;
3232
import static java.util.Locale.ENGLISH;
3333
import static java.util.Objects.requireNonNull;
34+
import static java.util.stream.Collectors.toSet;
3435

3536
import java.io.File;
3637
import java.util.Collections;
@@ -40,6 +41,7 @@
4041
import java.util.Map;
4142
import java.util.Optional;
4243
import java.util.Set;
44+
import java.util.concurrent.ExecutionException;
4345
import java.util.concurrent.TimeUnit;
4446
import java.util.stream.Collectors;
4547

@@ -165,7 +167,7 @@ public List<HostAddress> getAddresses() {
165167
return Collections.emptyList();
166168
}
167169

168-
public Set<String> getAllTables() throws SchemaNotFoundException {
170+
private Set<String> listIndexNames() throws SchemaNotFoundException {
169171
ImmutableSet.Builder<String> builder = ImmutableSet.builder();
170172
builder.addAll(connection.sync().ftList());
171173
return builder.build();
@@ -179,13 +181,17 @@ public Set<String> getAllTables() throws SchemaNotFoundException {
179181
*/
180182
public RediSearchTable getTable(SchemaTableName tableName) throws TableNotFoundException {
181183
try {
182-
return tableCache.getUnchecked(tableName);
183-
} catch (UncheckedExecutionException e) {
184+
return tableCache.get(tableName, () -> loadTableSchema(tableName));
185+
} catch (ExecutionException | UncheckedExecutionException e) {
184186
throwIfInstanceOf(e.getCause(), TrinoException.class);
185-
throw e;
187+
throw new RuntimeException(e);
186188
}
187189
}
188190

191+
public Set<String> getAllTables() {
192+
return listIndexNames().stream().collect(toSet());
193+
}
194+
189195
@SuppressWarnings("unchecked")
190196
public void createTable(SchemaTableName schemaTableName, List<RediSearchColumnHandle> columns) {
191197
String index = index(schemaTableName);
@@ -214,7 +220,7 @@ private String toRemoteTableName(String tableName) {
214220
if (!config.isCaseInsensitiveNames()) {
215221
return tableName;
216222
}
217-
for (String remoteTableName : getAllTables()) {
223+
for (String remoteTableName : listIndexNames()) {
218224
if (tableName.equals(remoteTableName.toLowerCase(ENGLISH))) {
219225
return remoteTableName;
220226
}
@@ -233,7 +239,7 @@ public void dropColumn(SchemaTableName schemaTableName, String columnName) {
233239
* @throws TableNotFoundException if no index by that name was found
234240
*/
235241
private RediSearchTable loadTableSchema(SchemaTableName schemaTableName) throws TableNotFoundException {
236-
String index = schemaTableName.getTableName();
242+
String index = toRemoteTableName(schemaTableName.getTableName());
237243
Optional<IndexInfo> indexInfoOptional = indexInfo(index);
238244
if (indexInfoOptional.isEmpty()) {
239245
throw new TableNotFoundException(schemaTableName, format("Index '%s' not found", index), null);

src/test/java/com/redis/trino/RediSearchLoader.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@
2020
import com.redis.lettucemod.api.StatefulRedisModulesConnection;
2121
import com.redis.lettucemod.search.CreateOptions;
2222
import com.redis.lettucemod.search.Field;
23-
import com.redis.testcontainers.junit.RedisTestContext;
23+
import com.redis.lettucemod.util.RedisModulesUtils;
2424

25+
import io.lettuce.core.AbstractRedisClient;
2526
import io.lettuce.core.LettuceFutures;
2627
import io.lettuce.core.RedisFuture;
2728
import io.trino.Session;
@@ -35,15 +36,16 @@
3536
import io.trino.testing.ResultsSession;
3637

3738
public class RediSearchLoader extends AbstractTestingTrinoClient<Void> {
39+
3840
private final String tableName;
39-
private final RedisTestContext context;
41+
private final StatefulRedisModulesConnection<String, String> connection;
4042

41-
public RediSearchLoader(RedisTestContext context, String tableName, TestingTrinoServer trinoServer,
43+
public RediSearchLoader(AbstractRedisClient client, String tableName, TestingTrinoServer trinoServer,
4244
Session defaultSession) {
4345
super(trinoServer, defaultSession);
44-
46+
requireNonNull(client, "client is null");
47+
this.connection = RedisModulesUtils.connection(client);
4548
this.tableName = requireNonNull(tableName, "tableName is null");
46-
this.context = requireNonNull(context, "client is null");
4749
}
4850

4951
@Override
@@ -52,6 +54,12 @@ public ResultsSession<Void> getResultSession(Session session) {
5254
return new RediSearchLoadingSession();
5355
}
5456

57+
@Override
58+
public void close() {
59+
connection.close();
60+
super.close();
61+
}
62+
5563
private class RediSearchLoadingSession implements ResultsSession<Void> {
5664

5765
private final AtomicReference<List<Type>> types = new AtomicReference<>();
@@ -71,17 +79,16 @@ public void addResults(QueryStatusInfo statusInfo, QueryData data) {
7179
}
7280
checkState(types.get() != null, "Type information is missing");
7381
List<Column> columns = statusInfo.getColumns();
74-
if (!context.sync().ftList().contains(tableName)) {
82+
if (!connection.sync().ftList().contains(tableName)) {
7583
List<Field<String>> schema = new ArrayList<>();
7684
for (int i = 0; i < columns.size(); i++) {
7785
Type type = types.get().get(i);
7886
schema.add(field(columns.get(i).getName(), type));
7987
}
80-
context.sync().ftCreate(tableName,
88+
connection.sync().ftCreate(tableName,
8189
CreateOptions.<String, String>builder().prefix(tableName + ":").build(),
8290
schema.toArray(Field[]::new));
8391
}
84-
StatefulRedisModulesConnection<String, String> connection = context.getConnection();
8592
connection.setAutoFlushCommands(false);
8693
try {
8794
UlidFactory factory = UlidFactory.newInstance(new Random());
@@ -94,10 +101,10 @@ public void addResults(QueryStatusInfo statusInfo, QueryData data) {
94101
String value = convertValue(fields.get(i), type);
95102
map.put(columns.get(i).getName(), value);
96103
}
97-
futures.add(context.async().hset(key, map));
104+
futures.add(connection.async().hset(key, map));
98105
}
99106
connection.flushCommands();
100-
LettuceFutures.awaitAll(context.getConnection().getTimeout(), futures.toArray(new RedisFuture[0]));
107+
LettuceFutures.awaitAll(connection.getTimeout(), futures.toArray(new RedisFuture[0]));
101108
} finally {
102109
connection.setAutoFlushCommands(true);
103110
}

src/test/java/com/redis/trino/RediSearchQueryRunner.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,19 +88,20 @@ public static <T extends Throwable> T closeAllSuppress(T rootCause, AutoCloseabl
8888
private static void installRediSearchPlugin(RediSearchServer server, QueryRunner queryRunner,
8989
RediSearchConnectorFactory factory, Map<String, String> extraConnectorProperties) {
9090
queryRunner.installPlugin(new RediSearchPlugin(factory));
91-
Map<String, String> config = ImmutableMap.<String, String>builder()
92-
.put("redisearch.uri", server.getTestContext().getRedisURI()).put("redisearch.default-limit", "100000")
93-
.put("redisearch.default-schema-name", TPCH_SCHEMA).putAll(extraConnectorProperties).build();
91+
Map<String, String> config = ImmutableMap.<String, String>builder().put("redisearch.uri", server.getRedisURI())
92+
.put("redisearch.default-limit", "100000").put("redisearch.default-schema-name", TPCH_SCHEMA)
93+
.putAll(extraConnectorProperties).build();
9494
queryRunner.createCatalog("redisearch", "redisearch", config);
9595
}
9696

9797
private static void loadTpchTopic(RediSearchServer server, TestingTrinoClient trinoClient, TpchTable<?> table) {
9898
long start = System.nanoTime();
9999
LOG.info("Running import for %s", table.getTableName());
100-
RediSearchLoader loader = new RediSearchLoader(server.getTestContext(),
101-
table.getTableName().toLowerCase(ENGLISH), trinoClient.getServer(), trinoClient.getDefaultSession());
102-
loader.execute(format("SELECT * from %s",
103-
new QualifiedObjectName(TPCH_SCHEMA, TINY_SCHEMA_NAME, table.getTableName().toLowerCase(ENGLISH))));
100+
try (RediSearchLoader loader = new RediSearchLoader(server.getClient(),
101+
table.getTableName().toLowerCase(ENGLISH), trinoClient.getServer(), trinoClient.getDefaultSession())) {
102+
loader.execute(format("SELECT * from %s",
103+
new QualifiedObjectName(TPCH_SCHEMA, TINY_SCHEMA_NAME, table.getTableName().toLowerCase(ENGLISH))));
104+
}
104105
LOG.info("Imported %s in %s s", table.getTableName(), Duration.ofNanos(System.nanoTime() - start).toSeconds());
105106
}
106107

src/test/java/com/redis/trino/RediSearchServer.java

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,49 @@
22

33
import java.io.Closeable;
44

5+
import org.testcontainers.utility.DockerImageName;
6+
7+
import com.redis.lettucemod.api.StatefulRedisModulesConnection;
8+
import com.redis.lettucemod.util.ClientBuilder;
9+
import com.redis.lettucemod.util.RedisModulesUtils;
510
import com.redis.testcontainers.RedisStackContainer;
6-
import com.redis.testcontainers.junit.RedisTestContext;
11+
12+
import io.lettuce.core.AbstractRedisClient;
13+
import io.lettuce.core.RedisURI;
714

815
public class RediSearchServer implements Closeable {
916

10-
private final RedisStackContainer dockerContainer;
11-
private final RedisTestContext context;
17+
private static final DockerImageName DOCKER_IMAGE_NAME = RedisStackContainer.DEFAULT_IMAGE_NAME
18+
.withTag(RedisStackContainer.DEFAULT_TAG);
19+
private final RedisStackContainer container = new RedisStackContainer(DOCKER_IMAGE_NAME).withEnv("REDISEARCH_ARGS",
20+
"MAXAGGREGATERESULTS -1");
21+
private final AbstractRedisClient client;
22+
private final StatefulRedisModulesConnection<String, String> connection;
1223

1324
public RediSearchServer() {
14-
this.dockerContainer = new RedisStackContainer(
15-
RedisStackContainer.DEFAULT_IMAGE_NAME.withTag(RedisStackContainer.DEFAULT_TAG));
16-
this.dockerContainer.withEnv("REDISEARCH_ARGS", "MAXAGGREGATERESULTS -1");
17-
this.dockerContainer.start();
18-
this.context = new RedisTestContext(dockerContainer);
25+
this.container.start();
26+
this.client = ClientBuilder.create(RedisURI.create(container.getRedisURI())).cluster(container.isCluster())
27+
.build();
28+
this.connection = RedisModulesUtils.connection(client);
29+
}
30+
31+
public String getRedisURI() {
32+
return container.getRedisURI();
33+
}
34+
35+
public AbstractRedisClient getClient() {
36+
return client;
1937
}
2038

21-
public RedisTestContext getTestContext() {
22-
return context;
39+
public StatefulRedisModulesConnection<String, String> getConnection() {
40+
return connection;
2341
}
2442

2543
@Override
2644
public void close() {
27-
context.close();
28-
dockerContainer.close();
45+
connection.close();
46+
client.shutdown();
47+
client.getResources().shutdown();
48+
container.close();
2949
}
3050
}

src/test/java/com/redis/trino/TestRediSearchConfig.java renamed to src/test/java/com/redis/trino/TestConfig.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
import io.airlift.configuration.ConfigurationFactory;
1414

15-
public class TestRediSearchConfig {
15+
public class TestConfig {
1616

1717
@Test
1818
public void testDefaults() {

src/test/java/com/redis/trino/TestRediSearchConnectorSmokeTest.java renamed to src/test/java/com/redis/trino/TestConnectorSmokeTest.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@
2020

2121
import com.google.common.base.Throwables;
2222
import com.redis.lettucemod.Beers;
23+
import com.redis.lettucemod.api.StatefulRedisModulesConnection;
2324
import com.redis.lettucemod.api.sync.RedisModulesCommands;
2425
import com.redis.lettucemod.search.CreateOptions;
2526
import com.redis.lettucemod.search.CreateOptions.DataType;
2627
import com.redis.lettucemod.search.Field;
28+
import com.redis.lettucemod.util.RedisModulesUtils;
2729

2830
import io.airlift.log.Logger;
2931
import io.trino.spi.TrinoException;
@@ -33,9 +35,9 @@
3335
import io.trino.testing.TestingConnectorBehavior;
3436
import io.trino.testing.sql.TestTable;
3537

36-
public class TestRediSearchConnectorSmokeTest extends BaseConnectorSmokeTest {
38+
public class TestConnectorSmokeTest extends BaseConnectorSmokeTest {
3739

38-
private static final Logger log = Logger.get(TestRediSearchConnectorSmokeTest.class);
40+
private static final Logger log = Logger.get(TestConnectorSmokeTest.class);
3941

4042
private RediSearchServer redisearch;
4143

@@ -46,7 +48,10 @@ protected QueryRunner createQueryRunner() throws Exception {
4648
}
4749

4850
private void populateBeers() throws IOException, InterruptedException {
49-
Beers.populateIndex(redisearch.getTestContext().getConnection());
51+
try (StatefulRedisModulesConnection<String, String> connection = RedisModulesUtils
52+
.connection(redisearch.getClient())) {
53+
Beers.populateIndex(connection);
54+
}
5055
}
5156

5257
@Override
@@ -121,14 +126,14 @@ public void testRediSearchFields() throws IOException, InterruptedException {
121126
public void testCountEmptyIndex() throws IOException, InterruptedException {
122127
String index = "emptyidx";
123128
CreateOptions<String, String> options = CreateOptions.<String, String>builder().prefix(index + ":").build();
124-
redisearch.getTestContext().sync().ftCreate(index, options, Field.tag("field1").build());
129+
redisearch.getConnection().sync().ftCreate(index, options, Field.tag("field1").build());
125130
assertQuery("SELECT count(*) FROM " + index, "VALUES 0");
126131
}
127132

128133
@SuppressWarnings("unchecked")
129134
@Test
130135
public void testJsonSearch() throws IOException {
131-
RedisModulesCommands<String, String> sync = redisearch.getTestContext().getConnection().sync();
136+
RedisModulesCommands<String, String> sync = redisearch.getConnection().sync();
132137
sync.ftCreate("jsontest", CreateOptions.<String, String>builder().on(DataType.JSON).build(),
133138
Field.tag("$.id").as("id").build(), Field.text("$.message").as("message").build());
134139
sync.jsonSet("doc:1", "$", "{\"id\": \"1\", \"message\": \"this is a test\"}");
@@ -152,11 +157,11 @@ public void testInsertIndex() throws IOException, InterruptedException {
152157
String index = "insertidx";
153158
String prefix = index + ":";
154159
CreateOptions<String, String> options = CreateOptions.<String, String>builder().prefix(prefix).build();
155-
redisearch.getTestContext().sync().ftCreate(index, options, Field.tag("id").build(), Field.tag("name").build());
160+
redisearch.getConnection().sync().ftCreate(index, options, Field.tag("id").build(), Field.tag("name").build());
156161
assertUpdate(String.format("INSERT INTO %s (id, name) VALUES ('abc', 'mybeer')", index), 1);
157162
assertThat(query(String.format("SELECT id, name FROM %s", index)))
158163
.matches("VALUES (VARCHAR 'abc', VARCHAR 'mybeer')");
159-
List<String> keys = redisearch.getTestContext().sync().keys(prefix + "*");
164+
List<String> keys = redisearch.getConnection().sync().keys(prefix + "*");
160165
assertEquals(keys.size(), 1);
161166
assertTrue(keys.get(0).startsWith(prefix));
162167
}
@@ -167,8 +172,8 @@ public final void destroy() {
167172
}
168173

169174
static RuntimeException getTrinoExceptionCause(Throwable e) {
170-
return Throwables.getCausalChain(e).stream().filter(TestRediSearchConnectorSmokeTest::isTrinoException)
171-
.findFirst().map(RuntimeException.class::cast)
175+
return Throwables.getCausalChain(e).stream().filter(TestConnectorSmokeTest::isTrinoException).findFirst()
176+
.map(RuntimeException.class::cast)
172177
.orElseThrow(() -> new IllegalArgumentException("Exception does not have TrinoException cause", e));
173178
}
174179

src/test/java/com/redis/trino/TestRediSearchPlugin.java renamed to src/test/java/com/redis/trino/TestPlugin.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import io.trino.spi.connector.ConnectorFactory;
1414
import io.trino.testing.TestingConnectorContext;
1515

16-
public class TestRediSearchPlugin {
16+
public class TestPlugin {
1717

1818
private RediSearchServer server;
1919

@@ -27,8 +27,7 @@ public void testCreateConnector() {
2727
RediSearchPlugin plugin = new RediSearchPlugin();
2828

2929
ConnectorFactory factory = getOnlyElement(plugin.getConnectorFactories());
30-
Connector connector = factory.create("test",
31-
ImmutableMap.of("redisearch.uri", server.getTestContext().getRedisURI()),
30+
Connector connector = factory.create("test", ImmutableMap.of("redisearch.uri", server.getRedisURI()),
3231
new TestingConnectorContext());
3332

3433
assertFalse(plugin.getTypes().iterator().hasNext());

src/test/java/com/redis/trino/TestRediSearchQueryBuilder.java renamed to src/test/java/com/redis/trino/TestQueryBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import io.trino.spi.predicate.ValueSet;
2121
import io.trino.spi.type.DoubleType;
2222

23-
public class TestRediSearchQueryBuilder {
23+
public class TestQueryBuilder {
2424

2525
private static final RediSearchColumnHandle COL1 = new RediSearchColumnHandle("col1", BIGINT, Field.Type.NUMERIC,
2626
false, true);

src/test/java/com/redis/trino/TestRediSearchTableHandle.java renamed to src/test/java/com/redis/trino/TestTableHandle.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
import io.airlift.json.JsonCodec;
88
import io.trino.spi.connector.SchemaTableName;
99

10-
public class TestRediSearchTableHandle {
10+
public class TestTableHandle {
11+
1112
private final JsonCodec<RediSearchTableHandle> codec = JsonCodec.jsonCodec(RediSearchTableHandle.class);
1213

1314
@Test

0 commit comments

Comments
 (0)