You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ji...@apache.org on 2019/06/25 14:46:35 UTC

[incubator-iotdb] branch feature_prepared_statement created (now a8f58b6)

This is an automated email from the ASF dual-hosted git repository.

jiangtian pushed a change to branch feature_prepared_statement
in repository https://gitbox.apache.org/repos/asf/incubator-iotdb.git.


      at a8f58b6  add prepared statement

This branch includes the following new commits:

     new a8f58b6  add prepared statement

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[incubator-iotdb] 01/01: add prepared statement

Posted by ji...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

jiangtian pushed a commit to branch feature_prepared_statement
in repository https://gitbox.apache.org/repos/asf/incubator-iotdb.git

commit a8f58b65d4f13840baaf6a3f5c671cc97746a7fb
Author: 江天 <jt...@163.com>
AuthorDate: Tue Jun 25 22:44:27 2019 +0800

    add prepared statement
---
 .../org/apache/iotdb/db/service/TSServiceImpl.java |  20 +++
 .../iotdb/db/integration/IoTDBPreparedStmtIT.java  | 186 +++++++++++++++++++++
 .../org/apache/iotdb/jdbc/IoTDBConnection.java     |   5 +-
 .../jdbc/IoTDBPreparedInsertionStatement.java      |  57 +++++++
 ...eStatement.java => IoTDBPreparedStatement.java} |  11 +-
 .../java/org/apache/iotdb/jdbc/IoTDBStatement.java |   2 +-
 ...ntTest.java => IoTDBPreparedStatementTest.java} |  32 ++--
 service-rpc/src/main/thrift/rpc.thrift             |   9 +
 8 files changed, 301 insertions(+), 21 deletions(-)

diff --git a/iotdb/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java b/iotdb/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
index 6fe08c8..0458f3a 100644
--- a/iotdb/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
+++ b/iotdb/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
@@ -52,6 +52,7 @@ import org.apache.iotdb.db.qp.QueryProcessor;
 import org.apache.iotdb.db.qp.executor.OverflowQPExecutor;
 import org.apache.iotdb.db.qp.logical.Operator;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
+import org.apache.iotdb.db.qp.physical.crud.InsertPlan;
 import org.apache.iotdb.db.qp.physical.crud.QueryPlan;
 import org.apache.iotdb.db.qp.physical.sys.AuthorPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
@@ -74,6 +75,7 @@ import org.apache.iotdb.service.rpc.thrift.TSFetchResultsResp;
 import org.apache.iotdb.service.rpc.thrift.TSGetTimeZoneResp;
 import org.apache.iotdb.service.rpc.thrift.TSHandleIdentifier;
 import org.apache.iotdb.service.rpc.thrift.TSIService;
+import org.apache.iotdb.service.rpc.thrift.TSInsertionReq;
 import org.apache.iotdb.service.rpc.thrift.TSOpenSessionReq;
 import org.apache.iotdb.service.rpc.thrift.TSOpenSessionResp;
 import org.apache.iotdb.service.rpc.thrift.TSOperationHandle;
@@ -948,5 +950,23 @@ public class TSServiceImpl implements TSIService.Iface, ServerContext {
     return properties;
   }
 
+  @Override
+  public TSExecuteStatementResp executeInsertion(TSInsertionReq req) {
+    if (!checkLogin()) {
+      LOGGER.info(INFO_NOT_LOGIN, IoTDBConstant.GLOBAL_DB_NAME);
+      return getTSExecuteStatementResp(TS_StatusCode.ERROR_STATUS, ERROR_NOT_LOGIN);
+    }
+    InsertPlan plan = new InsertPlan();
+    plan.setTime(req.getTimestamp());
+    plan.setDeviceId(req.getDeviceId());
+    plan.setMeasurements(req.getMeasurements().toArray(new String[0]));
+    plan.setValues(req.getValues().toArray(new String[0]));
+    try {
+      return executeUpdateStatement(plan);
+    } catch (Exception e) {
+      LOGGER.info("meet error while executing an insertion into {}", req.getDeviceId(), e);
+      return getTSExecuteStatementResp(TS_StatusCode.ERROR_STATUS, e.getMessage());
+    }
+  }
 }
 
diff --git a/iotdb/src/test/java/org/apache/iotdb/db/integration/IoTDBPreparedStmtIT.java b/iotdb/src/test/java/org/apache/iotdb/db/integration/IoTDBPreparedStmtIT.java
new file mode 100644
index 0000000..47c15ec
--- /dev/null
+++ b/iotdb/src/test/java/org/apache/iotdb/db/integration/IoTDBPreparedStmtIT.java
@@ -0,0 +1,186 @@
+/**
+ * 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.integration;
+
+import static org.junit.Assert.assertEquals;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Arrays;
+import org.apache.iotdb.db.service.IoTDB;
+import org.apache.iotdb.db.utils.EnvironmentUtils;
+import org.apache.iotdb.jdbc.Config;
+import org.apache.iotdb.jdbc.IoTDBPreparedInsertionStatement;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class IoTDBPreparedStmtIT {
+
+  private static IoTDB daemon;
+
+  @BeforeClass
+  public static void setUp() throws Exception {
+    EnvironmentUtils.closeStatMonitor();
+    EnvironmentUtils.closeMemControl();
+    daemon = IoTDB.getInstance();
+    daemon.active();
+    EnvironmentUtils.envSetUp();
+    Class.forName(Config.JDBC_DRIVER_NAME);
+    prepareSeries();
+  }
+
+  @AfterClass
+  public static void tearDown() throws Exception {
+    daemon.stop();
+    EnvironmentUtils.cleanEnv();
+  }
+
+  private static void prepareSeries() throws SQLException {
+    Connection connection;
+    connection = DriverManager
+        .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
+    try {
+      Statement statement = connection.createStatement();
+
+      statement.execute("SET STORAGE GROUP TO root.device1");
+      statement.execute("SET STORAGE GROUP TO root.device2");
+
+      for (int i = 0; i < 5; i++) {
+        statement.execute(String.format("CREATE TIMESERIES root.device1.sensor%d WITH "
+            + "DATATYPE=DOUBLE,ENCODING=PLAIN", i));
+        statement.execute(String.format("CREATE TIMESERIES root.device2.sensor%d WITH "
+            + "DATATYPE=DOUBLE,ENCODING=PLAIN", i));
+      }
+      // to create processors
+      statement.execute("INSERT INTO root.device1(timestamp,sensor0,sensor1,sensor2,sensor3,"
+          + "sensor4) VALUES (1,1,1,1,1,1)");
+      statement.execute("INSERT INTO root.device2(timestamp,sensor0,sensor1,sensor2,sensor3,"
+          + "sensor4) VALUES (1,1,1,1,1,1)");
+      statement.close();
+    } finally {
+      connection.close();
+    }
+  }
+
+  @Test
+  public void testPreparedInsertion() throws SQLException {
+    Connection connection;
+    connection = DriverManager
+        .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
+    IoTDBPreparedInsertionStatement statement = (IoTDBPreparedInsertionStatement) connection.prepareStatement("INSERT");
+
+    try {
+      statement.setDeviceId("root.device1");
+      String[] measurements = new String[5];
+      for (int i = 0; i < 5; i++) {
+        measurements[i] = "sensor" + i;
+      }
+      statement.setMeasurements(Arrays.asList(measurements));
+      String[] values = new String[5];
+      for (int i = 1; i <= 100; i++) {
+        statement.setTimestamp(i);
+        for (int j = 0; j < 5; j ++) {
+          values[j] = String.valueOf(j);
+        }
+        statement.setValues(Arrays.asList(values));
+        statement.execute();
+      }
+      statement.close();
+
+      Statement queryStmt = connection.createStatement();
+      ResultSet resultSet = queryStmt.executeQuery("SELECT * FROM root.device1");
+      int cnt = 0;
+      while (resultSet.next()) {
+        cnt++;
+        assertEquals(cnt, resultSet.getLong(1));
+        for (int i = 0; i < 5; i++) {
+          assertEquals((double) i, resultSet.getDouble(i+2), 0.0001);
+        }
+      }
+      assertEquals(100, cnt);
+      resultSet.close();
+      queryStmt.close();
+    } finally {
+      connection.close();
+    }
+  }
+
+  @Test
+  public void testPreparedInsertionPerf() throws SQLException {
+    Connection connection;
+    connection = DriverManager
+        .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
+    long preparedConsumption;
+    long normalConsumption;
+
+    try {
+      IoTDBPreparedInsertionStatement statement = (IoTDBPreparedInsertionStatement) connection.prepareStatement("INSERT");
+      long startTime = System.currentTimeMillis();
+      statement.setDeviceId("root.device1");
+      String[] measurements = new String[5];
+      for (int i = 0; i < 5; i++) {
+        measurements[i] = "sensor" + i;
+      }
+      statement.setMeasurements(Arrays.asList(measurements));
+      String[] values = new String[5];
+      for (int i = 1000000; i <= 2000000; i++) {
+        statement.setTimestamp(i);
+        for (int j = 0; j < 5; j ++) {
+          values[j] = String.valueOf(j);
+        }
+        statement.setValues(Arrays.asList(values));
+        statement.execute();
+      }
+      statement.close();
+      preparedConsumption = System.currentTimeMillis() - startTime;
+
+    } finally {
+      connection.close();
+    }
+
+    connection = DriverManager
+        .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
+    try {
+      Statement statement = connection.createStatement();
+      long startTime = System.currentTimeMillis();
+      String insertionTemplate = "INSERT INTO root.device2(timestamp,sensor0,sensor1,sensor2,"
+          + "sensor3,sensor4) VALUES (%d,%d,%d,%d,%d,%d)";
+      Object[] args = new Object[6];
+
+      for (int i = 1000000; i <= 2000000; i++) {
+        args[0] = i;
+        for (int j = 0; j < 5; j ++) {
+          args[j+1] = j;
+        }
+        statement.execute(String.format(insertionTemplate, args));
+      }
+      statement.close();
+      normalConsumption = System.currentTimeMillis() - startTime;
+    } finally {
+      connection.close();
+    }
+    System.out.printf("Prepared statement costs %d, normal statement costs %d \n",
+        preparedConsumption, normalConsumption);
+  }
+}
diff --git a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java
index e94b926..e380f5c 100644
--- a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java
@@ -340,7 +340,10 @@ public class IoTDBConnection implements Connection {
 
   @Override
   public PreparedStatement prepareStatement(String sql) throws SQLException {
-    return new IoTDBPrepareStatement(this, client, sessionHandle, sql, zoneId);
+    if (sql.equalsIgnoreCase("INSERT")) {
+      return new IoTDBPreparedInsertionStatement(this, client, sessionHandle, zoneId);
+    }
+    return new IoTDBPreparedStatement(this, client, sessionHandle, sql, zoneId);
   }
 
   @Override
diff --git a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBPreparedInsertionStatement.java b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBPreparedInsertionStatement.java
new file mode 100644
index 0000000..7c7edf8
--- /dev/null
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBPreparedInsertionStatement.java
@@ -0,0 +1,57 @@
+package org.apache.iotdb.jdbc;
+
+import java.sql.SQLException;
+import java.time.ZoneId;
+import java.util.List;
+import org.apache.iotdb.service.rpc.thrift.TSExecuteStatementResp;
+import org.apache.iotdb.service.rpc.thrift.TSIService.Iface;
+import org.apache.iotdb.service.rpc.thrift.TSInsertionReq;
+import org.apache.iotdb.service.rpc.thrift.TS_SessionHandle;
+import org.apache.iotdb.service.rpc.thrift.TS_StatusCode;
+import org.apache.thrift.TException;
+
+public class IoTDBPreparedInsertionStatement extends IoTDBPreparedStatement {
+
+  private long timestamp;
+  private String deviceId;
+  private List<String> measurements;
+  private List<String> values;
+  private TSInsertionReq req = new TSInsertionReq();
+
+  public IoTDBPreparedInsertionStatement(IoTDBConnection connection,
+      Iface client,
+      TS_SessionHandle sessionHandle, ZoneId zoneId) {
+    super(connection, client, sessionHandle, zoneId);
+  }
+
+  @Override
+  public boolean execute() throws SQLException {
+    req.setDeviceId(deviceId);
+    req.setMeasurements(measurements);
+    req.setValues(values);
+    req.setTimestamp(timestamp);
+    try {
+      TSExecuteStatementResp resp = client.executeInsertion(req);
+      return resp.getStatus().getStatusCode() == TS_StatusCode.SUCCESS_STATUS;
+    } catch (TException e) {
+      throw new SQLException(e);
+    }
+  }
+
+  public void setTimestamp(long timestamp) {
+    this.timestamp = timestamp;
+  }
+
+  public void setDeviceId(String deviceId) {
+    this.deviceId = deviceId;
+  }
+
+  public void setMeasurements(List<String> measurements) {
+    this.measurements = measurements;
+  }
+
+  public void setValues(List<String> values) {
+    this.values = values;
+  }
+
+}
diff --git a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBPrepareStatement.java b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBPreparedStatement.java
similarity index 97%
rename from jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBPrepareStatement.java
rename to jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBPreparedStatement.java
index dcbf1b9..6d18fd7 100644
--- a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBPrepareStatement.java
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBPreparedStatement.java
@@ -49,9 +49,9 @@ import java.util.Map;
 import org.apache.iotdb.service.rpc.thrift.TSIService.Iface;
 import org.apache.iotdb.service.rpc.thrift.TS_SessionHandle;
 
-public class IoTDBPrepareStatement extends IoTDBStatement implements PreparedStatement {
+public class IoTDBPreparedStatement extends IoTDBStatement implements PreparedStatement {
 
-  private final String sql;
+  private String sql;
   private static final String METHOD_NOT_SUPPORTED_STRING = "Method not supported";
 
   /**
@@ -59,7 +59,12 @@ public class IoTDBPrepareStatement extends IoTDBStatement implements PreparedSta
    */
   private final Map<Integer, String> parameters = new HashMap<>();
 
-  public IoTDBPrepareStatement(IoTDBConnection connection, Iface client,
+  public IoTDBPreparedStatement(IoTDBConnection connection, Iface client,
+      TS_SessionHandle sessionHandle, ZoneId zoneId) {
+    super(connection, client, sessionHandle, zoneId);
+  }
+
+  public IoTDBPreparedStatement(IoTDBConnection connection, Iface client,
       TS_SessionHandle sessionHandle, String sql,
       ZoneId zoneId) {
     super(connection, client, sessionHandle, zoneId);
diff --git a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBStatement.java b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBStatement.java
index 3c4e298..edb2bce 100644
--- a/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBStatement.java
+++ b/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBStatement.java
@@ -61,7 +61,7 @@ public class IoTDBStatement implements Statement {
   private IoTDBConnection connection;
   private int fetchSize = Config.fetchSize;
   private int queryTimeout = 10;
-  private TSIService.Iface client = null;
+  protected TSIService.Iface client = null;
   private TS_SessionHandle sessionHandle = null;
   private TSOperationHandle operationHandle = null;
   private List<String> batchSQLList;
diff --git a/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBPrepareStatementTest.java b/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBPreparedStatementTest.java
similarity index 88%
rename from jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBPrepareStatementTest.java
rename to jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBPreparedStatementTest.java
index 1b60ec8..ca9928e 100644
--- a/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBPrepareStatementTest.java
+++ b/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBPreparedStatementTest.java
@@ -40,7 +40,7 @@ import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-public class IoTDBPrepareStatementTest {
+public class IoTDBPreparedStatementTest {
 
   @Mock
   TSExecuteStatementResp execStatementResp;
@@ -72,7 +72,7 @@ public class IoTDBPrepareStatementTest {
   @Test
   public void testNonParameterized() throws Exception {
     String sql = "SELECT status, temperature FROM root.ln.wf01.wt01 WHERE temperature < 24 and time > 2017-11-1 0:13:00";
-    IoTDBPrepareStatement ps = new IoTDBPrepareStatement(connection, client, sessHandle, sql,
+    IoTDBPreparedStatement ps = new IoTDBPreparedStatement(connection, client, sessHandle, sql,
         zoneId);
     ps.execute();
 
@@ -88,7 +88,7 @@ public class IoTDBPrepareStatementTest {
   @Test
   public void unusedArgument() throws SQLException {
     String sql = "SELECT status, temperature FROM root.ln.wf01.wt01 WHERE temperature < 24 and time > 2017-11-1 0:13:00";
-    IoTDBPrepareStatement ps = new IoTDBPrepareStatement(connection, client, sessHandle, sql,
+    IoTDBPreparedStatement ps = new IoTDBPreparedStatement(connection, client, sessHandle, sql,
         zoneId);
     ps.setString(1, "123");
     ps.execute();
@@ -98,7 +98,7 @@ public class IoTDBPrepareStatementTest {
   @Test(expected = SQLException.class)
   public void unsetArgument() throws SQLException {
     String sql = "SELECT status, temperature FROM root.ln.wf01.wt01 WHERE temperature < 24 and time > ?";
-    IoTDBPrepareStatement ps = new IoTDBPrepareStatement(connection, client, sessHandle, sql,
+    IoTDBPreparedStatement ps = new IoTDBPreparedStatement(connection, client, sessHandle, sql,
         zoneId);
     ps.execute();
   }
@@ -107,7 +107,7 @@ public class IoTDBPrepareStatementTest {
   @Test
   public void oneIntArgument() throws Exception {
     String sql = "SELECT status, temperature FROM root.ln.wf01.wt01 WHERE temperature < ? and time > 2017-11-1 0:13:00";
-    IoTDBPrepareStatement ps = new IoTDBPrepareStatement(connection, client, sessHandle, sql,
+    IoTDBPreparedStatement ps = new IoTDBPreparedStatement(connection, client, sessHandle, sql,
         zoneId);
     ps.setInt(1, 123);
     ps.execute();
@@ -123,7 +123,7 @@ public class IoTDBPrepareStatementTest {
   @Test
   public void oneLongArgument() throws Exception {
     String sql = "SELECT status, temperature FROM root.ln.wf01.wt01 WHERE temperature < ? and time > 2017-11-1 0:13:00";
-    IoTDBPrepareStatement ps = new IoTDBPrepareStatement(connection, client, sessHandle, sql,
+    IoTDBPreparedStatement ps = new IoTDBPreparedStatement(connection, client, sessHandle, sql,
         zoneId);
     ps.setLong(1, 123);
     ps.execute();
@@ -139,7 +139,7 @@ public class IoTDBPrepareStatementTest {
   @Test
   public void oneFloatArgument() throws Exception {
     String sql = "SELECT status, temperature FROM root.ln.wf01.wt01 WHERE temperature < ? and time > 2017-11-1 0:13:00";
-    IoTDBPrepareStatement ps = new IoTDBPrepareStatement(connection, client, sessHandle, sql,
+    IoTDBPreparedStatement ps = new IoTDBPreparedStatement(connection, client, sessHandle, sql,
         zoneId);
     ps.setFloat(1, 123.133f);
     ps.execute();
@@ -155,7 +155,7 @@ public class IoTDBPrepareStatementTest {
   @Test
   public void oneDoubleArgument() throws Exception {
     String sql = "SELECT status, temperature FROM root.ln.wf01.wt01 WHERE temperature < ? and time > 2017-11-1 0:13:00";
-    IoTDBPrepareStatement ps = new IoTDBPrepareStatement(connection, client, sessHandle, sql,
+    IoTDBPreparedStatement ps = new IoTDBPreparedStatement(connection, client, sessHandle, sql,
         zoneId);
     ps.setDouble(1, 123.456);
     ps.execute();
@@ -171,7 +171,7 @@ public class IoTDBPrepareStatementTest {
   @Test
   public void oneBooleanArgument() throws Exception {
     String sql = "SELECT status, temperature FROM root.ln.wf01.wt01 WHERE temperature < ? and time > 2017-11-1 0:13:00";
-    IoTDBPrepareStatement ps = new IoTDBPrepareStatement(connection, client, sessHandle, sql,
+    IoTDBPreparedStatement ps = new IoTDBPreparedStatement(connection, client, sessHandle, sql,
         zoneId);
     ps.setBoolean(1, false);
     ps.execute();
@@ -187,7 +187,7 @@ public class IoTDBPrepareStatementTest {
   @Test
   public void oneStringArgument() throws Exception {
     String sql = "SELECT status, temperature FROM root.ln.wf01.wt01 WHERE temperature < ? and time > 2017-11-1 0:13:00";
-    IoTDBPrepareStatement ps = new IoTDBPrepareStatement(connection, client, sessHandle, sql,
+    IoTDBPreparedStatement ps = new IoTDBPreparedStatement(connection, client, sessHandle, sql,
         zoneId);
     ps.setString(1, "abcde");
     ps.execute();
@@ -203,7 +203,7 @@ public class IoTDBPrepareStatementTest {
   @Test
   public void oneTimeLongArgument() throws Exception {
     String sql = "SELECT status, temperature FROM root.ln.wf01.wt01 WHERE time > ?";
-    IoTDBPrepareStatement ps = new IoTDBPrepareStatement(connection, client, sessHandle, sql,
+    IoTDBPreparedStatement ps = new IoTDBPreparedStatement(connection, client, sessHandle, sql,
         zoneId);
     ps.setLong(1, 1233);
     ps.execute();
@@ -218,7 +218,7 @@ public class IoTDBPrepareStatementTest {
   @Test
   public void oneTimeTimestampArgument() throws Exception {
     String sql = "SELECT status, temperature FROM root.ln.wf01.wt01 WHERE time > ?";
-    IoTDBPrepareStatement ps = new IoTDBPrepareStatement(connection, client, sessHandle, sql,
+    IoTDBPreparedStatement ps = new IoTDBPreparedStatement(connection, client, sessHandle, sql,
         zoneId);
     ps.setTimestamp(1, Timestamp.valueOf("2017-11-01 00:13:00"));
     ps.execute();
@@ -234,7 +234,7 @@ public class IoTDBPrepareStatementTest {
   @Test
   public void escapingOfStringArgument() throws Exception {
     String sql = "SELECT status, temperature FROM root.ln.wf01.wt01 WHERE status = '134' and temperature = ?";
-    IoTDBPrepareStatement ps = new IoTDBPrepareStatement(connection, client, sessHandle, sql,
+    IoTDBPreparedStatement ps = new IoTDBPreparedStatement(connection, client, sessHandle, sql,
         zoneId);
     ps.setLong(1, 1333);
     ps.execute();
@@ -252,7 +252,7 @@ public class IoTDBPrepareStatementTest {
   public void pastingIntoEscapedQuery() throws Exception {
     String sql = "SELECT status, temperature FROM root.ln.wf01.wt01 WHERE status = '\\044e' || temperature = ?";
 
-    IoTDBPrepareStatement ps = new IoTDBPrepareStatement(connection, client, sessHandle, sql,
+    IoTDBPreparedStatement ps = new IoTDBPreparedStatement(connection, client, sessHandle, sql,
         zoneId);
     ps.setDouble(1, -1323.0);
     ps.execute();
@@ -270,7 +270,7 @@ public class IoTDBPrepareStatementTest {
   public void testInsertStatement1() throws Exception {
     String sql = "INSERT INTO root.ln.wf01.wt01(timestamp,a,b,c,d,e,f) VALUES(?,?,?,?,?,?,?)";
 
-    IoTDBPrepareStatement ps = new IoTDBPrepareStatement(connection, client, sessHandle, sql,
+    IoTDBPreparedStatement ps = new IoTDBPreparedStatement(connection, client, sessHandle, sql,
         zoneId);
     ps.setLong(1, 12324);
     ps.setBoolean(2, false);
@@ -294,7 +294,7 @@ public class IoTDBPrepareStatementTest {
   public void testInsertStatement2() throws Exception {
     String sql = "INSERT INTO root.ln.wf01.wt01(timestamp,a,b,c,d,e,f) VALUES(?,?,?,?,?,?,?)";
 
-    IoTDBPrepareStatement ps = new IoTDBPrepareStatement(connection, client, sessHandle, sql,
+    IoTDBPreparedStatement ps = new IoTDBPreparedStatement(connection, client, sessHandle, sql,
         zoneId);
     ps.setTimestamp(1, Timestamp.valueOf("2017-11-01 00:13:00"));
     ps.setBoolean(2, false);
diff --git a/service-rpc/src/main/thrift/rpc.thrift b/service-rpc/src/main/thrift/rpc.thrift
index 6e857e8..c4ed4e2 100644
--- a/service-rpc/src/main/thrift/rpc.thrift
+++ b/service-rpc/src/main/thrift/rpc.thrift
@@ -248,6 +248,13 @@ struct TSSetTimeZoneResp {
     1: required TS_Status status
 }
 
+struct TSInsertionReq {
+    1: required string deviceId
+    2: required list<string> measurements
+    3: required list<string> values
+    4: required i64 timestamp
+}
+
 struct ServerProperties {
 	1: required string version;
 	2: required list<string> supportedTimeAggregationOperations;
@@ -279,4 +286,6 @@ service TSIService {
 	TSSetTimeZoneResp setTimeZone(1:TSSetTimeZoneReq req);
 	
 	ServerProperties getProperties();
+
+	TSExecuteStatementResp executeInsertion(1:TSInsertionReq req);
 	}