mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-28 17:18:58 +00:00
ec8f059506
Signed-off-by: Shreyan Jain <shreyan11@duck.com> Co-authored-by: Shreyan Jain <shreyan11@duck.com> Co-authored-by: heihutu <heihutu@gmail.com> Co-authored-by: loverustfs <hello@rustfs.com> Co-authored-by: cxymds <Cxymds@qq.com> Co-authored-by: 安正超 <anzhengchao@gmail.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: houseme <4829346+houseme@users.noreply.github.com>
113 lines
3.6 KiB
Rust
113 lines
3.6 KiB
Rust
// Copyright 2024 RustFS Team
|
|
//
|
|
// Licensed 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.
|
|
|
|
use std::sync::Arc;
|
|
|
|
use async_trait::async_trait;
|
|
use futures::stream::AbortHandle;
|
|
use parking_lot::Mutex;
|
|
use rustfs_s3select_api::query::execution::{Output, QueryExecution, QueryStateMachineRef};
|
|
use rustfs_s3select_api::query::logical_planner::QueryPlan;
|
|
use rustfs_s3select_api::query::optimizer::Optimizer;
|
|
use rustfs_s3select_api::query::scheduler::SchedulerRef;
|
|
use rustfs_s3select_api::{QueryError, QueryResult};
|
|
use tracing::debug;
|
|
|
|
pub struct SqlQueryExecution {
|
|
query_state_machine: QueryStateMachineRef,
|
|
plan: QueryPlan,
|
|
optimizer: Arc<dyn Optimizer + Send + Sync>,
|
|
scheduler: SchedulerRef,
|
|
|
|
abort_handle: Mutex<Option<AbortHandle>>,
|
|
}
|
|
|
|
impl SqlQueryExecution {
|
|
pub fn new(
|
|
query_state_machine: QueryStateMachineRef,
|
|
plan: QueryPlan,
|
|
optimizer: Arc<dyn Optimizer + Send + Sync>,
|
|
scheduler: SchedulerRef,
|
|
) -> Self {
|
|
Self {
|
|
query_state_machine,
|
|
plan,
|
|
optimizer,
|
|
scheduler,
|
|
abort_handle: Mutex::new(None),
|
|
}
|
|
}
|
|
|
|
async fn start(&self) -> QueryResult<Output> {
|
|
let physical_plan = {
|
|
// Time optimize phase - dropped at end of this block
|
|
let _optimize_timer = self.query_state_machine.time_phase("optimize");
|
|
self.query_state_machine.begin_optimize();
|
|
let plan = self.optimizer.optimize(&self.plan, &self.query_state_machine.session).await?;
|
|
self.query_state_machine.end_optimize();
|
|
plan
|
|
};
|
|
|
|
let stream = {
|
|
// Time schedule phase - dropped at end of this block
|
|
let _schedule_timer = self.query_state_machine.time_phase("schedule");
|
|
self.query_state_machine.begin_schedule();
|
|
let stream = self
|
|
.scheduler
|
|
.schedule(physical_plan.clone(), self.query_state_machine.session.inner().task_ctx())
|
|
.await?
|
|
.stream();
|
|
self.query_state_machine.end_schedule();
|
|
stream
|
|
};
|
|
|
|
Ok(Output::StreamData(stream))
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl QueryExecution for SqlQueryExecution {
|
|
async fn start(&self) -> QueryResult<Output> {
|
|
let (task, abort_handle) = futures::future::abortable(self.start());
|
|
|
|
{
|
|
*self.abort_handle.lock() = Some(abort_handle);
|
|
}
|
|
|
|
task.await.map_err(|_| QueryError::Cancel)?
|
|
}
|
|
|
|
fn cancel(&self) -> QueryResult<()> {
|
|
debug!(
|
|
"cancel sql query execution: sql: {}, state: {:?}",
|
|
self.query_state_machine.query.content(),
|
|
self.query_state_machine.state()
|
|
);
|
|
|
|
// change state
|
|
self.query_state_machine.cancel();
|
|
// stop future task
|
|
if let Some(e) = self.abort_handle.lock().as_ref() {
|
|
e.abort()
|
|
};
|
|
|
|
debug!(
|
|
"canceled sql query execution: sql: {}, state: {:?}",
|
|
self.query_state_machine.query.content(),
|
|
self.query_state_machine.state()
|
|
);
|
|
Ok(())
|
|
}
|
|
}
|