Skip to content

Commit

Permalink
Allow order by to work with different data types
Browse files Browse the repository at this point in the history
  • Loading branch information
AmrDeveloper committed Jun 26, 2023
1 parent c5d841c commit ad89ac9
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 10 deletions.
38 changes: 35 additions & 3 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub fn parse_gql(tokens: Vec<Token>) -> Result<GQLQuery, GQLError> {

let mut statements: HashMap<String, Box<dyn Statement>> = HashMap::new();
let mut aggregations: HashMap<String, AggregateFunction> = HashMap::new();
let mut extra_type_table: HashMap<String, DataType> = HashMap::new();

while position < len {
let token = &tokens[position];
Expand All @@ -55,8 +56,12 @@ pub fn parse_gql(tokens: Vec<Token>) -> Result<GQLQuery, GQLError> {
});
}

let parse_result =
parse_select_statement(&tokens, &mut position, &mut aggregations);
let parse_result = parse_select_statement(
&tokens,
&mut position,
&mut aggregations,
&mut extra_type_table,
);
if parse_result.is_err() {
return Err(parse_result.err().unwrap());
}
Expand Down Expand Up @@ -139,7 +144,9 @@ pub fn parse_gql(tokens: Vec<Token>) -> Result<GQLQuery, GQLError> {
});
}

let parse_result = parse_order_by_statement(&tokens, &mut position);
let parse_result =
parse_order_by_statement(&tokens, &mut position, &mut extra_type_table);

if parse_result.is_err() {
return Err(parse_result.err().unwrap());
}
Expand Down Expand Up @@ -167,6 +174,7 @@ fn parse_select_statement(
tokens: &Vec<Token>,
position: &mut usize,
aggregations: &mut HashMap<String, AggregateFunction>,
extra_type_table: &mut HashMap<String, DataType>,
) -> Result<Box<dyn Statement>, GQLError> {
*position += 1;
let mut fields: Vec<String> = Vec::new();
Expand Down Expand Up @@ -289,6 +297,8 @@ fn parse_select_statement(
format!("{}_{}", "field", aggregation_function_index)
};

extra_type_table.insert(column_name.to_string(), prototype.result.clone());

aggregations.insert(
column_name.to_string(),
AggregateFunction {
Expand Down Expand Up @@ -329,6 +339,10 @@ fn parse_select_statement(

*position += 1;

// Update extra type table for this alias
let field_type = TABLES_FIELDS_TYPES.get(field_name.as_str()).unwrap();
extra_type_table.insert(alias_name.to_string(), field_type.clone());

// Insert the alias name to used later in conditions
fields_set.insert(alias_name.to_string());

Expand Down Expand Up @@ -519,6 +533,7 @@ fn parse_offset_statement(
fn parse_order_by_statement(
tokens: &Vec<Token>,
position: &mut usize,
extra_type_table: &mut HashMap<String, DataType>,
) -> Result<Box<dyn Statement>, GQLError> {
*position += 1;
if *position >= tokens.len() || tokens[*position].kind != TokenKind::By {
Expand All @@ -536,6 +551,22 @@ fn parse_order_by_statement(
}

let field_name = tokens[*position].literal.to_string();

let field_type: DataType;
if TABLES_FIELDS_TYPES.contains_key(field_name.as_str()) {
field_type = TABLES_FIELDS_TYPES
.get(field_name.as_str())
.unwrap()
.clone();
} else if extra_type_table.contains_key(field_name.as_str()) {
field_type = extra_type_table.get(field_name.as_str()).unwrap().clone();
} else {
return Err(GQLError {
message: "Un resolved field name".to_owned(),
location: tokens[*position].location,
});
}

*position += 1;

// Consume optional ordering ASC or DES
Expand All @@ -551,6 +582,7 @@ fn parse_order_by_statement(
return Ok(Box::new(OrderByStatement {
field_name,
is_ascending,
field_type,
}));
}

Expand Down
37 changes: 30 additions & 7 deletions src/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::aggregation::AGGREGATIONS;
use crate::engine_function::select_gql_objects;
use crate::expression::Expression;
use crate::object::GQLObject;
use crate::types::DataType;

pub trait Statement {
fn execute(&self, repo: &git2::Repository, groups: &mut Vec<Vec<GQLObject>>);
Expand Down Expand Up @@ -119,6 +120,7 @@ impl Statement for OffsetStatement {
pub struct OrderByStatement {
pub field_name: String,
pub is_ascending: bool,
pub field_type: DataType,
}

impl Statement for OrderByStatement {
Expand All @@ -133,13 +135,34 @@ impl Statement for OrderByStatement {
}

if main_group[0].attributes.contains_key(&self.field_name) {
main_group.sort_by_key(|object| {
object
.attributes
.get(&self.field_name.to_string())
.unwrap()
.to_string()
});
if self.field_type == DataType::Number {
main_group.sort_by(|a, b| {
let first_value = a
.attributes
.get(&self.field_name.to_string())
.unwrap()
.to_string()
.parse::<i64>()
.unwrap();

let other = b
.attributes
.get(&self.field_name.to_string())
.unwrap()
.to_string()
.parse::<i64>()
.unwrap();
first_value.partial_cmp(&other).unwrap()
});
} else {
main_group.sort_by_cached_key(|object| {
object
.attributes
.get(&self.field_name.to_string())
.unwrap()
.to_string()
});
}

if !self.is_ascending {
main_group.reverse();
Expand Down

0 comments on commit ad89ac9

Please sign in to comment.