Skip to content

Commit

Permalink
Add Decode
Browse files Browse the repository at this point in the history
  • Loading branch information
mediuminvader committed Feb 27, 2024
1 parent a39a5d0 commit 222fd60
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 1 deletion.
22 changes: 22 additions & 0 deletions dozer-sql/expression/src/scalar/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use dozer_types::types::Record;
use dozer_types::types::{Field, FieldType, Schema};
use std::fmt::{Display, Formatter};

use super::field::{evaluate_decode, validate_decode};
use super::string::{
evaluate_chr, evaluate_replace, evaluate_substr, validate_replace, validate_substr,
};
Expand All @@ -27,6 +28,7 @@ pub enum ScalarFunctionType {
Substr,
Nvl,
Replace,
Decode,
}

impl Display for ScalarFunctionType {
Expand All @@ -42,6 +44,7 @@ impl Display for ScalarFunctionType {
ScalarFunctionType::Substr => f.write_str("SUBSTR"),
ScalarFunctionType::Nvl => f.write_str("NVL"),
ScalarFunctionType::Replace => f.write_str("REPLACE"),
ScalarFunctionType::Decode => f.write_str("DECODE"),
}
}
}
Expand Down Expand Up @@ -92,6 +95,7 @@ pub(crate) fn get_scalar_function_type(
Ok(validate_two_arguments(args, schema, ScalarFunctionType::Nvl)?.0)
}
ScalarFunctionType::Replace => validate_replace(args, schema),
ScalarFunctionType::Decode => validate_decode(args, schema),
}
}

Expand Down Expand Up @@ -171,6 +175,24 @@ impl ScalarFunctionType {
record,
)
}
ScalarFunctionType::Decode => {
validate_decode(args, schema)?;

let (arg0, results) = args.split_at_mut(1);
let (results, default) = if results.len() % 2 == 0 {
results.split_at_mut(results.len() - 1)
} else {
results.split_at_mut(results.len())
};

let default = if default.len() == 0 {
None
} else {
Some(default[0].clone())
};

evaluate_decode(schema, &mut arg0[0], results, default, record)
}
}
}
}
45 changes: 44 additions & 1 deletion dozer-sql/expression/src/scalar/field.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::error::Error;
use crate::execution::Expression;
use crate::execution::{Expression, ExpressionType};
use dozer_types::types::Record;
use dozer_types::types::{Field, Schema};

Expand All @@ -17,3 +17,46 @@ pub(crate) fn evaluate_nvl(
Ok(arg_field)
}
}

pub fn validate_decode(args: &[Expression], schema: &Schema) -> Result<ExpressionType, Error> {
if args.len() < 3 {
return Err(Error::InvalidNumberOfArguments {
function_name: "decode".to_string(),
expected: 3..usize::MAX,
actual: args.len(),
});
}

let ret_type = args[2].get_type(schema)?.return_type;

Ok(ExpressionType::new(
ret_type,
false,
dozer_types::types::SourceDefinition::Dynamic,
false,
))
}

pub(crate) fn evaluate_decode(
schema: &Schema,
arg: &mut Expression,
results: &mut [Expression],
default: Option<Expression>,
record: &Record,
) -> Result<Field, Error> {
let arg_field = arg.evaluate(record, schema)?;
let mut i = 0;
while i < results.len() {
let result = &mut results[i];
let result_field = result.evaluate(record, schema)?;
if arg_field == result_field {
return Ok(results[i + 1].evaluate(record, schema)?);
}
i += 2;
}
if let Some(mut default) = default {
default.evaluate(record, schema)
} else {
Ok(Field::Null)
}
}

0 comments on commit 222fd60

Please sign in to comment.