diff --git a/src/frontend/sql.rs b/src/frontend/sql.rs
index fb973e88815ea40132995b48a47230073bee8597..6aefb34e68f7c0dc389c74af62e852dee8458ddc 100644
--- a/src/frontend/sql.rs
+++ b/src/frontend/sql.rs
@@ -3,6 +3,7 @@
 //! Parses an SQL statement to the abstract syntax tree (AST)
 //! and builds the intermediate representation (IR).
 
+use ahash::RandomState;
 use pest::Parser;
 use std::collections::{HashMap, HashSet};
 use traversal::DftPost;
@@ -764,53 +765,106 @@ impl Plan {
         let mut idx = 0;
 
         // Add parameter values to the plan arena (but they are still unlinked to the tree).
-        let mut value_ids: Vec<usize> = Vec::with_capacity(params.len());
+        let value_ids: Vec<usize> = params
+            .iter()
+            .map(|param| self.add_const(param.clone()))
+            .collect();
+
         // We need to use rows instead of values in some cases (AST can solve
         // this problem for non-parameterized queries, but for parameterized
         // queries it is IR responsibility).
-        let mut row_ids: Vec<usize> = Vec::with_capacity(params.len());
-        for param in params {
-            let val_id = self.add_const(param.clone());
-            value_ids.push(val_id);
-            let row_id = self.nodes.add_row(vec![val_id], None);
-            row_ids.push(row_id);
-        }
+        let mut row_ids: HashMap<usize, usize, RandomState> =
+            HashMap::with_hasher(RandomState::new());
 
         // Gather all parameter nodes from the tree to a hash set.
         let param_set = self.get_params();
 
         // Closure to retrieve a corresponding value for a parameter node.
-        let get_value =
-            |param_id: &usize, pos: usize| -> Result<Option<usize>, QueryPlannerError> {
-                if !param_set.contains(param_id) {
-                    return Ok(None);
-                }
-                let val_id = value_ids.get(pos).ok_or_else(|| {
-                    QueryPlannerError::CustomError(format!(
-                        "Parameter in position {} is not found.",
-                        pos
-                    ))
-                })?;
-                Ok(Some(*val_id))
-            };
-
-        // Closure to retrieve a corresponding row for a parameter node.
-        let get_row = |param_id: &usize, pos: usize| -> Result<Option<usize>, QueryPlannerError> {
-            if !param_set.contains(param_id) {
-                return Ok(None);
-            }
-            let row_id = row_ids.get(pos).ok_or_else(|| {
+        let get_value = |pos: usize| -> Result<usize, QueryPlannerError> {
+            let val_id = value_ids.get(pos).ok_or_else(|| {
                 QueryPlannerError::CustomError(format!(
                     "Parameter in position {} is not found.",
                     pos
                 ))
             })?;
-            Ok(Some(*row_id))
+            Ok(*val_id)
+        };
+
+        // Populate rows.
+        for id in &nodes {
+            let node = self.get_node(*id)?;
+            match node {
+                Node::Relational(rel) => match rel {
+                    Relational::Selection {
+                        filter: ref param_id,
+                        ..
+                    }
+                    | Relational::InnerJoin {
+                        condition: ref param_id,
+                        ..
+                    }
+                    | Relational::Projection {
+                        output: ref param_id,
+                        ..
+                    } => {
+                        if param_set.contains(param_id) {
+                            let val_id = get_value(idx)?;
+                            row_ids.insert(idx, self.nodes.add_row(vec![val_id], None));
+                            idx += 1;
+                        }
+                    }
+                    _ => {}
+                },
+                Node::Expression(expr) => match expr {
+                    Expression::Alias {
+                        child: ref param_id,
+                        ..
+                    }
+                    | Expression::Unary {
+                        child: ref param_id,
+                        ..
+                    } => {
+                        if param_set.contains(param_id) {
+                            idx += 1;
+                        }
+                    }
+                    Expression::Bool {
+                        ref left,
+                        ref right,
+                        ..
+                    } => {
+                        for param_id in &[*left, *right] {
+                            if param_set.contains(param_id) {
+                                let val_id = get_value(idx)?;
+                                row_ids.insert(idx, self.nodes.add_row(vec![val_id], None));
+                                idx += 1;
+                            }
+                        }
+                    }
+                    Expression::Row { ref list, .. } => {
+                        for param_id in list {
+                            if param_set.contains(param_id) {
+                                idx += 1;
+                            }
+                        }
+                    }
+                    Expression::Constant { .. } | Expression::Reference { .. } => {}
+                },
+                Node::Parameter => {}
+            }
+        }
+
+        let get_row = |idx: usize| -> Result<usize, QueryPlannerError> {
+            let row_id = row_ids.get(&idx).ok_or_else(|| {
+                QueryPlannerError::CustomError(format!("Row in position {} is not found.", idx))
+            })?;
+            Ok(*row_id)
         };
 
         // Replace parameters in the plan.
-        for id in nodes {
-            let node = self.get_mut_node(id)?;
+        idx = 0;
+        for id in &nodes {
+            let node = self.get_mut_node(*id)?;
             match node {
                 Node::Relational(rel) => match rel {
                     Relational::Selection {
@@ -825,7 +879,8 @@ impl Plan {
                         output: ref mut param_id,
                         ..
                     } => {
-                        if let Some(row_id) = get_row(param_id, idx)? {
+                        if param_set.contains(param_id) {
+                            let row_id = get_row(idx)?;
                             *param_id = row_id;
                             idx += 1;
                         }
@@ -841,7 +896,8 @@ impl Plan {
                         child: ref mut param_id,
                         ..
                     } => {
-                        if let Some(val_id) = get_value(param_id, idx)? {
+                        if param_set.contains(param_id) {
+                            let val_id = get_value(idx)?;
                             *param_id = val_id;
                             idx += 1;
                         }
@@ -852,7 +908,8 @@ impl Plan {
                         ..
                     } => {
                         for param_id in &mut [left, right].iter_mut() {
-                            if let Some(row_id) = get_row(param_id, idx)? {
+                            if param_set.contains(param_id) {
+                                let row_id = get_row(idx)?;
                                 **param_id = row_id;
                                 idx += 1;
                             }
@@ -860,7 +917,8 @@ impl Plan {
                     }
                     Expression::Row { ref mut list, .. } => {
                         for param_id in list {
-                            if let Some(val_id) = get_value(param_id, idx)? {
+                            if param_set.contains(param_id) {
+                                let val_id = get_value(idx)?;
                                 *param_id = val_id;
                                 idx += 1;
                             }
@@ -873,11 +931,8 @@ impl Plan {
         }
 
         // Update values row output.
-        let tree = DftPost::new(&top_id, |node| self.nodes.rel_iter(node));
-        let nodes: Vec<usize> = tree.map(|(_, id)| *id).collect();
         for id in nodes {
-            let rel = self.get_relation_node(id)?;
-            if let Relational::ValuesRow { .. } = rel {
+            if let Ok(Relational::ValuesRow { .. }) = self.get_relation_node(id) {
                 self.update_values_row(id)?;
             }
         }