Fix a few join() bugs
diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php
index d5367b4..1060ecc 100644
--- a/system/database/DB_driver.php
+++ b/system/database/DB_driver.php
@@ -970,7 +970,7 @@
 	 */
 	public function escape_identifiers($item)
 	{
-		if ($this->_escape_char === '')
+		if ($this->_escape_char === '' OR empty($item))
 		{
 			return $item;
 		}
@@ -983,8 +983,8 @@
 
 			return $item;
 		}
-		// Avoid breaking functions inside queries
-		elseif (strpos($item, '(') !== FALSE)
+		// Avoid breaking functions and literal values inside queries
+		elseif (ctype_digit($item) OR $item[0] === "'" OR strpos($item, '(') !== FALSE)
 		{
 			return $item;
 		}
diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php
index 79e67e0..479b7f2 100644
--- a/system/database/DB_query_builder.php
+++ b/system/database/DB_query_builder.php
@@ -350,18 +350,18 @@
 		is_bool($escape) OR $escape = $this->_protect_identifiers;
 
 		// Split multiple conditions
-		if ($escape === TRUE && preg_match_all('/\sAND\s|\sOR\s/i', $cond, $m, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
+		if ($escape === TRUE && preg_match_all('/\sAND\s|\sOR\s/i', $cond, $m, PREG_OFFSET_CAPTURE))
 		{
 			$newcond = '';
 			$m[0][] = array('', strlen($cond));
 
 			for ($i = 0, $c = count($m[0]), $s = 0;
 				$i < $c;
-				$s += $m[0][$i][1] + strlen($m[0][$i][0]), $i++)
+				$s = $m[0][$i][1] + strlen($m[0][$i][0]), $i++)
 			{
-				$temp = substr($cond, $s, $m[0][$i][1]);
+				$temp = substr($cond, $s, ($m[0][$i][1] - $s));
 
-				$newcond .= preg_match('/([\[\w\.-]+)([\W\s]+)(.+)/i', $temp, $match)
+				$newcond .= preg_match("/([\[\]\w\.'-]+)(\s*[^\"\[`'\w]+\s*)(.+)/i", $temp, $match)
 						? $this->protect_identifiers($match[1]).$match[2].$this->protect_identifiers($match[3])
 						: $temp;
 
@@ -371,7 +371,7 @@
 			$cond = ' ON '.$newcond;
 		}
 		// Split apart the condition and protect the identifiers
-		elseif ($escape === TRUE && preg_match('/([\[\w\.-]+)([\W\s]+)(.+)/i', $cond, $match))
+		elseif ($escape === TRUE && preg_match("/([\[\]\w\.'-]+)(\s*[^\"\[`'\w]+\s*)(.+)/i", $cond, $match))
 		{
 			$cond = ' ON '.$this->protect_identifiers($match[1]).$match[2].$this->protect_identifiers($match[3]);
 		}
diff --git a/tests/codeigniter/database/query_builder/join_test.php b/tests/codeigniter/database/query_builder/join_test.php
index b8cf2a8..6d5fc64 100644
--- a/tests/codeigniter/database/query_builder/join_test.php
+++ b/tests/codeigniter/database/query_builder/join_test.php
@@ -35,4 +35,24 @@
 		$this->assertEquals('Developer', $job_user[0]['job_name']);
 	}
 
+	// ------------------------------------------------------------------------
+
+	public function test_join_escape_multiple_conditions()
+	{
+		// We just need a valid query produced, not one that makes sense
+		$fields = array($this->db->protect_identifiers('table1.field1'), $this->db->protect_identifiers('table2.field2'));
+
+		$expected = 'SELECT '.implode(', ', $fields)
+				."\nFROM ".$this->db->escape_identifiers('table1')
+				."\nLEFT JOIN ".$this->db->escape_identifiers('table2').' ON '.implode(' = ', $fields)
+				.' AND '.$fields[0]." = 'foo' AND ".$fields[1].' = 0';
+
+		$result = $this->db->select('table1.field1, table2.field2')
+				->from('table1')
+				->join('table2', "table1.field1 = table2.field2 AND table1.field1 = 'foo' AND table2.field2 = 0", 'LEFT')
+				->get_compiled_select();
+
+		$this->assertEquals($sql, $result);
+	}
+
 }
\ No newline at end of file
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index 716e08f..75229f9 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -307,6 +307,7 @@
 -  Fixed a bug (#427) - :doc:`Form Validation Library <libraries/form_validation>` method ``strip_image_tags()`` was an alias to a non-existent method.
 -  Fixed a bug (#1545) - :doc:`Query Builder <database/query_builder>` method ``limit()`` wasn't executed properly under Oracle.
 -  Fixed a bug (#1551) - :doc:`Date Helper <helpers/date_helper>` function ``standard_date()`` didn't properly format *W3C* and *ATOM* standard dates.
+-  Fixed a bug in :doc:`Query Builder <database/query_builder>` method join() where literal values were escaped as if they were fields.
 
 Version 2.1.2
 =============