From 4cca62ee5fa40b3b73257d2a17008ae436d8097b Mon Sep 17 00:00:00 2001
From: Denis Smirnov <sd@picodata.io>
Date: Tue, 14 May 2024 15:43:22 +0700
Subject: [PATCH] fix: cte with left join

---
 .../test_app/test/integration/cte_test.lua         | 14 +++++++++++++-
 sbroad-core/src/executor/ir.rs                     | 13 ++++++-------
 2 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/sbroad-cartridge/test_app/test/integration/cte_test.lua b/sbroad-cartridge/test_app/test/integration/cte_test.lua
index cad5167b8..cbf0e74ec 100644
--- a/sbroad-cartridge/test_app/test/integration/cte_test.lua
+++ b/sbroad-cartridge/test_app/test/integration/cte_test.lua
@@ -55,7 +55,7 @@ g.test_cte = function ()
     t.assert_items_equals(r["metadata"], { {name = "CTE.B", type = "number"} })
     t.assert_items_equals(r["rows"], { {4}, {5}, {4}, {5} })
 
-    -- join table with cte
+    -- inner join table with cte
     r, err = api:call("sbroad.execute", { [[
         WITH cte (b) AS (SELECT "a" FROM "t" WHERE "id" = 1 OR "id" = 2)
         SELECT cte.b, "t"."a" FROM cte JOIN "t" ON cte.b = "t"."id"
@@ -67,6 +67,18 @@ g.test_cte = function ()
     )
     t.assert_items_equals(r["rows"], { {1, 1}, {2, 2} })
 
+    -- left outer join table with cte
+    r, err = api:call("sbroad.execute", { [[
+        WITH cte (b) AS (SELECT "a" FROM "t" WHERE "id" = 1 OR "id" = 2)
+        SELECT cte.b, "t"."a" FROM cte LEFT JOIN "t" ON cte.b = "t"."id"
+    ]], })
+    t.assert_equals(err, nil)
+    t.assert_items_equals(
+        r["metadata"],
+        { {name = "B", type = "number"}, {name = "a", type = "number"} }
+    )
+    t.assert_items_equals( r["rows"], { {1, 1}, {2, 2} })
+
     -- cte in aggregate
     r, err = api:call("sbroad.execute", { [[
         WITH cte (b) AS (SELECT "a" FROM "t" WHERE "id" > 3)
diff --git a/sbroad-core/src/executor/ir.rs b/sbroad-core/src/executor/ir.rs
index a13c40ec9..b1014daf4 100644
--- a/sbroad-core/src/executor/ir.rs
+++ b/sbroad-core/src/executor/ir.rs
@@ -263,14 +263,13 @@ impl ExecutionPlan {
     /// # Errors
     /// - node is not valid
     pub fn get_motion_alias(&self, node_id: usize) -> Result<Option<SmolStr>, SbroadError> {
-        let sq_id = &self.get_motion_child(node_id)?;
-        if let Relational::ScanSubQuery { alias, .. } =
-            self.get_ir_plan().get_relation_node(*sq_id)?
-        {
-            return Ok(alias.clone());
+        let child_id = &self.get_motion_child(node_id)?;
+        let child_rel = self.get_ir_plan().get_relation_node(*child_id)?;
+        match child_rel {
+            Relational::ScanSubQuery { alias, .. } => Ok(alias.clone()),
+            Relational::ScanCte { alias, .. } => Ok(Some(alias.clone())),
+            _ => Ok(None),
         }
-
-        Ok(None)
     }
 
     /// Get root from motion sub tree
-- 
GitLab