This is an automated email from the ASF dual-hosted git repository.
jiangtian pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/tsfile.git
The following commit(s) were added to refs/heads/develop by this push:
new a6680a46 add validation in table schema constructor (#324)
a6680a46 is described below
commit a6680a46fc9eb7411c958328bf1cf9a62ac7661b
Author: shuwenwei <[email protected]>
AuthorDate: Mon Dec 9 10:00:49 2024 +0800
add validation in table schema constructor (#324)
---
.../apache/tsfile/file/metadata/TableSchema.java | 57 +++++++++++++++-------
.../org/apache/tsfile/write/record/Tablet.java | 42 ++++++++++++++++
.../apache/tsfile/tableview/TableSchemaTest.java | 16 ++++++
.../org/apache/tsfile/write/record/TabletTest.java | 37 ++++++++++++++
4 files changed, 135 insertions(+), 17 deletions(-)
diff --git
a/java/tsfile/src/main/java/org/apache/tsfile/file/metadata/TableSchema.java
b/java/tsfile/src/main/java/org/apache/tsfile/file/metadata/TableSchema.java
index fcd3b434..f9c9f5d8 100644
--- a/java/tsfile/src/main/java/org/apache/tsfile/file/metadata/TableSchema.java
+++ b/java/tsfile/src/main/java/org/apache/tsfile/file/metadata/TableSchema.java
@@ -75,6 +75,7 @@ public class TableSchema {
measurementSchema.getProps()))
.collect(Collectors.toList());
this.columnCategories = columnCategories;
+ this.updatable = false;
}
public TableSchema(
@@ -82,18 +83,26 @@ public class TableSchema {
List<IMeasurementSchema> columnSchemas,
List<ColumnCategory> columnCategories) {
this.tableName = tableName.toLowerCase();
- this.measurementSchemas =
- columnSchemas.stream()
- .map(
- measurementSchema ->
- new MeasurementSchema(
- measurementSchema.getMeasurementName().toLowerCase(),
- measurementSchema.getType(),
- measurementSchema.getEncodingType(),
- measurementSchema.getCompressor(),
- measurementSchema.getProps()))
- .collect(Collectors.toList());
+ this.measurementSchemas = new ArrayList<>(columnSchemas.size());
+ this.columnPosIndex = new HashMap<>(columnSchemas.size());
+ for (int i = 0; i < columnSchemas.size(); i++) {
+ IMeasurementSchema columnSchema = columnSchemas.get(i);
+ String measurementName = columnSchema.getMeasurementName().toLowerCase();
+ this.measurementSchemas.add(
+ new MeasurementSchema(
+ measurementName,
+ columnSchema.getType(),
+ columnSchema.getEncodingType(),
+ columnSchema.getCompressor(),
+ columnSchema.getProps()));
+ columnPosIndex.put(measurementName, i);
+ }
+ if (measurementSchemas.size() != columnPosIndex.size()) {
+ throw new IllegalArgumentException(
+ "Each column name in the table should be unique(case insensitive).");
+ }
this.columnCategories = columnCategories;
+ this.updatable = false;
}
public TableSchema(
@@ -103,11 +112,18 @@ public class TableSchema {
List<ColumnCategory> categoryList) {
this.tableName = tableName.toLowerCase();
this.measurementSchemas = new ArrayList<>(columnNameList.size());
+ this.columnPosIndex = new HashMap<>(columnNameList.size());
for (int i = 0; i < columnNameList.size(); i++) {
- measurementSchemas.add(
- new MeasurementSchema(columnNameList.get(i).toLowerCase(),
dataTypeList.get(i)));
+ String columnName = columnNameList.get(i).toLowerCase();
+ measurementSchemas.add(new MeasurementSchema(columnName,
dataTypeList.get(i)));
+ columnPosIndex.put(columnName, i);
+ }
+ if (columnNameList.size() != columnPosIndex.size()) {
+ throw new IllegalArgumentException(
+ "Each column name in the table should be unique(case insensitive).");
}
this.columnCategories = categoryList;
+ this.updatable = false;
}
@TsFileApi
@@ -115,12 +131,19 @@ public class TableSchema {
this.tableName = tableName.toLowerCase();
this.measurementSchemas = new ArrayList<>(columnSchemaList.size());
this.columnCategories = new ArrayList<>(columnSchemaList.size());
- for (ColumnSchema columnSchema : columnSchemaList) {
- this.measurementSchemas.add(
- new MeasurementSchema(
- columnSchema.getColumnName().toLowerCase(),
columnSchema.getDataType()));
+ this.columnPosIndex = new HashMap<>(columnSchemaList.size());
+ for (int i = 0; i < columnSchemaList.size(); i++) {
+ ColumnSchema columnSchema = columnSchemaList.get(i);
+ String columnName = columnSchema.getColumnName().toLowerCase();
+ this.measurementSchemas.add(new MeasurementSchema(columnName,
columnSchema.getDataType()));
this.columnCategories.add(columnSchema.getColumnCategory());
+ this.columnPosIndex.put(columnName, i);
+ }
+ if (columnSchemaList.size() != columnPosIndex.size()) {
+ throw new IllegalArgumentException(
+ "Each column name in the table should be unique(case insensitive).");
}
+ this.updatable = false;
}
public Map<String, Integer> getColumnPosIndex() {
diff --git
a/java/tsfile/src/main/java/org/apache/tsfile/write/record/Tablet.java
b/java/tsfile/src/main/java/org/apache/tsfile/write/record/Tablet.java
index 515b41bb..4acf943b 100644
--- a/java/tsfile/src/main/java/org/apache/tsfile/write/record/Tablet.java
+++ b/java/tsfile/src/main/java/org/apache/tsfile/write/record/Tablet.java
@@ -294,6 +294,12 @@ public class Tablet {
case STRING:
case BLOB:
{
+ if (value != null && !(value instanceof Binary) && !(value
instanceof String)) {
+ throw new IllegalArgumentException(
+ String.format(
+ "Expected value of type Binary for data type %s, but got
%s",
+ dataType, value.getClass().getName()));
+ }
final Binary[] sensor = (Binary[]) values[indexOfSchema];
if (value instanceof Binary) {
sensor[rowIndex] = (Binary) value;
@@ -307,18 +313,36 @@ public class Tablet {
}
case FLOAT:
{
+ if (value != null && !(value instanceof Float)) {
+ throw new IllegalArgumentException(
+ String.format(
+ "Expected value of type Float for data type %s, but got
%s",
+ dataType, value.getClass().getName()));
+ }
final float[] sensor = (float[]) values[indexOfSchema];
sensor[rowIndex] = value != null ? (float) value : Float.MIN_VALUE;
break;
}
case INT32:
{
+ if (value != null && !(value instanceof Integer)) {
+ throw new IllegalArgumentException(
+ String.format(
+ "Expected value of type Integer for data type %s, but got
%s",
+ dataType, value.getClass().getName()));
+ }
final int[] sensor = (int[]) values[indexOfSchema];
sensor[rowIndex] = value != null ? (int) value : Integer.MIN_VALUE;
break;
}
case DATE:
{
+ if (value != null && !(value instanceof LocalDate)) {
+ throw new IllegalArgumentException(
+ String.format(
+ "Expected value of type LocalDate for data type %s, but
got %s",
+ dataType, value.getClass().getName()));
+ }
final LocalDate[] sensor = (LocalDate[]) values[indexOfSchema];
sensor[rowIndex] = value != null ? (LocalDate) value : EMPTY_DATE;
break;
@@ -326,18 +350,36 @@ public class Tablet {
case INT64:
case TIMESTAMP:
{
+ if (value != null && !(value instanceof Long)) {
+ throw new IllegalArgumentException(
+ String.format(
+ "Expected value of type Long for data type %s, but got %s",
+ dataType, value.getClass().getName()));
+ }
final long[] sensor = (long[]) values[indexOfSchema];
sensor[rowIndex] = value != null ? (long) value : Long.MIN_VALUE;
break;
}
case DOUBLE:
{
+ if (value != null && !(value instanceof Double)) {
+ throw new IllegalArgumentException(
+ String.format(
+ "Expected value of type Double for data type %s, but got
%s",
+ dataType, value.getClass().getName()));
+ }
final double[] sensor = (double[]) values[indexOfSchema];
sensor[rowIndex] = value != null ? (double) value : Double.MIN_VALUE;
break;
}
case BOOLEAN:
{
+ if (value != null && !(value instanceof Boolean)) {
+ throw new IllegalArgumentException(
+ String.format(
+ "Expected value of type Boolean for data type %s, but got
%s",
+ dataType, value.getClass().getName()));
+ }
final boolean[] sensor = (boolean[]) values[indexOfSchema];
sensor[rowIndex] = value != null && (boolean) value;
break;
diff --git
a/java/tsfile/src/test/java/org/apache/tsfile/tableview/TableSchemaTest.java
b/java/tsfile/src/test/java/org/apache/tsfile/tableview/TableSchemaTest.java
index bdd2dcb3..76276d5b 100644
--- a/java/tsfile/src/test/java/org/apache/tsfile/tableview/TableSchemaTest.java
+++ b/java/tsfile/src/test/java/org/apache/tsfile/tableview/TableSchemaTest.java
@@ -32,12 +32,14 @@ import org.apache.tsfile.write.record.Tablet.ColumnCategory;
import org.apache.tsfile.write.schema.IMeasurementSchema;
import org.apache.tsfile.write.schema.MeasurementSchema;
+import org.junit.Assert;
import org.junit.Test;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import static org.apache.tsfile.write.record.Tablet.ColumnCategory.ID;
@@ -121,4 +123,18 @@ public class TableSchemaTest {
assertEquals(measurementSchemaCnt + 2,
deserialized.getColumnSchemas().size());
}
}
+
+ @Test
+ public void testConstructTableSchemaWithDuplicateColumnName() {
+ try {
+ new TableSchema(
+ "t1",
+ Arrays.asList("id1", "ID1", "id2", "s1"),
+ Arrays.asList(TSDataType.STRING, TSDataType.STRING,
TSDataType.STRING, TSDataType.STRING),
+ Arrays.asList(ID, ID, MEASUREMENT, MEASUREMENT));
+ } catch (IllegalArgumentException e) {
+ return;
+ }
+ Assert.fail();
+ }
}
diff --git
a/java/tsfile/src/test/java/org/apache/tsfile/write/record/TabletTest.java
b/java/tsfile/src/test/java/org/apache/tsfile/write/record/TabletTest.java
index fabb9573..64572c8c 100644
--- a/java/tsfile/src/test/java/org/apache/tsfile/write/record/TabletTest.java
+++ b/java/tsfile/src/test/java/org/apache/tsfile/write/record/TabletTest.java
@@ -241,4 +241,41 @@ public class TabletTest {
fail();
}
}
+
+ @Test
+ public void testWriteWrongType() {
+ final String deviceId = "root.sg";
+ final List<IMeasurementSchema> measurementSchemas = new ArrayList<>();
+ measurementSchemas.add(new MeasurementSchema("s0", TSDataType.INT32,
TSEncoding.PLAIN));
+ measurementSchemas.add(new MeasurementSchema("s1", TSDataType.INT64,
TSEncoding.PLAIN));
+ measurementSchemas.add(new MeasurementSchema("s2", TSDataType.FLOAT,
TSEncoding.PLAIN));
+ measurementSchemas.add(new MeasurementSchema("s3", TSDataType.DOUBLE,
TSEncoding.PLAIN));
+ measurementSchemas.add(new MeasurementSchema("s4", TSDataType.BOOLEAN,
TSEncoding.PLAIN));
+ measurementSchemas.add(new MeasurementSchema("s5", TSDataType.TEXT,
TSEncoding.PLAIN));
+ measurementSchemas.add(new MeasurementSchema("s6", TSDataType.STRING,
TSEncoding.PLAIN));
+ measurementSchemas.add(new MeasurementSchema("s7", TSDataType.BLOB,
TSEncoding.PLAIN));
+ measurementSchemas.add(new MeasurementSchema("s8", TSDataType.TIMESTAMP,
TSEncoding.PLAIN));
+ measurementSchemas.add(new MeasurementSchema("s9", TSDataType.DATE,
TSEncoding.PLAIN));
+
+ Tablet tablet = new Tablet(deviceId, measurementSchemas);
+ addValueWithException(tablet, "s0", 0, 1L);
+ addValueWithException(tablet, "s1", 0, 1);
+ addValueWithException(tablet, "s2", 0, 0.1d);
+ addValueWithException(tablet, "s3", 0, 0.1f);
+ addValueWithException(tablet, "s3", 0, "1");
+ addValueWithException(tablet, "s5", 0, 1L);
+ addValueWithException(tablet, "s6", 0, 1L);
+ addValueWithException(tablet, "s7", 0, 1L);
+ addValueWithException(tablet, "s8", 0, "str");
+ addValueWithException(tablet, "s9", 0, 1L);
+ }
+
+ private void addValueWithException(Tablet tablet, String column, int
rowIndex, Object value) {
+ try {
+ tablet.addValue(column, rowIndex, value);
+ } catch (IllegalArgumentException e) {
+ return;
+ }
+ Assert.fail();
+ }
}