blob: b0ca914f1829c092b37f3d945bd626e5e7f69e39 [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.stat;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.ignite.cluster.ClusterState;
import org.apache.ignite.internal.processors.query.stat.config.StatisticsColumnConfiguration;
import org.apache.ignite.internal.processors.query.stat.config.StatisticsColumnOverrides;
import org.apache.ignite.internal.processors.query.stat.config.StatisticsObjectConfiguration;
import org.apache.ignite.testframework.GridTestUtils;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.config.Configurator;
import org.junit.Test;
/**
* Tests for statistics related views.
*/
public abstract class StatisticsViewsTest extends StatisticsAbstractTest {
/** {@inheritDoc} */
@Override protected void beforeTestsStarted() throws Exception {
super.beforeTestsStarted();
cleanPersistenceDir();
startGrid(0);
grid(0).cluster().state(ClusterState.ACTIVE);
grid(0).getOrCreateCache(DEFAULT_CACHE_NAME);
createSmallTable(null);
collectStatistics(StatisticsType.GLOBAL, SMALL_TARGET);
}
/**
* Check small table configuration in statistics column configuration view.
*/
@Test
public void testConfigurationView() throws Exception {
collectStatistics(StatisticsType.GLOBAL, SMALL_TARGET);
ObjectStatisticsImpl smallStat = (ObjectStatisticsImpl)statisticsMgr(0).getLocalStatistics(SMALL_KEY);
long aVer = smallStat.columnStatistics("A").version();
long bVer = smallStat.columnStatistics("B").version();
long cVer = smallStat.columnStatistics("C").version();
List<List<Object>> config = Arrays.asList(
Arrays.asList(SCHEMA, "TABLE", "SMALL", "A", (byte)15, null, null, null, null, aVer),
Arrays.asList(SCHEMA, "TABLE", "SMALL", "B", (byte)15, null, null, null, null, bVer),
Arrays.asList(SCHEMA, "TABLE", "SMALL", "C", (byte)15, null, null, null, null, cVer)
);
checkSqlResult("select * from SYS.STATISTICS_CONFIGURATION where name = 'SMALL'", null, config::equals);
}
/**
* Check that no deleted configuration available throw view:
* 1) Create table,
* 2) Create statistics for new table.
* 3) Check statistics configuration presence.
* 4) Drop statistics for some column of new table.
* 5) Check statistics configuration without dropped column.
* 6) Drop statistics for new table.
* 7) Check statistics configuration without it.
*
* @throws Exception
*/
@Test
public void testConfigurationViewDeletion() throws Exception {
// 1) Create table,
String name = createSmallTable("DELETE");
name = name.toUpperCase();
// 2) Create statistics for new table.
// TODO: revert after IGNITE-15455
//grid(0).cache(DEFAULT_CACHE_NAME).query(new SqlFieldsQuery("ANALYZE " + name)).getAll();
collectStatistics(StatisticsType.GLOBAL, name);
// 3) Check statistics configuration presence.
List<List<Object>> config = new ArrayList<>();
config.add(Arrays.asList(SCHEMA, "TABLE", name, "A", (byte)15, null, null, null, null, 1L));
config.add(Arrays.asList(SCHEMA, "TABLE", name, "B", (byte)15, null, null, null, null, 1L));
config.add(Arrays.asList(SCHEMA, "TABLE", name, "C", (byte)15, null, null, null, null, 1L));
checkSqlResult("select * from SYS.STATISTICS_CONFIGURATION where NAME = '" + name + "'", null, config::equals);
// 4) Drop statistics for some column of new table.
//grid(0).cache(DEFAULT_CACHE_NAME).query(new SqlFieldsQuery("DROP STATISTICS " + name + "(A);")).getAll();
statisticsMgr(0).statisticConfiguration().dropStatistics(
Collections.singletonList(new StatisticsTarget(SCHEMA, name, "A")), true);
// 5) Check statistics configuration without dropped column.
List<Object> removed = config.remove(0);
checkSqlResult("select * from SYS.STATISTICS_CONFIGURATION where NAME = '" + name + "'", null,
act -> testContains(config, act) == null && testContains(Arrays.asList(removed), act) != null);
// 6) Drop statistics for new table.
// TODO: revert after IGNITE-15455
//grid(0).cache(DEFAULT_CACHE_NAME).query(new SqlFieldsQuery("DROP STATISTICS " + name)).getAll();
statisticsMgr(0).statisticConfiguration().dropStatistics(
Collections.singletonList(new StatisticsTarget(SCHEMA, name)), true);
// 7) Check statistics configuration without it.
checkSqlResult("select * from SYS.STATISTICS_CONFIGURATION where NAME = '" + name + "'", null, List::isEmpty);
}
/**
* Check partition from small table in statistics partition data view.
*/
@Test
public void testPartitionDataView() throws Exception {
List<List<Object>> partLines = Arrays.asList(
Arrays.asList(SCHEMA, "TABLE", "SMALL", "A", 0, null, null, null, 0L, null, null, null, null)
);
checkSqlResult("select * from SYS.STATISTICS_PARTITION_DATA where PARTITION < 10", null, act -> {
checkContains(partLines, act);
return true;
});
}
/**
* Check small table local data in statistics local data view.
*/
@Test
public void testLocalDataView() throws Exception {
long size = SMALL_SIZE;
ObjectStatisticsImpl smallStat = (ObjectStatisticsImpl)statisticsMgr(0).getLocalStatistics(SMALL_KEY);
assertNotNull(smallStat);
Timestamp tsA = new Timestamp(smallStat.columnStatistics("A").createdAt());
Timestamp tsB = new Timestamp(smallStat.columnStatistics("B").createdAt());
Timestamp tsC = new Timestamp(smallStat.columnStatistics("C").createdAt());
List<List<Object>> localData = Arrays.asList(
Arrays.asList(SCHEMA, "TABLE", "SMALL", "A", size, size, 0L, size, 4, 1L, tsA.toString()),
Arrays.asList(SCHEMA, "TABLE", "SMALL", "B", size, size, 0L, size, 4, 1L, tsB.toString()),
Arrays.asList(SCHEMA, "TABLE", "SMALL", "C", size, 10L, 0L, size, 4, 1L, tsC.toString())
);
checkSqlResult("select * from SYS.STATISTICS_LOCAL_DATA", null, localData::equals);
}
/**
* Check statistics rowCount=size, analyze with overridden values and check values.
*
* @throws Exception in case of error.
*/
@Test
public void testEnforceStatisticValues() throws Exception {
long size = SMALL_SIZE;
Configurator.setLevel(StatisticsProcessor.class.getName(), Level.TRACE);
ObjectStatisticsImpl smallStat = (ObjectStatisticsImpl)statisticsMgr(0).getLocalStatistics(SMALL_KEY);
assertNotNull(smallStat);
assertEquals(size, smallStat.rowCount());
// TODO: revert after IGNITE-15455
// sql("DROP STATISTICS SMALL");
// sql("ANALYZE SMALL (A) WITH \"DISTINCT=5,NULLS=6,TOTAL=7,SIZE=8\"");
// sql("ANALYZE SMALL (B) WITH \"DISTINCT=6,NULLS=7,TOTAL=8\"");
// sql("ANALYZE SMALL (C)");
IgniteStatisticsConfigurationManager cfgMgr = statisticsMgr(0).statisticConfiguration();
cfgMgr.dropStatistics(Collections.singletonList(SMALL_TARGET), true);
StatisticsColumnConfiguration aCfg = new StatisticsColumnConfiguration("A",
new StatisticsColumnOverrides(6L, 5L, 7L, 8));
StatisticsObjectConfiguration smallACfg = new StatisticsObjectConfiguration(SMALL_KEY,
Collections.singleton(aCfg), StatisticsObjectConfiguration.DEFAULT_OBSOLESCENCE_MAX_PERCENT);
cfgMgr.updateStatistics(smallACfg);
StatisticsColumnConfiguration bCfg = new StatisticsColumnConfiguration("B",
new StatisticsColumnOverrides(7L, 6L, 8L, null));
StatisticsObjectConfiguration smallBCfg = new StatisticsObjectConfiguration(SMALL_KEY,
Collections.singleton(bCfg), StatisticsObjectConfiguration.DEFAULT_OBSOLESCENCE_MAX_PERCENT);
cfgMgr.updateStatistics(smallBCfg);
StatisticsColumnConfiguration cCfg = new StatisticsColumnConfiguration("C", null);
StatisticsObjectConfiguration smallCCfg = new StatisticsObjectConfiguration(SMALL_KEY,
Collections.singleton(cCfg), StatisticsObjectConfiguration.DEFAULT_OBSOLESCENCE_MAX_PERCENT);
cfgMgr.updateStatistics(smallCCfg);
checkSqlResult("select * from SYS.STATISTICS_LOCAL_DATA where NAME = 'SMALL' and COLUMN = 'C'", null,
list -> !list.isEmpty());
assertTrue(GridTestUtils.waitForCondition(() -> {
ObjectStatisticsImpl stat = (ObjectStatisticsImpl)statisticsMgr(0).getLocalStatistics(SMALL_KEY);
return stat != null && stat.rowCount() == 8;
}, TIMEOUT));
smallStat = (ObjectStatisticsImpl)statisticsMgr(0).getLocalStatistics(SMALL_KEY);
Timestamp tsA = new Timestamp(smallStat.columnStatistics("A").createdAt());
Timestamp tsB = new Timestamp(smallStat.columnStatistics("B").createdAt());
Timestamp tsC = new Timestamp(smallStat.columnStatistics("C").createdAt());
long aVer = smallStat.columnStatistics("A").version();
long bVer = smallStat.columnStatistics("B").version();
long cVer = smallStat.columnStatistics("C").version();
List<List<Object>> localData = Arrays.asList(
Arrays.asList(SCHEMA, "TABLE", "SMALL", "A", 8L, 5L, 6L, 7L, 8, aVer, tsA.toString()),
Arrays.asList(SCHEMA, "TABLE", "SMALL", "B", 8L, 6L, 7L, 8L, 4, bVer, tsB.toString()),
Arrays.asList(SCHEMA, "TABLE", "SMALL", "C", 8L, 10L, 0L, size, 4, cVer, tsC.toString())
);
checkSqlResult("select * from SYS.STATISTICS_LOCAL_DATA where NAME = 'SMALL'", null,
localData::equals);
}
}