From bbcb04cc15a8fd3dde612f458952a7a9b2eaeb9a Mon Sep 17 00:00:00 2001 From: Arseniy Volynets <a.volynets@picodata.io> Date: Mon, 23 Sep 2024 12:09:32 +0300 Subject: [PATCH] feat: handle no values for params case correctly --- .../test_app/test/integration/api_test.lua | 4 +-- sbroad-core/src/ir/api/parameter.rs | 30 +++++++++++++++++-- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/sbroad-cartridge/test_app/test/integration/api_test.lua b/sbroad-cartridge/test_app/test/integration/api_test.lua index cf60d18a39..5985e48780 100644 --- a/sbroad-cartridge/test_app/test/integration/api_test.lua +++ b/sbroad-cartridge/test_app/test/integration/api_test.lua @@ -213,9 +213,9 @@ g.test_query_errored = function() -- check err when params lenght is less then amount of sign `?` local _, err = api:call("sbroad.execute", { [[SELECT * FROM "testing_space" where "id" = ?]], {} }) - t.assert_equals( + t.assert_str_contains( tostring(err), - "Sbroad Error: build query: invalid node: parameter node does not refer to an expression" + "Expected at least 1 values for parameters. Got 0" ) end diff --git a/sbroad-core/src/ir/api/parameter.rs b/sbroad-core/src/ir/api/parameter.rs index 7fe94423bb..eb6597ecc8 100644 --- a/sbroad-core/src/ir/api/parameter.rs +++ b/sbroad-core/src/ir/api/parameter.rs @@ -1,4 +1,4 @@ -use crate::errors::SbroadError; +use crate::errors::{Entity, SbroadError}; use crate::ir::node::block::{Block, MutBlock}; use crate::ir::node::expression::{Expression, MutExpression}; use crate::ir::node::relational::{MutRelational, Relational}; @@ -7,7 +7,7 @@ use crate::ir::node::{ MutNode, Node64, NodeId, Parameter, Procedure, Row, Selection, StableFunction, Trim, UnaryExpr, ValuesRow, }; -use crate::ir::tree::traversal::{LevelNode, PostOrder}; +use crate::ir::tree::traversal::{LevelNode, PostOrder, PostOrderWithFilter}; use crate::ir::value::Value; use crate::ir::{ArenaType, Node, OptionParamValue, Plan, ValueIdx}; use crate::otm::child_span; @@ -687,8 +687,32 @@ impl Plan { #[allow(clippy::too_many_lines)] #[otm_child_span("plan.bind")] pub fn bind_params(&mut self, values: Vec<Value>) -> Result<(), SbroadError> { - // Nothing to do here. if values.is_empty() { + // Check there are no parameters in the plan, + // we must fail early here, rather than on + // later pipeline stages. + let mut param_count: usize = 0; + let filter = Box::new(|x: NodeId| -> bool { + if let Ok(Node::Parameter(_)) = self.get_node(x) { + param_count += 1; + } + false + }); + let mut dfs = + PostOrderWithFilter::with_capacity(|x| self.subtree_iter(x, false), 0, filter); + dfs.populate_nodes(self.get_top()?); + drop(dfs); + + if param_count > 0 { + return Err(SbroadError::Invalid( + Entity::Query, + Some(format_smolstr!( + "Expected at least {param_count} values for parameters. Got 0" + )), + )); + } + + // Nothing to do here. return Ok(()); } -- GitLab