@Get
    @Post
    @Path("/api/v1/query")
    public HttpResponse query(
        @Param("query") String query,
        @Param("time") Optional<String> time,
        @Param("timeout") Optional<String> timeout) throws IOException {
        long endTS = System.currentTimeMillis();
        if (time.isPresent()) {
            endTS = formatTimestamp2Millis(time.get());
        }
        long startTS = endTS - 120000; //look back 2m by default
        Duration duration = DurationUtils.timestamp2Duration(startTS, endTS);
        ExprQueryRsp response = new ExprQueryRsp();

        PromQLLexer lexer = new PromQLLexer(
            CharStreams.fromString(query));
        lexer.addErrorListener(new ParseErrorListener());
        PromQLParser parser = new PromQLParser(new CommonTokenStream(lexer));
        parser.addErrorListener(new ParseErrorListener());
        ParseTree tree;
        try {
            tree = parser.expression();
        } catch (ParseCancellationException e) {
            response.setStatus(ResultStatus.ERROR);
            response.setErrorType(ErrorType.BAD_DATA);
            response.setError(e.getMessage());
            return jsonResponse(response);
        }
        PromQLExprQueryVisitor visitor = new PromQLExprQueryVisitor(
            getMetricsQueryService(), getRecordQueryService(), getAggregationQueryService(), duration, QueryType.INSTANT);
        ParseResult parseResult = visitor.visit(tree);

        if (parseResult == null) {
            response.setStatus(ResultStatus.ERROR);
            response.setErrorType(ErrorType.BAD_DATA);
            response.setError("Bad expression, can not parse it.");
        } else if (StringUtil.isBlank(parseResult.getErrorInfo())) {
            //The expression include range, such as: metric_name[1m]
            if (parseResult.isRangeExpression()) {
                buildMatrixRsp(parseResult, response);
            } else {
                switch (parseResult.getResultType()) {
                    case METRICS_RANGE:
                        buildVectorRsp(parseResult, response);
                        break;
                    case SCALAR:
                        buildScalarRsp(parseResult, response);
                        break;
                }
            }
        } else {
            response.setStatus(ResultStatus.ERROR);
            response.setErrorType(parseResult.getErrorType());
            response.setError(parseResult.getErrorInfo());
        }
        return jsonResponse(response);
    }
If match[] is not present, return general labels values.
If end time is not present, use current time as default end time.
The start param will be ignored, reserve this param to keep consistent with API protocol.
Always query with day step.
oap-server/server-query-plugin/promql-plugin/src/main/java/org/apache/skywalking/oap/query/promql/handler/PromQLApiHandler.java