This is an automated email from the ASF dual-hosted git repository.
jackietien pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new ccd3060f14a Fixed the reserved word introduced by tree view in tree
model SQL & Enhanced the tree view IT & Handled the cases in field /
measurement names & Temporarily banned source measurements with the same name
(#15475)
ccd3060f14a is described below
commit ccd3060f14adb364a639964dd5c4dfaab633081b
Author: Caideyipi <[email protected]>
AuthorDate: Tue May 13 14:47:07 2025 +0800
Fixed the reserved word introduced by tree view in tree model SQL &
Enhanced the tree view IT & Handled the cases in field / measurement names &
Temporarily banned source measurements with the same name (#15475)
---
.../iotdb/relational/it/schema/IoTDBTableIT.java | 98 +++++++++++++++++++---
.../java/org/apache/iotdb/rpc/TSStatusCode.java | 2 +
.../org/apache/iotdb/db/qp/sql/IdentifierParser.g4 | 5 ++
.../org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4 | 3 +-
.../schema/TreeDeviceViewFieldDetector.java | 96 +++++++++++++--------
.../schema/table/view/AddViewColumnProcedure.java | 32 +++----
.../request/ConfigPhysicalPlanSerDeTest.java | 8 +-
.../persistence/schema/ConfigMTreeTest.java | 2 +-
.../pipe/receiver/PipeEnrichedProcedureTest.java | 6 +-
.../schema/table/CreateTableProcedureTest.java | 2 +-
.../schema/table/CreateTableViewProcedureTest.java | 4 +-
.../table/view/CreateTableViewProcedureTest.java | 4 +-
.../schema/source/TableDeviceQuerySource.java | 2 +-
.../execution/config/TableConfigTaskVisitor.java | 14 +++-
.../db/queryengine/plan/parser/ASTVisitor.java | 22 +++--
.../metadata/fetcher/SchemaPredicateUtil.java | 2 +-
.../metadata/fetcher/TableDeviceSchemaFetcher.java | 8 +-
.../relational/sql/ast/ViewFieldDefinition.java | 2 +-
.../plan/relational/sql/parser/AstBuilder.java | 23 +++--
.../iotdb/commons/schema/table/TreeViewSchema.java | 8 ++
.../apache/iotdb/commons/schema/table/TsTable.java | 2 +-
21 files changed, 248 insertions(+), 97 deletions(-)
diff --git
a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTableIT.java
b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTableIT.java
index e88b04d8248..3104a7cd932 100644
---
a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTableIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTableIT.java
@@ -51,6 +51,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import static
org.apache.iotdb.commons.schema.column.ColumnHeaderConstant.describeTableColumnHeaders;
import static
org.apache.iotdb.commons.schema.column.ColumnHeaderConstant.describeTableDetailsColumnHeaders;
@@ -761,14 +762,55 @@ public class IoTDBTableIT {
try (final Connection connection = EnvFactory.getEnv().getConnection();
final Statement statement = connection.createStatement()) {
statement.execute("create database root.a.b");
- statement.execute("create timeSeries root.a.b.c.s1 int32");
+ statement.execute("create timeSeries root.a.b.c.S1 int32");
statement.execute("create timeSeries root.a.b.c.s2 string");
- statement.execute("create timeSeries root.a.b.s1 int32");
- statement.execute("create timeSeries root.a.b.d.s1 boolean");
- statement.execute("create timeSeries root.a.b.c.f.g.h.s1 int32");
+ statement.execute("create timeSeries root.a.b.S1 int32");
+ } catch (SQLException e) {
+ fail(e.getMessage());
+ }
+
+ try (final Connection connection =
+ EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ final Statement statement = connection.createStatement()) {
+ statement.execute("create database tree_view_db");
+ statement.execute("use tree_view_db");
+ statement.execute("create table view tree_table (tag1 tag, tag2 tag) as
root.a.**");
+ statement.execute("drop view tree_table");
+ }
+
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
+ statement.execute("create timeSeries root.a.b.d.s1 int32");
+ } catch (SQLException e) {
+ fail(e.getMessage());
+ }
+
+ try (final Connection connection =
+ EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ final Statement statement = connection.createStatement()) {
+ statement.execute("use tree_view_db");
+
+ try {
+ statement.execute("create table view tree_table (tag1 tag, tag2 tag)
as root.a.**");
+ fail();
+ } catch (final SQLException e) {
+ final Set<String> result =
+ new HashSet<>(
+ Arrays.asList(
+ "617: The measurements s1 and S1 share the same lower case
when auto detecting type, please check",
+ "617: The measurements S1 and s1 share the same lower case
when auto detecting type, please check"));
+ assertTrue(result.contains(e.getMessage()));
+ }
+ }
+
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
+ statement.execute("drop timeSeries root.a.b.d.s1");
+ statement.execute("create timeSeries root.a.b.d.S1 boolean");
+ statement.execute("create timeSeries root.a.b.c.f.g.h.S1 int32");
// Put schema cache
- statement.execute("select s1, s2 from root.a.b.c");
+ statement.execute("select S1, s2 from root.a.b.c");
} catch (SQLException e) {
fail(e.getMessage());
}
@@ -776,18 +818,52 @@ public class IoTDBTableIT {
try (final Connection connection =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
final Statement statement = connection.createStatement()) {
- statement.execute("create database tree_view_db");
statement.execute("use tree_view_db");
+
try {
statement.execute("create table view tree_table (tag1 tag, tag2 tag)
as root.a.**");
fail();
} catch (final SQLException e) {
assertEquals(
- "614: Multiple types encountered when auto detecting type of
measurement 's1', please check",
+ "614: Multiple types encountered when auto detecting type of
measurement 'S1', please check",
e.getMessage());
}
+
+ try {
+ statement.execute(
+ "create table view tree_table (tag1 tag, tag2 tag, S1 field) as
root.a.**");
+ fail();
+ } catch (final SQLException e) {
+ assertEquals(
+ "614: Multiple types encountered when auto detecting type of
measurement 'S1', please check",
+ e.getMessage());
+ }
+ }
+
+ try (final Connection connection = EnvFactory.getEnv().getConnection();
+ final Statement statement = connection.createStatement()) {
+ statement.execute("create timeSeries root.a.b.e.s1 int32");
+ } catch (SQLException e) {
+ fail(e.getMessage());
+ }
+
+ try (final Connection connection =
+ EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ final Statement statement = connection.createStatement()) {
+ statement.execute("use tree_view_db");
+
+ // Temporary
+ try {
+ statement.execute(
+ "create or replace table view tree_table (tag1 tag, tag2 tag, S1
int32 field, s3 boolean from S1) as root.a.**");
+ fail();
+ } catch (final SQLException e) {
+ assertEquals(
+ "701: The duplicated source measurement S1 is unsupported yet.",
e.getMessage());
+ }
+
statement.execute(
- "create or replace table view tree_table (tag1 tag, tag2 tag, s1
int32 field, s3 from s2) as root.a.**");
+ "create or replace table view tree_table (tag1 tag, tag2 tag, S1
int32 field, s3 from s2) as root.a.**");
statement.execute("alter view tree_table rename to view_table");
statement.execute("alter view view_table rename column s1 to s11");
statement.execute("alter view view_table set properties ttl=100");
@@ -808,13 +884,13 @@ public class IoTDBTableIT {
"tag2,STRING,TAG,",
"s11,INT32,FIELD,",
"s3,STRING,FIELD,")));
- // Currently we show the device even if all of its measurements does not
match the type,
+ // Currently we show the device even if all of its measurements does not
match,
// the handling logic at query because validate it at fetching will
potentially cause a
// lot of time
TestUtils.assertResultSetEqual(
statement.executeQuery("show devices from view_table where tag1 =
'b'"),
"tag1,tag2,",
- new HashSet<>(Arrays.asList("b,c,", "b,null,", "b,d,")));
+ new HashSet<>(Arrays.asList("b,c,", "b,null,", "b,d,", "b,e,")));
TestUtils.assertResultSetEqual(
statement.executeQuery("show devices from view_table where tag1 =
'b' and tag2 is null"),
"tag1,tag2,",
@@ -822,7 +898,7 @@ public class IoTDBTableIT {
TestUtils.assertResultSetEqual(
statement.executeQuery("count devices from view_table"),
"count(devices),",
- Collections.singleton("3,"));
+ Collections.singleton("4,"));
}
// Test tree session
diff --git
a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
index a3114333bcc..25afac67974 100644
---
a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
+++
b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java
@@ -111,6 +111,8 @@ public enum TSStatusCode {
DATA_TYPE_MISMATCH(614),
COLUMN_CATEGORY_MISMATCH(615),
COLUMN_NOT_EXISTS(616),
+ MEASUREMENT_NAME_CONFLICT(617),
+
WAL_ENTRY_TOO_LARGE(620),
// Query Engine
diff --git
a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IdentifierParser.g4
b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IdentifierParser.g4
index fca3fb47cff..4ba4196dad6 100644
---
a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IdentifierParser.g4
+++
b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IdentifierParser.g4
@@ -60,6 +60,7 @@ keyWords
| CLEAR
| CLUSTER
| CLUSTERID
+ | COMMENT
| CONCAT
| CONDITION
| CONFIGNODE
@@ -87,6 +88,7 @@ keyWords
| DATASET
| DEACTIVATE
| DEBUG
+ | DEFAULT
| DELETE
| DESC
| DESCRIBE
@@ -105,6 +107,7 @@ keyWords
| EXPLAIN
| EXTRACTOR
| FALSE
+ | FIELD
| FILL
| FILE
| FIRST
@@ -198,6 +201,7 @@ keyWords
| RESOURCE
| REPAIR
| REPLACE
+ | RESTRICT
| REVOKE
| ROLE
| ROUND
@@ -229,6 +233,7 @@ keyWords
| SUBSTRING
| SYSTEM
| TABLE
+ | TAG
| TAGS
| TAIL
| TASK
diff --git
a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
index 5ffc89370bc..2dfd93e5b39 100644
---
a/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
+++
b/iotdb-core/antlr/src/main/antlr4/org/apache/iotdb/db/qp/sql/IoTDBSqlParser.g4
@@ -789,7 +789,8 @@ createTableView
;
viewColumnDefinition
- : identifier (type)? (columnCategory=(TAG | TIME | FIELD))? comment?
+ : identifier columnCategory=(TAG | TIME | FIELD) comment?
+ | identifier type (columnCategory=(TAG | TIME | FIELD))? comment?
| identifier (type)? (columnCategory=FIELD)? FROM
original_measurement=identifier comment?
;
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/TreeDeviceViewFieldDetector.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/TreeDeviceViewFieldDetector.java
index 3f5aec7fba2..3527e62e7a3 100644
---
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/TreeDeviceViewFieldDetector.java
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/TreeDeviceViewFieldDetector.java
@@ -28,6 +28,7 @@ import org.apache.iotdb.commons.path.PathPatternTree;
import org.apache.iotdb.commons.schema.table.TreeViewSchema;
import org.apache.iotdb.commons.schema.table.TsTable;
import org.apache.iotdb.commons.schema.table.column.FieldColumnSchema;
+import org.apache.iotdb.commons.schema.table.column.TsTableColumnSchema;
import org.apache.iotdb.commons.utils.StatusUtils;
import org.apache.iotdb.confignode.client.async.CnToDnAsyncRequestType;
import org.apache.iotdb.confignode.manager.ConfigManager;
@@ -44,28 +45,30 @@ import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Collectors;
public class TreeDeviceViewFieldDetector {
private static final Logger LOGGER =
LoggerFactory.getLogger(TreeDeviceViewFieldDetector.class);
- private static final int MEASUREMENT_TRIMMING_THRESHOLD = 1000;
private final ConfigManager configManager;
private final PartialPath path;
private final TsTable table;
- private final Map<String, FieldColumnSchema> fields;
+ private final Map<String, Set<FieldColumnSchema>> fields;
private TDeviceViewResp result = new TDeviceViewResp(StatusUtils.OK, new
ConcurrentHashMap<>());
+ private final Map<String, String> lowerCase2OriginalMap = new HashMap<>();
public TreeDeviceViewFieldDetector(
final ConfigManager configManager,
final TsTable table,
- final Map<String, FieldColumnSchema> fields) {
+ final Map<String, Set<FieldColumnSchema>> fields) {
this.configManager = configManager;
this.path = TreeViewSchema.getPrefixPattern(table);
this.table = table;
@@ -77,7 +80,7 @@ public class TreeDeviceViewFieldDetector {
new TreeDeviceViewFieldDetectionTaskExecutor(
configManager,
getLatestSchemaRegionMap(),
- table.getIdNums(),
+ table.getTagNum(),
TreeViewSchema.isRestrict(table))
.execute();
if (result.getStatus().getCode() !=
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
@@ -86,47 +89,56 @@ public class TreeDeviceViewFieldDetector {
result
.getDeviewViewFieldTypeMap()
.forEach(
- (field, type) ->
- table.addColumnSchema(
- new FieldColumnSchema(field,
TSDataType.getTsDataType(type))));
+ (field, type) -> {
+ final FieldColumnSchema columnSchema =
+ new FieldColumnSchema(field,
TSDataType.getTsDataType(type));
+ if (!field.equals(lowerCase2OriginalMap.get(field))) {
+ TreeViewSchema.setOriginalName(columnSchema,
lowerCase2OriginalMap.get(field));
+ }
+ table.addColumnSchema(columnSchema);
+ });
} else {
- final Map<String, FieldColumnSchema> unknownFields =
- Objects.isNull(fields)
- ? table.getColumnList().stream()
- .filter(
- columnSchema ->
- columnSchema instanceof FieldColumnSchema
- && columnSchema.getDataType() ==
TSDataType.UNKNOWN)
- .collect(
- Collectors.toMap(
- fieldColumnSchema ->
-
Objects.nonNull(TreeViewSchema.getOriginalName(fieldColumnSchema))
- ?
TreeViewSchema.getOriginalName(fieldColumnSchema)
- : fieldColumnSchema.getColumnName(),
- FieldColumnSchema.class::cast))
- : fields;
+ final Map<String, Set<FieldColumnSchema>> unknownFields;
+ if (Objects.isNull(fields)) {
+ unknownFields = new HashMap<>();
+ for (final TsTableColumnSchema schema : table.getColumnList()) {
+ if (!(schema instanceof FieldColumnSchema)
+ || schema.getDataType() != TSDataType.UNKNOWN) {
+ continue;
+ }
+ final String key = TreeViewSchema.getSourceName(schema);
+ if (!unknownFields.containsKey(key)) {
+ unknownFields.put(key, new HashSet<>());
+ }
+ unknownFields.get(key).add((FieldColumnSchema) schema);
+ }
+ } else {
+ unknownFields = fields;
+ }
+
if (unknownFields.isEmpty()) {
return StatusUtils.OK;
}
new TreeDeviceViewFieldDetectionTaskExecutor(
configManager,
getLatestSchemaRegionMap(),
- table.getIdNums(),
+ table.getTagNum(),
TreeViewSchema.isRestrict(table),
- unknownFields.size() <= MEASUREMENT_TRIMMING_THRESHOLD
- ? unknownFields.keySet()
- : null)
+ unknownFields.keySet())
.execute();
if (result.getStatus().getCode() !=
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
return result.getStatus();
}
- for (final Map.Entry<String, FieldColumnSchema> unknownField :
unknownFields.entrySet()) {
+ for (final Map.Entry<String, Set<FieldColumnSchema>> unknownField :
+ unknownFields.entrySet()) {
if
(result.getDeviewViewFieldTypeMap().containsKey(unknownField.getKey())) {
unknownField
.getValue()
- .setDataType(
- TSDataType.getTsDataType(
-
result.getDeviewViewFieldTypeMap().get(unknownField.getKey())));
+ .forEach(
+ field ->
+ field.setDataType(
+ TSDataType.getTsDataType(
+
result.getDeviewViewFieldTypeMap().get(unknownField.getKey()))));
} else {
return new TSStatus(TSStatusCode.TYPE_NOT_FOUND.getStatusCode())
.setMessage(
@@ -226,9 +238,13 @@ public class TreeDeviceViewFieldDetector {
resp.getDeviewViewFieldTypeMap()
.forEach(
(measurement, type) -> {
- if
(!result.getDeviewViewFieldTypeMap().containsKey(measurement)) {
- result.getDeviewViewFieldTypeMap().put(measurement, type);
- } else {
+ final String fieldName =
measurement.toLowerCase(Locale.ENGLISH);
+
+ // Field type collection
+ if
(!result.getDeviewViewFieldTypeMap().containsKey(fieldName)) {
+ result.getDeviewViewFieldTypeMap().put(fieldName, type);
+ } else if (!Objects.equals(
+ result.getDeviewViewFieldTypeMap().get(fieldName), type)) {
result.setStatus(
RpcUtils.getStatus(
TSStatusCode.DATA_TYPE_MISMATCH,
@@ -236,6 +252,18 @@ public class TreeDeviceViewFieldDetector {
"Multiple types encountered when auto detecting
type of measurement '%s', please check",
measurement)));
}
+
+ // Field name detection
+ if (!lowerCase2OriginalMap.containsKey(fieldName)) {
+ lowerCase2OriginalMap.put(fieldName, measurement);
+ } else if
(!Objects.equals(lowerCase2OriginalMap.get(fieldName), measurement)) {
+ result.setStatus(
+ RpcUtils.getStatus(
+ TSStatusCode.MEASUREMENT_NAME_CONFLICT,
+ String.format(
+ "The measurements %s and %s share the same lower
case when auto detecting type, please check",
+ lowerCase2OriginalMap.get(fieldName),
measurement)));
+ }
});
}
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/view/AddViewColumnProcedure.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/view/AddViewColumnProcedure.java
index 84e4025548d..5418822aafb 100644
---
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/view/AddViewColumnProcedure.java
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/view/AddViewColumnProcedure.java
@@ -23,7 +23,6 @@ import org.apache.iotdb.common.rpc.thrift.TSStatus;
import org.apache.iotdb.commons.exception.IoTDBException;
import org.apache.iotdb.commons.schema.table.TreeViewSchema;
import org.apache.iotdb.commons.schema.table.column.FieldColumnSchema;
-import org.apache.iotdb.commons.schema.table.column.TsTableColumnCategory;
import org.apache.iotdb.commons.schema.table.column.TsTableColumnSchema;
import
org.apache.iotdb.confignode.persistence.schema.TreeDeviceViewFieldDetector;
import org.apache.iotdb.confignode.procedure.env.ConfigNodeProcedureEnv;
@@ -36,10 +35,11 @@ import org.apache.tsfile.enums.TSDataType;
import java.io.DataOutputStream;
import java.io.IOException;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
-import java.util.stream.Collectors;
+import java.util.Set;
public class AddViewColumnProcedure extends AddTableColumnProcedure {
public AddViewColumnProcedure(final boolean isGeneratedByPipe) {
@@ -58,19 +58,19 @@ public class AddViewColumnProcedure extends
AddTableColumnProcedure {
@Override
protected void columnCheck(final ConfigNodeProcedureEnv env) {
super.columnCheck(env);
- final Map<String, FieldColumnSchema> fields2Detect =
- addedColumnList.stream()
- .filter(
- columnSchema ->
- columnSchema.getColumnCategory() ==
TsTableColumnCategory.FIELD
- && columnSchema.getDataType() == TSDataType.UNKNOWN)
- .collect(
- Collectors.toMap(
- fieldColumnSchema ->
-
Objects.nonNull(TreeViewSchema.getOriginalName(fieldColumnSchema))
- ? TreeViewSchema.getOriginalName(fieldColumnSchema)
- : fieldColumnSchema.getColumnName(),
- FieldColumnSchema.class::cast));
+
+ final Map<String, Set<FieldColumnSchema>> fields2Detect = new HashMap<>();
+ for (final TsTableColumnSchema schema : addedColumnList) {
+ if (!(schema instanceof FieldColumnSchema) || schema.getDataType() !=
TSDataType.UNKNOWN) {
+ continue;
+ }
+ final String key = TreeViewSchema.getSourceName(schema);
+ if (!fields2Detect.containsKey(key)) {
+ fields2Detect.put(key, new HashSet<>());
+ }
+ fields2Detect.get(key).add((FieldColumnSchema) schema);
+ }
+
if (!fields2Detect.isEmpty()) {
final TSStatus status =
new TreeDeviceViewFieldDetector(env.getConfigManager(), table,
fields2Detect)
diff --git
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanSerDeTest.java
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanSerDeTest.java
index 451b820269a..1505640ff90 100644
---
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanSerDeTest.java
+++
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/consensus/request/ConfigPhysicalPlanSerDeTest.java
@@ -1248,7 +1248,7 @@ public class ConfigPhysicalPlanSerDeTest {
preCreateTablePlan0.getTable().getColumnNum(),
preCreateTablePlan1.getTable().getColumnNum());
Assert.assertEquals(
- preCreateTablePlan0.getTable().getIdNums(),
preCreateTablePlan1.getTable().getIdNums());
+ preCreateTablePlan0.getTable().getTagNum(),
preCreateTablePlan1.getTable().getTagNum());
}
@Test
@@ -1272,7 +1272,7 @@ public class ConfigPhysicalPlanSerDeTest {
preCreateTableViewPlan0.getTable().getColumnNum(),
preCreateTablePlan1.getTable().getColumnNum());
Assert.assertEquals(
- preCreateTableViewPlan0.getTable().getIdNums(),
preCreateTablePlan1.getTable().getIdNums());
+ preCreateTableViewPlan0.getTable().getTagNum(),
preCreateTablePlan1.getTable().getTagNum());
Assert.assertEquals(preCreateTableViewPlan0.getStatus(),
preCreateTablePlan1.getStatus());
}
@@ -1929,8 +1929,8 @@ public class ConfigPhysicalPlanSerDeTest {
pipeCreateTableOrViewPlan0.getTable().getColumnNum(),
pipeCreateTableOrViewPlan1.getTable().getColumnNum());
Assert.assertEquals(
- pipeCreateTableOrViewPlan0.getTable().getIdNums(),
- pipeCreateTableOrViewPlan1.getTable().getIdNums());
+ pipeCreateTableOrViewPlan0.getTable().getTagNum(),
+ pipeCreateTableOrViewPlan1.getTable().getTagNum());
}
@Test
diff --git
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTreeTest.java
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTreeTest.java
index 2ea3a0bc434..73fe77e40e7 100644
---
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTreeTest.java
+++
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTreeTest.java
@@ -385,7 +385,7 @@ public class ConfigMTreeTest {
assertEquals(1, tables.size());
final TsTable table = tables.get(0);
assertEquals("table" + i, table.getTableName());
- assertEquals(1, table.getIdNums());
+ assertEquals(1, table.getTagNum());
assertEquals(4, table.getColumnNum());
}
}
diff --git
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/pipe/receiver/PipeEnrichedProcedureTest.java
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/pipe/receiver/PipeEnrichedProcedureTest.java
index ff5b0782166..53d025d6b2f 100644
---
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/pipe/receiver/PipeEnrichedProcedureTest.java
+++
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/pipe/receiver/PipeEnrichedProcedureTest.java
@@ -414,7 +414,7 @@ public class PipeEnrichedProcedureTest {
createTableProcedure.getTable().getColumnNum(),
deserializedProcedure.getTable().getColumnNum());
Assert.assertEquals(
- createTableProcedure.getTable().getIdNums(),
deserializedProcedure.getTable().getIdNums());
+ createTableProcedure.getTable().getTagNum(),
deserializedProcedure.getTable().getTagNum());
}
@Test
@@ -617,8 +617,8 @@ public class PipeEnrichedProcedureTest {
createTableViewProcedure.getTable().getColumnNum(),
deserializedProcedure.getTable().getColumnNum());
Assert.assertEquals(
- createTableViewProcedure.getTable().getIdNums(),
- deserializedProcedure.getTable().getIdNums());
+ createTableViewProcedure.getTable().getTagNum(),
+ deserializedProcedure.getTable().getTagNum());
}
@Test
diff --git
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/table/CreateTableProcedureTest.java
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/table/CreateTableProcedureTest.java
index 2126f41f704..fab1bfb2660 100644
---
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/table/CreateTableProcedureTest.java
+++
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/table/CreateTableProcedureTest.java
@@ -68,6 +68,6 @@ public class CreateTableProcedureTest {
createTableProcedure.getTable().getColumnNum(),
deserializedProcedure.getTable().getColumnNum());
Assert.assertEquals(
- createTableProcedure.getTable().getIdNums(),
deserializedProcedure.getTable().getIdNums());
+ createTableProcedure.getTable().getTagNum(),
deserializedProcedure.getTable().getTagNum());
}
}
diff --git
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/table/CreateTableViewProcedureTest.java
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/table/CreateTableViewProcedureTest.java
index cf7372386e3..8d89fe58df5 100644
---
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/table/CreateTableViewProcedureTest.java
+++
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/table/CreateTableViewProcedureTest.java
@@ -69,7 +69,7 @@ public class CreateTableViewProcedureTest {
createTableViewProcedure.getTable().getColumnNum(),
deserializedProcedure.getTable().getColumnNum());
Assert.assertEquals(
- createTableViewProcedure.getTable().getIdNums(),
- deserializedProcedure.getTable().getIdNums());
+ createTableViewProcedure.getTable().getTagNum(),
+ deserializedProcedure.getTable().getTagNum());
}
}
diff --git
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/table/view/CreateTableViewProcedureTest.java
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/table/view/CreateTableViewProcedureTest.java
index 4a20d65befb..0fb0d344356 100644
---
a/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/table/view/CreateTableViewProcedureTest.java
+++
b/iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/procedure/impl/schema/table/view/CreateTableViewProcedureTest.java
@@ -70,7 +70,7 @@ public class CreateTableViewProcedureTest {
createTableViewProcedure.getTable().getColumnNum(),
deserializedProcedure.getTable().getColumnNum());
Assert.assertEquals(
- createTableViewProcedure.getTable().getIdNums(),
- deserializedProcedure.getTable().getIdNums());
+ createTableViewProcedure.getTable().getTagNum(),
+ deserializedProcedure.getTable().getTagNum());
}
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/TableDeviceQuerySource.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/TableDeviceQuerySource.java
index a23ce8bb8e3..b3d0cd80be2 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/TableDeviceQuerySource.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/schema/source/TableDeviceQuerySource.java
@@ -218,7 +218,7 @@ public class TableDeviceQuerySource implements
ISchemaSource<IDeviceSchemaInfo>
!TreeViewSchema.isTreeViewTable(table)
? new String[] {PATH_ROOT, database, tableName}
: DataNodeTreeViewSchemaUtils.getPatternNodes(table),
- DataNodeTableCache.getInstance().getTable(database,
tableName).getIdNums(),
+ DataNodeTableCache.getInstance().getTable(database,
tableName).getTagNum(),
tagDeterminedPredicateList,
TreeViewSchema.isRestrict(table));
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
index eccfc710069..610da9375b8 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
@@ -213,11 +213,13 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
+import java.util.Set;
import java.util.function.Predicate;
import static
org.apache.iotdb.commons.conf.IoTDBConstant.MAX_DATABASE_NAME_LENGTH;
@@ -500,6 +502,7 @@ public class TableConfigTaskVisitor extends
AstVisitor<IConfigTask, MPPQueryCont
// TODO: Place the check at statement analyzer
boolean hasTimeColumn = false;
+ final Set<String> sourceNameSet = new HashSet<>();
for (final ColumnDefinition columnDefinition : node.getElements()) {
final TsTableColumnCategory category =
columnDefinition.getColumnCategory();
final String columnName = columnDefinition.getName().getValue();
@@ -514,7 +517,7 @@ public class TableConfigTaskVisitor extends
AstVisitor<IConfigTask, MPPQueryCont
throw new SemanticException(
String.format("Columns in table shall not share the same name
%s.", columnName));
}
- table.addColumnSchema(
+ final TsTableColumnSchema schema =
TableHeaderSchemaValidator.generateColumnSchema(
category,
columnName,
@@ -523,7 +526,14 @@ public class TableConfigTaskVisitor extends
AstVisitor<IConfigTask, MPPQueryCont
columnDefinition instanceof ViewFieldDefinition
&& Objects.nonNull(((ViewFieldDefinition)
columnDefinition).getFrom())
? ((ViewFieldDefinition)
columnDefinition).getFrom().getValue()
- : null));
+ : null);
+ if (!sourceNameSet.add(TreeViewSchema.getSourceName(schema))) {
+ throw new SemanticException(
+ String.format(
+ "The duplicated source measurement %s is unsupported yet.",
+ TreeViewSchema.getSourceName(schema)));
+ }
+ table.addColumnSchema(schema);
}
return new Pair<>(database, table);
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java
index 451e64ca085..0d2c719373c 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/parser/ASTVisitor.java
@@ -4627,10 +4627,22 @@ public class ASTVisitor extends
IoTDBSqlParserBaseVisitor<Statement> {
public ColumnDefinition parseViewColumnDefinition(
final IoTDBSqlParser.ViewColumnDefinitionContext ctx) {
- return Objects.nonNull(ctx.FROM())
+ final Identifier rawColumnName =
+ new Identifier(parseIdentifier(ctx.identifier().get(0).getText()));
+ final Identifier columnName = lowerIdentifier(rawColumnName);
+ final TsTableColumnCategory columnCategory =
getColumnCategory(ctx.columnCategory);
+ Identifier originalMeasurement = null;
+
+ if (Objects.nonNull(ctx.FROM())) {
+ originalMeasurement = new
Identifier(parseIdentifier(ctx.original_measurement.getText()));
+ } else if (columnCategory == FIELD && !columnName.equals(rawColumnName)) {
+ originalMeasurement = rawColumnName;
+ }
+
+ return columnCategory == FIELD
? new ViewFieldDefinition(
null,
- lowerIdentifier(new
Identifier(parseIdentifier(ctx.identifier().get(0).getText()))),
+ columnName,
Objects.nonNull(ctx.type())
? parseGenericType((IoTDBSqlParser.GenericTypeContext)
ctx.type())
: null,
@@ -4638,14 +4650,14 @@ public class ASTVisitor extends
IoTDBSqlParserBaseVisitor<Statement> {
ctx.comment() == null
? null
: parseStringLiteral(ctx.comment().STRING_LITERAL().getText()),
- lowerIdentifier(new
Identifier(parseIdentifier(ctx.original_measurement.getText()))))
+ originalMeasurement)
: new ColumnDefinition(
null,
- lowerIdentifier(new
Identifier(parseIdentifier(ctx.identifier().get(0).getText()))),
+ columnName,
Objects.nonNull(ctx.type())
? parseGenericType((IoTDBSqlParser.GenericTypeContext)
ctx.type())
: null,
- getColumnCategory(ctx.columnCategory),
+ columnCategory,
null,
ctx.comment() == null
? null
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/SchemaPredicateUtil.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/SchemaPredicateUtil.java
index 99fabf4cd60..0620f3b5383 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/SchemaPredicateUtil.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/SchemaPredicateUtil.java
@@ -223,7 +223,7 @@ public class SchemaPredicateUtil {
final List<Map<Integer, List<SchemaFilter>>> index2FilterMapList,
final TsTable tableInstance) {
final List<Integer> selectedExpressionCases = new ArrayList<>();
- final int idCount = tableInstance.getIdNums();
+ final int idCount = tableInstance.getTagNum();
for (int i = 0; i < index2FilterMapList.size(); i++) {
final Map<Integer, List<SchemaFilter>> filterMap =
index2FilterMapList.get(i);
if (filterMap.size() == idCount
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableDeviceSchemaFetcher.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableDeviceSchemaFetcher.java
index 468ab424c85..61f8689e7ec 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableDeviceSchemaFetcher.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableDeviceSchemaFetcher.java
@@ -133,7 +133,7 @@ public class TableDeviceSchemaFetcher {
final List<ColumnHeader> columnHeaderList =
coordinator.getQueryExecution(queryId).getDatasetHeader().getColumnHeaders();
- final int idLength = DataNodeTableCache.getInstance().getTable(database,
table).getIdNums();
+ final int idLength = DataNodeTableCache.getInstance().getTable(database,
table).getTagNum();
final Map<IDeviceID, Map<String, Binary>> fetchedDeviceSchema = new
HashMap<>();
while (coordinator.getQueryExecution(queryId).hasNextResult()) {
@@ -347,7 +347,7 @@ public class TableDeviceSchemaFetcher {
final List<IDeviceID> fetchPaths,
final boolean isDirectDeviceQuery,
final MPPQueryContext queryContext) {
- final String[] idValues = new String[tableInstance.getIdNums()];
+ final String[] idValues = new String[tableInstance.getTagNum()];
for (final List<SchemaFilter> schemaFilters : idFilters.values()) {
final TagFilter tagFilter = (TagFilter) schemaFilters.get(0);
final SchemaFilter childFilter = tagFilter.getChild();
@@ -534,7 +534,7 @@ public class TableDeviceSchemaFetcher {
final List<DeviceEntry> deviceEntryList) {
final Column[] columns = tsBlock.getValueColumns();
for (int i = 0; i < tsBlock.getPositionCount(); i++) {
- final String[] nodes = new String[tableInstance.getIdNums() + 1];
+ final String[] nodes = new String[tableInstance.getTagNum() + 1];
final Map<String, Binary> attributeMap = new HashMap<>();
constructNodsArrayAndAttributeMap(
attributeMap,
@@ -566,7 +566,7 @@ public class TableDeviceSchemaFetcher {
final Map<String, List<DeviceEntry>> deviceEntryMap) {
final Column[] columns = tsBlock.getValueColumns();
for (int i = 0; i < tsBlock.getPositionCount(); i++) {
- final String[] nodes = new String[tableInstance.getIdNums()];
+ final String[] nodes = new String[tableInstance.getTagNum()];
constructNodsArrayAndAttributeMap(
Collections.emptyMap(), nodes, null, columnHeaderList, columns,
tableInstance, i);
final IDeviceID deviceID =
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/ViewFieldDefinition.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/ViewFieldDefinition.java
index f23144b7f2b..376a8634f8b 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/ViewFieldDefinition.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/ViewFieldDefinition.java
@@ -36,7 +36,7 @@ public class ViewFieldDefinition extends ColumnDefinition {
final DataType type,
final @Nullable String charsetName,
final @Nullable String comment,
- final Identifier from) {
+ final @Nullable Identifier from) {
super(location, name, type, TsTableColumnCategory.FIELD, charsetName,
comment);
this.from = from;
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
index 2a9988c34c1..6e0f789b767 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/sql/parser/AstBuilder.java
@@ -616,23 +616,32 @@ public class AstBuilder extends
RelationalSqlBaseVisitor<Node> {
@Override
public Node visitViewColumnDefinition(final
RelationalSqlParser.ViewColumnDefinitionContext ctx) {
- return Objects.nonNull(ctx.FROM()) || Objects.nonNull(ctx.FIELD())
+ final Identifier rawColumnName = (Identifier)
visit(ctx.identifier().get(0));
+ final Identifier columnName = lowerIdentifier(rawColumnName);
+ final TsTableColumnCategory columnCategory =
getColumnCategory(ctx.columnCategory);
+ Identifier originalMeasurement = null;
+
+ if (Objects.nonNull(ctx.FROM())) {
+ originalMeasurement = (Identifier) visit(ctx.original_measurement);
+ } else if (columnCategory == FIELD && !columnName.equals(rawColumnName)) {
+ originalMeasurement = rawColumnName;
+ }
+
+ return columnCategory == FIELD
? new ViewFieldDefinition(
getLocation(ctx),
- lowerIdentifier((Identifier) visit(ctx.identifier().get(0))),
+ columnName,
Objects.nonNull(ctx.type()) ? (DataType) visit(ctx.type()) : null,
null,
ctx.comment() == null
? null
: ((StringLiteral) visit(ctx.comment().string())).getValue(),
- Objects.nonNull(ctx.FROM())
- ? lowerIdentifier((Identifier) visit(ctx.original_measurement))
- : null)
+ originalMeasurement)
: new ColumnDefinition(
getLocation(ctx),
- lowerIdentifier((Identifier) visit(ctx.identifier().get(0))),
+ columnName,
Objects.nonNull(ctx.type()) ? (DataType) visit(ctx.type()) : null,
- getColumnCategory(ctx.columnCategory),
+ columnCategory,
null,
ctx.comment() == null
? null
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TreeViewSchema.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TreeViewSchema.java
index 39fc5d5e23c..eea48fd2aee 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TreeViewSchema.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TreeViewSchema.java
@@ -26,6 +26,8 @@ import org.apache.iotdb.commons.path.PathPatternUtil;
import org.apache.iotdb.commons.schema.table.column.TsTableColumnSchema;
import org.apache.iotdb.rpc.TSStatusCode;
+import java.util.Objects;
+
public class TreeViewSchema {
public static final String ORIGINAL_NAME = "__original_name";
public static final String TREE_PATH_PATTERN = "__tree_path_pattern";
@@ -61,6 +63,12 @@ public class TreeViewSchema {
return partialPath;
}
+ public static String getSourceName(final TsTableColumnSchema schema) {
+ return Objects.nonNull(TreeViewSchema.getOriginalName(schema))
+ ? TreeViewSchema.getOriginalName(schema)
+ : schema.getColumnName();
+ }
+
public static String getOriginalName(final TsTableColumnSchema schema) {
return schema.getProps().get(ORIGINAL_NAME);
}
diff --git
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java
index 5a89192971d..aa29ea6d427 100644
---
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java
+++
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java
@@ -218,7 +218,7 @@ public class TsTable {
}
}
- public int getIdNums() {
+ public int getTagNum() {
readWriteLock.readLock().lock();
try {
return idNums;