From 492a2aaf6842ea5d13709acf73a94ed00c553117 Mon Sep 17 00:00:00 2001 From: Josh Pschorr Date: Mon, 9 Jan 2023 13:58:52 -0800 Subject: [PATCH] Refactor trim functions to return MISSING on arg mismatch --- partiql-eval/src/eval.rs | 108 +++++++++++++++++++++------------------ 1 file changed, 59 insertions(+), 49 deletions(-) diff --git a/partiql-eval/src/eval.rs b/partiql-eval/src/eval.rs index ce1b19cf..b8124dae 100644 --- a/partiql-eval/src/eval.rs +++ b/partiql-eval/src/eval.rs @@ -1112,7 +1112,6 @@ where fn evaluate(&self, bindings: &Tuple, ctx: &dyn EvalContext) -> Value { let value = self.input().evaluate(bindings, ctx); match value { - Null => Value::Null, Missing => Value::Missing, Value::String(s) => self.evaluate_str(s.as_ref()), _ => Value::Null, @@ -1223,6 +1222,35 @@ impl EvalExpr for EvalFnSubstring { } } +#[inline] +#[track_caller] +fn trim( + value: &dyn EvalExpr, + to_trim: &dyn EvalExpr, + bindings: &Tuple, + ctx: &dyn EvalContext, + trim_fn: FnTrim, +) -> Value +where + FnTrim: Fn(&str, &str) -> Value, +{ + let value = match value.evaluate(bindings, ctx) { + Value::String(s) => Some(s), + Null => None, + _ => return Value::Missing, + }; + let to_trim = match to_trim.evaluate(bindings, ctx) { + Value::String(s) => s, + Null => return Value::Null, + _ => return Value::Missing, + }; + if let Some(s) = value { + trim_fn(&s, &to_trim) + } else { + Value::Null + } +} + #[derive(Debug)] pub struct EvalFnBtrim { pub value: Box, @@ -1232,22 +1260,16 @@ pub struct EvalFnBtrim { impl EvalExpr for EvalFnBtrim { #[inline] fn evaluate(&self, bindings: &Tuple, ctx: &dyn EvalContext) -> Value { - let value = match self.value.evaluate(bindings, ctx) { - Missing => return Value::Missing, - Value::String(s) => Some(s), - _ => None, - }; - let to_trim = match self.to_trim.evaluate(bindings, ctx) { - Missing => return Value::Missing, - Value::String(s) => s, - _ => return Value::Null, - }; - if let Some(s) = value { - let to_trim = to_trim.chars().collect_vec(); - s.trim_matches(&to_trim[..]).into() - } else { - Value::Null - } + trim( + self.value.as_ref(), + self.to_trim.as_ref(), + bindings, + ctx, + |s, to_trim| { + let to_trim = to_trim.chars().collect_vec(); + s.trim_matches(&to_trim[..]).into() + }, + ) } } @@ -1260,22 +1282,16 @@ pub struct EvalFnRtrim { impl EvalExpr for EvalFnRtrim { #[inline] fn evaluate(&self, bindings: &Tuple, ctx: &dyn EvalContext) -> Value { - let value = match self.value.evaluate(bindings, ctx) { - Missing => return Value::Missing, - Value::String(s) => Some(s), - _ => None, - }; - let to_trim = match self.to_trim.evaluate(bindings, ctx) { - Missing => return Value::Missing, - Value::String(s) => s, - _ => return Value::Null, - }; - if let Some(s) = value { - let to_trim = to_trim.chars().collect_vec(); - s.trim_end_matches(&to_trim[..]).into() - } else { - Value::Null - } + trim( + self.value.as_ref(), + self.to_trim.as_ref(), + bindings, + ctx, + |s, to_trim| { + let to_trim = to_trim.chars().collect_vec(); + s.trim_end_matches(&to_trim[..]).into() + }, + ) } } @@ -1288,22 +1304,16 @@ pub struct EvalFnLtrim { impl EvalExpr for EvalFnLtrim { #[inline] fn evaluate(&self, bindings: &Tuple, ctx: &dyn EvalContext) -> Value { - let value = match self.value.evaluate(bindings, ctx) { - Missing => return Value::Missing, - Value::String(s) => Some(s), - _ => None, - }; - let to_trim = match self.to_trim.evaluate(bindings, ctx) { - Missing => return Value::Missing, - Value::String(s) => s, - _ => return Value::Null, - }; - if let Some(s) = value { - let to_trim = to_trim.chars().collect_vec(); - s.trim_start_matches(&to_trim[..]).into() - } else { - Value::Null - } + trim( + self.value.as_ref(), + self.to_trim.as_ref(), + bindings, + ctx, + |s, to_trim| { + let to_trim = to_trim.chars().collect_vec(); + s.trim_start_matches(&to_trim[..]).into() + }, + ) } }