Repository: codeigniter4/CodeIgniter4 (PHP)

Issue:
Bug: table has double prefix when LIKE clause
### PHP Version

7.3

### CodeIgniter4 Version

4.1.9 + dev

### CodeIgniter4 Installation Method

Git

### Which operating systems have you tested for this bug?

Windows

### Which server did you use?

cli

### Database

_No response_

### What happened?

see https://forum.codeigniter.com/thread-81454.html

### Steps to Reproduce

```php
// database.default.DBPrefix = db_

db_connect()->table('test')->like('test.field', 'string')->getCompiledSelect();

// SELECT * FROM `db_test` WHERE `db_``db_test`.`field` LIKE '%string%' ESCAPE '!' 

```

### Expected Output

```
SELECT * FROM `db_test` WHERE `db_test`.`field` LIKE '%string%' ESCAPE '!' 
```

### Anything else?

_No response_


Discussion:
I had the same error, using CI 4.1.9.

I think it can be solved replacing the operator !== ( not identical ) to != ( not equal ) in the BaseConnection.php on line 1061.

`elseif (strpos($parts[$i], $this->DBPrefix) !== 0) {`
to
`elseif (strpos($parts[$i], $this->DBPrefix) != 0) {`
@joaisbn This was fixed by  #5778
Try the latest `develop` branch.




Patch:
diff --git a/system/Database/BaseBuilder.php b/system/Database/BaseBuilder.php
index 79bdf08ffb43..1d0c241903e8 100644
--- a/system/Database/BaseBuilder.php
+++ b/system/Database/BaseBuilder.php
@@ -1051,7 +1051,7 @@ protected function _like($field, string $match = '', string $type = 'AND ', stri
                 $bind = $this->setBind($k, "%{$v}%", $escape);
             }
 
-            $likeStatement = $this->_like_statement($prefix, $this->db->protectIdentifiers($k, false, $escape), $not, $bind, $insensitiveSearch);
+            $likeStatement = $this->_like_statement($prefix, $k, $not, $bind, $insensitiveSearch);
 
             // some platforms require an escape sequence definition for LIKE wildcards
             if ($escape === true && $this->db->likeEscapeStr !== '') {
@@ -1073,7 +1073,7 @@ protected function _like($field, string $match = '', string $type = 'AND ', stri
     protected function _like_statement(?string $prefix, string $column, ?string $not, string $bind, bool $insensitiveSearch = false): string
     {
         if ($insensitiveSearch === true) {
-            return "{$prefix} LOWER({$column}) {$not} LIKE :{$bind}:";
+            return "{$prefix} LOWER(" . $this->db->escapeIdentifiers($column) . ") {$not} LIKE :{$bind}:";
         }
 
         return "{$prefix} {$column} {$not} LIKE :{$bind}:";
diff --git a/system/Database/BaseConnection.php b/system/Database/BaseConnection.php
index 134a50517ae6..4f54c1980830 100644
--- a/system/Database/BaseConnection.php
+++ b/system/Database/BaseConnection.php
@@ -962,8 +962,9 @@ public function getConnectDuration(int $decimals = 6): string
      * the correct identifiers.
      *
      * @param array|string $item
-     * @param bool         $prefixSingle Prefix an item with no segments?
-     * @param bool         $fieldExists  Supplied $item contains a field name?
+     * @param bool         $prefixSingle       Prefix a table name with no segments?
+     * @param bool         $protectIdentifiers Protect table or column names?
+     * @param bool         $fieldExists        Supplied $item contains a column name?
      *
      * @return array|string
      */
@@ -1021,8 +1022,7 @@ public function protectIdentifiers($item, bool $prefixSingle = false, ?bool $pro
             //
             // NOTE: The ! empty() condition prevents this method
             // from breaking when QB isn't enabled.
-            $firstSegment = trim($parts[0], $this->escapeChar);
-            if (! empty($this->aliasedTables) && in_array($firstSegment, $this->aliasedTables, true)) {
+            if (! empty($this->aliasedTables) && in_array($parts[0], $this->aliasedTables, true)) {
                 if ($protectIdentifiers === true) {
                     foreach ($parts as $key => $val) {
                         if (! in_array($val, $this->reservedIdentifiers, true)) {


Test patch:
diff --git a/tests/system/Database/Builder/LikeTest.php b/tests/system/Database/Builder/LikeTest.php
index ba7c176b7c90..2d81db2b90fa 100644
--- a/tests/system/Database/Builder/LikeTest.php
+++ b/tests/system/Database/Builder/LikeTest.php
@@ -183,4 +183,27 @@ public function testCaseInsensitiveLike()
         $this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect()));
         $this->assertSame($expectedBinds, $builder->getBinds());
     }
+
+    /**
+     * @see https://github.com/codeigniter4/CodeIgniter4/issues/5775
+     */
+    public function testDBPrefixAndCoulmnWithTablename()
+    {
+        $this->db = new MockConnection(['DBPrefix' => 'db_']);
+        $builder  = new BaseBuilder('test', $this->db);
+
+        $builder->like('test.field', 'string');
+
+        $expectedSQL = <<<'SQL'
+            SELECT * FROM "db_test" WHERE "db_test"."field" LIKE '%string%' ESCAPE '!'
+            SQL;
+        $expectedBinds = [
+            'test.field' => [
+                '%string%',
+                true,
+            ],
+        ];
+        $this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect()));
+        $this->assertSame($expectedBinds, $builder->getBinds());
+    }
 }