@@ -24,7 +24,9 @@ use sql::{
24
24
} ;
25
25
26
26
use crate :: handlers:: {
27
- error:: { CreatePlan , InterpreterExec , ParseSql , QueryBlock , QueryTimeout , TooMuchStmt } ,
27
+ error:: {
28
+ CreatePlan , InterpreterExec , ParseInfluxql , ParseSql , QueryBlock , QueryTimeout , TooMuchStmt ,
29
+ } ,
28
30
prelude:: * ,
29
31
} ;
30
32
@@ -104,18 +106,33 @@ impl From<Bytes> for Request {
104
106
}
105
107
}
106
108
107
- pub async fn handle_sql < Q : QueryExecutor + ' static > (
109
+ #[ derive( Debug ) ]
110
+ pub enum QueryRequest {
111
+ Sql ( Request ) ,
112
+ // TODO: influxql include more parameters, we should add it in later.
113
+ Influxql ( Request ) ,
114
+ }
115
+ impl QueryRequest {
116
+ fn query ( & self ) -> & str {
117
+ match self {
118
+ QueryRequest :: Sql ( request) => request. query . as_str ( ) ,
119
+ QueryRequest :: Influxql ( request) => request. query . as_str ( ) ,
120
+ }
121
+ }
122
+ }
123
+
124
+ pub async fn handle_query < Q : QueryExecutor + ' static > (
108
125
ctx : & RequestContext ,
109
126
instance : InstanceRef < Q > ,
110
- request : Request ,
127
+ query_request : QueryRequest ,
111
128
) -> Result < Output > {
112
129
let request_id = RequestId :: next_id ( ) ;
113
130
let begin_instant = Instant :: now ( ) ;
114
131
let deadline = ctx. timeout . map ( |t| begin_instant + t) ;
115
132
116
133
info ! (
117
- "sql handler try to process request, request_id:{}, request:{:?}" ,
118
- request_id, request
134
+ "Query handler try to process request, request_id:{}, request:{:?}" ,
135
+ request_id, query_request
119
136
) ;
120
137
121
138
// TODO(yingwen): Privilege check, cannot access data of other tenant
@@ -127,38 +144,66 @@ pub async fn handle_sql<Q: QueryExecutor + 'static>(
127
144
function_registry : & * instance. function_registry ,
128
145
} ;
129
146
let frontend = Frontend :: new ( provider) ;
130
-
131
147
let mut sql_ctx = SqlContext :: new ( request_id, deadline) ;
132
- // Parse sql, frontend error of invalid sql already contains sql
133
- // TODO(yingwen): Maybe move sql from frontend error to outer error
134
- let mut stmts = frontend
135
- . parse_sql ( & mut sql_ctx, & request. query )
136
- . context ( ParseSql ) ?;
137
-
138
- if stmts. is_empty ( ) {
139
- return Ok ( Output :: AffectedRows ( 0 ) ) ;
140
- }
141
148
142
- // TODO(yingwen): For simplicity, we only support executing one statement now
143
- // TODO(yingwen): INSERT/UPDATE/DELETE can be batched
144
- ensure ! (
145
- stmts. len( ) == 1 ,
146
- TooMuchStmt {
147
- len: stmts. len( ) ,
148
- query: request. query,
149
+ let plan = match & query_request {
150
+ QueryRequest :: Sql ( request) => {
151
+ // Parse sql, frontend error of invalid sql already contains sql
152
+ // TODO(yingwen): Maybe move sql from frontend error to outer error
153
+ let mut stmts = frontend
154
+ . parse_sql ( & mut sql_ctx, & request. query )
155
+ . context ( ParseSql ) ?;
156
+
157
+ if stmts. is_empty ( ) {
158
+ return Ok ( Output :: AffectedRows ( 0 ) ) ;
159
+ }
160
+
161
+ // TODO(yingwen): For simplicity, we only support executing one statement now
162
+ // TODO(yingwen): INSERT/UPDATE/DELETE can be batched
163
+ ensure ! (
164
+ stmts. len( ) == 1 ,
165
+ TooMuchStmt {
166
+ len: stmts. len( ) ,
167
+ query: & request. query,
168
+ }
169
+ ) ;
170
+
171
+ // Create logical plan
172
+ // Note: Remember to store sql in error when creating logical plan
173
+ frontend
174
+ . statement_to_plan ( & mut sql_ctx, stmts. remove ( 0 ) )
175
+ . context ( CreatePlan {
176
+ query : & request. query ,
177
+ } ) ?
149
178
}
150
- ) ;
151
179
152
- // Create logical plan
153
- // Note: Remember to store sql in error when creating logical plan
154
- let plan = frontend
155
- . statement_to_plan ( & mut sql_ctx, stmts. remove ( 0 ) )
156
- . context ( CreatePlan {
157
- query : & request. query ,
158
- } ) ?;
180
+ QueryRequest :: Influxql ( request) => {
181
+ let mut stmts = frontend
182
+ . parse_influxql ( & mut sql_ctx, & request. query )
183
+ . context ( ParseInfluxql ) ?;
184
+
185
+ if stmts. is_empty ( ) {
186
+ return Ok ( Output :: AffectedRows ( 0 ) ) ;
187
+ }
188
+
189
+ ensure ! (
190
+ stmts. len( ) == 1 ,
191
+ TooMuchStmt {
192
+ len: stmts. len( ) ,
193
+ query: & request. query,
194
+ }
195
+ ) ;
196
+
197
+ frontend
198
+ . influxql_stmt_to_plan ( & mut sql_ctx, stmts. remove ( 0 ) )
199
+ . context ( CreatePlan {
200
+ query : & request. query ,
201
+ } ) ?
202
+ }
203
+ } ;
159
204
160
205
instance. limiter . try_limit ( & plan) . context ( QueryBlock {
161
- query : & request . query ,
206
+ query : query_request . query ( ) ,
162
207
} ) ?;
163
208
164
209
// Execute in interpreter
@@ -177,7 +222,7 @@ pub async fn handle_sql<Q: QueryExecutor + 'static>(
177
222
interpreter_factory
178
223
. create ( interpreter_ctx, plan)
179
224
. context ( InterpreterExec {
180
- query : & request . query ,
225
+ query : query_request . query ( ) ,
181
226
} ) ?;
182
227
183
228
let output = if let Some ( deadline) = deadline {
@@ -187,24 +232,24 @@ pub async fn handle_sql<Q: QueryExecutor + 'static>(
187
232
)
188
233
. await
189
234
. context ( QueryTimeout {
190
- query : & request . query ,
235
+ query : query_request . query ( ) ,
191
236
} )
192
237
. and_then ( |v| {
193
238
v. context ( InterpreterExec {
194
- query : & request . query ,
239
+ query : query_request . query ( ) ,
195
240
} )
196
241
} ) ?
197
242
} else {
198
243
interpreter. execute ( ) . await . context ( InterpreterExec {
199
- query : & request . query ,
244
+ query : query_request . query ( ) ,
200
245
} ) ?
201
246
} ;
202
247
203
248
info ! (
204
- "sql handler finished, request_id:{}, cost:{}ms, request:{:?}" ,
249
+ "Query handler finished, request_id:{}, cost:{}ms, request:{:?}" ,
205
250
request_id,
206
251
begin_instant. saturating_elapsed( ) . as_millis( ) ,
207
- request
252
+ query_request
208
253
) ;
209
254
210
255
Ok ( output)
0 commit comments