This is an automated email from the ASF dual-hosted git repository.
zyk 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 e7dd6b9060b [IOTDB-5938] Fix select into alias series (#10124)
e7dd6b9060b is described below
commit e7dd6b9060b48c9608a063fd2e6d9fc55ed06277
Author: Marcos_Zyk <[email protected]>
AuthorDate: Mon Jun 12 14:28:31 2023 +0800
[IOTDB-5938] Fix select into alias series (#10124)
---
.../db/it/schema/view/IoTDBAliasSeriesIT.java | 97 ++++++++++++++++++++++
.../it/schema/view/IoTDBCreateAndShowViewIT.java | 1 -
.../iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java | 1 +
.../iotdb/db/mpp/plan/analyze/SelectIntoUtils.java | 18 ++++
4 files changed, 116 insertions(+), 1 deletion(-)
diff --git
a/integration-test/src/test/java/org/apache/iotdb/db/it/schema/view/IoTDBAliasSeriesIT.java
b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/view/IoTDBAliasSeriesIT.java
new file mode 100644
index 00000000000..fa66c77ce80
--- /dev/null
+++
b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/view/IoTDBAliasSeriesIT.java
@@ -0,0 +1,97 @@
+/*
+ * 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.db.it.schema.view;
+
+import org.apache.iotdb.it.env.EnvFactory;
+import org.apache.iotdb.it.framework.IoTDBTestRunner;
+import org.apache.iotdb.itbase.category.ClusterIT;
+import org.apache.iotdb.itbase.category.LocalStandaloneIT;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+@RunWith(IoTDBTestRunner.class)
+@Category({LocalStandaloneIT.class, ClusterIT.class})
+public class IoTDBAliasSeriesIT {
+
+ @Before
+ public void setUp() throws Exception {
+ EnvFactory.getEnv().initClusterEnvironment();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+ try {
+ statement.execute("DELETE DATABASE root.**");
+ } catch (Exception e) {
+ // If database is null, it will throw exception. Do nothing.
+ }
+ }
+ EnvFactory.getEnv().cleanClusterEnvironment();
+ }
+
+ @Test
+ public void testSelectIntoAliasSeries() throws SQLException {
+ try (Connection connection = EnvFactory.getEnv().getConnection();
+ Statement statement = connection.createStatement()) {
+
+ statement.execute("CREATE DATABASE root.db");
+ statement.execute("CREATE DATABASE root.view");
+
+ statement.execute("create timeseries root.db.device.s01 with
datatype=INT32");
+ statement.execute("create timeseries root.db.device.s02 with
datatype=INT32");
+ statement.execute("CREATE VIEW root.view.device.status AS SELECT s01
FROM root.db.device");
+ statement.execute("insert into root.db.device(time,s02) values(1,1)");
+
+ try (ResultSet resultSet =
+ statement.executeQuery("select s02 into root.view.device(status)
from root.db.device")) {
+ StringBuilder stringBuilder = new StringBuilder();
+ if (resultSet.next()) {
+ for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {
+ stringBuilder.append(resultSet.getString(i)).append(",");
+ }
+ Assert.assertEquals(
+ "root.db.device.s02,root.view.device.status,1,",
stringBuilder.toString());
+ }
+ Assert.assertFalse(resultSet.next());
+ }
+ try (ResultSet resultSet = statement.executeQuery("select status from
root.view.device")) {
+ StringBuilder stringBuilder = new StringBuilder();
+ if (resultSet.next()) {
+ for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {
+ stringBuilder.append(resultSet.getString(i)).append(",");
+ }
+ Assert.assertEquals("1,1,", stringBuilder.toString());
+ }
+ Assert.assertFalse(resultSet.next());
+ }
+ }
+ }
+}
diff --git
a/integration-test/src/test/java/org/apache/iotdb/db/it/schema/view/IoTDBCreateAndShowViewIT.java
b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/view/IoTDBCreateAndShowViewIT.java
index ef838404ed4..758ffad2209 100644
---
a/integration-test/src/test/java/org/apache/iotdb/db/it/schema/view/IoTDBCreateAndShowViewIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/db/it/schema/view/IoTDBCreateAndShowViewIT.java
@@ -43,7 +43,6 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-/** This is an example for integration test. */
@RunWith(IoTDBTestRunner.class)
@Category({LocalStandaloneIT.class, ClusterIT.class})
public class IoTDBCreateAndShowViewIT {
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
index dc0775633ae..4d8011df083 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/AnalyzeVisitor.java
@@ -1840,6 +1840,7 @@ public class AnalyzeVisitor extends
StatementVisitor<Analysis, MPPQueryContext>
// fetch schema of target paths
long startTime = System.nanoTime();
ISchemaTree targetSchemaTree = schemaFetcher.fetchSchema(targetPathTree,
null);
+ updateSchemaTreeByViews(analysis, targetSchemaTree);
QueryPlanCostMetricSet.getInstance()
.recordPlanCost(SCHEMA_FETCHER, System.nanoTime() - startTime);
intoPathDescriptor.bindType(targetSchemaTree);
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/SelectIntoUtils.java
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/SelectIntoUtils.java
index ede0384dfcb..6916fea6a29 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/SelectIntoUtils.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/plan/analyze/SelectIntoUtils.java
@@ -21,6 +21,7 @@ package org.apache.iotdb.db.mpp.plan.analyze;
import org.apache.iotdb.commons.path.MeasurementPath;
import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.commons.schema.view.LogicalViewSchema;
import org.apache.iotdb.db.exception.sql.SemanticException;
import org.apache.iotdb.db.mpp.common.schematree.ISchemaTree;
import org.apache.iotdb.db.mpp.plan.expression.Expression;
@@ -137,6 +138,23 @@ public class SelectIntoUtils {
} else {
checkState(actualTargetPaths.size() == 1);
MeasurementPath actualTargetPath = actualTargetPaths.get(0);
+ if (actualTargetPath.getMeasurementSchema().isLogicalView()) {
+ LogicalViewSchema viewSchema =
+ (LogicalViewSchema) actualTargetPath.getMeasurementSchema();
+ if (viewSchema.isWritable()) {
+ MeasurementPath viewSourceSeriesPath =
+ targetSchemaTree
+
.searchMeasurementPaths(viewSchema.getSourcePathIfWritable())
+ .left
+ .get(0);
+ actualTargetPath =
+ new MeasurementPath(targetPath,
viewSourceSeriesPath.getSeriesType());
+
actualTargetPath.setUnderAlignedEntity(viewSourceSeriesPath.isUnderAlignedEntity());
+ } else {
+ throw new SemanticException(
+ String.format("View %s doesn't support data insertion.",
targetPath));
+ }
+ }
if (!TypeInferenceUtils.canAutoCast(sourceColumnType,
actualTargetPath.getSeriesType())) {
throw new SemanticException(
String.format(