diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index b5fab70899c9..324bef4791bc 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -449,6 +449,7 @@ jobs:
!:trino-accumulo,
!:trino-bigquery,
!:trino-cassandra,
+ !:trino-scylla,
!:trino-clickhouse,
!:trino-delta-lake,
!:trino-docs,!:trino-server,!:trino-server-rpm,
@@ -554,6 +555,7 @@ jobs:
- { modules: plugin/trino-bigquery }
- { modules: plugin/trino-bigquery, profile: cloud-tests-arrow }
- { modules: plugin/trino-cassandra }
+ - { modules: plugin/trino-scylla }
- { modules: plugin/trino-clickhouse }
- { modules: plugin/trino-delta-lake }
- { modules: plugin/trino-delta-lake, profile: cloud-tests }
@@ -983,6 +985,9 @@ jobs:
- config: default
suite: suite-cassandra
# this suite is not meant to be run with different configs
+ - config: default
+ suite: suite-scylla
+ # this suite is not meant to be run with different configs
- config: default
suite: suite-clickhouse
# this suite is not meant to be run with different configs
diff --git a/core/trino-server/src/main/provisio/trino.xml b/core/trino-server/src/main/provisio/trino.xml
index 8e014d0b9a57..c747cf584498 100644
--- a/core/trino-server/src/main/provisio/trino.xml
+++ b/core/trino-server/src/main/provisio/trino.xml
@@ -306,4 +306,10 @@
+
+
+
+
+
+
diff --git a/docs/src/main/sphinx/connector.md b/docs/src/main/sphinx/connector.md
index 3b86e28f3d56..1ada1a9e7d60 100644
--- a/docs/src/main/sphinx/connector.md
+++ b/docs/src/main/sphinx/connector.md
@@ -36,6 +36,7 @@ PostgreSQL
Prometheus
Redis
Redshift
+Scylla
SingleStore
SQL Server
System
diff --git a/docs/src/main/sphinx/connector/scylla.rst b/docs/src/main/sphinx/connector/scylla.rst
new file mode 100644
index 000000000000..d3b0498a8ead
--- /dev/null
+++ b/docs/src/main/sphinx/connector/scylla.rst
@@ -0,0 +1,38 @@
+================
+Scylla connector
+================
+
+The Scylla connector allows querying data stored in
+`Scylla `_.
+
+Requirements
+------------
+
+To connect to Scylla, you need:
+
+* Scylla version 3.0.0 or higher.
+* Network access from the Trino coordinator and workers to Scylla.
+ Port 9042 is the default port.
+
+Configuration
+-------------
+
+To configure the Scylla connector, create a catalog properties file
+``etc/catalog/example.properties`` with the following contents,
+replacing ``host1,host2`` with a comma-separated list of the Scylla
+nodes, used to discovery the cluster topology:
+
+.. code-block:: text
+
+ connector.name=scylla
+ cassandra.contact-points=host1,host2
+
+You also need to set ``cassandra.native-protocol-port``, if your
+Scylla nodes are not using the default port 9042.
+
+Compatibility with Cassandra connector
+--------------------------------------
+
+The Scylla connector is very similar to the Cassandra connector with the
+only difference being the underlying driver.
+See :doc:`Cassandra connector ` for more details.
diff --git a/plugin/trino-scylla/pom.xml b/plugin/trino-scylla/pom.xml
new file mode 100644
index 000000000000..cd217ad90109
--- /dev/null
+++ b/plugin/trino-scylla/pom.xml
@@ -0,0 +1,192 @@
+
+
+ 4.0.0
+
+
+ io.trino
+ trino-root
+ 423-SNAPSHOT
+ ../../pom.xml
+
+
+ trino-scylla
+ trino-plugin
+ Trino - Scylla Connector
+
+
+ ${project.parent.basedir}
+
+
+
+
+ com.google.guava
+ guava
+
+
+
+ io.trino
+ trino-cassandra
+ ${project.version}
+
+
+ com.datastax.oss
+ java-driver-core
+
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ provided
+
+
+
+ io.airlift
+ slice
+ provided
+
+
+
+ io.opentelemetry
+ opentelemetry-api
+ provided
+
+
+
+ io.opentelemetry
+ opentelemetry-context
+ provided
+
+
+
+ io.trino
+ trino-spi
+ provided
+
+
+
+ org.openjdk.jol
+ jol-core
+ provided
+
+
+
+ com.scylladb
+ java-driver-core
+ 4.13.0.0
+ runtime
+
+
+
+ io.airlift
+ json
+ runtime
+
+
+
+ io.airlift
+ log
+ runtime
+
+
+
+ io.airlift
+ log-manager
+ runtime
+
+
+
+ io.airlift
+ units
+ runtime
+
+
+
+ io.airlift
+ testing
+ test
+
+
+
+
+ io.trino
+ trino-cassandra
+ ${project.version}
+ test-jar
+ test
+
+
+
+ io.trino
+ trino-main
+ test-jar
+ test
+
+
+
+ io.trino
+ trino-main
+ test
+
+
+
+ io.trino
+ trino-testing
+ test
+
+
+
+ io.trino
+ trino-tpch
+ test
+
+
+
+ io.trino.tpch
+ tpch
+ test
+
+
+
+ org.apache.thrift
+ libthrift
+ test
+
+
+
+ org.assertj
+ assertj-core
+ test
+
+
+
+ org.testcontainers
+ testcontainers
+ test
+
+
+
+ org.testng
+ testng
+ test
+
+
+
+
+
+
+ org.basepom.maven
+ duplicate-finder-maven-plugin
+
+
+
+ com.datastax.oss
+ java-driver-core
+
+
+
+
+
+
+
diff --git a/plugin/trino-scylla/src/main/java/io/trino/plugin/scylla/ScyllaConnectorFactory.java b/plugin/trino-scylla/src/main/java/io/trino/plugin/scylla/ScyllaConnectorFactory.java
new file mode 100644
index 000000000000..9260ca48e65b
--- /dev/null
+++ b/plugin/trino-scylla/src/main/java/io/trino/plugin/scylla/ScyllaConnectorFactory.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.plugin.scylla;
+
+import io.trino.plugin.cassandra.CassandraConnectorFactory;
+
+public class ScyllaConnectorFactory
+ extends CassandraConnectorFactory
+{
+ @Override
+ public String getName()
+ {
+ return "scylla";
+ }
+}
diff --git a/plugin/trino-scylla/src/main/java/io/trino/plugin/scylla/ScyllaPlugin.java b/plugin/trino-scylla/src/main/java/io/trino/plugin/scylla/ScyllaPlugin.java
new file mode 100644
index 000000000000..6c9b549123ca
--- /dev/null
+++ b/plugin/trino-scylla/src/main/java/io/trino/plugin/scylla/ScyllaPlugin.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.plugin.scylla;
+
+import com.google.common.collect.ImmutableList;
+import io.trino.spi.Plugin;
+import io.trino.spi.connector.ConnectorFactory;
+
+public class ScyllaPlugin
+ implements Plugin
+{
+ @Override
+ public Iterable getConnectorFactories()
+ {
+ return ImmutableList.of(new ScyllaConnectorFactory());
+ }
+}
diff --git a/plugin/trino-cassandra/src/test/java/io/trino/plugin/cassandra/ScyllaQueryRunner.java b/plugin/trino-scylla/src/test/java/io/trino/plugin/scylla/ScyllaQueryRunner.java
similarity index 92%
rename from plugin/trino-cassandra/src/test/java/io/trino/plugin/cassandra/ScyllaQueryRunner.java
rename to plugin/trino-scylla/src/test/java/io/trino/plugin/scylla/ScyllaQueryRunner.java
index 52de69544c78..81e63d75c47e 100644
--- a/plugin/trino-cassandra/src/test/java/io/trino/plugin/cassandra/ScyllaQueryRunner.java
+++ b/plugin/trino-scylla/src/test/java/io/trino/plugin/scylla/ScyllaQueryRunner.java
@@ -11,12 +11,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.trino.plugin.cassandra;
+package io.trino.plugin.scylla;
import com.google.common.collect.ImmutableMap;
import io.airlift.log.Logger;
import io.airlift.log.Logging;
import io.trino.Session;
+import io.trino.plugin.cassandra.CassandraServer;
import io.trino.plugin.tpch.TpchPlugin;
import io.trino.testing.DistributedQueryRunner;
import io.trino.tpch.TpchTable;
@@ -35,7 +36,7 @@ public final class ScyllaQueryRunner
private ScyllaQueryRunner() {}
public static DistributedQueryRunner createScyllaQueryRunner(
- TestingScyllaServer server,
+ CassandraServer server,
Map extraProperties,
Map connectorProperties,
Iterable> tables)
@@ -57,8 +58,8 @@ public static DistributedQueryRunner createScyllaQueryRunner(
connectorProperties.putIfAbsent("cassandra.load-policy.use-dc-aware", "true");
connectorProperties.putIfAbsent("cassandra.load-policy.dc-aware.local-dc", "datacenter1");
- queryRunner.installPlugin(new CassandraPlugin());
- queryRunner.createCatalog("cassandra", "cassandra", connectorProperties);
+ queryRunner.installPlugin(new ScyllaPlugin());
+ queryRunner.createCatalog("scylla", "scylla", connectorProperties);
createKeyspace(server.getSession(), "tpch");
copyTpchTables(queryRunner, "tpch", TINY_SCHEMA_NAME, createSession("tpch"), tables);
@@ -76,7 +77,7 @@ public static DistributedQueryRunner createScyllaQueryRunner(
public static Session createSession(String schema)
{
return testSessionBuilder()
- .setCatalog("cassandra")
+ .setCatalog("scylla")
.setSchema(schema)
.build();
}
diff --git a/plugin/trino-cassandra/src/test/java/io/trino/plugin/cassandra/TestScyllaConnectorSmokeTest.java b/plugin/trino-scylla/src/test/java/io/trino/plugin/scylla/TestScyllaConnectorSmokeTest.java
similarity index 80%
rename from plugin/trino-cassandra/src/test/java/io/trino/plugin/cassandra/TestScyllaConnectorSmokeTest.java
rename to plugin/trino-scylla/src/test/java/io/trino/plugin/scylla/TestScyllaConnectorSmokeTest.java
index 3c9c992d1100..8d29cff27edd 100644
--- a/plugin/trino-cassandra/src/test/java/io/trino/plugin/cassandra/TestScyllaConnectorSmokeTest.java
+++ b/plugin/trino-scylla/src/test/java/io/trino/plugin/scylla/TestScyllaConnectorSmokeTest.java
@@ -11,15 +11,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.trino.plugin.cassandra;
+package io.trino.plugin.scylla;
import com.google.common.collect.ImmutableMap;
+import io.trino.plugin.cassandra.BaseCassandraConnectorSmokeTest;
+import io.trino.plugin.cassandra.CassandraSession;
import io.trino.testing.QueryRunner;
import java.sql.Timestamp;
import static io.trino.plugin.cassandra.CassandraTestingUtils.createTestTables;
-import static io.trino.plugin.cassandra.ScyllaQueryRunner.createScyllaQueryRunner;
+import static io.trino.plugin.scylla.ScyllaQueryRunner.createScyllaQueryRunner;
+import static io.trino.plugin.scylla.TestingScyllaServer.V3_TAG;
public class TestScyllaConnectorSmokeTest
extends BaseCassandraConnectorSmokeTest
@@ -28,7 +31,7 @@ public class TestScyllaConnectorSmokeTest
protected QueryRunner createQueryRunner()
throws Exception
{
- TestingScyllaServer server = closeAfterClass(new TestingScyllaServer("3.3.4"));
+ TestingScyllaServer server = closeAfterClass(new TestingScyllaServer(V3_TAG));
CassandraSession session = server.getSession();
createTestTables(session, KEYSPACE, Timestamp.from(TIMESTAMP_VALUE.toInstant()));
return createScyllaQueryRunner(server, ImmutableMap.of(), ImmutableMap.of(), REQUIRED_TPCH_TABLES);
diff --git a/plugin/trino-scylla/src/test/java/io/trino/plugin/scylla/TestScyllaConnectorTest.java b/plugin/trino-scylla/src/test/java/io/trino/plugin/scylla/TestScyllaConnectorTest.java
new file mode 100644
index 000000000000..6b31f8674bed
--- /dev/null
+++ b/plugin/trino-scylla/src/test/java/io/trino/plugin/scylla/TestScyllaConnectorTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.plugin.scylla;
+
+import com.google.common.collect.ImmutableMap;
+import io.trino.plugin.cassandra.BaseCassandraConnectorTest;
+import io.trino.testing.QueryRunner;
+
+import java.sql.Timestamp;
+
+import static io.trino.plugin.cassandra.CassandraTestingUtils.createTestTables;
+import static io.trino.plugin.scylla.ScyllaQueryRunner.createScyllaQueryRunner;
+import static io.trino.plugin.scylla.TestingScyllaServer.V3_TAG;
+
+public class TestScyllaConnectorTest
+ extends BaseCassandraConnectorTest
+{
+ @Override
+ protected QueryRunner createQueryRunner()
+ throws Exception
+ {
+ server = closeAfterClass(new TestingScyllaServer(V3_TAG));
+ session = server.getSession();
+ createTestTables(session, KEYSPACE, Timestamp.from(TIMESTAMP_VALUE.toInstant()));
+ return createScyllaQueryRunner(
+ server,
+ ImmutableMap.of(),
+ ImmutableMap.of("cassandra.batch-size", "50"), // The default 100 causes 'Batch too large' error
+ REQUIRED_TPCH_TABLES);
+ }
+}
diff --git a/plugin/trino-scylla/src/test/java/io/trino/plugin/scylla/TestScyllaLatestConnectorSmokeTest.java b/plugin/trino-scylla/src/test/java/io/trino/plugin/scylla/TestScyllaLatestConnectorSmokeTest.java
new file mode 100644
index 000000000000..a714b8d6fa98
--- /dev/null
+++ b/plugin/trino-scylla/src/test/java/io/trino/plugin/scylla/TestScyllaLatestConnectorSmokeTest.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.plugin.scylla;
+
+import com.google.common.collect.ImmutableMap;
+import io.trino.plugin.cassandra.BaseCassandraConnectorSmokeTest;
+import io.trino.plugin.cassandra.CassandraSession;
+import io.trino.testing.QueryRunner;
+
+import java.sql.Timestamp;
+
+import static io.trino.plugin.cassandra.CassandraTestingUtils.createTestTables;
+import static io.trino.plugin.scylla.ScyllaQueryRunner.createScyllaQueryRunner;
+import static io.trino.plugin.scylla.TestingScyllaServer.V4_TAG;
+
+public class TestScyllaLatestConnectorSmokeTest
+ extends BaseCassandraConnectorSmokeTest
+{
+ @Override
+ protected QueryRunner createQueryRunner()
+ throws Exception
+ {
+ TestingScyllaServer server = closeAfterClass(new TestingScyllaServer(V4_TAG));
+ CassandraSession session = server.getSession();
+ createTestTables(session, KEYSPACE, Timestamp.from(TIMESTAMP_VALUE.toInstant()));
+ return createScyllaQueryRunner(server, ImmutableMap.of(), ImmutableMap.of(), REQUIRED_TPCH_TABLES);
+ }
+}
diff --git a/plugin/trino-cassandra/src/test/java/io/trino/plugin/cassandra/TestingScyllaServer.java b/plugin/trino-scylla/src/test/java/io/trino/plugin/scylla/TestingScyllaServer.java
similarity index 92%
rename from plugin/trino-cassandra/src/test/java/io/trino/plugin/cassandra/TestingScyllaServer.java
rename to plugin/trino-scylla/src/test/java/io/trino/plugin/scylla/TestingScyllaServer.java
index 5888408b06d5..dcdd7977aede 100644
--- a/plugin/trino-cassandra/src/test/java/io/trino/plugin/cassandra/TestingScyllaServer.java
+++ b/plugin/trino-scylla/src/test/java/io/trino/plugin/scylla/TestingScyllaServer.java
@@ -11,7 +11,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package io.trino.plugin.cassandra;
+package io.trino.plugin.scylla;
import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.CqlSessionBuilder;
@@ -21,9 +21,12 @@
import io.airlift.json.JsonCodec;
import io.airlift.log.Logger;
import io.airlift.units.Duration;
+import io.trino.plugin.cassandra.CassandraServer;
+import io.trino.plugin.cassandra.CassandraSession;
+import io.trino.plugin.cassandra.ExtraColumnMetadata;
+import io.trino.plugin.cassandra.SizeEstimate;
import org.testcontainers.containers.GenericContainer;
-import java.io.Closeable;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.concurrent.TimeoutException;
@@ -40,12 +43,14 @@
import static java.util.concurrent.TimeUnit.SECONDS;
public class TestingScyllaServer
- implements Closeable
+ implements CassandraServer
{
private static final Logger log = Logger.get(TestingScyllaServer.class);
- private static final int PORT = 9042;
+ public static final String V4_TAG = "4.5.3";
+ public static final String V3_TAG = "3.0.0";
+ private static final int PORT = 9042;
private static final Duration REFRESH_SIZE_ESTIMATES_TIMEOUT = new Duration(1, MINUTES);
private final GenericContainer> container;
@@ -53,7 +58,7 @@ public class TestingScyllaServer
public TestingScyllaServer()
{
- this("2.2.0");
+ this(V3_TAG);
}
public TestingScyllaServer(String version)
@@ -83,21 +88,25 @@ public TestingScyllaServer(String version)
new Duration(1, MINUTES));
}
+ @Override
public CassandraSession getSession()
{
return requireNonNull(session, "session is null");
}
+ @Override
public String getHost()
{
return container.getHost();
}
+ @Override
public int getPort()
{
return container.getMappedPort(PORT);
}
+ @Override
public void refreshSizeEstimates(String keyspace, String table)
throws Exception
{
diff --git a/pom.xml b/pom.xml
index a9662c95012f..1a419636545c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -100,6 +100,7 @@
plugin/trino-redis
plugin/trino-redshift
plugin/trino-resource-group-managers
+ plugin/trino-scylla
plugin/trino-session-property-managers
plugin/trino-singlestore
plugin/trino-sqlserver
diff --git a/testing/trino-product-tests-launcher/src/main/java/io/trino/tests/product/launcher/env/environment/EnvMultinodeAllConnectors.java b/testing/trino-product-tests-launcher/src/main/java/io/trino/tests/product/launcher/env/environment/EnvMultinodeAllConnectors.java
index 0ba9cf6edd05..91e71489f803 100644
--- a/testing/trino-product-tests-launcher/src/main/java/io/trino/tests/product/launcher/env/environment/EnvMultinodeAllConnectors.java
+++ b/testing/trino-product-tests-launcher/src/main/java/io/trino/tests/product/launcher/env/environment/EnvMultinodeAllConnectors.java
@@ -77,6 +77,7 @@ public void extendEnvironment(Environment.Builder builder)
"raptor_legacy",
"redis",
"redshift",
+ "scylla",
"sqlserver",
"trino_thrift",
"tpcds")
diff --git a/testing/trino-product-tests-launcher/src/main/java/io/trino/tests/product/launcher/env/environment/EnvMultinodeScylla.java b/testing/trino-product-tests-launcher/src/main/java/io/trino/tests/product/launcher/env/environment/EnvMultinodeScylla.java
new file mode 100644
index 000000000000..61d85450126a
--- /dev/null
+++ b/testing/trino-product-tests-launcher/src/main/java/io/trino/tests/product/launcher/env/environment/EnvMultinodeScylla.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.tests.product.launcher.env.environment;
+
+import com.google.inject.Inject;
+import io.trino.tests.product.launcher.docker.DockerFiles;
+import io.trino.tests.product.launcher.docker.DockerFiles.ResourceProvider;
+import io.trino.tests.product.launcher.env.DockerContainer;
+import io.trino.tests.product.launcher.env.Environment.Builder;
+import io.trino.tests.product.launcher.env.EnvironmentProvider;
+import io.trino.tests.product.launcher.env.common.StandardMultinode;
+import io.trino.tests.product.launcher.env.common.TestsEnvironment;
+import io.trino.tests.product.launcher.testcontainers.PortBinder;
+import org.testcontainers.containers.startupcheck.IsRunningStartupCheckStrategy;
+
+import java.time.Duration;
+
+import static io.trino.tests.product.launcher.docker.ContainerUtil.forSelectedPorts;
+import static io.trino.tests.product.launcher.env.EnvironmentContainers.configureTempto;
+import static java.util.Objects.requireNonNull;
+import static org.testcontainers.utility.MountableFile.forHostPath;
+
+@TestsEnvironment
+public class EnvMultinodeScylla
+ extends EnvironmentProvider
+{
+ public static final int SCYLLA_PORT = 9042;
+
+ private final ResourceProvider configDir;
+ private final PortBinder portBinder;
+
+ @Inject
+ public EnvMultinodeScylla(StandardMultinode standardMultinode, DockerFiles dockerFiles, PortBinder portBinder)
+ {
+ super(standardMultinode);
+ this.configDir = requireNonNull(dockerFiles, "dockerFiles is null").getDockerFilesHostDirectory("conf/environment/multinode-scylla/");
+ this.portBinder = requireNonNull(portBinder, "portBinder is null");
+ }
+
+ @Override
+ public void extendEnvironment(Builder builder)
+ {
+ builder.addConnector("scylla", forHostPath(configDir.getPath("scylla.properties")));
+ builder.addContainer(createScylla());
+ configureTempto(builder, configDir);
+ }
+
+ private DockerContainer createScylla()
+ {
+ DockerContainer container = new DockerContainer("scylladb/scylla:4.6.2", "scylla")
+ .withEnv("HEAP_NEWSIZE", "128M")
+ .withEnv("MAX_HEAP_SIZE", "512M")
+ // Limit SMP to run in a machine having many cores https://github.com/scylladb/scylla/issues/5638
+ .withCommand("--smp", "1")
+ .withStartupCheckStrategy(new IsRunningStartupCheckStrategy())
+ .waitingFor(forSelectedPorts(SCYLLA_PORT))
+ .withStartupTimeout(Duration.ofMinutes(5));
+
+ portBinder.exposePort(container, SCYLLA_PORT);
+
+ return container;
+ }
+}
diff --git a/testing/trino-product-tests-launcher/src/main/java/io/trino/tests/product/launcher/suite/suites/SuiteScylla.java b/testing/trino-product-tests-launcher/src/main/java/io/trino/tests/product/launcher/suite/suites/SuiteScylla.java
new file mode 100644
index 000000000000..87eddd7d0a60
--- /dev/null
+++ b/testing/trino-product-tests-launcher/src/main/java/io/trino/tests/product/launcher/suite/suites/SuiteScylla.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.tests.product.launcher.suite.suites;
+
+import com.google.common.collect.ImmutableList;
+import io.trino.tests.product.launcher.env.EnvironmentConfig;
+import io.trino.tests.product.launcher.env.environment.EnvMultinodeScylla;
+import io.trino.tests.product.launcher.suite.Suite;
+import io.trino.tests.product.launcher.suite.SuiteTestRun;
+
+import java.util.List;
+
+import static io.trino.tests.product.launcher.suite.SuiteTestRun.testOnEnvironment;
+
+public class SuiteScylla
+ extends Suite
+{
+ @Override
+ public List getTestRuns(EnvironmentConfig config)
+ {
+ return ImmutableList.of(
+ testOnEnvironment(EnvMultinodeScylla.class)
+ .withGroups("configured_features", "scylla")
+ .build());
+ }
+}
diff --git a/testing/trino-product-tests-launcher/src/main/resources/docker/presto-product-tests/conf/environment/multinode-all/scylla.properties b/testing/trino-product-tests-launcher/src/main/resources/docker/presto-product-tests/conf/environment/multinode-all/scylla.properties
new file mode 100644
index 000000000000..48d4ab86786e
--- /dev/null
+++ b/testing/trino-product-tests-launcher/src/main/resources/docker/presto-product-tests/conf/environment/multinode-all/scylla.properties
@@ -0,0 +1,3 @@
+connector.name=scylla
+cassandra.contact-points=host1.invalid,host2.invalid
+cassandra.load-policy.dc-aware.local-dc=datacenter1
diff --git a/testing/trino-product-tests-launcher/src/main/resources/docker/presto-product-tests/conf/environment/multinode-scylla/scylla.properties b/testing/trino-product-tests-launcher/src/main/resources/docker/presto-product-tests/conf/environment/multinode-scylla/scylla.properties
new file mode 100644
index 000000000000..883f48a5452b
--- /dev/null
+++ b/testing/trino-product-tests-launcher/src/main/resources/docker/presto-product-tests/conf/environment/multinode-scylla/scylla.properties
@@ -0,0 +1,5 @@
+connector.name=scylla
+cassandra.contact-points=scylla
+cassandra.allow-drop-table=true
+cassandra.load-policy.use-dc-aware=true
+cassandra.load-policy.dc-aware.local-dc=datacenter1
diff --git a/testing/trino-product-tests-launcher/src/main/resources/docker/presto-product-tests/conf/environment/multinode-scylla/tempto-configuration.yaml b/testing/trino-product-tests-launcher/src/main/resources/docker/presto-product-tests/conf/environment/multinode-scylla/tempto-configuration.yaml
new file mode 100644
index 000000000000..cefae6c56579
--- /dev/null
+++ b/testing/trino-product-tests-launcher/src/main/resources/docker/presto-product-tests/conf/environment/multinode-scylla/tempto-configuration.yaml
@@ -0,0 +1,3 @@
+databases:
+ presto:
+ jdbc_url: "jdbc:trino://${databases.presto.host}:${databases.presto.port}/scylla/test"
diff --git a/testing/trino-product-tests/src/main/java/io/trino/tests/product/TestGroups.java b/testing/trino-product-tests/src/main/java/io/trino/tests/product/TestGroups.java
index 9bb8110f04a1..802e8960d396 100644
--- a/testing/trino-product-tests/src/main/java/io/trino/tests/product/TestGroups.java
+++ b/testing/trino-product-tests/src/main/java/io/trino/tests/product/TestGroups.java
@@ -58,6 +58,7 @@ public final class TestGroups
public static final String HIVE_COERCION = "hive_coercion";
public static final String AZURE = "azure";
public static final String CASSANDRA = "cassandra";
+ public static final String SCYLLA = "scylla";
public static final String SQL_SERVER = "sqlserver";
public static final String LDAP = "ldap";
public static final String LDAP_AND_FILE = "ldap_and_file";
diff --git a/testing/trino-product-tests/src/main/java/io/trino/tests/product/scylla/TestScylla.java b/testing/trino-product-tests/src/main/java/io/trino/tests/product/scylla/TestScylla.java
new file mode 100644
index 000000000000..99c9bd45f970
--- /dev/null
+++ b/testing/trino-product-tests/src/main/java/io/trino/tests/product/scylla/TestScylla.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.tests.product.scylla;
+
+import com.datastax.oss.driver.api.core.CqlSession;
+import com.google.inject.Inject;
+import io.trino.tempto.BeforeMethodWithContext;
+import io.trino.tempto.ProductTest;
+import io.trino.tempto.configuration.Configuration;
+import io.trino.tempto.query.QueryResult;
+import org.intellij.lang.annotations.Language;
+import org.testng.annotations.Test;
+
+import java.net.InetSocketAddress;
+
+import static io.trino.tempto.assertions.QueryAssert.Row.row;
+import static io.trino.tests.product.TestGroups.PROFILE_SPECIFIC_TESTS;
+import static io.trino.tests.product.TestGroups.SCYLLA;
+import static io.trino.tests.product.utils.QueryExecutors.onTrino;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class TestScylla
+ extends ProductTest
+{
+ @Inject
+ private Configuration configuration;
+
+ @BeforeMethodWithContext
+ public void setUp()
+ {
+ onScylla("DROP KEYSPACE IF EXISTS test");
+ onScylla("CREATE KEYSPACE test WITH replication={'class':'SimpleStrategy', 'replication_factor':1}");
+ }
+
+ @Test(groups = {SCYLLA, PROFILE_SPECIFIC_TESTS})
+ public void testCreateTableAsSelect()
+ {
+ onTrino().executeQuery("DROP TABLE IF EXISTS scylla.test.nation");
+ QueryResult result = onTrino().executeQuery("CREATE TABLE scylla.test.nation AS SELECT * FROM tpch.tiny.nation");
+ try {
+ assertThat(result).updatedRowsCountIsEqualTo(25);
+ assertThat(onTrino().executeQuery("SELECT COUNT(*) FROM scylla.test.nation"))
+ .containsOnly(row(25));
+ }
+ finally {
+ onTrino().executeQuery("DROP TABLE scylla.test.nation");
+ }
+ }
+
+ private void onScylla(@Language("SQL") String query)
+ {
+ try (CqlSession session = CqlSession.builder()
+ .addContactPoint(new InetSocketAddress(configuration.getStringMandatory("databases.scylla.host"), configuration.getIntMandatory("databases.scylla.port")))
+ .withLocalDatacenter(configuration.getStringMandatory("databases.scylla.local_datacenter"))
+ .build()) {
+ session.execute(query);
+ }
+ }
+}
diff --git a/testing/trino-product-tests/src/main/resources/tempto-configuration.yaml b/testing/trino-product-tests/src/main/resources/tempto-configuration.yaml
index 839c23c7b112..fdea1ffa5a17 100644
--- a/testing/trino-product-tests/src/main/resources/tempto-configuration.yaml
+++ b/testing/trino-product-tests/src/main/resources/tempto-configuration.yaml
@@ -136,6 +136,11 @@ databases:
request:
timeout_seconds: 30
+ scylla:
+ host: scylla
+ port: 9042
+ local_datacenter: datacenter1
+
sqlserver:
jdbc_driver_class: com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc_url: jdbc:sqlserver://sqlserver;encrypt=false
diff --git a/testing/trino-server-dev/etc/catalog/scylla.properties b/testing/trino-server-dev/etc/catalog/scylla.properties
new file mode 100644
index 000000000000..e264b15f0548
--- /dev/null
+++ b/testing/trino-server-dev/etc/catalog/scylla.properties
@@ -0,0 +1,5 @@
+connector.name=scylla
+cassandra.contact-points=scylla
+cassandra.load-policy.use-dc-aware=true
+cassandra.load-policy.dc-aware.local-dc=datacenter1
+cassandra.allow-drop-table=true
diff --git a/testing/trino-server-dev/etc/config.properties b/testing/trino-server-dev/etc/config.properties
index b786657e8d2b..815d068bc6f9 100644
--- a/testing/trino-server-dev/etc/config.properties
+++ b/testing/trino-server-dev/etc/config.properties
@@ -34,6 +34,7 @@ plugin.bundles=\
../../plugin/trino-delta-lake/pom.xml,\
../../plugin/trino-blackhole/pom.xml,\
../../plugin/trino-cassandra/pom.xml,\
+ ../../plugin/trino-scylla/pom.xml,\
../../plugin/trino-memory/pom.xml,\
../../plugin/trino-jmx/pom.xml,\
../../plugin/trino-raptor-legacy/pom.xml,\