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(

Reply via email to