diff --git a/sbroad-cartridge/test_app/test/integration/cte_test.lua b/sbroad-cartridge/test_app/test/integration/cte_test.lua
index cbf0e74ecafddadd9c7b8d8325576ec52c22f4da..96c761bab7c265f13119a442ba1d49edc73c3def 100644
--- a/sbroad-cartridge/test_app/test/integration/cte_test.lua
+++ b/sbroad-cartridge/test_app/test/integration/cte_test.lua
@@ -110,6 +110,16 @@ g.test_cte = function ()
     t.assert_items_equals(r["metadata"], { {name = "CTE.B", type = "any"} })
     t.assert_items_equals(r["rows"], { {1}, {2}, {3} })
 
+    -- union in cte
+    r, err = api:call("sbroad.execute", { [[
+        WITH c1 (a) AS (VALUES (1), (2)),
+             c2 AS (SELECT * FROM c1 UNION SELECT * FROM c1)
+        SELECT a FROM c2
+    ]], })
+    t.assert_equals(err, nil)
+    t.assert_items_equals(r["metadata"], { {name = "C2.A", type = "any"} })
+    t.assert_items_equals(r["rows"], { {1}, {2} })
+
     -- union all in cte
     r, err = api:call("sbroad.execute", { [[
         WITH cte1 (a) AS (SELECT "a" FROM "t" WHERE "id" = 1),
diff --git a/sbroad-core/src/ir/transformation/redistribution.rs b/sbroad-core/src/ir/transformation/redistribution.rs
index 701a3df8409d58cef0ddca632a5b99d51e883d5d..d713f6d2ae498f1a5fe83763b33d3725d942f3f6 100644
--- a/sbroad-core/src/ir/transformation/redistribution.rs
+++ b/sbroad-core/src/ir/transformation/redistribution.rs
@@ -1869,7 +1869,11 @@ impl Plan {
             }
             _ => {
                 // Build a virtual table on the router node.
-                map.add_child(child_id, MotionPolicy::Full, Program::default());
+                // If the child node is already some motion (UNION DISTINCT, etc.),
+                // no need to add another motion.
+                if !self.get_relation_node(child_id)?.is_motion() {
+                    map.add_child(child_id, MotionPolicy::Full, Program::default());
+                }
             }
         }
         Ok(map)