blob: b943df6d8b6aab6eaaac7a6259d3b48788b2f378 [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.iotdb.session.it;
import org.apache.iotdb.isession.ISession;
import org.apache.iotdb.isession.SessionDataSet;
import org.apache.iotdb.isession.template.Template;
import org.apache.iotdb.isession.template.TemplateNode;
import org.apache.iotdb.it.env.EnvFactory;
import org.apache.iotdb.itbase.category.ClusterIT;
import org.apache.iotdb.itbase.category.LocalStandaloneIT;
import org.apache.iotdb.rpc.IoTDBConnectionException;
import org.apache.iotdb.rpc.StatementExecutionException;
import org.apache.iotdb.rpc.TSStatusCode;
import org.apache.iotdb.session.template.MeasurementNode;
import org.apache.iotdb.util.AbstractSchemaIT;
import org.apache.tsfile.enums.TSDataType;
import org.apache.tsfile.file.metadata.enums.CompressionType;
import org.apache.tsfile.file.metadata.enums.TSEncoding;
import org.apache.tsfile.read.common.RowRecord;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@Category({LocalStandaloneIT.class, ClusterIT.class})
public class IoTDBSessionSchemaTemplateIT extends AbstractSchemaIT {
private ISession session;
public IoTDBSessionSchemaTemplateIT(SchemaTestMode schemaTestMode) {
super(schemaTestMode);
}
@Before
public void setUp() throws Exception {
EnvFactory.getEnv().initClusterEnvironment();
session = EnvFactory.getEnv().getSessionConnection();
}
@After
public void tearDown() throws Exception {
if (session != null) {
session.close();
}
EnvFactory.getEnv().cleanClusterEnvironment();
}
@Test
public void testCreateFlatTemplate()
throws IOException, StatementExecutionException, IoTDBConnectionException {
String tempName = "flatTemplate";
List<String> measurements = Arrays.asList("x", "y", "speed");
List<TSDataType> dataTypes =
Arrays.asList(TSDataType.FLOAT, TSDataType.FLOAT, TSDataType.DOUBLE);
List<TSEncoding> encodings = Arrays.asList(TSEncoding.RLE, TSEncoding.RLE, TSEncoding.GORILLA);
List<CompressionType> compressors =
Arrays.asList(CompressionType.SNAPPY, CompressionType.SNAPPY, CompressionType.LZ4);
session.setStorageGroup("root.sg");
session.createSchemaTemplate(tempName, measurements, dataTypes, encodings, compressors, true);
session.setSchemaTemplate("flatTemplate", "root.sg.d0");
try {
session.setSchemaTemplate("flatTemplate", "root.sg.d0");
fail();
} catch (StatementExecutionException e) {
assertEquals(
TSStatusCode.METADATA_ERROR.getStatusCode() + ": Template already exists on root.sg.d0",
e.getMessage());
}
}
@Test
public void testShowTemplates()
throws StatementExecutionException, IoTDBConnectionException, IOException {
session.setStorageGroup("root.sg");
Template temp1 = getTemplate("template1");
Template temp2 = getTemplate("template2");
assertEquals("[]", session.showAllTemplates().toString());
session.createSchemaTemplate(temp1);
session.createSchemaTemplate(temp2);
assertEquals(
new HashSet<>(Arrays.asList("template1", "template2")),
new HashSet<>(session.showAllTemplates()));
session.setSchemaTemplate("template1", "root.sg.v1");
session.setSchemaTemplate("template1", "root.sg.v2");
session.setSchemaTemplate("template1", "root.sg.v3");
assertEquals(
new HashSet<>(Arrays.asList("root.sg.v1", "root.sg.v2", "root.sg.v3")),
new HashSet<>(session.showPathsTemplateSetOn("template1")));
assertEquals(
new HashSet<>(Collections.emptyList()),
new HashSet<>(session.showPathsTemplateUsingOn("template1")));
session.setSchemaTemplate("template2", "root.sg.v4");
session.setSchemaTemplate("template2", "root.sg.v5");
session.setSchemaTemplate("template2", "root.sg.v6");
assertEquals(
new HashSet<>(Arrays.asList("root.sg.v4", "root.sg.v5", "root.sg.v6")),
new HashSet<>(session.showPathsTemplateSetOn("template2")));
assertEquals(
new HashSet<>(
Arrays.asList(
"root.sg.v1",
"root.sg.v2",
"root.sg.v3",
"root.sg.v4",
"root.sg.v5",
"root.sg.v6")),
new HashSet<>(session.showPathsTemplateSetOn("*")));
session.insertRecord(
"root.sg.v1.GPS",
110L,
Collections.singletonList("x"),
Collections.singletonList(TSDataType.FLOAT),
Collections.singletonList(1.0f));
assertEquals(
new HashSet<>(Collections.singletonList("root.sg.v1.GPS")),
new HashSet<>(session.showPathsTemplateUsingOn("template1")));
session.insertRecord(
"root.sg.v5.GPS",
110L,
Collections.singletonList("x"),
Collections.singletonList(TSDataType.FLOAT),
Collections.singletonList(1.0f));
assertEquals(
new HashSet<>(Collections.singletonList("root.sg.v1.GPS")),
new HashSet<>(session.showPathsTemplateUsingOn("template1")));
assertEquals(
new HashSet<>(Collections.singletonList("root.sg.v5.GPS")),
new HashSet<>(session.showPathsTemplateUsingOn("template2")));
}
@Test
public void testDropTemplate()
throws StatementExecutionException, IoTDBConnectionException, IOException {
session.setStorageGroup("root.sg");
Template temp1 = getTemplate("template1");
assertEquals("[]", session.showAllTemplates().toString());
session.createSchemaTemplate(temp1);
assertEquals("[]", session.showPathsTemplateSetOn("template1").toString());
try {
session.createSchemaTemplate(temp1);
fail();
} catch (Exception e) {
assertEquals(
TSStatusCode.METADATA_ERROR.getStatusCode() + ": Duplicated template name: template1",
e.getMessage());
}
session.dropSchemaTemplate("template1");
session.createSchemaTemplate(temp1);
session.setSchemaTemplate("template1", "root.sg.v1");
try {
session.dropSchemaTemplate("template1");
fail();
} catch (Exception e) {
assertEquals(
TSStatusCode.METADATA_ERROR.getStatusCode()
+ ": Template [template1] has been set on MTree, cannot be dropped now.",
e.getMessage());
}
session.unsetSchemaTemplate("root.sg.v1", "template1");
session.dropSchemaTemplate("template1");
session.createSchemaTemplate(temp1);
}
private Template getTemplate(String name) throws StatementExecutionException {
Template sessionTemplate = new Template(name, false);
TemplateNode mNodeX =
new MeasurementNode("x", TSDataType.FLOAT, TSEncoding.RLE, CompressionType.SNAPPY);
TemplateNode mNodeY =
new MeasurementNode("y", TSDataType.FLOAT, TSEncoding.RLE, CompressionType.SNAPPY);
sessionTemplate.addToTemplate(mNodeX);
sessionTemplate.addToTemplate(mNodeY);
return sessionTemplate;
}
@Test
public void testBatchActivateTemplate()
throws StatementExecutionException, IoTDBConnectionException, IOException {
try {
session.createTimeseriesUsingSchemaTemplate(Collections.singletonList(null));
fail();
} catch (StatementExecutionException e) {
assertEquals("Given device path list should not be or contains null.", e.getMessage());
}
try {
session.createTimeseriesUsingSchemaTemplate(Collections.singletonList("root.db.d1"));
fail();
} catch (StatementExecutionException e) {
assertTrue(e.getMessage().contains("Path [root.db.d1] has not been set any template"));
}
session.createDatabase("root.db");
Template temp1 = getTemplate("template1");
Template temp2 = getTemplate("template2");
assertEquals("[]", session.showAllTemplates().toString());
session.createSchemaTemplate(temp1);
session.createSchemaTemplate(temp2);
assertEquals(
new HashSet<>(Arrays.asList("template1", "template2")),
new HashSet<>(session.showAllTemplates()));
session.setSchemaTemplate("template1", "root.db.v1");
session.setSchemaTemplate("template1", "root.db.v2");
session.setSchemaTemplate("template1", "root.db.v3");
assertEquals(
new HashSet<>(Collections.emptyList()),
new HashSet<>(session.showPathsTemplateUsingOn("template1")));
session.setSchemaTemplate("template2", "root.db.v4");
session.setSchemaTemplate("template2", "root.db.v5");
session.setSchemaTemplate("template2", "root.db.v6");
assertEquals(
new HashSet<>(Arrays.asList("root.db.v4", "root.db.v5", "root.db.v6")),
new HashSet<>(session.showPathsTemplateSetOn("template2")));
session.createTimeseriesUsingSchemaTemplate(Collections.singletonList("root.db.v1.GPS"));
assertEquals(
new HashSet<>(Collections.singletonList("root.db.v1.GPS")),
new HashSet<>(session.showPathsTemplateUsingOn("template1")));
session.createTimeseriesUsingSchemaTemplate(Collections.singletonList("root.db.v5.GPS"));
assertEquals(
new HashSet<>(Collections.singletonList("root.db.v1.GPS")),
new HashSet<>(session.showPathsTemplateUsingOn("template1")));
assertEquals(
new HashSet<>(Collections.singletonList("root.db.v5.GPS")),
new HashSet<>(session.showPathsTemplateUsingOn("template2")));
session.createTimeseriesUsingSchemaTemplate(
Arrays.asList("root.db.v2.GPS", "root.db.v3.GPS", "root.db.v4.GPS", "root.db.v6.GPS"));
assertEquals(
new HashSet<>(Arrays.asList("root.db.v1.GPS", "root.db.v2.GPS", "root.db.v3.GPS")),
new HashSet<>(session.showPathsTemplateUsingOn("template1")));
assertEquals(
new HashSet<>(Arrays.asList("root.db.v4.GPS", "root.db.v5.GPS", "root.db.v6.GPS")),
new HashSet<>(session.showPathsTemplateUsingOn("template2")));
}
@Test
public void testInsertRecordsWithTemplate() throws Exception {
session.createDatabase("root.db");
Template temp1 = getTemplate("template1");
session.createSchemaTemplate(temp1);
session.setSchemaTemplate("template1", "root.db.v1");
List<String> devices = new ArrayList<>();
List<List<String>> measurementsList = new ArrayList<>();
List<String> measurements = Arrays.asList(new String[] {"x", "y"});
List<Long> times = new ArrayList<>();
List<List<String>> values = new ArrayList<>();
List<String> value = Arrays.asList(new String[] {"1.23", "2.34"});
for (int i = 0; i < 101; i++) {
devices.add("root.db.v1.d" + i);
measurementsList.add(measurements);
times.add(12345L + i);
values.add(value);
}
session.insertRecords(devices, times, measurementsList, values);
SessionDataSet dataSet;
RowRecord row;
for (int i = 0; i < 10; i++) {
dataSet =
session.executeQueryStatement(
String.format("SELECT * from root.db.v1.d%d", (int) (Math.random() * 100)));
while (dataSet.hasNext()) {
row = dataSet.next();
Assert.assertEquals("1.23", row.getFields().get(0).toString());
Assert.assertEquals("2.34", row.getFields().get(1).toString());
}
}
}
@Test
public void testHybridAutoCreateSchema()
throws StatementExecutionException, IoTDBConnectionException, IOException {
session.createDatabase("root.db");
Template temp1 = getTemplate("template1");
Template temp2 = getTemplate("template2");
assertEquals("[]", session.showAllTemplates().toString());
session.createSchemaTemplate(temp1);
session.createSchemaTemplate(temp2);
session.setSchemaTemplate("template1", "root.db.v1");
session.createTimeseriesUsingSchemaTemplate(Collections.singletonList("root.db.v1.d1"));
session.setSchemaTemplate("template2", "root.db.v4");
List<String> deviceIds =
Arrays.asList("root.db.v1.d1", "root.db.v1.d2", "root.db.v2.d1", "root.db.v4.d1");
List<Long> timestamps = Arrays.asList(1L, 1L, 1L, 1L);
List<String> measurements = Arrays.asList("x", "y", "z");
List<List<String>> allMeasurements =
Arrays.asList(measurements, measurements, measurements, measurements);
List<TSDataType> tsDataTypes =
Arrays.asList(TSDataType.FLOAT, TSDataType.FLOAT, TSDataType.TEXT);
List<List<TSDataType>> allTsDataTypes =
Arrays.asList(tsDataTypes, tsDataTypes, tsDataTypes, tsDataTypes);
List<Object> values = Arrays.asList(1f, 2f, "3");
List<List<Object>> allValues = Arrays.asList(values, values, values, values);
session.insertRecords(deviceIds, timestamps, allMeasurements, allTsDataTypes, allValues);
Set<String> expectedSeries =
new HashSet<>(
Arrays.asList(
"root.db.v1.d1.x",
"root.db.v1.d1.y",
"root.db.v1.d1.z",
"root.db.v1.d2.x",
"root.db.v1.d2.y",
"root.db.v1.d2.z",
"root.db.v2.d1.x",
"root.db.v2.d1.y",
"root.db.v2.d1.z",
"root.db.v4.d1.x",
"root.db.v4.d1.y",
"root.db.v4.d1.z"));
try (SessionDataSet dataSet = session.executeQueryStatement("show timeseries")) {
SessionDataSet.DataIterator iterator = dataSet.iterator();
while (iterator.next()) {
Assert.assertTrue(expectedSeries.contains(iterator.getString(1)));
expectedSeries.remove(iterator.getString(1));
}
}
Assert.assertTrue(expectedSeries.isEmpty());
}
@Test
public void testHybridAutoExtendSchemaTemplate()
throws StatementExecutionException, IoTDBConnectionException, IOException {
session.createDatabase("root.db");
Template temp1 = getTemplate("template1");
Template temp2 = new Template("template2", false);
assertEquals("[]", session.showAllTemplates().toString());
session.createSchemaTemplate(temp1);
session.createSchemaTemplate(temp2);
session.setSchemaTemplate("template1", "root.db.v1");
session.createTimeseriesUsingSchemaTemplate(Collections.singletonList("root.db.v1.d1"));
session.setSchemaTemplate("template2", "root.db.v4");
List<String> deviceIds =
Arrays.asList(
"root.db.v1.d1", "root.db.v1.d2", "root.db.v2.d1", "root.db.v4.d1", "root.db.v4.d2");
List<Long> timestamps = Arrays.asList(1L, 1L, 1L, 1L, 1L);
List<String> measurements = Arrays.asList("x", "y", "z");
List<List<String>> allMeasurements =
Arrays.asList(measurements, measurements, measurements, measurements, measurements);
List<TSDataType> tsDataTypes =
Arrays.asList(TSDataType.FLOAT, TSDataType.FLOAT, TSDataType.TEXT);
List<List<TSDataType>> allTsDataTypes =
Arrays.asList(tsDataTypes, tsDataTypes, tsDataTypes, tsDataTypes, tsDataTypes);
List<Object> values = Arrays.asList(1f, 2f, "3");
List<List<Object>> allValues = Arrays.asList(values, values, values, values, values);
session.insertRecords(deviceIds, timestamps, allMeasurements, allTsDataTypes, allValues);
Set<String> expectedSeries =
new HashSet<>(
Arrays.asList(
"root.db.v1.d1.x",
"root.db.v1.d1.y",
"root.db.v1.d1.z",
"root.db.v1.d2.x",
"root.db.v1.d2.y",
"root.db.v1.d2.z",
"root.db.v2.d1.x",
"root.db.v2.d1.y",
"root.db.v2.d1.z",
"root.db.v4.d1.x",
"root.db.v4.d1.y",
"root.db.v4.d1.z",
"root.db.v4.d2.x",
"root.db.v4.d2.y",
"root.db.v4.d2.z"));
try (SessionDataSet dataSet = session.executeQueryStatement("show timeseries")) {
SessionDataSet.DataIterator iterator = dataSet.iterator();
while (iterator.next()) {
Assert.assertTrue(expectedSeries.contains(iterator.getString(1)));
expectedSeries.remove(iterator.getString(1));
}
}
Assert.assertTrue(expectedSeries.isEmpty());
measurements = Arrays.asList("a", "b", "c");
try {
session.insertRecord(
"root.db.v4.d1",
1L,
measurements,
Arrays.asList(TSDataType.FLOAT, TSDataType.FLOAT, TSDataType.TEXT),
Arrays.asList(1f, 2f, "3"));
session.insertRecord(
"root.db.v4.d2",
1L,
measurements,
Arrays.asList(TSDataType.DOUBLE, TSDataType.DOUBLE, TSDataType.INT32),
Arrays.asList(1d, 2d, 3));
Assert.fail();
} catch (StatementExecutionException e) {
Assert.assertTrue(
e.getMessage()
.contains(
"data type of root.db.v4.d2.a is not consistent, registered type FLOAT, inserting type DOUBLE"));
Assert.assertTrue(
e.getMessage()
.contains(
"data type of root.db.v4.d2.b is not consistent, registered type FLOAT, inserting type DOUBLE"));
Assert.assertTrue(
e.getMessage()
.contains(
"data type of root.db.v4.d2.c is not consistent, registered type TEXT, inserting type INT32"));
}
}
}