diff --git a/plugin/trino-cassandra/src/test/java/io/trino/plugin/cassandra/TestCassandraConnectorTest.java b/plugin/trino-cassandra/src/test/java/io/trino/plugin/cassandra/TestCassandraConnectorTest.java index d5f42ef711236..8ed75da8e2e01 100644 --- a/plugin/trino-cassandra/src/test/java/io/trino/plugin/cassandra/TestCassandraConnectorTest.java +++ b/plugin/trino-cassandra/src/test/java/io/trino/plugin/cassandra/TestCassandraConnectorTest.java @@ -909,6 +909,43 @@ public void testClusteringKeyPushdownInequality() } } + @Test + void testMultiColumnKey() + { + try (TestCassandraTable table = testTable( + "test_multi_column_key", + ImmutableList.of( + partitionColumn("user_id", "text"), + partitionColumn("key", "text"), + partitionColumn("updated_at", "timestamp"), + generalColumn("value", "text")), + ImmutableList.of( + "'Alice', 'a1', '2015-01-01 01:01:01', 'Test value 1'", + "'Bob', 'b1', '2014-02-02 03:04:05', 'Test value 2'"))) { + // equality filter on clustering key + assertQuery("SELECT value FROM " + table.getTableName() + " WHERE key = 'a1'", "VALUES 'Test value 1'"); + + // equality filter on primary and clustering keys + assertQuery("SELECT value FROM " + table.getTableName() + " WHERE user_id = 'Alice' and key = 'a1' and updated_at = TIMESTAMP '2015-01-01 01:01:01Z'", + "VALUES 'Test value 1'"); + + // mixed filter on primary and clustering keys + assertQuery("SELECT value FROM " + table.getTableName() + " WHERE user_id = 'Alice' and key < 'b' and updated_at >= TIMESTAMP '2015-01-01 01:01:01Z'", + "VALUES 'Test value 1'"); + + // filter on primary key doesn't match + assertQueryReturnsEmptyResult("SELECT value FROM " + table.getTableName() + " WHERE user_id = 'George'"); + + // filter on prefix of clustering key + assertQuery("SELECT value FROM " + table.getTableName() + " WHERE user_id = 'Bob' and key = 'b1'", + "VALUES 'Test value 2'"); + + // filter on second clustering key + assertQuery("SELECT value FROM " + table.getTableName() + " WHERE user_id = 'Bob' and updated_at = TIMESTAMP '2014-02-02 03:04:05Z'", + "VALUES 'Test value 2'"); + } + } + @Test public void testSelectWithSecondaryIndex() { diff --git a/testing/trino-product-tests/src/main/java/io/trino/tests/product/cassandra/MultiColumnKeyTableDefinition.java b/testing/trino-product-tests/src/main/java/io/trino/tests/product/cassandra/MultiColumnKeyTableDefinition.java deleted file mode 100644 index a39bda567da1d..0000000000000 --- a/testing/trino-product-tests/src/main/java/io/trino/tests/product/cassandra/MultiColumnKeyTableDefinition.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.cassandra; - -import com.google.common.collect.ImmutableList; -import io.trino.tempto.fulfillment.table.jdbc.RelationalDataSource; -import io.trino.tempto.internal.fulfillment.table.cassandra.CassandraTableDefinition; - -import java.time.OffsetDateTime; -import java.time.ZoneOffset; -import java.util.List; - -import static io.trino.tests.product.cassandra.TestConstants.CONNECTOR_NAME; -import static io.trino.tests.product.cassandra.TestConstants.KEY_SPACE; - -public final class MultiColumnKeyTableDefinition -{ - private MultiColumnKeyTableDefinition() {} - - private static final String MULTI_COLUMN_KEY_DDL = - "CREATE TABLE %NAME% (" + - "user_id text, " + - "key text, " + - "updated_at timestamp, " + - "value text, " + - "PRIMARY KEY (user_id, key, updated_at));"; - private static final String MULTI_COLUMN_KEY_TABLE_NAME = "multicolumnkey"; - - public static final CassandraTableDefinition CASSANDRA_MULTI_COLUMN_KEY; - - static { - RelationalDataSource dataSource = () -> ImmutableList.>of( - ImmutableList.of( - "Alice", - "a1", - OffsetDateTime.of(2015, 1, 1, 1, 1, 1, 0, ZoneOffset.UTC).toInstant(), - "Test value 1"), - ImmutableList.of( - "Bob", - "b1", - OffsetDateTime.of(2014, 2, 2, 3, 4, 5, 0, ZoneOffset.UTC).toInstant(), - "Test value 2") - ).iterator(); - CASSANDRA_MULTI_COLUMN_KEY = CassandraTableDefinition.cassandraBuilder(MULTI_COLUMN_KEY_TABLE_NAME) - .withDatabase(CONNECTOR_NAME) - .withSchema(KEY_SPACE) - .setCreateTableDDLTemplate(MULTI_COLUMN_KEY_DDL) - .setDataSource(dataSource) - .build(); - } -} diff --git a/testing/trino-product-tests/src/main/java/io/trino/tests/product/cassandra/TestSelectMultiColumnKey.java b/testing/trino-product-tests/src/main/java/io/trino/tests/product/cassandra/TestSelectMultiColumnKey.java deleted file mode 100644 index 3fdc6a3ff8555..0000000000000 --- a/testing/trino-product-tests/src/main/java/io/trino/tests/product/cassandra/TestSelectMultiColumnKey.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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.cassandra; - -import io.trino.tempto.ProductTest; -import io.trino.tempto.Requirement; -import io.trino.tempto.RequirementsProvider; -import io.trino.tempto.configuration.Configuration; -import io.trino.tempto.query.QueryResult; -import org.testng.annotations.Test; - -import static io.trino.tempto.assertions.QueryAssert.Row.row; -import static io.trino.tempto.fulfillment.table.TableRequirements.immutableTable; -import static io.trino.tests.product.TestGroups.CASSANDRA; -import static io.trino.tests.product.TestGroups.PROFILE_SPECIFIC_TESTS; -import static io.trino.tests.product.cassandra.MultiColumnKeyTableDefinition.CASSANDRA_MULTI_COLUMN_KEY; -import static io.trino.tests.product.cassandra.TestConstants.CONNECTOR_NAME; -import static io.trino.tests.product.cassandra.TestConstants.KEY_SPACE; -import static io.trino.tests.product.utils.QueryExecutors.onTrino; -import static java.lang.String.format; -import static org.assertj.core.api.Assertions.assertThat; - -public class TestSelectMultiColumnKey - extends ProductTest - implements RequirementsProvider -{ - @Override - public Requirement getRequirements(Configuration configuration) - { - return immutableTable(CASSANDRA_MULTI_COLUMN_KEY); - } - - @Test(groups = {CASSANDRA, PROFILE_SPECIFIC_TESTS}) - public void testSelectWithEqualityFilterOnClusteringKey() - { - String sql = format( - "SELECT value FROM %s.%s.%s WHERE key = 'a1'", - CONNECTOR_NAME, - KEY_SPACE, - CASSANDRA_MULTI_COLUMN_KEY.getName()); - QueryResult queryResult = onTrino() - .executeQuery(sql); - - assertThat(queryResult).containsOnly(row("Test value 1")); - } - - @Test(groups = {CASSANDRA, PROFILE_SPECIFIC_TESTS}) - public void testSelectWithEqualityFilterOnPrimaryAndClusteringKeys() - { - String sql = format( - "SELECT value FROM %s.%s.%s WHERE user_id = 'Alice' and key = 'a1' and updated_at = TIMESTAMP '2015-01-01 01:01:01Z'", - CONNECTOR_NAME, - KEY_SPACE, - CASSANDRA_MULTI_COLUMN_KEY.getName()); - QueryResult queryResult = onTrino() - .executeQuery(sql); - - assertThat(queryResult).containsOnly(row("Test value 1")); - } - - @Test(groups = {CASSANDRA, PROFILE_SPECIFIC_TESTS}) - public void testSelectWithMixedFilterOnPrimaryAndClusteringKeys() - { - String sql = format( - "SELECT value FROM %s.%s.%s WHERE user_id = 'Alice' and key < 'b' and updated_at >= TIMESTAMP '2015-01-01 01:01:01Z'", - CONNECTOR_NAME, - KEY_SPACE, - CASSANDRA_MULTI_COLUMN_KEY.getName()); - QueryResult queryResult = onTrino() - .executeQuery(sql); - - assertThat(queryResult).containsOnly(row("Test value 1")); - } - - @Test(groups = {CASSANDRA, PROFILE_SPECIFIC_TESTS}) - public void testSelectWithFilterOnPrimaryKeyNoMatch() - { - String sql = format( - "SELECT value FROM %s.%s.%s WHERE user_id = 'George'", - CONNECTOR_NAME, - KEY_SPACE, - CASSANDRA_MULTI_COLUMN_KEY.getName()); - QueryResult queryResult = onTrino() - .executeQuery(sql); - - assertThat(queryResult).hasNoRows(); - } - - @Test(groups = {CASSANDRA, PROFILE_SPECIFIC_TESTS}) - public void testSelectWithFilterOnPrefixOfClusteringKey() - { - String sql = format( - "SELECT value FROM %s.%s.%s WHERE user_id = 'Bob' and key = 'b1'", - CONNECTOR_NAME, - KEY_SPACE, - CASSANDRA_MULTI_COLUMN_KEY.getName()); - QueryResult queryResult = onTrino() - .executeQuery(sql); - - assertThat(queryResult).containsOnly(row("Test value 2")); - } - - @Test(groups = {CASSANDRA, PROFILE_SPECIFIC_TESTS}) - public void testSelectWithFilterOnSecondClusteringKey() - { - // Since update_at is the second clustering key, this forces a full table scan. - String sql = format( - "SELECT value FROM %s.%s.%s WHERE user_id = 'Bob' and updated_at = TIMESTAMP '2014-02-02 03:04:05Z'", - CONNECTOR_NAME, - KEY_SPACE, - CASSANDRA_MULTI_COLUMN_KEY.getName()); - QueryResult queryResult = onTrino() - .executeQuery(sql); - - assertThat(queryResult).containsOnly(row("Test value 2")); - } -}