Skip to content

Instantly share code, notes, and snippets.

@narfbg
Last active December 16, 2015 09:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save narfbg/5412104 to your computer and use it in GitHub Desktop.
Save narfbg/5412104 to your computer and use it in GitHub Desktop.
Possible fix for CI issue 2406
diff --git a/system/database/DB_query_builder.php b/system/database/DB_query_builder.php
index 292621b..569490e 100644
--- a/system/database/DB_query_builder.php
+++ b/system/database/DB_query_builder.php
@@ -2554,7 +2554,7 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
{
continue;
}
- $this->$qb_variable = array_merge($this->$qb_variable, array_diff($this->$qb_cache_var, $this->$qb_variable));
+ $this->$qb_variable = array_merge($this->$qb_variable, array_udiff($this->$qb_cache_var, $this->$qb_variable, '_ci_array_diff'));
}
// If we are "protecting identifiers" we need to examine the "from"
@@ -2679,5 +2679,36 @@ abstract class CI_DB_query_builder extends CI_DB_driver {
}
+// --------------------------------------------------------------------
+
+if ( ! function_exists('_ci_array_diff'))
+{
+ /**
+ * An alternative to the native array_diff() function
+ * that can also compare multi-dimensional arrays and is
+ * intended to be used with array_udiff() only.
+ *
+ * @deprecated 3.0.0 Replace its usage with a lambda function
+ * when PHP 5.3 becomes the minimum requirement.
+ *
+ * @param mixed $value1
+ * @param mixed $value2
+ * @return int
+ */
+ function _ci_array_diff($value1, $value2)
+ {
+ if ($value1 === $value2)
+ {
+ return 0;
+ }
+ elseif ($value1 > $value2)
+ {
+ return 1;
+ }
+
+ return -1;
+ }
+}
+
/* End of file DB_query_builder.php */
/* Location: ./system/database/DB_query_builder.php */
\ No newline at end of file
@GDmac
Copy link

GDmac commented Apr 18, 2013

New values should be appended, e.g. any new where clause should come after any cached values.

// $this->$qb_variable = 
//      array_merge(
//           $this->$qb_variable, 
//           array_udiff(
//                  $this->$qb_cache_var, 
//                  $this->$qb_variable, 
//                  '_ci_array_diff'
//              )
//         );

$this->$qb_variable = 
    array_merge(
        $this->$qb_cache_var,
        array_udiff(
            $this->$qb_variable,
            $this->$qb_cache_var, 
            '_ci_array_diff'
        )
    );

You can test with the following, where the or_where would otherwise be placed before the other where clauses, causing an mysql error.

$this->output->enable_profiler(TRUE);

$this->db->start_cache();

$foo = $this->db
  ->select('id, title')
  ->from('pages')
  ->where('id', 2)
  ->or_where('id', 3);

$this->db->stop_cache();

echo $foo->count_all_results();

$foo->or_where('id', 4);

var_dump( $foo->get()->result() );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment