mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-29 09:38:59 +00:00
0e680eae31
* fix typos * build(deps): bump the dependencies group with 9 updates (#613) Bumps the dependencies group with 9 updates: | Package | From | To | | --- | --- | --- | | [axum](https://github.com/tokio-rs/axum) | `0.8.4` | `0.8.6` | | [axum-extra](https://github.com/tokio-rs/axum) | `0.10.1` | `0.10.3` | | [regex](https://github.com/rust-lang/regex) | `1.11.2` | `1.11.3` | | [serde](https://github.com/serde-rs/serde) | `1.0.226` | `1.0.228` | | [shadow-rs](https://github.com/baoyachi/shadow-rs) | `1.3.0` | `1.4.0` | | [sysinfo](https://github.com/GuillaumeGomez/sysinfo) | `0.37.0` | `0.37.1` | | [thiserror](https://github.com/dtolnay/thiserror) | `2.0.16` | `2.0.17` | | [tokio-rustls](https://github.com/rustls/tokio-rustls) | `0.26.3` | `0.26.4` | | [zeroize](https://github.com/RustCrypto/utils) | `1.8.1` | `1.8.2` | Updates `axum` from 0.8.4 to 0.8.6 - [Release notes](https://github.com/tokio-rs/axum/releases) - [Changelog](https://github.com/tokio-rs/axum/blob/main/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/axum/compare/axum-v0.8.4...axum-v0.8.6) Updates `axum-extra` from 0.10.1 to 0.10.3 - [Release notes](https://github.com/tokio-rs/axum/releases) - [Changelog](https://github.com/tokio-rs/axum/blob/main/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/axum/compare/axum-extra-v0.10.1...axum-extra-v0.10.3) Updates `regex` from 1.11.2 to 1.11.3 - [Release notes](https://github.com/rust-lang/regex/releases) - [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md) - [Commits](https://github.com/rust-lang/regex/compare/1.11.2...1.11.3) Updates `serde` from 1.0.226 to 1.0.228 - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.226...v1.0.228) Updates `shadow-rs` from 1.3.0 to 1.4.0 - [Release notes](https://github.com/baoyachi/shadow-rs/releases) - [Commits](https://github.com/baoyachi/shadow-rs/compare/1.3.0...v1.4.0) Updates `sysinfo` from 0.37.0 to 0.37.1 - [Changelog](https://github.com/GuillaumeGomez/sysinfo/blob/master/CHANGELOG.md) - [Commits](https://github.com/GuillaumeGomez/sysinfo/compare/v0.37.0...v0.37.1) Updates `thiserror` from 2.0.16 to 2.0.17 - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/2.0.16...2.0.17) Updates `tokio-rustls` from 0.26.3 to 0.26.4 - [Release notes](https://github.com/rustls/tokio-rustls/releases) - [Commits](https://github.com/rustls/tokio-rustls/compare/v/0.26.3...v/0.26.4) Updates `zeroize` from 1.8.1 to 1.8.2 - [Commits](https://github.com/RustCrypto/utils/compare/zeroize-v1.8.1...zeroize-v1.8.2) --- updated-dependencies: - dependency-name: axum dependency-version: 0.8.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: axum-extra dependency-version: 0.10.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: regex dependency-version: 1.11.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: serde dependency-version: 1.0.228 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: shadow-rs dependency-version: 1.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: sysinfo dependency-version: 0.37.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: thiserror dependency-version: 2.0.17 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: tokio-rustls dependency-version: 0.26.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies - dependency-name: zeroize dependency-version: 1.8.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
256 lines
6.3 KiB
Rust
256 lines
6.3 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::fmt::Display;
|
|
use std::pin::Pin;
|
|
use std::sync::Arc;
|
|
use std::sync::atomic::{AtomicPtr, Ordering};
|
|
use std::task::{Context, Poll};
|
|
use std::time::{Duration, Instant};
|
|
|
|
use async_trait::async_trait;
|
|
use datafusion::arrow::datatypes::{Schema, SchemaRef};
|
|
use datafusion::arrow::record_batch::RecordBatch;
|
|
use datafusion::physical_plan::SendableRecordBatchStream;
|
|
use futures::{Stream, StreamExt, TryStreamExt};
|
|
|
|
use crate::{QueryError, QueryResult};
|
|
|
|
use super::Query;
|
|
use super::logical_planner::Plan;
|
|
use super::session::SessionCtx;
|
|
|
|
pub type QueryExecutionRef = Arc<dyn QueryExecution>;
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum QueryType {
|
|
Batch,
|
|
Stream,
|
|
}
|
|
|
|
impl Display for QueryType {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
Self::Batch => write!(f, "batch"),
|
|
Self::Stream => write!(f, "stream"),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
pub trait QueryExecution: Send + Sync {
|
|
fn query_type(&self) -> QueryType {
|
|
QueryType::Batch
|
|
}
|
|
// Start
|
|
async fn start(&self) -> QueryResult<Output>;
|
|
// Stop
|
|
fn cancel(&self) -> QueryResult<()>;
|
|
}
|
|
|
|
pub enum Output {
|
|
StreamData(SendableRecordBatchStream),
|
|
Nil(()),
|
|
}
|
|
|
|
impl Output {
|
|
pub fn schema(&self) -> SchemaRef {
|
|
match self {
|
|
Self::StreamData(stream) => stream.schema(),
|
|
Self::Nil(_) => Arc::new(Schema::empty()),
|
|
}
|
|
}
|
|
|
|
pub async fn chunk_result(self) -> QueryResult<Vec<RecordBatch>> {
|
|
match self {
|
|
Self::Nil(_) => Ok(vec![]),
|
|
Self::StreamData(stream) => {
|
|
let schema = stream.schema();
|
|
let mut res: Vec<RecordBatch> = stream.try_collect::<Vec<RecordBatch>>().await?;
|
|
if res.is_empty() {
|
|
res.push(RecordBatch::new_empty(schema));
|
|
}
|
|
Ok(res)
|
|
}
|
|
}
|
|
}
|
|
|
|
pub async fn num_rows(self) -> usize {
|
|
match self.chunk_result().await {
|
|
Ok(rb) => rb.iter().map(|e| e.num_rows()).sum(),
|
|
Err(_) => 0,
|
|
}
|
|
}
|
|
|
|
/// Returns the number of records affected by the query operation
|
|
///
|
|
/// If it is a select statement, returns the number of rows in the result set
|
|
///
|
|
/// -1 means unknown
|
|
///
|
|
/// panic! when StreamData's number of records greater than i64::Max
|
|
pub async fn affected_rows(self) -> i64 {
|
|
self.num_rows().await as i64
|
|
}
|
|
}
|
|
|
|
impl Stream for Output {
|
|
type Item = Result<RecordBatch, QueryError>;
|
|
|
|
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
|
let this = self.get_mut();
|
|
match this {
|
|
Output::StreamData(stream) => stream.poll_next_unpin(cx).map_err(|e| e.into()),
|
|
Output::Nil(_) => Poll::Ready(None),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
pub trait QueryExecutionFactory {
|
|
async fn create_query_execution(
|
|
&self,
|
|
plan: Plan,
|
|
query_state_machine: QueryStateMachineRef,
|
|
) -> QueryResult<QueryExecutionRef>;
|
|
}
|
|
|
|
pub type QueryStateMachineRef = Arc<QueryStateMachine>;
|
|
|
|
pub struct QueryStateMachine {
|
|
pub session: SessionCtx,
|
|
pub query: Query,
|
|
|
|
state: AtomicPtr<QueryState>,
|
|
start: Instant,
|
|
}
|
|
|
|
impl QueryStateMachine {
|
|
pub fn begin(query: Query, session: SessionCtx) -> Self {
|
|
Self {
|
|
session,
|
|
query,
|
|
state: AtomicPtr::new(Box::into_raw(Box::new(QueryState::ACCEPTING))),
|
|
start: Instant::now(),
|
|
}
|
|
}
|
|
|
|
pub fn begin_analyze(&self) {
|
|
// TODO record time
|
|
self.translate_to(Box::new(QueryState::RUNNING(RUNNING::ANALYZING)));
|
|
}
|
|
|
|
pub fn end_analyze(&self) {
|
|
// TODO record time
|
|
}
|
|
|
|
pub fn begin_optimize(&self) {
|
|
// TODO record time
|
|
self.translate_to(Box::new(QueryState::RUNNING(RUNNING::OPTIMIZING)));
|
|
}
|
|
|
|
pub fn end_optimize(&self) {
|
|
// TODO
|
|
}
|
|
|
|
pub fn begin_schedule(&self) {
|
|
// TODO
|
|
self.translate_to(Box::new(QueryState::RUNNING(RUNNING::SCHEDULING)));
|
|
}
|
|
|
|
pub fn end_schedule(&self) {
|
|
// TODO
|
|
}
|
|
|
|
pub fn finish(&self) {
|
|
// TODO
|
|
self.translate_to(Box::new(QueryState::DONE(DONE::FINISHED)));
|
|
}
|
|
|
|
pub fn cancel(&self) {
|
|
// TODO
|
|
self.translate_to(Box::new(QueryState::DONE(DONE::CANCELLED)));
|
|
}
|
|
|
|
pub fn fail(&self) {
|
|
// TODO
|
|
self.translate_to(Box::new(QueryState::DONE(DONE::FAILED)));
|
|
}
|
|
|
|
pub fn state(&self) -> &QueryState {
|
|
unsafe { &*self.state.load(Ordering::Relaxed) }
|
|
}
|
|
|
|
pub fn duration(&self) -> Duration {
|
|
self.start.elapsed()
|
|
}
|
|
|
|
fn translate_to(&self, state: Box<QueryState>) {
|
|
self.state.store(Box::into_raw(state), Ordering::Relaxed);
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum QueryState {
|
|
ACCEPTING,
|
|
RUNNING(RUNNING),
|
|
DONE(DONE),
|
|
}
|
|
|
|
impl AsRef<str> for QueryState {
|
|
fn as_ref(&self) -> &str {
|
|
match self {
|
|
QueryState::ACCEPTING => "ACCEPTING",
|
|
QueryState::RUNNING(e) => e.as_ref(),
|
|
QueryState::DONE(e) => e.as_ref(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum RUNNING {
|
|
DISPATCHING,
|
|
ANALYZING,
|
|
OPTIMIZING,
|
|
SCHEDULING,
|
|
}
|
|
|
|
impl AsRef<str> for RUNNING {
|
|
fn as_ref(&self) -> &str {
|
|
match self {
|
|
Self::DISPATCHING => "DISPATCHING",
|
|
Self::ANALYZING => "ANALYZING",
|
|
Self::OPTIMIZING => "OPTIMIZING",
|
|
Self::SCHEDULING => "SCHEDULING",
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub enum DONE {
|
|
FINISHED,
|
|
FAILED,
|
|
CANCELLED,
|
|
}
|
|
|
|
impl AsRef<str> for DONE {
|
|
fn as_ref(&self) -> &str {
|
|
match self {
|
|
Self::FINISHED => "FINISHED",
|
|
Self::FAILED => "FAILED",
|
|
Self::CANCELLED => "CANCELLED",
|
|
}
|
|
}
|
|
}
|