From 442168a6e94e57138b6eb092d8302ead8d68c760 Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Fri, 7 Jul 2023 21:16:02 +0200 Subject: [PATCH] Add SUM Aggregation function and fix ignore comma after aggregation function --- docs/function/aggregations.md | 7 +++++++ src/aggregation.rs | 17 +++++++++++++++++ src/parser.rs | 5 +++++ 3 files changed, 29 insertions(+) diff --git a/docs/function/aggregations.md b/docs/function/aggregations.md index 30b4eaaa..fd5a59fb 100644 --- a/docs/function/aggregations.md +++ b/docs/function/aggregations.md @@ -14,6 +14,13 @@ Accept field name with `NUMBER` to calculate the minimum value of it for all ele SELECT name, commit_count, min(commit_count) FROM branches ``` +### Aggregation `sum` +The function sum() is an aggregate function that returns the sum of items in a group + +```sql +SELECT name, sum(insertions) FROM diffs GROUP BY name +``` + ### Aggregation `count` The function COUNT() is an aggregate function that returns the number of items in a group diff --git a/src/aggregation.rs b/src/aggregation.rs index ddffb684..023de114 100644 --- a/src/aggregation.rs +++ b/src/aggregation.rs @@ -16,6 +16,7 @@ lazy_static! { let mut map: HashMap<&'static str, Aggregation> = HashMap::new(); map.insert("max", aggregation_max); map.insert("min", aggregation_min); + map.insert("sum", aggregation_sum); map.insert("count", aggregation_count); map }; @@ -38,6 +39,13 @@ lazy_static! { result: DataType::Number, }, ); + map.insert( + "sum", + AggregationPrototype { + parameter: DataType::Any, + result: DataType::Number, + }, + ); map.insert( "count", AggregationPrototype { @@ -73,6 +81,15 @@ fn aggregation_min(field_name: &String, objects: &Vec) -> String { return max_length.to_string(); } +fn aggregation_sum(field_name: &String, objects: &Vec) -> String { + let mut sum: i64 = 0; + for object in objects { + let field_value = &object.attributes.get(field_name).unwrap(); + sum += field_value.parse::().unwrap(); + } + return sum.to_string(); +} + fn aggregation_count(_field_name: &String, objects: &Vec) -> String { return objects.len().to_string(); } diff --git a/src/parser.rs b/src/parser.rs index c36862e2..1bfab016 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -322,6 +322,10 @@ fn parse_select_statement( }, ); + if tokens[*position].kind == TokenKind::Comma { + *position += 1; + } + continue; } @@ -381,6 +385,7 @@ fn parse_select_statement( } if tokens[*position].kind != TokenKind::From { + println!("{}", tokens[*position].literal); return Err(GQLError { message: "Expect `from` keyword after attributes".to_owned(), location: tokens[*position].location,