Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -886,13 +886,7 @@ public void testInsertSingleColumn() throws SQLException, InterruptedException {
// only tag
st1.execute("insert into sg21(tag1) values('1')");
// only time
try {
st1.execute("insert into sg21(time) values(1)");
} catch (SQLException e) {
assertEquals(
"305: [INTERNAL_SERVER_ERROR(305)] Exception occurred: \"insert into sg21(time) values(1)\". executeStatement failed. No column other than Time present, please check the request",
e.getMessage());
}
st1.execute("insert into sg21(time) values(1)");
// sleep a while to avoid the same timestamp between two insertions
Thread.sleep(10);
// only attribute
Expand All @@ -912,6 +906,9 @@ public void testInsertSingleColumn() throws SQLException, InterruptedException {
assertFalse(rs1.next());

rs1 = st1.executeQuery("select time, ss1, ss2 from sg21 order by time");
assertTrue(rs1.next());
assertEquals(1, rs1.getLong("time"));

assertTrue(rs1.next());
rs1.getString("ss1");
assertTrue(rs1.wasNull());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,40 @@ public void insertRelationalTabletTest()
}
}

@Test
public void insertTimeOnlyTest() throws IoTDBConnectionException, StatementExecutionException {
try (ITableSession session = EnvFactory.getEnv().getTableSessionConnection()) {
session.executeNonQueryStatement("USE \"db1\"");
session.executeNonQueryStatement("CREATE TABLE IF NOT EXISTS time_only (time time)");

List<IMeasurementSchema> schemaList = Collections.emptyList();
final List<ColumnCategory> columnTypes = Collections.emptyList();

Tablet tablet =
new Tablet(
"time_only",
IMeasurementSchema.getMeasurementNameList(schemaList),
IMeasurementSchema.getDataTypeList(schemaList),
columnTypes);

long timestamp = 0;
for (int row = 0; row < 10; row++) {
tablet.addTimestamp(row, timestamp++);
}
session.insert(tablet);
tablet.reset();

for (int i = 0; i < 10; i++) {
session.executeNonQueryStatement(
String.format("INSERT INTO time_only (time) VALUES (%d)", timestamp++));
}

SessionDataSet dataSet = session.executeQueryStatement("select count(time) from time_only");
RowRecord rec = dataSet.next();
assertEquals(20, rec.getFields().get(0).getLongV());
}
}

@Test
public void insertRelationalTabletWithCacheLeaderTest()
throws IoTDBConnectionException, StatementExecutionException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import org.apache.tsfile.write.TsFileWriter;
import org.apache.tsfile.write.record.TSRecord;
import org.apache.tsfile.write.record.Tablet;
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.After;
Expand Down Expand Up @@ -1907,6 +1908,52 @@ public void convertRecordsToTabletsTest() {
}
}

@Test
@Category({LocalStandaloneIT.class, ClusterIT.class})
public void insertTimeOnlyTest() throws IoTDBConnectionException, StatementExecutionException {
try (ISession session = EnvFactory.getEnv().getSessionConnection()) {

List<IMeasurementSchema> schemaList = Collections.emptyList();
final List<ColumnCategory> columnTypes = Collections.emptyList();

Tablet tablet =
new Tablet(
"root.sg1.d1",
IMeasurementSchema.getMeasurementNameList(schemaList),
IMeasurementSchema.getDataTypeList(schemaList),
columnTypes);

long timestamp = 0;
for (int row = 0; row < 10; row++) {
tablet.addTimestamp(row, timestamp++);
}
session.insertTablet(tablet);
tablet.setDeviceId("root.sg1.d2");
session.insertAlignedTablet(tablet);
tablet.reset();

try {
session.executeNonQueryStatement(
String.format("INSERT INTO root.sg1.d3 (time) VALUES (%d)", timestamp++));
fail("Exception expected");
} catch (StatementExecutionException e) {
assertEquals(
"701: InsertStatement should contain at least one measurement", e.getMessage());
}

try {
session.executeNonQueryStatement(
String.format("INSERT INTO root.sg1.d4 (time) ALIGNED VALUES (%d)", timestamp++));
} catch (StatementExecutionException e) {
assertEquals(
"701: InsertStatement should contain at least one measurement", e.getMessage());
}

SessionDataSet dataSet = session.executeQueryStatement("select count(*) from root.sg1.**");
assertFalse(dataSet.hasNext());
}
}

@Test
@Category({LocalStandaloneIT.class, ClusterIT.class})
public void insertMinMaxTimeTest() throws IoTDBConnectionException, StatementExecutionException {
Expand Down Expand Up @@ -2070,6 +2117,7 @@ record = dataSet.next();
}

@Test
@Category({LocalStandaloneIT.class, ClusterIT.class})
public void testWriteRestartAndDeleteDB()
throws IoTDBConnectionException, StatementExecutionException {
try (ISession session = EnvFactory.getEnv().getSessionConnection()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2964,12 +2964,17 @@ private TSInsertTabletReq genTSInsertTabletReq(Tablet tablet, boolean sorted, bo

TSInsertTabletReq request = new TSInsertTabletReq();

for (IMeasurementSchema measurementSchema : tablet.getSchemas()) {
if (measurementSchema.getMeasurementName() == null) {
throw new IllegalArgumentException("measurement should be non null value");
if (tablet.getSchemas().isEmpty()) {
request.measurements = Collections.emptyList();
request.types = Collections.emptyList();
} else {
for (IMeasurementSchema measurementSchema : tablet.getSchemas()) {
if (measurementSchema.getMeasurementName() == null) {
throw new IllegalArgumentException("measurement should be non null value");
}
request.addToMeasurements(measurementSchema.getMeasurementName());
request.addToTypes(measurementSchema.getType().ordinal());
}
request.addToMeasurements(measurementSchema.getMeasurementName());
request.addToTypes(measurementSchema.getType().ordinal());
}

request.setPrefixPath(tablet.getDeviceId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2243,7 +2243,7 @@ public TSStatus insertTablet(TSInsertTabletReq req) {
// Step 1: transfer from TSInsertTabletReq to Statement
InsertTabletStatement statement = StatementGenerator.createStatement(req);
// return success when this statement is empty because server doesn't need to execute it
if (statement.isEmpty()) {
if (statement.isEmpty() && !req.isWriteToTable()) {
return RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,8 @@ public void setColumnCategories(TsTableColumnCategory[] columnCategories) {
idColumnIndices.add(i);
}
}
} else {
idColumnIndices = Collections.emptyList();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,9 @@ public List<String> getOutputColumnNames() {

@Override
public TSDataType[] getDataTypes() {
if (dataTypes == null) {
dataTypes = new TSDataType[0];
}
if (isNeedInferType) {
TSDataType[] predictedDataTypes = new TSDataType[dataTypes.length];
for (int i = 0; i < dataTypes.length; i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,4 +246,12 @@ public void updateLastCache(String databaseName) {
TableDeviceSchemaCache.getInstance()
.updateLastCacheIfExists(databaseName, getDeviceID(), rawMeasurements, timeValuePairs);
}

@Override
public boolean allMeasurementFailed() {
if (measurements != null && measurements.length > 0) {
return failedMeasurementNumber >= measurements.length;
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -372,4 +372,12 @@ public void updateLastCache(String databaseName) {
startOffset = endOffset;
}
}

@Override
public boolean allMeasurementFailed() {
if (measurements != null && measurements.length > 0) {
return failedMeasurementNumber >= measurements.length;
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,6 @@ public Optional<TableSchema> validateTableHeaderSchema(
.takeReadLock(context, SchemaLockType.VALIDATE_VS_DELETION);

final List<ColumnSchema> inputColumnList = tableSchema.getColumns();
if (inputColumnList == null || inputColumnList.isEmpty()) {
throw new IllegalArgumentException(
"No column other than Time present, please check the request");
}
// Get directly if there is a table because we do not want "addColumn" to affect
// original writings
TsTable table =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ public List<String> getAttributeColumnNameList() {

@Override
public List<Object[]> getAttributeValueList() {
if (insertRowStatement.getColumnCategories() == null) {
return Collections.singletonList(new Object[0]);
}
List<Object> attributeValueList = new ArrayList<>();
for (int i = 0; i < insertRowStatement.getColumnCategories().length; i++) {
if (insertRowStatement.getColumnCategories()[i] == TsTableColumnCategory.ATTRIBUTE) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,8 @@ public List<Integer> getIdColumnIndices() {
idColumnIndices.add(i);
}
}
} else if (columnCategories == null) {
return Collections.emptyList();
}
return idColumnIndices;
}
Expand Down Expand Up @@ -542,7 +544,18 @@ public void insertColumn(final int pos, final ColumnSchema columnSchema) {
throw new ArrayIndexOutOfBoundsException(pos);
}

if (measurementSchemas != null) {
String[] tmpMeasurements = new String[measurements.length + 1];
System.arraycopy(measurements, 0, tmpMeasurements, 0, pos);
tmpMeasurements[pos] = columnSchema.getName();
System.arraycopy(measurements, pos, tmpMeasurements, pos + 1, measurements.length - pos);
measurements = tmpMeasurements;

if (measurementSchemas == null) {
measurementSchemas = new MeasurementSchema[measurements.length];
measurementSchemas[pos] =
new MeasurementSchema(
columnSchema.getName(), InternalTypeManager.getTSDataType(columnSchema.getType()));
} else {
final MeasurementSchema[] tmp = new MeasurementSchema[measurementSchemas.length + 1];
System.arraycopy(measurementSchemas, 0, tmp, 0, pos);
tmp[pos] =
Expand All @@ -552,15 +565,9 @@ public void insertColumn(final int pos, final ColumnSchema columnSchema) {
measurementSchemas = tmp;
}

String[] tmpMeasurements = new String[measurements.length + 1];
System.arraycopy(measurements, 0, tmpMeasurements, 0, pos);
tmpMeasurements[pos] = columnSchema.getName();
System.arraycopy(measurements, pos, tmpMeasurements, pos + 1, measurements.length - pos);
measurements = tmpMeasurements;

if (dataTypes == null) {
// sql insertion
dataTypes = new TSDataType[measurements.length + 1];
dataTypes = new TSDataType[measurements.length];
dataTypes[pos] = InternalTypeManager.getTSDataType(columnSchema.getType());
} else {
final TSDataType[] tmpTypes = new TSDataType[dataTypes.length + 1];
Expand All @@ -571,7 +578,7 @@ public void insertColumn(final int pos, final ColumnSchema columnSchema) {
}

if (columnCategories == null) {
columnCategories = new TsTableColumnCategory[measurements.length + 1];
columnCategories = new TsTableColumnCategory[measurements.length];
columnCategories[pos] = columnSchema.getColumnCategory();
} else {
final TsTableColumnCategory[] tmpCategories =
Expand Down Expand Up @@ -649,6 +656,9 @@ public void toLowerCase() {

@TableModel
public List<String> getAttributeColumnNameList() {
if (getColumnCategories() == null) {
return Collections.emptyList();
}
final List<String> attributeColumnNameList = new ArrayList<>();
for (int i = 0; i < getColumnCategories().length; i++) {
if (getColumnCategories()[i] == TsTableColumnCategory.ATTRIBUTE) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ protected boolean checkAndCastDataType(int columnIndex, TSDataType dataType) {
*/
@SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity warning
public void transferType(ZoneId zoneId) throws QueryProcessException {
if (measurementSchemas == null) {
return;
}

for (int i = 0; i < measurementSchemas.length; i++) {
// null when time series doesn't exist
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,7 @@ public int insertAlignedRow(InsertRowNode insertRowNode) {
schemaList.add(schema);
dataTypes.add(schema.getType());
}
if (schemaList.isEmpty()) {
return 0;
}

memSize +=
MemUtils.getAlignedRowRecordSize(dataTypes, values, insertRowNode.getColumnCategories());
writeAlignedRow(insertRowNode.getDeviceID(), schemaList, insertRowNode.getTime(), values);
Expand Down Expand Up @@ -356,18 +354,18 @@ public void writeAlignedTablet(
InsertTabletNode insertTabletNode, int start, int end, TSStatus[] results) {

List<IMeasurementSchema> schemaList = new ArrayList<>();
for (int i = 0; i < insertTabletNode.getMeasurementSchemas().length; i++) {
if (insertTabletNode.getColumns()[i] == null
|| (insertTabletNode.getColumnCategories() != null
&& insertTabletNode.getColumnCategories()[i] != TsTableColumnCategory.FIELD)) {
schemaList.add(null);
} else {
schemaList.add(insertTabletNode.getMeasurementSchemas()[i]);
if (insertTabletNode.getMeasurementSchemas() != null) {
for (int i = 0; i < insertTabletNode.getMeasurementSchemas().length; i++) {
if (insertTabletNode.getColumns()[i] == null
|| (insertTabletNode.getColumnCategories() != null
&& insertTabletNode.getColumnCategories()[i] != TsTableColumnCategory.FIELD)) {
schemaList.add(null);
} else {
schemaList.add(insertTabletNode.getMeasurementSchemas()[i]);
}
}
}
if (schemaList.isEmpty()) {
return;
}

final List<Pair<IDeviceID, Integer>> deviceEndOffsetPair =
insertTabletNode.splitByDevice(start, end);
int splitStart = start;
Expand Down