blob: e8932f5dd27d5c118a5c4efb76b235bbef926bf9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.ignite.internal.processors.query.calcite.integration;
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.cache.CacheAtomicityMode;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.cache.CachePeekMode;
import org.apache.ignite.cache.CacheWriteSynchronizationMode;
import org.apache.ignite.cache.QueryEntity;
import org.apache.ignite.configuration.CacheConfiguration;
import org.apache.ignite.internal.processors.cache.IgniteInternalCache;
import org.apache.ignite.internal.processors.query.IgniteSQLException;
import org.apache.ignite.internal.processors.query.calcite.QueryChecker;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.testframework.GridTestUtils;
import org.hamcrest.CustomMatcher;
import org.hamcrest.Matcher;
import org.junit.Ignore;
import org.junit.Test;
import static org.apache.ignite.internal.processors.query.calcite.TestUtils.hasSize;
import static org.apache.ignite.internal.util.IgniteUtils.map;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;
/** */
public class TableDdlIntegrationTest extends AbstractDdlIntegrationTest {
/**
* Creates table with two columns, where the first column is PK,
* and verifies created cache.
*/
@Test
public void createTableSimpleCase() {
Set<String> cachesBefore = new HashSet<>(client.cacheNames());
sql("create table my_table (id int primary key, val varchar)");
Set<String> newCaches = new HashSet<>(client.cacheNames());
newCaches.removeAll(cachesBefore);
assertThat(newCaches, hasSize(1));
CacheConfiguration<?, ?> ccfg = client.cachex(newCaches.iterator().next()).configuration();
assertThat(ccfg.getQueryEntities(), hasSize(1));
QueryEntity ent = ccfg.getQueryEntities().iterator().next();
assertThat(ent.getTableName(), equalTo("MY_TABLE"));
assertThat(ent.getKeyFieldName(), equalTo("ID"));
assertThat(
ent.getFields(),
equalTo(new LinkedHashMap<>(
map(
"ID", Integer.class.getName(),
"VAL", String.class.getName()
)
))
);
}
/**
* Creates table with columns of different data types and check DML on these columns.
*/
@Test
public void createTableDifferentDataTypes() {
sql("create table my_table (" +
"id int primary key, " +
"c1 varchar, " +
"c2 date, " +
"c3 time, " +
"c4 timestamp, " +
"c5 integer, " +
"c6 bigint, " +
"c7 smallint, " +
"c8 tinyint, " +
"c9 boolean, " +
"c10 double, " +
"c11 float, " +
"c12 decimal(20, 10) " +
")");
sql("insert into my_table values (" +
"0, " +
"'test', " +
"date '2021-01-01', " +
"time '12:34:56', " +
"timestamp '2021-01-01 12:34:56', " +
"1, " +
"9876543210, " +
"3, " +
"4, " +
"true, " +
"123.456, " +
"654.321, " +
"1234567890.1234567890" +
")");
List<List<?>> res = sql("select * from my_table");
assertEquals(1, res.size());
List<?> row = res.get(0);
assertEquals(0, row.get(0));
assertEquals("test", row.get(1));
assertEquals(Date.valueOf("2021-01-01"), row.get(2));
assertEquals(Time.valueOf("12:34:56"), row.get(3));
assertEquals(Timestamp.valueOf("2021-01-01 12:34:56"), row.get(4));
assertEquals(1, row.get(5));
assertEquals(9876543210L, row.get(6));
assertEquals((short)3, row.get(7));
assertEquals((byte)4, row.get(8));
assertEquals(Boolean.TRUE, row.get(9));
assertEquals(123.456d, row.get(10));
assertEquals(654.321f, row.get(11));
assertEquals(new BigDecimal("1234567890.1234567890"), row.get(12));
}
/**
* Creates table with all possible options except template,
* and verifies created cache.
*/
@Test
public void createTableWithOptions() {
Set<String> cachesBefore = new HashSet<>(client.cacheNames());
sql("create table my_table (id1 int, id2 int, val varchar, primary key(id1, id2)) with " +
" backups=2," +
" affinity_key=id2," +
" atomicity=transactional," +
" write_synchronization_mode=full_async," +
" cache_group=my_cache_group," +
" cache_name=my_cache_name," +
" data_region=\"" + DATA_REGION_NAME + "\"," +
" key_type=my_key_type," +
" value_type=my_value_type"
// due to uncertain reason a test hangs if encryption is enabled
// " encrypted=true"
);
Set<String> newCaches = new HashSet<>(client.cacheNames());
newCaches.removeAll(cachesBefore);
assertThat(newCaches, hasSize(1));
CacheConfiguration<?, ?> ccfg = client.cachex(newCaches.iterator().next()).configuration();
assertThat(ccfg.getQueryEntities(), hasSize(1));
assertThat(ccfg.getBackups(), equalTo(2));
assertThat(ccfg.getAtomicityMode(), equalTo(CacheAtomicityMode.TRANSACTIONAL));
assertThat(ccfg.getWriteSynchronizationMode(), equalTo(CacheWriteSynchronizationMode.FULL_ASYNC));
assertThat(ccfg.getGroupName(), equalTo("MY_CACHE_GROUP"));
assertThat(ccfg.getName(), equalTo("MY_CACHE_NAME"));
assertThat(ccfg.getDataRegionName(), equalTo(DATA_REGION_NAME));
assertThat(ccfg.getKeyConfiguration()[0].getAffinityKeyFieldName(), equalTo("ID2"));
QueryEntity ent = ccfg.getQueryEntities().iterator().next();
assertThat(ent.getTableName(), equalTo("MY_TABLE"));
assertThat(ent.getKeyType(), equalTo("MY_KEY_TYPE"));
assertThat(ent.getValueType(), equalTo("MY_VALUE_TYPE"));
assertThat(ent.getKeyFields(), equalTo(new LinkedHashSet<>(F.asList("ID1", "ID2"))));
}
/**
* Creates table with all possible options (as double-quoted identifier) except template,
* and verifies created cache.
*/
@Test
public void createTableWithOptionsQuoted() {
Set<String> cachesBefore = new HashSet<>(client.cacheNames());
sql("create table my_table (id1 int, id2 int, val varchar, primary key(id1, id2)) with \"" +
" backups=2," +
" affinity_key=id2," +
" atomicity=transactional," +
" write_synchronization_mode=full_async," +
" cache_group=my_cache_group," +
" cache_name=my_cache_name," +
" data_region=" + DATA_REGION_NAME + "," +
" key_type=my_key_type," +
" value_type=my_value_type" +
// due to uncertain reason a test hangs if encryption is enabled
// " encrypted=true" +
"\""
);
Set<String> newCaches = new HashSet<>(client.cacheNames());
newCaches.removeAll(cachesBefore);
assertThat(newCaches, hasSize(1));
CacheConfiguration<?, ?> ccfg = client.cachex(newCaches.iterator().next()).configuration();
assertThat(ccfg.getQueryEntities(), hasSize(1));
assertThat(ccfg.getBackups(), equalTo(2));
assertThat(ccfg.getAtomicityMode(), equalTo(CacheAtomicityMode.TRANSACTIONAL));
assertThat(ccfg.getWriteSynchronizationMode(), equalTo(CacheWriteSynchronizationMode.FULL_ASYNC));
assertThat(ccfg.getGroupName(), equalTo("my_cache_group"));
assertThat(ccfg.getName(), equalTo("my_cache_name"));
assertThat(ccfg.getDataRegionName(), equalTo(DATA_REGION_NAME));
assertThat(ccfg.getKeyConfiguration()[0].getAffinityKeyFieldName(), equalTo("id2"));
QueryEntity ent = ccfg.getQueryEntities().iterator().next();
assertThat(ent.getTableName(), equalTo("MY_TABLE"));
assertThat(ent.getKeyType(), equalTo("my_key_type"));
assertThat(ent.getValueType(), equalTo("my_value_type"));
assertThat(ent.getKeyFields(), equalTo(new LinkedHashSet<>(F.asList("ID1", "ID2"))));
}
/**
* Creates several tables with specified templates,
* and verifies created caches.
*/
@Test
@SuppressWarnings("rawtypes")
public void createTableWithTemplate() {
Set<String> cachesBefore = new HashSet<>(client.cacheNames());
sql("create table my_table_replicated (id int, val varchar) with template=replicated, cache_name=repl");
sql("create table my_table_partitioned (id int, val varchar) with template=partitioned, cache_name=part");
Set<String> newCaches = new HashSet<>(client.cacheNames());
newCaches.removeAll(cachesBefore);
assertThat(newCaches, hasSize(2));
List<CacheConfiguration> ccfgs = newCaches.stream()
.map(client::cachex)
.map(IgniteInternalCache::configuration)
.collect(Collectors.toList());
assertThat(ccfgs, hasItem(matches("replicated cache",
ccfg -> "REPL".equals(ccfg.getName()) && ccfg.getCacheMode() == CacheMode.REPLICATED)));
assertThat(ccfgs, hasItem(matches("partitioned cache",
ccfg -> "PART".equals(ccfg.getName()) && ccfg.getCacheMode() == CacheMode.PARTITIONED)));
}
/**
* Tries to create several tables with the same name.
*/
@Test
@SuppressWarnings("ThrowableNotThrown")
public void createTableIfNotExists() {
sql("create table my_table (id int, val varchar)");
GridTestUtils.assertThrows(log,
() -> sql("create table my_table (id int, val varchar)"),
IgniteSQLException.class, "Table already exists: MY_TABLE");
sql("create table if not exists my_table (id int, val varchar)");
}
/**
* Creates a table without a primary key and then insert a few rows.
*/
@Test
public void createTableWithoutPk() {
sql("create table my_table (f1 int, f2 varchar)");
sql("insert into my_table(f1, f2) values (1, '1'),(2, '2')");
sql("insert into my_table values (1, '1'),(2, '2')");
assertThat(sql("select * from my_table"), hasSize(4));
}
/**
* Creates a table in a custom schema.
*/
@Test
public void createTableCustomSchema() {
sql("create table my_schema.my_table (f1 int, f2 varchar)");
sql("insert into my_schema.my_table(f1, f2) values (1, '1'),(2, '2')");
sql("insert into my_schema.my_table values (1, '1'),(2, '2')");
assertThat(sql("select * from my_schema.my_table"), hasSize(4));
}
/**
* Creates a table for already existing cache.
*/
@Test
public void createTableOnExistingCache() {
IgniteCache<Object, Object> cache = client.getOrCreateCache("my_cache");
sql("create table my_schema.my_table (f1 int, f2 varchar) with cache_name=\"my_cache\"");
sql("insert into my_schema.my_table(f1, f2) values (1, '1'),(2, '2')");
assertThat(sql("select * from my_schema.my_table"), hasSize(2));
assertEquals(2, cache.size(CachePeekMode.PRIMARY));
}
/**
* Creates table as select.
*/
@Test
public void createTableAsSelectSimpleCase() {
sql("create table my_table as select 1 as i, 'test' as s");
List<List<?>> res = sql("select i, s from my_table");
assertEquals(1, res.size());
List<?> row = res.get(0);
assertEquals(1, row.get(0));
assertEquals("test", row.get(1));
}
/**
* Creates table with specified columns as select.
*/
@Test
public void createTableAsSelectWithColumns() {
sql("create table my_table(i, s) as select 1 as a, 'test' as b");
List<List<?>> res = sql("select i, s from my_table");
assertEquals(1, res.size());
List<?> row = res.get(0);
assertEquals(1, row.get(0));
assertEquals("test", row.get(1));
assertThrows("select a from my_table", IgniteSQLException.class, "Column 'A' not found in any table");
}
/**
* Creates table with options as select.
*/
@SuppressWarnings("unchecked")
@Test
public void createTableAsSelectWithOptions() {
sql("create table my_table(s, i) with cache_name=\"CacheWithOpts\", cache_group=\"CacheGroup\" as select '1', 1");
List<List<?>> res = sql("select * from my_table");
assertEquals(1, res.size());
List<?> row = res.get(0);
assertEquals("1", row.get(0));
assertEquals(1, row.get(1));
IgniteCache<?, ?> cache = client.cache("CacheWithOpts");
assertNotNull(cache);
assertEquals("CacheGroup", cache.getConfiguration(CacheConfiguration.class).getGroupName());
}
/**
* Creates table as select with dynamic parameters to query.
*/
@Test
public void createTableAsSelectWithParameters() {
sql("create table my_table(s, i) as select cast(? as varchar), cast(? as int)", "a", 1);
List<List<?>> res = sql("select * from my_table");
assertEquals(1, res.size());
List<?> row = res.get(0);
assertEquals("a", row.get(0));
assertEquals(1, row.get(1));
}
/** */
@Test
public void createTableAsSelectWrongColumnsCount() {
GridTestUtils.assertThrowsAnyCause(log,
() -> sql("create table my_table(i, s1, s2) as select 1, 'test'"),
IgniteSQLException.class, "Number of columns");
}
/**
* Creates table as select from another table.
*/
@Test
public void createTableAsSelectFromDistributedTable() {
sql("create table my_table1(i) as select x from table(system_range(1, 100))");
assertEquals(100L, sql("select count(*) from my_table1").get(0).get(0));
sql("create table my_table2(i) as select * from my_table1");
assertEquals(100L, sql("select count(*) from my_table2").get(0).get(0));
}
/**
* Drops a table created in a default schema.
*/
@Test
public void dropTableDefaultSchema() {
Set<String> cachesBefore = new HashSet<>(client.cacheNames());
sql("create table my_table (id int primary key, val varchar)");
Set<String> cachesAfter = new HashSet<>(client.cacheNames());
cachesAfter.removeAll(cachesBefore);
assertThat(cachesAfter, hasSize(1));
String createdCacheName = cachesAfter.iterator().next();
sql("drop table my_table");
cachesAfter = new HashSet<>(client.cacheNames());
cachesAfter.removeAll(cachesBefore);
assertThat(cachesAfter, hasSize(0));
assertThat(client.cachex(createdCacheName), nullValue());
}
/**
* Drops a table created in a custom schema.
*/
@Test
public void dropTableCustomSchema() {
Set<String> cachesBefore = new HashSet<>(client.cacheNames());
sql("create table my_schema.my_table (id int primary key, val varchar)");
Set<String> cachesAfter = new HashSet<>(client.cacheNames());
cachesAfter.removeAll(cachesBefore);
assertThat(cachesAfter, hasSize(1));
String createdCacheName = cachesAfter.iterator().next();
sql("drop table my_schema.my_table");
cachesAfter = new HashSet<>(client.cacheNames());
cachesAfter.removeAll(cachesBefore);
assertThat(cachesAfter, hasSize(0));
assertThat(client.cachex(createdCacheName), nullValue());
}
/**
* Drops a table several times with and without
* specifying IF EXISTS.
*/
@Test
@SuppressWarnings("ThrowableNotThrown")
public void dropTableIfExists() {
sql("create table my_schema.my_table (id int primary key, val varchar)");
GridTestUtils.assertThrows(log,
() -> sql("drop table my_table"),
IgniteSQLException.class, "Table doesn't exist: MY_TABLE");
sql("drop table my_schema.my_table");
GridTestUtils.assertThrows(log,
() -> sql("drop table my_schema.my_table"),
IgniteSQLException.class, "Table doesn't exist: MY_TABLE");
sql("drop table if exists my_schema.my_table");
}
/**
* Add/drop column simple case.
*/
@Test
public void alterTableAddDropSimpleCase() {
sql("create table my_table (id int primary key, val varchar)");
sql("alter table my_table add column val2 varchar");
sql("insert into my_table (id, val, val2) values (0, '1', '2')");
List<List<?>> res = sql("select * from my_table ");
assertEquals(1, res.size());
assertEquals("2", res.get(0).get(2));
sql("alter table my_table drop column val2");
res = sql("select * from my_table ");
assertEquals(1, res.size());
assertEquals(2, res.get(0).size());
}
/**
* Add/drop two columns at the same time.
*/
@Test
public void alterTableAddDropTwoColumns() {
sql("create table my_table (id int primary key, val varchar)");
sql("alter table my_table add column (val2 varchar, val3 int)");
sql("insert into my_table (id, val, val2, val3) values (0, '1', '2', 3)");
List<List<?>> res = sql("select * from my_table ");
assertEquals(1, res.size());
assertEquals("2", res.get(0).get(2));
assertEquals(3, res.get(0).get(3));
sql("alter table my_table drop column (val2, val3)");
res = sql("select * from my_table ");
assertEquals(1, res.size());
assertEquals(2, res.get(0).size());
}
/**
* Add/drop column for table in custom schema.
*/
@Test
public void alterTableAddDropCustomSchema() {
sql("create table my_schema.my_table (id int primary key, val varchar)");
sql("alter table my_schema.my_table add column val2 varchar");
sql("insert into my_schema.my_table (id, val, val2) values (0, '1', '2')");
List<List<?>> res = sql("select * from my_schema.my_table ");
assertEquals(1, res.size());
assertEquals("2", res.get(0).get(2));
sql("alter table my_schema.my_table drop column val2");
res = sql("select * from my_schema.my_table ");
assertEquals(1, res.size());
assertEquals(2, res.get(0).size());
}
/**
* Add/drop column if table exists.
*/
@Test
public void alterTableAddDropIfTableExists() {
assertThrows("alter table my_table add val2 varchar", IgniteSQLException.class, "Table doesn't exist");
sql("alter table if exists my_table add column val2 varchar");
assertThrows("alter table my_table drop column val2", IgniteSQLException.class, "Table doesn't exist");
sql("alter table if exists my_table drop column val2");
sql("create table my_table (id int primary key, val varchar)");
sql("alter table if exists my_table add column val3 varchar");
sql("insert into my_table (id, val, val3) values (0, '1', '2')");
List<List<?>> res = sql("select * from my_table ");
assertEquals(1, res.size());
assertEquals("2", res.get(0).get(2));
sql("alter table if exists my_table drop column val3");
assertThrows("alter table if exists my_table drop column val3", IgniteSQLException.class,
"Column doesn't exist");
res = sql("select * from my_table ");
assertEquals(1, res.size());
assertEquals(2, res.get(0).size());
}
/**
* Add/drop column if column not exists/exists.
*/
@Test
public void alterTableAddDropIfColumnExists() {
sql("create table my_table (id int primary key, val varchar)");
sql("insert into my_table (id, val) values (0, '1')");
assertThrows("alter table my_table add column val varchar", IgniteSQLException.class,
"Column already exist");
sql("alter table my_table add column if not exists val varchar");
List<List<?>> res = sql("select * from my_table ");
assertEquals(1, res.size());
assertEquals(2, res.get(0).size());
assertThrows("alter table my_table drop column val2", IgniteSQLException.class,
"Column doesn't exist");
sql("alter table my_table drop column if exists val2");
res = sql("select * from my_table ");
assertEquals(1, res.size());
assertEquals(2, res.get(0).size());
sql("alter table my_table add column if not exists val3 varchar");
res = sql("select * from my_table ");
assertEquals(1, res.size());
assertEquals(3, res.get(0).size());
sql("alter table my_table drop column if exists val3");
res = sql("select * from my_table ");
assertEquals(1, res.size());
assertEquals(2, res.get(0).size());
// Mixing existsing and not existsing columns
sql("alter table my_table add column if not exists (val varchar, val4 varchar)");
res = sql("select * from my_table ");
assertEquals(1, res.size());
assertEquals(3, res.get(0).size());
sql("alter table my_table drop column if exists (val4, val5)");
res = sql("select * from my_table ");
assertEquals(1, res.size());
assertEquals(2, res.get(0).size());
}
/**
* Add not null column.
*/
@Test
public void alterTableAddNotNullColumn() {
sql("create table my_table (id int primary key, val varchar)");
sql("alter table my_table add column val2 varchar not null");
assertThrows("insert into my_table (id, val, val2) values (0, '1', null)", IgniteSQLException.class,
"Null value is not allowed");
sql("insert into my_table (id, val, val2) values (0, '1', '2')");
List<List<?>> res = sql("select * from my_table ");
assertEquals(1, res.size());
assertEquals("2", res.get(0).get(2));
}
/**
* Drop forbidden column.
*/
@Test
public void alterTableDropForbiddenColumn() {
sql("create table my_table (id int primary key, val varchar, val2 varchar)");
sql("create index my_index on my_table(val)");
sql("insert into my_table (id, val, val2) values (0, '1', '2')");
assertThrows("alter table my_table drop column id", IgniteSQLException.class,
"Cannot drop column");
assertThrows("alter table my_table drop column val", IgniteSQLException.class,
"Cannot drop column");
List<List<?>> res = sql("select * from my_table ");
assertEquals(1, res.size());
assertEquals(3, res.get(0).size());
sql("alter table my_table drop column val2");
res = sql("select * from my_table ");
assertEquals(1, res.size());
assertEquals(2, res.get(0).size());
}
/**
* Alter table from server and client nodes.
*/
@Test
@Ignore("https://issues.apache.org/jira/browse/IGNITE-16292")
public void alterTableServerAndClient() throws Exception {
sql(grid(0), "create table my_table (id int primary key, val varchar)");
sql(grid(0), "alter table my_table add column val2 varchar");
sql(grid(0), "insert into my_table (id, val, val2) values (0, '1', '2')");
List<List<?>> res = sql(grid(0), "select * from my_table ");
assertEquals(1, res.size());
assertEquals(3, res.get(0).size());
sql(grid(0), "drop table my_table");
awaitPartitionMapExchange();
sql("create table my_table (id int primary key, val varchar)");
sql("alter table my_table add column val2 varchar");
sql("insert into my_table (id, val, val2) values (0, '1', '2')");
res = sql("select * from my_table ");
assertEquals(1, res.size());
assertEquals(3, res.get(0).size());
awaitPartitionMapExchange();
sql(grid(0), "alter table my_table drop column val2");
awaitPartitionMapExchange();
res = sql("select * from my_table ");
assertEquals(1, res.size());
assertEquals(2, res.get(0).size());
}
/**
* Drop and add the same column with different NOT NULL modificator.
*/
@Test
public void alterTableDropAddColumn() {
sql("create table my_table (id int primary key, val varchar, val2 varchar)");
sql("insert into my_table (id, val, val2) values (0, '1', '2')");
sql("alter table my_table drop column val2");
List<List<?>> res = sql("select * from my_table ");
assertEquals(1, res.size());
assertEquals(2, res.get(0).size());
sql("alter table my_table add column val2 varchar not null");
res = sql("select * from my_table ");
assertEquals(1, res.size());
assertEquals(3, res.get(0).size());
// The command DROP COLUMN does not remove actual data from the cluster, it's a known and documented limitation.
assertEquals("2", res.get(0).get(2));
assertThrows("insert into my_table (id, val, val2) values (1, '2', null)", IgniteSQLException.class,
"Null value is not allowed");
sql("insert into my_table (id, val, val2) values (1, '2', '3')");
assertEquals(2, sql("select * from my_table").size());
}
/**
* Drop or add column and check indexes works.
*/
@Test
public void alterTableChangeColumnAndUseIndex() {
sql("create table my_table(c1 int, c2 int, c3 int, c4 int)");
sql("create index my_index on my_table(c4)");
for (int i = 0; i < 100; i++)
sql("insert into my_table values (1, 2, 3, ?)", i);
assertQuery("select * from my_table where c4 = 50")
.matches(QueryChecker.containsIndexScan("PUBLIC", "MY_TABLE", "MY_INDEX"))
.returns(1, 2, 3, 50)
.check();
sql("alter table my_table add column c5 int");
assertQuery("select * from my_table where c4 = 50")
.matches(QueryChecker.containsIndexScan("PUBLIC", "MY_TABLE", "MY_INDEX"))
.returns(1, 2, 3, 50, null)
.check();
sql("alter table my_table drop column c2");
assertQuery("select * from my_table where c4 = 50")
.matches(QueryChecker.containsIndexScan("PUBLIC", "MY_TABLE", "MY_INDEX"))
.returns(1, 3, 50, null)
.check();
sql("alter table my_table drop column (c1, c3)");
assertQuery("select * from my_table where c4 = 50")
.matches(QueryChecker.containsIndexScan("PUBLIC", "MY_TABLE", "MY_INDEX"))
.returns(50, null)
.check();
sql("alter table my_table drop column (c5)");
assertQuery("select * from my_table where c4 = 50")
.matches(QueryChecker.containsIndexScan("PUBLIC", "MY_TABLE", "MY_INDEX"))
.returns(50)
.check();
}
/**
* Alter table logging/nologing.
*/
@Test
public void alterTableLogging() {
String cacheName = "cache";
client.getOrCreateCache(new CacheConfiguration<>(cacheName)
.setDataRegionName(PERSISTENT_DATA_REGION).setIndexedTypes(Integer.class, Integer.class));
assertTrue(client.cluster().isWalEnabled(cacheName));
sql("alter table \"" + cacheName + "\".Integer nologging");
assertFalse(client.cluster().isWalEnabled(cacheName));
sql("alter table \"" + cacheName + "\".Integer logging");
assertTrue(client.cluster().isWalEnabled(cacheName));
}
/**
* Tests that multiline statements with DDL and DML works as expected.
*/
@Test
public void testMulitlineWithCreateTable() {
String multiLineQuery = "CREATE TABLE test (val0 int primary key, val1 varchar);" +
"INSERT INTO test(val0, val1) VALUES (0, 'test0');" +
"ALTER TABLE test ADD COLUMN val2 int;" +
"INSERT INTO test(val0, val1, val2) VALUES(1, 'test1', 10);" +
"ALTER TABLE test DROP COLUMN val2;";
sql(multiLineQuery);
List<List<?>> res = sql("SELECT * FROM test order by val0");
assertEquals(2, res.size());
for (int i = 0; i < res.size(); i++) {
List<?> row = res.get(i);
assertEquals(2, row.size());
assertEquals(i, row.get(0));
assertEquals("test" + i, row.get(1));
}
}
/**
* Matcher to verify that an object of the expected type and matches the given predicat.
*
* @param desc Description for this matcher.
* @param pred Addition check that would be applied to the object.
* @return {@code true} in case the object if instance of the given class and matches the predicat.
*/
private static Matcher<CacheConfiguration<?, ?>> matches(String desc, Predicate<CacheConfiguration<?, ?>> pred) {
return new CustomMatcher<CacheConfiguration<?, ?>>(desc) {
@Override public boolean matches(Object item) {
return item instanceof CacheConfiguration && pred.test((CacheConfiguration<?, ?>)item);
}
};
}
}