From f66b7c8eec15b67634592ad954295e2791243aca Mon Sep 17 00:00:00 2001 From: Micha de Vries Date: Thu, 14 Dec 2023 22:23:58 +0100 Subject: [PATCH] Expand logic for static value validation (#3151) --- lib/src/sql/array.rs | 4 ++++ lib/src/sql/expression.rs | 14 ++++++++++++++ lib/src/sql/function.rs | 8 ++++++++ lib/src/sql/object.rs | 4 ++++ lib/src/sql/value/value.rs | 6 ++++-- lib/tests/field.rs | 10 +++++++++- 6 files changed, 43 insertions(+), 3 deletions(-) diff --git a/lib/src/sql/array.rs b/lib/src/sql/array.rs index 82bafdcc..8e246abe 100644 --- a/lib/src/sql/array.rs +++ b/lib/src/sql/array.rs @@ -149,6 +149,10 @@ impl Array { pub(crate) fn is_all_none_or_null(&self) -> bool { self.0.iter().all(|v| v.is_none_or_null()) } + + pub(crate) fn is_static(&self) -> bool { + self.iter().all(Value::is_static) + } } impl Display for Array { diff --git a/lib/src/sql/expression.rs b/lib/src/sql/expression.rs index f4fef327..aa337c6a 100644 --- a/lib/src/sql/expression.rs +++ b/lib/src/sql/expression.rs @@ -87,6 +87,20 @@ impl Expression { } } + pub(crate) fn is_static(&self) -> bool { + match self { + Self::Unary { + v, + .. + } => v.is_static(), + Self::Binary { + l, + r, + .. + } => l.is_static() && r.is_static(), + } + } + /// Returns the operator pub(crate) fn operator(&self) -> &Operator { match self { diff --git a/lib/src/sql/function.rs b/lib/src/sql/function.rs index f351c5d9..1691cd95 100644 --- a/lib/src/sql/function.rs +++ b/lib/src/sql/function.rs @@ -89,6 +89,14 @@ impl Function { matches!(self, Self::Script(_, _)) } + /// Check if this function has static arguments + pub fn is_static(&self) -> bool { + match self { + Self::Normal(_, a) => a.iter().all(Value::is_static), + _ => false, + } + } + /// Check if this function is a rolling function pub fn is_rolling(&self) -> bool { match self { diff --git a/lib/src/sql/object.rs b/lib/src/sql/object.rs index 030aa87d..900cfdcf 100644 --- a/lib/src/sql/object.rs +++ b/lib/src/sql/object.rs @@ -222,6 +222,10 @@ impl Object { } Ok(Value::Object(Object(x))) } + + pub(crate) fn is_static(&self) -> bool { + self.values().all(Value::is_static) + } } impl Display for Object { diff --git a/lib/src/sql/value/value.rs b/lib/src/sql/value/value.rs index 14f21387..01733030 100644 --- a/lib/src/sql/value/value.rs +++ b/lib/src/sql/value/value.rs @@ -2313,8 +2313,10 @@ impl Value { Value::Duration(_) => true, Value::Datetime(_) => true, Value::Geometry(_) => true, - Value::Array(v) => v.iter().all(Value::is_static), - Value::Object(v) => v.values().all(Value::is_static), + Value::Array(v) => v.is_static(), + Value::Object(v) => v.is_static(), + Value::Expression(v) => v.is_static(), + Value::Function(v) => v.is_static(), Value::Constant(_) => true, _ => false, } diff --git a/lib/tests/field.rs b/lib/tests/field.rs index a9c0d390..c089cd5d 100644 --- a/lib/tests/field.rs +++ b/lib/tests/field.rs @@ -447,6 +447,7 @@ async fn field_definition_default_value() -> Result<(), Error> { DEFINE FIELD primary ON product TYPE number VALUE 123.456; DEFINE FIELD secondary ON product TYPE bool DEFAULT true VALUE $value; DEFINE FIELD tertiary ON product TYPE string DEFAULT 'hello' VALUE 'tester'; + DEFINE FIELD quaternary ON product TYPE bool VALUE array::all([1, 2]); -- CREATE product:test SET primary = NULL; CREATE product:test SET secondary = 'oops'; @@ -460,7 +461,10 @@ async fn field_definition_default_value() -> Result<(), Error> { let dbs = new_ds().await?; let ses = Session::owner().with_ns("test").with_db("test"); let res = &mut dbs.execute(sql, &ses, None).await?; - assert_eq!(res.len(), 11); + assert_eq!(res.len(), 12); + // + let tmp = res.remove(0).result; + assert!(tmp.is_ok()); // let tmp = res.remove(0).result; assert!(tmp.is_ok()); @@ -510,6 +514,7 @@ async fn field_definition_default_value() -> Result<(), Error> { { id: product:test, primary: 123.456, + quaternary: true, secondary: true, tertiary: 'tester', } @@ -523,6 +528,7 @@ async fn field_definition_default_value() -> Result<(), Error> { { id: product:test, primary: 123.456, + quaternary: true, secondary: true, tertiary: 'tester', } @@ -536,6 +542,7 @@ async fn field_definition_default_value() -> Result<(), Error> { { id: product:test, primary: 123.456, + quaternary: true, secondary: false, tertiary: 'tester', } @@ -549,6 +556,7 @@ async fn field_definition_default_value() -> Result<(), Error> { { id: product:test, primary: 123.456, + quaternary: true, secondary: false, tertiary: 'tester', }