diff --git a/src/ir.rs b/src/ir.rs
index a800e5f847e9903b98b798450dc220cac38a2c21..6e4be5ddff1143f27d8dcfdcafd8690ba16f875b 100644
--- a/src/ir.rs
+++ b/src/ir.rs
@@ -158,6 +158,14 @@ impl Plan {
         }
     }
 
+    /// Get a top node of the plan tree.
+    ///
+    /// # Errors
+    /// - top node is None (i.e. invalid plan)
+    pub fn get_top(&self) -> Result<usize, QueryPlannerError> {
+        self.top.ok_or(QueryPlannerError::InvalidPlan)
+    }
+
     /// Construct a plan from the YAML file.
     ///
     /// # Errors
diff --git a/src/ir/tree/tests.rs b/src/ir/tree/tests.rs
index f7bc9d5a978fc7a3fb6ae2d1f9420788aca6348d..a78f7a0441275afc5cfc478643f54f3aaaa865cb 100644
--- a/src/ir/tree/tests.rs
+++ b/src/ir/tree/tests.rs
@@ -99,7 +99,7 @@ fn relational_post() {
 
     let union_id = plan.add_union_all(scan_t1_id, selection_id).unwrap();
     plan.set_top(union_id).unwrap();
-    let top = plan.top.unwrap();
+    let top = plan.get_top().unwrap();
 
     // Traverse the tree
     let mut dft_post = DftPost::new(&top, |node| plan.nodes.rel_iter(node));