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 1dc47d48e07 Rest Service add FastLastQuery method
1dc47d48e07 is described below

commit 1dc47d48e074211940c1e5a0d9ef8440eabacbcf
Author: CloudWise-Lukemiao <[email protected]>
AuthorDate: Thu Jun 26 09:19:39 2025 +0800

    Rest Service add FastLastQuery method
---
 .../protocol/rest/v2/handler/FastLastHandler.java  |  71 +++++++
 .../rest/v2/handler/RequestValidationHandler.java  |   8 +
 .../protocol/rest/v2/impl/RestApiServiceImpl.java  | 230 ++++++++++++++++-----
 .../openapi/src/main/openapi3/iotdb_rest_v2.yaml   |  25 +++
 4 files changed, 278 insertions(+), 56 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v2/handler/FastLastHandler.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v2/handler/FastLastHandler.java
new file mode 100644
index 00000000000..59ebb57ffbb
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v2/handler/FastLastHandler.java
@@ -0,0 +1,71 @@
+/*
+ * 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.protocol.rest.v2.handler;
+
+import org.apache.iotdb.common.rpc.thrift.TSStatus;
+import org.apache.iotdb.db.protocol.rest.v2.model.ExecutionStatus;
+import org.apache.iotdb.db.protocol.rest.v2.model.PrefixPathList;
+import org.apache.iotdb.db.protocol.session.IClientSession;
+import org.apache.iotdb.rpc.TSStatusCode;
+import org.apache.iotdb.service.rpc.thrift.TSLastDataQueryReq;
+
+import javax.ws.rs.core.Response;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+public class FastLastHandler {
+
+  public static TSLastDataQueryReq createTSLastDataQueryReq(
+      IClientSession clientSession, PrefixPathList prefixPathList) {
+    TSLastDataQueryReq req = new TSLastDataQueryReq();
+    req.sessionId = clientSession.getId();
+    req.paths =
+        Collections.singletonList(String.join(".", 
prefixPathList.getPrefixPaths()) + ".**");
+    req.time = Long.MIN_VALUE;
+    req.setLegalPathNodes(true);
+    return req;
+  }
+
+  public static Response buildErrorResponse(TSStatusCode statusCode) {
+    return Response.ok()
+        .entity(
+            new org.apache.iotdb.db.protocol.rest.model.ExecutionStatus()
+                .code(statusCode.getStatusCode())
+                .message(statusCode.name()))
+        .build();
+  }
+
+  public static Response buildExecutionStatusResponse(TSStatus status) {
+    return Response.ok()
+        .entity(new 
ExecutionStatus().code(status.getCode()).message(status.getMessage()))
+        .build();
+  }
+
+  public static void setupTargetDataSet(
+      org.apache.iotdb.db.protocol.rest.v2.model.QueryDataSet dataSet) {
+    dataSet.addExpressionsItem("Timeseries");
+    dataSet.addExpressionsItem("Value");
+    dataSet.addExpressionsItem("DataType");
+    dataSet.addDataTypesItem("TEXT");
+    dataSet.addDataTypesItem("TEXT");
+    dataSet.addDataTypesItem("TEXT");
+    dataSet.setValues(new ArrayList<>());
+    dataSet.setTimestamps(new ArrayList<>());
+  }
+}
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v2/handler/RequestValidationHandler.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v2/handler/RequestValidationHandler.java
index 9a620da64ed..c1fc9c6327f 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v2/handler/RequestValidationHandler.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v2/handler/RequestValidationHandler.java
@@ -20,6 +20,7 @@ package org.apache.iotdb.db.protocol.rest.v2.handler;
 import org.apache.iotdb.db.protocol.rest.v2.model.ExpressionRequest;
 import org.apache.iotdb.db.protocol.rest.v2.model.InsertRecordsRequest;
 import org.apache.iotdb.db.protocol.rest.v2.model.InsertTabletRequest;
+import org.apache.iotdb.db.protocol.rest.v2.model.PrefixPathList;
 import org.apache.iotdb.db.protocol.rest.v2.model.SQL;
 
 import org.apache.commons.lang3.Validate;
@@ -40,6 +41,13 @@ public class RequestValidationHandler {
     }
   }
 
+  public static void validatePrefixPaths(PrefixPathList prefixPathList) {
+    Objects.requireNonNull(prefixPathList.getPrefixPaths(), "prefix_paths 
should not be null");
+    if (prefixPathList.getPrefixPaths().isEmpty()) {
+      throw new IllegalArgumentException("prefix_paths should not be empty");
+    }
+  }
+
   public static void validateInsertTabletRequest(InsertTabletRequest 
insertTabletRequest) {
     Objects.requireNonNull(insertTabletRequest.getTimestamps(), "timestamps 
should not be null");
     Objects.requireNonNull(insertTabletRequest.getIsAligned(), "is_aligned 
should not be null");
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v2/impl/RestApiServiceImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v2/impl/RestApiServiceImpl.java
index 781f2b3b3ab..53699256761 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v2/impl/RestApiServiceImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v2/impl/RestApiServiceImpl.java
@@ -18,23 +18,30 @@
 package org.apache.iotdb.db.protocol.rest.v2.impl;
 
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
+import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.conf.rest.IoTDBRestServiceDescriptor;
 import org.apache.iotdb.db.protocol.rest.handler.AuthorizationHandler;
+import org.apache.iotdb.db.protocol.rest.model.ExecutionStatus;
 import org.apache.iotdb.db.protocol.rest.utils.InsertTabletSortDataUtils;
+import org.apache.iotdb.db.protocol.rest.v2.NotFoundException;
 import org.apache.iotdb.db.protocol.rest.v2.RestApiService;
 import org.apache.iotdb.db.protocol.rest.v2.handler.ExceptionHandler;
 import org.apache.iotdb.db.protocol.rest.v2.handler.ExecuteStatementHandler;
+import org.apache.iotdb.db.protocol.rest.v2.handler.FastLastHandler;
 import org.apache.iotdb.db.protocol.rest.v2.handler.QueryDataSetHandler;
 import org.apache.iotdb.db.protocol.rest.v2.handler.RequestValidationHandler;
 import 
org.apache.iotdb.db.protocol.rest.v2.handler.StatementConstructionHandler;
-import org.apache.iotdb.db.protocol.rest.v2.model.ExecutionStatus;
 import org.apache.iotdb.db.protocol.rest.v2.model.InsertRecordsRequest;
 import org.apache.iotdb.db.protocol.rest.v2.model.InsertTabletRequest;
+import org.apache.iotdb.db.protocol.rest.v2.model.PrefixPathList;
+import org.apache.iotdb.db.protocol.rest.v2.model.QueryDataSet;
 import org.apache.iotdb.db.protocol.rest.v2.model.SQL;
+import org.apache.iotdb.db.protocol.session.IClientSession;
 import org.apache.iotdb.db.protocol.session.SessionManager;
 import org.apache.iotdb.db.protocol.thrift.OperationType;
+import org.apache.iotdb.db.queryengine.common.SessionInfo;
 import org.apache.iotdb.db.queryengine.plan.Coordinator;
 import org.apache.iotdb.db.queryengine.plan.analyze.ClusterPartitionFetcher;
 import org.apache.iotdb.db.queryengine.plan.analyze.IPartitionFetcher;
@@ -43,21 +50,32 @@ import 
org.apache.iotdb.db.queryengine.plan.analyze.schema.ISchemaFetcher;
 import org.apache.iotdb.db.queryengine.plan.execution.ExecutionResult;
 import org.apache.iotdb.db.queryengine.plan.execution.IQueryExecution;
 import org.apache.iotdb.db.queryengine.plan.parser.StatementGenerator;
-import org.apache.iotdb.db.queryengine.plan.planner.LocalExecutionPlanner;
-import org.apache.iotdb.db.queryengine.plan.relational.sql.parser.SqlParser;
+import 
org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.cache.TableDeviceSchemaCache;
+import 
org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.cache.TableId;
 import org.apache.iotdb.db.queryengine.plan.statement.Statement;
 import org.apache.iotdb.db.queryengine.plan.statement.crud.InsertRowsStatement;
 import 
org.apache.iotdb.db.queryengine.plan.statement.crud.InsertTabletStatement;
-import 
org.apache.iotdb.db.queryengine.plan.statement.metadata.view.CreateTableViewStatement;
+import org.apache.iotdb.db.schemaengine.SchemaEngine;
+import org.apache.iotdb.db.schemaengine.schemaregion.ISchemaRegion;
 import org.apache.iotdb.db.utils.CommonUtils;
 import org.apache.iotdb.db.utils.SetThreadName;
 import org.apache.iotdb.rpc.TSStatusCode;
+import org.apache.iotdb.service.rpc.thrift.TSLastDataQueryReq;
+
+import org.apache.tsfile.common.constant.TsFileConstant;
+import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.file.metadata.IDeviceID;
+import org.apache.tsfile.read.TimeValuePair;
+import org.apache.tsfile.utils.Pair;
 
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.SecurityContext;
 
 import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 
 public class RestApiServiceImpl extends RestApiService {
@@ -83,6 +101,126 @@ public class RestApiServiceImpl extends RestApiService {
         
IoTDBRestServiceDescriptor.getInstance().getConfig().getRestQueryDefaultRowSizeLimit();
   }
 
+  @Override
+  public Response executeFastLastQueryStatement(
+      PrefixPathList prefixPathList, SecurityContext securityContext) {
+    Long queryId = null;
+    Statement statement = null;
+    boolean finish = false;
+    long startTime = System.nanoTime();
+
+    try {
+      RequestValidationHandler.validatePrefixPaths(prefixPathList);
+
+      PartialPath prefixPath =
+          new PartialPath(prefixPathList.getPrefixPaths().toArray(new 
String[0]));
+      final Map<TableId, Map<IDeviceID, Map<String, Pair<TSDataType, 
TimeValuePair>>>> resultMap =
+          new HashMap<>();
+      int sensorNum = 0;
+
+      final String prefixString = prefixPath.toString();
+      for (final ISchemaRegion region : 
SchemaEngine.getInstance().getAllSchemaRegions()) {
+        if (!prefixString.startsWith(region.getDatabaseFullPath())
+            && !region.getDatabaseFullPath().startsWith(prefixString)) {
+          continue;
+        }
+        sensorNum += region.fillLastQueryMap(prefixPath, resultMap);
+      }
+      // Check cache first
+      if (!TableDeviceSchemaCache.getInstance().getLastCache(resultMap)) {
+        IClientSession clientSession = 
SESSION_MANAGER.getCurrSessionAndUpdateIdleTime();
+        TSLastDataQueryReq tsLastDataQueryReq =
+            FastLastHandler.createTSLastDataQueryReq(clientSession, 
prefixPathList);
+        statement = StatementGenerator.createStatement(tsLastDataQueryReq);
+
+        if (ExecuteStatementHandler.validateStatement(statement)) {
+          return 
FastLastHandler.buildErrorResponse(TSStatusCode.EXECUTE_STATEMENT_ERROR);
+        }
+
+        
Optional.ofNullable(authorizationHandler.checkAuthority(securityContext, 
statement))
+            .ifPresent(Response.class::cast);
+
+        queryId = SESSION_MANAGER.requestQueryId();
+        SessionInfo sessionInfo = 
SESSION_MANAGER.getSessionInfo(clientSession);
+
+        ExecutionResult result =
+            COORDINATOR.executeForTreeModel(
+                statement,
+                queryId,
+                sessionInfo,
+                "",
+                partitionFetcher,
+                schemaFetcher,
+                config.getQueryTimeoutThreshold(),
+                true);
+
+        finish = true;
+
+        if (result.status.code != TSStatusCode.SUCCESS_STATUS.getStatusCode()
+            && result.status.code != 
TSStatusCode.REDIRECTION_RECOMMEND.getStatusCode()) {
+          return FastLastHandler.buildExecutionStatusResponse(result.status);
+        }
+
+        IQueryExecution queryExecution = 
COORDINATOR.getQueryExecution(queryId);
+        try (SetThreadName ignored = new 
SetThreadName(result.queryId.getId())) {
+          return QueryDataSetHandler.fillQueryDataSet(
+              queryExecution, statement, defaultQueryRowLimit);
+        }
+      }
+
+      // Cache hit: build response directly
+      QueryDataSet targetDataSet = new QueryDataSet();
+
+      FastLastHandler.setupTargetDataSet(targetDataSet);
+      List<Object> timeseries = new ArrayList<>();
+      List<Object> valueList = new ArrayList<>();
+      List<Object> dataTypeList = new ArrayList<>();
+
+      for (final Map.Entry<TableId, Map<IDeviceID, Map<String, 
Pair<TSDataType, TimeValuePair>>>>
+          result : resultMap.entrySet()) {
+        for (final Map.Entry<IDeviceID, Map<String, Pair<TSDataType, 
TimeValuePair>>>
+            device2MeasurementLastEntry : result.getValue().entrySet()) {
+          final String deviceWithSeparator =
+              device2MeasurementLastEntry.getKey().toString() + 
TsFileConstant.PATH_SEPARATOR;
+          for (final Map.Entry<String, Pair<TSDataType, TimeValuePair>> 
measurementLastEntry :
+              device2MeasurementLastEntry.getValue().entrySet()) {
+            final TimeValuePair tvPair = 
measurementLastEntry.getValue().getRight();
+            valueList.add(tvPair.getValue().getStringValue());
+            dataTypeList.add(tvPair.getValue().getDataType().name());
+            targetDataSet.addTimestampsItem(tvPair.getTimestamp());
+            timeseries.add(deviceWithSeparator + 
measurementLastEntry.getKey());
+          }
+        }
+      }
+      if (!timeseries.isEmpty()) {
+        targetDataSet.addValuesItem(timeseries);
+        targetDataSet.addValuesItem(valueList);
+        targetDataSet.addValuesItem(dataTypeList);
+      }
+      return Response.ok().entity(targetDataSet).build();
+
+    } catch (Exception e) {
+      finish = true;
+      return 
Response.ok().entity(ExceptionHandler.tryCatchException(e)).build();
+    } finally {
+      long costTime = System.nanoTime() - startTime;
+      Optional.ofNullable(statement)
+          .ifPresent(
+              s ->
+                  CommonUtils.addStatementExecutionLatency(
+                      OperationType.EXECUTE_QUERY_STATEMENT, 
s.getType().name(), costTime));
+      if (queryId != null) {
+        if (finish) {
+          long executionTime = COORDINATOR.getTotalExecutionTime(queryId);
+          CommonUtils.addQueryLatency(
+              statement != null ? statement.getType() : null,
+              executionTime > 0 ? executionTime : costTime);
+        }
+        COORDINATOR.cleanupQueryExecution(queryId);
+      }
+    }
+  }
+
   @Override
   public Response executeNonQueryStatement(SQL sql, SecurityContext 
securityContext) {
     Long queryId = null;
@@ -95,7 +233,7 @@ public class RestApiServiceImpl extends RestApiService {
       if (statement == null) {
         return Response.ok()
             .entity(
-                new org.apache.iotdb.db.protocol.rest.model.ExecutionStatus()
+                new ExecutionStatus()
                     .code(TSStatusCode.SQL_PARSE_ERROR.getStatusCode())
                     .message("This operation type is not supported"))
             .build();
@@ -103,42 +241,27 @@ public class RestApiServiceImpl extends RestApiService {
       if (!ExecuteStatementHandler.validateStatement(statement)) {
         return Response.ok()
             .entity(
-                new org.apache.iotdb.db.protocol.rest.model.ExecutionStatus()
+                new ExecutionStatus()
                     .code(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode())
                     .message(TSStatusCode.EXECUTE_STATEMENT_ERROR.name()))
             .build();
       }
 
-      final ExecutionResult result;
-      queryId = SESSION_MANAGER.requestQueryId();
-      if (statement instanceof CreateTableViewStatement) {
-        result =
-            COORDINATOR.executeForTableModel(
-                ((CreateTableViewStatement) statement).getCreateTableView(),
-                new SqlParser(),
-                SESSION_MANAGER.getCurrSessionAndUpdateIdleTime(),
-                queryId,
-                
SESSION_MANAGER.getSessionInfo(SESSION_MANAGER.getCurrSession()),
-                sql.getSql(),
-                LocalExecutionPlanner.getInstance().metadata,
-                config.getQueryTimeoutThreshold(),
-                false);
-      } else {
-        Response response = 
authorizationHandler.checkAuthority(securityContext, statement);
-        if (response != null) {
-          return response;
-        }
-        result =
-            COORDINATOR.executeForTreeModel(
-                statement,
-                queryId,
-                
SESSION_MANAGER.getSessionInfo(SESSION_MANAGER.getCurrSession()),
-                sql.getSql(),
-                partitionFetcher,
-                schemaFetcher,
-                config.getQueryTimeoutThreshold(),
-                false);
+      Response response = authorizationHandler.checkAuthority(securityContext, 
statement);
+      if (response != null) {
+        return response;
       }
+      queryId = SESSION_MANAGER.requestQueryId();
+      ExecutionResult result =
+          COORDINATOR.executeForTreeModel(
+              statement,
+              queryId,
+              SESSION_MANAGER.getSessionInfo(SESSION_MANAGER.getCurrSession()),
+              sql.getSql(),
+              partitionFetcher,
+              schemaFetcher,
+              config.getQueryTimeoutThreshold(),
+              false);
       finish = true;
       return responseGenerateHelper(result);
     } catch (Exception e) {
@@ -146,12 +269,9 @@ public class RestApiServiceImpl extends RestApiService {
       return 
Response.ok().entity(ExceptionHandler.tryCatchException(e)).build();
     } finally {
       long costTime = System.nanoTime() - startTime;
-      Optional.ofNullable(statement)
-          .ifPresent(
-              s -> {
-                CommonUtils.addStatementExecutionLatency(
-                    OperationType.EXECUTE_NON_QUERY_PLAN, s.getType().name(), 
costTime);
-              });
+      if (statement != null)
+        CommonUtils.addStatementExecutionLatency(
+            OperationType.EXECUTE_NON_QUERY_PLAN, statement.getType().name(), 
costTime);
       if (queryId != null) {
         if (finish) {
           long executionTime = COORDINATOR.getTotalExecutionTime(queryId);
@@ -176,7 +296,7 @@ public class RestApiServiceImpl extends RestApiService {
       if (statement == null) {
         return Response.ok()
             .entity(
-                new org.apache.iotdb.db.protocol.rest.model.ExecutionStatus()
+                new ExecutionStatus()
                     .code(TSStatusCode.SQL_PARSE_ERROR.getStatusCode())
                     .message("This operation type is not supported"))
             .build();
@@ -185,7 +305,7 @@ public class RestApiServiceImpl extends RestApiService {
       if (ExecuteStatementHandler.validateStatement(statement)) {
         return Response.ok()
             .entity(
-                new org.apache.iotdb.db.protocol.rest.model.ExecutionStatus()
+                new ExecutionStatus()
                     .code(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode())
                     .message(TSStatusCode.EXECUTE_STATEMENT_ERROR.name()))
             .build();
@@ -232,10 +352,9 @@ public class RestApiServiceImpl extends RestApiService {
       long costTime = System.nanoTime() - startTime;
       Optional.ofNullable(statement)
           .ifPresent(
-              s -> {
-                CommonUtils.addStatementExecutionLatency(
-                    OperationType.EXECUTE_QUERY_STATEMENT, s.getType().name(), 
costTime);
-              });
+              s ->
+                  CommonUtils.addStatementExecutionLatency(
+                      OperationType.EXECUTE_QUERY_STATEMENT, 
s.getType().name(), costTime));
       if (queryId != null) {
         if (finish) {
           long executionTime = COORDINATOR.getTotalExecutionTime(queryId);
@@ -249,7 +368,8 @@ public class RestApiServiceImpl extends RestApiService {
 
   @Override
   public Response insertRecords(
-      InsertRecordsRequest insertRecordsRequest, SecurityContext 
securityContext) {
+      InsertRecordsRequest insertRecordsRequest, SecurityContext 
securityContext)
+      throws NotFoundException {
     Long queryId = null;
     long startTime = System.nanoTime();
     InsertRowsStatement insertRowsStatement = null;
@@ -282,10 +402,9 @@ public class RestApiServiceImpl extends RestApiService {
       long costTime = System.nanoTime() - startTime;
       Optional.ofNullable(insertRowsStatement)
           .ifPresent(
-              s -> {
-                CommonUtils.addStatementExecutionLatency(
-                    OperationType.INSERT_RECORDS, s.getType().name(), 
costTime);
-              });
+              s ->
+                  CommonUtils.addStatementExecutionLatency(
+                      OperationType.INSERT_RECORDS, s.getType().name(), 
costTime));
       if (queryId != null) {
         COORDINATOR.cleanupQueryExecution(queryId);
       }
@@ -337,10 +456,9 @@ public class RestApiServiceImpl extends RestApiService {
       long costTime = System.nanoTime() - startTime;
       Optional.ofNullable(insertTabletStatement)
           .ifPresent(
-              s -> {
-                CommonUtils.addStatementExecutionLatency(
-                    OperationType.INSERT_TABLET, s.getType().name(), costTime);
-              });
+              s ->
+                  CommonUtils.addStatementExecutionLatency(
+                      OperationType.INSERT_TABLET, s.getType().name(), 
costTime));
       if (queryId != null) {
         COORDINATOR.cleanupQueryExecution(queryId);
       }
diff --git a/iotdb-protocol/openapi/src/main/openapi3/iotdb_rest_v2.yaml 
b/iotdb-protocol/openapi/src/main/openapi3/iotdb_rest_v2.yaml
index 04d12359da4..0cae51bef23 100644
--- a/iotdb-protocol/openapi/src/main/openapi3/iotdb_rest_v2.yaml
+++ b/iotdb-protocol/openapi/src/main/openapi3/iotdb_rest_v2.yaml
@@ -102,6 +102,23 @@ paths:
             application/json:
               schema:
                 $ref: '#/components/schemas/QueryDataSet'
+  /rest/v2/fastLastQuery:
+    post:
+      summary: executeFastLastQueryStatement
+      description: executeFastLastQueryStatement
+      operationId: executeFastLastQueryStatement
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/PrefixPathList'
+      responses:
+        "200":
+          description: QueryDataSet
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/QueryDataSet'
 
   /grafana/v2/login:
     get:
@@ -185,6 +202,14 @@ components:
           type: integer
           format: int32
 
+    PrefixPathList:
+      title: PrefixPathList
+      type: object
+      properties:
+        prefix_paths:
+          type: array
+          items:
+            type: string
     InsertTabletRequest:
       title: InsertTabletRequest
       type: object

Reply via email to