Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: [SQLSRV] Query Builder always sets "<database>"."<schema>". to the table name. #8786

Merged
merged 10 commits into from
May 2, 2024

Conversation

ping-yee
Copy link
Contributor

Description
See #8697

Checklist:

  • Securely signed commits
  • Component(s) with PHPDoc blocks, only if necessary or adds value
  • Unit testing, with >80% coverage
  • User guide updated
  • Conforms to style guide

@kenjis kenjis added bug Verified issues on the current code behavior or pull requests that will fix them database Issues or pull requests that affect the database layer labels Apr 14, 2024
@kenjis
Copy link
Member

kenjis commented Apr 21, 2024

@codeigniter4/database-team
This PR resolves the issue consistent with the current implementation.
However, such ad hoc code complicates the code and is not a fundamental solution.

Then I am not sure why only SQLSRV generates table names with database and schema names.
I am not sure if this PR should be merged.

@sclubricants
Copy link
Member

sclubricants commented Apr 24, 2024

Do we have this problem with postgre too? I know it uses schema sometimes as well..

@kenjis
Copy link
Member

kenjis commented Apr 25, 2024

@sclubricants No. Only SQLSRV has the getFullName() method and use it.

private function getFullName(string $table): string

This test passes.

--- a/tests/system/Database/Builder/FromTest.php
+++ b/tests/system/Database/Builder/FromTest.php
@@ -15,6 +15,7 @@ namespace CodeIgniter\Database\Builder;
 
 use CodeIgniter\Database\BaseBuilder;
 use CodeIgniter\Database\SQLSRV\Builder as SQLSRVBuilder;
+use CodeIgniter\Database\Postgre\Builder as PostgreBuilder;
 use CodeIgniter\Test\CIUnitTestCase;
 use CodeIgniter\Test\Mock\MockConnection;
 
@@ -153,4 +154,15 @@ final class FromTest extends CIUnitTestCase
 
         $this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect()));
     }
+
+    public function testConstructorWithMultipleSegmentTable(): void
+    {
+        $this->db = new MockConnection(['DBDriver' => 'Postgre', 'database' => 'test', 'schema' => 'dbo']);
+
+        $builder = new PostgreBuilder('database.dbo.table', $this->db);
+
+        $expectedSQL = 'SELECT * FROM "database"."dbo"."table"';
+
+        $this->assertSame($expectedSQL, str_replace("\n", ' ', $builder->getCompiledSelect()));
+    }
 }

@michalsn
Copy link
Member

@kenjis

Then I am not sure why only SQLSRV generates table names with database and schema names.
I am not sure if this PR should be merged.

It was related to some reported issue, but I can't find it now.

I believe it was something related to using non-default schema. In that case, the generated queries weren't using the correct one...

AFAIR in SQLSRV you can't declare something like use mySchemaName. So if we're using the non-default schema, we have to declare it precisely every time in the query.

@kenjis
Copy link
Member

kenjis commented May 1, 2024

@michalsn This? #4246
But there is no getFullName() (and Builder for sqlsrv) in CI3.
https://github.com/bcit-ci/CodeIgniter/tree/develop/system/database/drivers/sqlsrv

It seems SQLSRV was added in #3714, and it uses getFullName() from the beginning.
1e43715#diff-9824e937f41ead0d8d69015f5c47e4adce5518bf7aea4bf87fbed37eb783c67cR157

getFullName() in #3714:

        /**
	 * Get full name of the table
	 *
	 * @param string $table
	 *
	 * @return string
	 */
	private function getFullName(string $table): string
	{
		if ($this->db->escapeChar === '"')
		{
			return '"' . $this->db->getDatabase() . '"."' . $this->db->schema . '"."' . str_replace('"', '', $table) . '"';
		}
		return '[' . $this->db->getDatabase() . '].[' . $this->db->schema . '].[' . str_replace('"', '', $table) . ']';
	}

@kenjis
Copy link
Member

kenjis commented May 1, 2024

AFAIR in SQLSRV you can't declare something like use mySchemaName. So if we're using the non-default schema, we have to declare it precisely every time in the query.

I googled, but yes, there seems no way to set schema in a connection.
https://stackoverflow.com/questions/4942023/set-default-schema-for-a-sql-query

@michalsn
Copy link
Member

michalsn commented May 1, 2024

Yes, that was the issue/PR I had in mind.

The getFullName() method was probably created to simplify the code. I've never worked with non-default schema, so I can't determine the exact differences with CI4, but it seems to me that in CI3 we had to manually declare the schema if it wasn't the default one. In CI4 we have a config variable for that, so implementing the getFullName() was a convenient way to build the proper table name.

@kenjis
Copy link
Member

kenjis commented May 2, 2024

Okay, in summary, it looks like this?

  • in CI3, we cannot set schema in DB config, and CI3 does nothing to schema in gererated SQL statements.
  • in CI4, we can set schema in DB config, and there is no way to set the schema in a DB connection. So CI4 generates full tablename (database.schema.table)

@michalsn
Copy link
Member

michalsn commented May 2, 2024

Yes.

@kenjis kenjis merged commit 4d1d361 into codeigniter4:develop May 2, 2024
40 checks passed
@kenjis
Copy link
Member

kenjis commented May 2, 2024

@ping-yee Thank you!

@kenjis kenjis changed the title fix: [SQLSRV] Query Builder always sets "<database>"."<schema>". to the table name. fix: [SQLSRV] Query Builder always sets "<database>"."<schema>". to the table name. Jun 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Verified issues on the current code behavior or pull requests that will fix them database Issues or pull requests that affect the database layer
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants