Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to write time column only #14703

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

package org.apache.iotdb.relational.it.db.it;

import org.apache.iotdb.isession.ISession;
import org.apache.iotdb.isession.ITableSession;
import org.apache.iotdb.isession.SessionDataSet;
import org.apache.iotdb.it.env.EnvFactory;
Expand Down Expand Up @@ -55,6 +56,7 @@
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -875,13 +877,7 @@ public void testInsertSingleColumn() throws SQLException {
// 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)");
// only attribute
st1.execute("insert into sg21(ss1) values('1')");
// only field
Expand All @@ -897,6 +893,9 @@ public void testInsertSingleColumn() throws SQLException {
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 Expand Up @@ -1140,4 +1139,49 @@ private List<Integer> checkHeader(
}
return actualIndexToExpectedIndexList;
}

@Test
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());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,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 @@ -2959,9 +2959,14 @@ private TSInsertTabletReq genTSInsertTabletReq(Tablet tablet, boolean sorted, bo

TSInsertTabletReq request = new TSInsertTabletReq();

for (IMeasurementSchema measurementSchema : tablet.getSchemas()) {
request.addToMeasurements(measurementSchema.getMeasurementName());
request.addToTypes(measurementSchema.getType().ordinal());
if (tablet.getSchemas().isEmpty()) {
request.measurements = Collections.emptyList();
request.types = Collections.emptyList();
} else {
for (IMeasurementSchema measurementSchema : tablet.getSchemas()) {
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 @@ -2212,7 +2212,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 @@ -382,6 +382,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 @@ -155,6 +155,9 @@ public List<String> getOutputColumnNames() {
@Override
public TSDataType[] getDataTypes() {
if (isNeedInferType) {
if (dataTypes == null) {
return new TSDataType[0];
}
TSDataType[] predictedDataTypes = new TSDataType[dataTypes.length];
for (int i = 0; i < dataTypes.length; i++) {
predictedDataTypes[i] = TypeInferenceUtils.getPredictedDataType(values[i], true);
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 @@ -98,10 +98,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 @@ -309,6 +309,8 @@ public List<Integer> getIdColumnIndices() {
idColumnIndices.add(i);
}
}
} else if (columnCategories == null) {
return Collections.emptyList();
}
return idColumnIndices;
}
Expand Down Expand Up @@ -492,7 +494,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 @@ -502,15 +515,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 @@ -521,7 +528,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 @@ -599,6 +606,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 @@ -205,6 +205,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
Loading