sql/statements/
tql.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::fmt::Display;
16
17use serde::Serialize;
18use sqlparser_derive::{Visit, VisitMut};
19
20#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
21pub enum Tql {
22    Eval(TqlEval),
23    Explain(TqlExplain),
24    Analyze(TqlAnalyze),
25}
26
27impl Display for Tql {
28    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29        match self {
30            Tql::Eval(t) => t.fmt(f),
31            Tql::Explain(t) => t.fmt(f),
32            Tql::Analyze(t) => t.fmt(f),
33        }
34    }
35}
36
37fn format_tql(
38    f: &mut std::fmt::Formatter<'_>,
39    start: &str,
40    end: &str,
41    step: &str,
42    lookback: Option<&str>,
43    query: &str,
44) -> std::fmt::Result {
45    write!(f, "({start}, {end}, {step}")?;
46    if let Some(lookback) = lookback {
47        write!(f, ", {lookback}")?;
48    }
49    write!(f, ") {query}")
50}
51
52/// TQL EVAL (<start>, <end>, <step>, [lookback]) <promql>
53#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
54pub struct TqlEval {
55    pub start: String,
56    pub end: String,
57    pub step: String,
58    pub lookback: Option<String>,
59    pub query: String,
60}
61
62impl Display for TqlEval {
63    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64        write!(f, "TQL EVAL ")?;
65        format_tql(
66            f,
67            &self.start,
68            &self.end,
69            &self.step,
70            self.lookback.as_deref(),
71            &self.query,
72        )
73    }
74}
75
76/// TQL EXPLAIN [VERBOSE] [<start>, <end>, <step>, [lookback]] <promql>
77/// doesn't execute the query but tells how the query would be executed (similar to SQL EXPLAIN).
78#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
79pub struct TqlExplain {
80    pub start: String,
81    pub end: String,
82    pub step: String,
83    pub lookback: Option<String>,
84    pub query: String,
85    pub is_verbose: bool,
86}
87
88impl Display for TqlExplain {
89    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90        write!(f, "TQL EXPLAIN ")?;
91        if self.is_verbose {
92            write!(f, "VERBOSE ")?;
93        }
94        format_tql(
95            f,
96            &self.start,
97            &self.end,
98            &self.step,
99            self.lookback.as_deref(),
100            &self.query,
101        )
102    }
103}
104
105/// TQL ANALYZE [VERBOSE] (<start>, <end>, <step>, [lookback]) <promql>
106/// executes the plan and tells the detailed per-step execution time (similar to SQL ANALYZE).
107#[derive(Debug, Clone, PartialEq, Eq, Visit, VisitMut, Serialize)]
108pub struct TqlAnalyze {
109    pub start: String,
110    pub end: String,
111    pub step: String,
112    pub lookback: Option<String>,
113    pub query: String,
114    pub is_verbose: bool,
115}
116
117impl Display for TqlAnalyze {
118    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
119        write!(f, "TQL ANALYZE ")?;
120        if self.is_verbose {
121            write!(f, "VERBOSE ")?;
122        }
123        format_tql(
124            f,
125            &self.start,
126            &self.end,
127            &self.step,
128            self.lookback.as_deref(),
129            &self.query,
130        )
131    }
132}
133
134/// Intermediate structure used to unify parameter mappings for various TQL operations.
135///
136/// This struct serves as a common parameter container for parsing TQL queries
137/// and constructing corresponding TQL operations: `TqlEval`, `TqlAnalyze` or `TqlExplain`.
138#[derive(Debug)]
139pub struct TqlParameters {
140    start: String,
141    end: String,
142    step: String,
143    lookback: Option<String>,
144    query: String,
145    pub is_verbose: bool,
146}
147
148impl TqlParameters {
149    pub fn new(
150        start: String,
151        end: String,
152        step: String,
153        lookback: Option<String>,
154        query: String,
155    ) -> Self {
156        TqlParameters {
157            start,
158            end,
159            step,
160            lookback,
161            query,
162            is_verbose: false,
163        }
164    }
165}
166
167impl From<TqlParameters> for TqlEval {
168    fn from(params: TqlParameters) -> Self {
169        TqlEval {
170            start: params.start,
171            end: params.end,
172            step: params.step,
173            lookback: params.lookback,
174            query: params.query,
175        }
176    }
177}
178
179impl From<TqlParameters> for TqlExplain {
180    fn from(params: TqlParameters) -> Self {
181        TqlExplain {
182            start: params.start,
183            end: params.end,
184            step: params.step,
185            query: params.query,
186            lookback: params.lookback,
187            is_verbose: params.is_verbose,
188        }
189    }
190}
191
192impl From<TqlParameters> for TqlAnalyze {
193    fn from(params: TqlParameters) -> Self {
194        TqlAnalyze {
195            start: params.start,
196            end: params.end,
197            step: params.step,
198            query: params.query,
199            lookback: params.lookback,
200            is_verbose: params.is_verbose,
201        }
202    }
203}