Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(fuzz): add fuzz test with delete rows #3867

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat(fuzz): add delete fuzz part
hanxuanliang committed May 6, 2024
commit b2f130a70c508ad28a194e5e751050b0c5624793
1 change: 1 addition & 0 deletions tests-fuzz/src/generator.rs
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ pub mod alter_expr;
pub mod create_expr;
pub mod insert_expr;
pub mod select_expr;
pub mod delete_expr;

use std::fmt;

51 changes: 51 additions & 0 deletions tests-fuzz/src/generator/delete_expr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use std::marker::PhantomData;

use derive_builder::Builder;
use rand::seq::SliceRandom;
use rand::Rng;

use crate::context::TableContextRef;
use crate::error::{Error, Result};
use crate::generator::Generator;
use crate::ir::delete_expr::{DeleteExpr, WhereExpr};
use crate::ir::generate_random_value;

#[derive(Builder)]
#[builder(pattern = "owned")]
pub struct DeleteExprGenerator<R: Rng + 'static> {
table_ctx: TableContextRef,
#[builder(default)]
_phantom: PhantomData<R>,
}

impl<R: Rng + 'static> Generator<DeleteExpr, R> for DeleteExprGenerator<R> {
type Error = Error;

fn generate(&self, rng: &mut R) -> Result<DeleteExpr> {
let selection = rng.gen_range(1..self.table_ctx.columns.len());
let mut selected_columns = self
.table_ctx
.columns
.choose_multiple(rng, selection)
.cloned()
.collect::<Vec<_>>();
selected_columns.shuffle(rng);

let mut where_clause = Vec::with_capacity(selected_columns.len());

for column in selected_columns.iter() {
let value = generate_random_value(rng, &column.column_type, None);
let condition = WhereExpr {
column: column.name.to_string(),
value,
};
where_clause.push(condition);
}

Ok(DeleteExpr {
table_name: self.table_ctx.name.to_string(),
columns: selected_columns,
where_clause,
})
}
}
1 change: 1 addition & 0 deletions tests-fuzz/src/ir.rs
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ pub(crate) mod alter_expr;
pub(crate) mod create_expr;
pub(crate) mod insert_expr;
pub(crate) mod select_expr;
pub(crate) mod delete_expr;

use core::fmt;

28 changes: 28 additions & 0 deletions tests-fuzz/src/ir/delete_expr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2023 Greptime 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 datatypes::value::Value;

use crate::ir::Column;

pub struct WhereExpr {
pub column: String,
pub value: Value,
}

pub struct DeleteExpr {
pub table_name: String,
pub columns: Vec<Column>,
pub where_clause: Vec<WhereExpr>,
}
1 change: 1 addition & 0 deletions tests-fuzz/src/translator/mysql.rs
Original file line number Diff line number Diff line change
@@ -16,3 +16,4 @@ pub mod alter_expr;
pub mod create_expr;
pub mod insert_expr;
pub mod select_expr;
pub mod delete_expr;
72 changes: 72 additions & 0 deletions tests-fuzz/src/translator/mysql/delete_expr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright 2023 Greptime 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 crate::error::{Error, Result};
use crate::ir::delete_expr::DeleteExpr;
use crate::translator::DslTranslator;

pub struct DeleteExprTranslator;

impl DslTranslator<DeleteExpr, String> for DeleteExprTranslator {
type Error = Error;

fn translate(&self, input: &DeleteExpr) -> Result<String> {
// Generating WHERE clause if exists
let where_clause = if !input.where_clause.is_empty() {
input
.where_clause
.iter()
.map(|where_expr| format!("{} = '{}'", where_expr.column, where_expr.value))
.collect::<Vec<_>>()
.join(" AND ")
} else {
"1".to_string()
};

Ok(format!(
"DELETE FROM {} WHERE {};",
input.table_name, where_clause,
))
}
}

#[cfg(test)]
mod tests {
use std::sync::Arc;

use rand::SeedableRng;

use super::DeleteExprTranslator;
use crate::generator::delete_expr::DeleteExprGeneratorBuilder;
use crate::generator::Generator;
use crate::test_utils;
use crate::translator::DslTranslator;

#[test]
fn test_select_expr_translator() {
let mut rng = rand_chacha::ChaCha8Rng::seed_from_u64(0);

let test_ctx = test_utils::new_test_ctx();
let delete_expr_generator = DeleteExprGeneratorBuilder::default()
.table_ctx(Arc::new(test_ctx))
.build()
.unwrap();

let delete_expr = delete_expr_generator.generate(&mut rng).unwrap();
let output = DeleteExprTranslator.translate(&delete_expr).unwrap();

let expected_output = "DELETE FROM test WHERE memory_util = '0.4147731206727985' AND ts = '+169626-08-17 05:35:46.714+0000' AND cpu_util = '0.494276426950336' AND disk_util = '0.9011706134313209';";
assert_eq!(output, expected_output);
}
}