Fix #2579: Query Builder's "no escape" functionality didn't work properly with query cache
diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php
index 1d41a19..c543e15 100644
--- a/system/database/DB_query_builder.php
+++ b/system/database/DB_query_builder.php
@@ -2556,6 +2556,10 @@
 		{
 			return;
 		}
+		elseif (in_array('select', $this->qb_cache_exists, TRUE))
+		{
+			$qb_no_escape = $this->qb_cache_no_escape;
+		}
 
 		foreach (array_unique($this->qb_cache_exists) as $val) // select, from, etc.
 		{
@@ -2563,12 +2567,23 @@
 			$qb_cache_var	= 'qb_cache_'.$val;
 			$qb_new 	= $this->$qb_cache_var;
 
-			foreach ($this->$qb_variable as &$qb_var)
+			for ($i = 0, $c = count($this->$qb_variable); $i < $c; $i++)
 			{
-			 	in_array($qb_var, $qb_new, TRUE) OR $qb_new[] = $qb_var;
+				if ( ! in_array($this->{$qb_variable}[$i], $qb_new, TRUE))
+				{
+					$qb_new[] = $this->{$qb_variable}[$i];
+					if ($val === 'select')
+					{
+						$qb_no_escape[] = $this->qb_no_escape[$i];
+					}
+				}
 			}
 
 			$this->$qb_variable = $qb_new;
+			if ($val === 'select')
+			{
+				$this->qb_no_escape = $qb_no_escape;
+			}
 		}
 
 		// If we are "protecting identifiers" we need to examine the "from"
@@ -2577,8 +2592,6 @@
 		{
 			$this->_track_aliases($this->qb_from);
 		}
-
-		$this->qb_no_escape = array_merge($this->qb_no_escape, array_diff($this->qb_cache_no_escape, $this->qb_no_escape));
 	}
 
 	// --------------------------------------------------------------------
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index 8bba394..7cc27eb 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -630,6 +630,7 @@
 -  Fixed a bug (#2515) - ``_exception_handler()`` used to send the 200 "OK" HTTP status code and didn't stop script exection even on fatal errors.
 -  Fixed a bug - Redis :doc:`Caching <libraries/caching>` driver didn't handle connection failures properly.
 -  Fixed a bug (#2756) - :doc:`Database Class <database/index>` executed the MySQL-specific `SET SESSION sql_mode` query for all drivers when the 'stricton' option is set.
+-  Fixed a bug (#2579) - :doc:`Query Builder <database/query_builder>`s "no escape" functionality didn't work properly with query cache.
 
 Version 2.1.4
 =============