Skip to content

Commit

Permalink
Implement DEDUP function (gluesql#1430)
Browse files Browse the repository at this point in the history
Removes consecutive repeated elements 
e.g.
SELECT DEDUP(CAST('[0, 1, 2, 2, 3, 4, 4]') AS List)
-- > [0, 1, 2, 3, 4]
  • Loading branch information
jinlee0 committed Oct 29, 2023
1 parent 8a3ba04 commit 1b37cdd
Show file tree
Hide file tree
Showing 8 changed files with 61 additions and 1 deletion.
10 changes: 10 additions & 0 deletions core/src/ast/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ pub enum Function {
end_index: Expr,
values: Option<Expr>,
},
Dedup(Expr),
}

impl ToSql for Function {
Expand Down Expand Up @@ -488,6 +489,7 @@ impl ToSql for Function {
end_index.to_sql(),
),
},
Function::Dedup(list) => format!("DEDUP({})", list.to_sql()),
}
}
}
Expand Down Expand Up @@ -1349,6 +1351,14 @@ mod tests {
}))
.to_sql()
);

assert_eq!(
r#"DEDUP("list")"#,
&Expr::Function(Box::new(Function::Dedup(Expr::Identifier(
"list".to_owned()
))))
.to_sql(),
)
}

#[test]
Expand Down
10 changes: 10 additions & 0 deletions core/src/executor/evaluate/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1050,3 +1050,13 @@ pub fn splice<'a>(

Continue(Evaluated::Value(Value::List(result)))
}

pub fn dedup<'a>(list: Evaluated<'_>) -> ControlFlow<Evaluated<'a>> {
match list.try_into().break_if_null()? {
Value::List(mut list) => {
list.dedup();
Continue(Evaluated::Value(Value::List(list)))
}
_ => Err(EvaluateError::ListTypeRequired.into()).into_control_flow(),
}
}
1 change: 1 addition & 0 deletions core/src/executor/evaluate/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,7 @@ async fn evaluate_function<'a, 'b: 'a, 'c: 'a, T: GStore>(
};
f::splice(name, list_data, begin_index, end_index, values)
}
Function::Dedup(list) => f::dedup(eval(list).await?),
};

match result {
Expand Down
5 changes: 4 additions & 1 deletion core/src/plan/expr/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ impl Function {
| Self::GetY(expr)
| Self::IsEmpty(expr)
| Self::Sort { expr, order: None }
| Self::Values(expr) => Exprs::Single([expr].into_iter()),
| Self::Values(expr)
| Self::Dedup(expr) => Exprs::Single([expr].into_iter()),
Self::Left { expr, size: expr2 }
| Self::Right { expr, size: expr2 }
| Self::Lpad {
Expand Down Expand Up @@ -291,6 +292,8 @@ mod tests {
test(r#"SIGN(3.0)"#, &["3.0"]);
test(r#"SIGN(-3.0)"#, &["-3.0"]);

test(r#"DEDUP(list)"#, &["list"]);

// Double
test(r#"LEFT("hello", 2)"#, &[r#""hello""#, "2"]);
test(r#"RIGHT("hello", 2)"#, &[r#""hello""#, "2"]);
Expand Down
5 changes: 5 additions & 0 deletions core/src/translate/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,11 @@ pub fn translate_function(sql_function: &SqlFunction) -> Result<Expr> {
values,
})))
}
"DEDUP" => {
check_len(name, args.len(), 1)?;
let list = translate_expr(args[0])?;
Ok(Expr::Function(Box::new(Function::Dedup(list))))
}
_ => {
let exprs = args
.into_iter()
Expand Down
29 changes: 29 additions & 0 deletions test-suite/src/function/dedup.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use {
crate::*,
gluesql_core::{executor::EvaluateError, prelude::Value::*},
};

test_case!(dedup, {
let g = get_tester!();

g.named_test(
"DEDUP(CAST('[1, 2, 3, 3, 4, 5, 5]' AS List)) should return '[1, 2, 3, 4, 5]'",
"SELECT DEDUP(CAST('[1, 2, 3, 3, 4, 5, 5]' AS List)) as actual",
Ok(select!(actual List; vec![I64(1), I64(2), I64(3), I64(4), I64(5)])),
)
.await;

g.named_test(
"DEDUP(CAST('['1', 1, '1']' AS List)) should return '['1', 1]'",
r#"SELECT DEDUP(CAST('["1", 1, 1, "1", "1"]' AS List)) as actual"#,
Ok(select!(actual List; vec![Str("1".to_owned()), I64(1), Str("1".to_owned())])),
)
.await;

g.named_test(
"DEDUP with invalid value should return EvaluateError::ListTypeRequired",
"SELECT DEDUP(1) AS actual",
Err(EvaluateError::ListTypeRequired.into()),
)
.await;
});
1 change: 1 addition & 0 deletions test-suite/src/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod chr;
pub mod coalesce;
pub mod concat;
pub mod concat_ws;
pub mod dedup;
pub mod degrees;
pub mod div_mod;
pub mod entries;
Expand Down
1 change: 1 addition & 0 deletions test-suite/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ macro_rules! generate_store_tests {
glue!(function_take, function::take::take);
glue!(column_alias, column_alias::column_alias);
glue!(function_splice, function::splice::splice);
glue!(function_dedup, function::dedup::dedup);

// ast-builder
glue!(ast_builder_basic, ast_builder::basic::basic);
Expand Down

0 comments on commit 1b37cdd

Please sign in to comment.