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

Optimize schema managers' ::listTables() methods #4882

Closed
wants to merge 57 commits into from
Closed
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
90b3daa
Adjust OraclePlatform and OracleSchemaManager (#1)
mondrake Oct 16, 2021
5cb5de7
Rename methods
mondrake Oct 17, 2021
42de5ec
Merge branch '3.2.x' into fix-2766
mondrake Oct 17, 2021
3670c99
Requested changes - first step
mondrake Oct 19, 2021
94a54d6
Requested changes - part 2
mondrake Oct 20, 2021
15cf5ba
Requested changes - step 3
mondrake Oct 22, 2021
b002f73
Requested changes - step 4
mondrake Oct 23, 2021
b06ad34
Merge branch '3.2.x' of https://github.com/doctrine/dbal into fix-2766
mondrake Oct 25, 2021
1bd2b6f
Requested changes - step 5
mondrake Oct 25, 2021
e78da5f
Merge branch '3.2.x' into fix-2766
mondrake Oct 25, 2021
dccb031
Requested changes - step 6
mondrake Oct 25, 2021
29e1104
Requested changes - step 7
mondrake Oct 27, 2021
8907aad
Requested changes - step 8
mondrake Oct 28, 2021
8ca9b44
Merge branch '3.2.x' into fix-2766
mondrake Oct 31, 2021
7b1266f
1
mondrake Oct 31, 2021
f4f6287
2
mondrake Oct 31, 2021
dc69211
3
mondrake Oct 31, 2021
a7be87e
4
mondrake Oct 31, 2021
a9b08f3
5
mondrake Oct 31, 2021
8cd965e
Merge branch 'fix-2766' of https://github.com/mondrake/dbal into fix-…
mondrake Oct 31, 2021
01fc721
Change approach
mondrake Oct 31, 2021
aecc823
Merge branch 'fix-2766' of https://github.com/mondrake/dbal into fix-…
mondrake Oct 31, 2021
af06f19
Cleanup
mondrake Oct 31, 2021
66edc17
Merge branch '3.2.x' into fix-2766
mondrake Nov 6, 2021
9f0f02c
Requested changes
mondrake Nov 6, 2021
1fdbacd
Reimplemented listTableDetails()
mondrake Nov 7, 2021
aa18e21
Introduce Result::fetchAllAssociativeGrouped()
morozov Nov 24, 2021
e6a48cd
Optimize OracleSchemaManager::listTables()
mondrake Nov 23, 2021
7f2bef6
Optimize MySQLSchemaManager::listTables()
morozov Nov 23, 2021
d1d629d
Deprecations
morozov Nov 24, 2021
5f4cbe6
Merge branch 'optimize-list-tables' of https://github.com/morozov/dba…
mondrake Nov 25, 2021
28e3241
fix rebase
mondrake Nov 25, 2021
f1ca87e
Fix deprecation silencing
mondrake Nov 25, 2021
c418dce
Deprecations
morozov Nov 24, 2021
c1cf64f
Add conversion for SQLite
mondrake Nov 25, 2021
eeb84cf
Merge branch '3.3.x' into fix-2766
mondrake Nov 28, 2021
6d791aa
Merge branch 'fix-2766' of https://github.com/mondrake/dbal into fix-…
mondrake Nov 28, 2021
d3371ac
Fix wrong merge
mondrake Nov 28, 2021
1822487
Merge branch 'fix-2766' of https://github.com/mondrake/dbal into fix-…
mondrake Nov 29, 2021
ade4064
Add conversion of DB2SchemaManager
mondrake Nov 30, 2021
63a7212
Add conversion of PostgreSQLSchemaManager (#23)
mondrake Dec 1, 2021
de4018d
Merge branch '3.3.x' of https://github.com/doctrine/dbal into fix-2766
mondrake Dec 1, 2021
d2aeefe
Convert SQLServerSchemaManager
mondrake Dec 1, 2021
1a79d14
Merge branch 'fix-2766' of https://github.com/mondrake/dbal into fix-…
mondrake Dec 1, 2021
9a5f4b7
Merge branch '3.3.x' of https://github.com/doctrine/dbal into fix-2766
mondrake Dec 1, 2021
9dea121
fix
mondrake Dec 1, 2021
c9205fc
Merge branch '3.3.x' into fix-2766
mondrake Dec 9, 2021
34a7ee5
Merge branch 'fix-2766' of https://github.com/mondrake/dbal into fix-…
mondrake Dec 9, 2021
b9e55fc
Fixes
mondrake Dec 9, 2021
a1e4186
Fix psalm.xml.dist
mondrake Dec 9, 2021
b799cd4
Merge branch '3.3.x' into fix-2766
mondrake Jan 1, 2022
11a1f66
Merge branch '3.3.x' into fix-2766
mondrake Jan 5, 2022
02ea328
Move listTables changes to AbstractSchemaManager default implementati…
mondrake Jan 6, 2022
570a49f
Move listTableDetails() implementation to AbstractSchemaManager (#27)
mondrake Jan 6, 2022
efe7c58
Add AbstractDatabaseIntrospectionSchemaManager extending AbstractSche…
mondrake Jan 7, 2022
02608ba
Fix static analysis (#29)
mondrake Jan 7, 2022
ff918a3
Merge branch '3.4.x' into fix-2766
mondrake Feb 4, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions psalm.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@
TODO: remove in 4.0.0
-->
<referencedClass name="Doctrine\DBAL\Schema\Constraint"/>
<!--
TODO: remove in 4.0.0
-->
<referencedClass name="Doctrine\DBAL\Platforms\DatabaseIntrospectionSQLBuilder"/>
</errorLevel>
</DeprecatedInterface>
<DeprecatedMethod>
Expand Down
28 changes: 28 additions & 0 deletions src/Platforms/DatabaseIntrospectionSQLBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Doctrine\DBAL\Platforms;

/**
* Database introspection SQL builder interface.
* Interface that DBAL platforms can implement when all database objects can be retrieved with a single metadata query.
*
* @deprecated The methods defined in this interface will be made part of the {@link AbstractPlatform} base class in
* the next major release.
*/
interface DatabaseIntrospectionSQLBuilder
{
/**
* Returns the SQL to list all the columns of all the tables in the database.
*/
public function getListDatabaseColumnsSQL(string $database): string;

/**
* Returns the SQL to list all the indexes in the database.
*/
public function getListDatabaseIndexesSQL(string $database): string;

/**
* Returns the SQL to list all the foreign keys in the database.
*/
public function getListDatabaseForeignKeysSQL(string $database): string;
}
237 changes: 150 additions & 87 deletions src/Platforms/OraclePlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use InvalidArgumentException;

use function array_merge;
use function assert;
use function count;
use function explode;
use function func_get_arg;
Expand All @@ -30,7 +31,7 @@
/**
* OraclePlatform.
*/
class OraclePlatform extends AbstractPlatform
class OraclePlatform extends AbstractPlatform implements DatabaseIntrospectionSQLBuilder
{
/**
* Assertion for Oracle identifiers.
Expand Down Expand Up @@ -431,43 +432,65 @@ protected function _getCreateTableSQL($name, array $columns, array $options = []
return $sql;
}

public function getListDatabaseIndexesSQL(string $database): string
{
return $this->getListIndexesSQL($database);
}

/**
* {@inheritDoc}
*
* @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaOracleReader.html
*/
public function getListTableIndexesSQL($table, $database = null)
{
$table = $this->normalizeIdentifier($table);
$table = $this->quoteStringLiteral($table->getName());
return $this->getListIndexesSQL($database, $table);
}

private function getListIndexesSQL(?string $database, ?string $table = null): string
{
$conditions = [];

return "SELECT uind_col.index_name AS name,
(
SELECT uind.index_type
FROM user_indexes uind
WHERE uind.index_name = uind_col.index_name
) AS type,
decode(
(
SELECT uind.uniqueness
FROM user_indexes uind
WHERE uind.index_name = uind_col.index_name
),
'NONUNIQUE',
0,
'UNIQUE',
1
) AS is_unique,
uind_col.column_name AS column_name,
uind_col.column_position AS column_pos,
(
SELECT ucon.constraint_type
FROM user_constraints ucon
WHERE ucon.index_name = uind_col.index_name
) AS is_primary
FROM user_ind_columns uind_col
WHERE uind_col.table_name = " . $table . '
ORDER BY uind_col.column_position ASC';
$sql = <<<SQL
SELECT ind_col.table_name,
ind_col.index_name AS name,
ind.index_type AS type,
decode(ind.uniqueness, 'NONUNIQUE', 0, 'UNIQUE', 1) AS is_unique,
ind_col.column_name AS column_name,
ind_col.column_position AS column_pos,
con.constraint_type AS is_primary
SQL;

if (isset($database)) {
$sql .= <<<SQL
FROM all_ind_columns ind_col
morozov marked this conversation as resolved.
Show resolved Hide resolved
LEFT JOIN all_indexes ind ON ind.owner = ind_col.index_owner AND ind.index_name = ind_col.index_name
LEFT JOIN all_constraints con ON con.owner = ind_col.index_owner AND con.index_name = ind_col.index_name
SQL;
$conditions[] = 'ind_col.index_owner = ' . $this->quoteStringLiteral(
$this->normalizeIdentifier($database)->getName()
);
if (isset($table)) {
morozov marked this conversation as resolved.
Show resolved Hide resolved
$conditions[] = 'ind_col.table_name = ' . $this->quoteStringLiteral(
$this->normalizeIdentifier($table)->getName()
);
}
} else {
$sql .= <<<SQL
FROM user_ind_columns ind_col
LEFT JOIN user_indexes ind ON ind.owner = ind_col.index_owner AND ind.index_name = ind_col.index_name
LEFT JOIN user_constraints con ON con.owner = ind_col.index_owner AND con.index_name = ind_col.index_name
SQL;
assert(isset($table));
morozov marked this conversation as resolved.
Show resolved Hide resolved
$conditions[] = 'ind_col.table_name = ' . $this->quoteStringLiteral(
$this->normalizeIdentifier($table)->getName()
);
}

$sql .= ' WHERE ' . implode(' AND ', $conditions);
$sql .= ' ORDER BY ind_col.table_name, ind_col.index_name, ind_col.column_position';

return $sql;
}

/**
Expand Down Expand Up @@ -632,36 +655,69 @@ private function getAutoincrementIdentifierName(Identifier $table)
: $identifierName;
}

public function getListDatabaseForeignKeysSQL(string $database): string
{
return $this->getListForeignKeysSQL($database);
}

/**
* {@inheritDoc}
*/
public function getListTableForeignKeysSQL($table)
{
$table = $this->normalizeIdentifier($table);
$table = $this->quoteStringLiteral($table->getName());
return $this->getListForeignKeysSQL(null, $table);
}

private function getListForeignKeysSQL(?string $database, ?string $table = null): string
{
$conditions = [];

$sql = <<<SQL
morozov marked this conversation as resolved.
Show resolved Hide resolved
SELECT cols.table_name,
alc.constraint_name,
alc.DELETE_RULE,
cols.column_name "local_column",
morozov marked this conversation as resolved.
Show resolved Hide resolved
cols.position,
r_cols.table_name "references_table",
r_cols.column_name "foreign_column"
SQL;

return "SELECT alc.constraint_name,
alc.DELETE_RULE,
cols.column_name \"local_column\",
cols.position,
(
SELECT r_cols.table_name
FROM user_cons_columns r_cols
WHERE alc.r_constraint_name = r_cols.constraint_name
AND r_cols.position = cols.position
) AS \"references_table\",
(
SELECT r_cols.column_name
FROM user_cons_columns r_cols
WHERE alc.r_constraint_name = r_cols.constraint_name
AND r_cols.position = cols.position
) AS \"foreign_column\"
FROM user_cons_columns cols
JOIN user_constraints alc
ON alc.constraint_name = cols.constraint_name
AND alc.constraint_type = 'R'
AND alc.table_name = " . $table . '
ORDER BY cols.constraint_name ASC, cols.position ASC';
if (isset($database)) {
$sql .= <<<SQL
morozov marked this conversation as resolved.
Show resolved Hide resolved
FROM all_cons_columns cols
LEFT JOIN all_constraints alc ON alc.owner = cols.owner AND alc.constraint_name = cols.constraint_name
LEFT JOIN all_cons_columns r_cols ON r_cols.owner = alc.r_owner AND
r_cols.constraint_name = alc.r_constraint_name AND
r_cols.position = cols.position
SQL;
$conditions[] = 'cols.owner = ' . $this->quoteStringLiteral(
$this->normalizeIdentifier($database)->getName()
);
if (isset($table)) {
$conditions[] = 'cols.table_name = ' . $this->quoteStringLiteral(
$this->normalizeIdentifier($table)->getName()
);
}
} else {
assert(isset($table));
$sql .= <<<SQL
FROM user_cons_columns cols
LEFT JOIN user_constraints alc ON alc.owner = cols.owner AND alc.constraint_name = cols.constraint_name
LEFT JOIN user_cons_columns r_cols ON r_cols.owner = alc.r_owner AND
r_cols.constraint_name = alc.r_constraint_name AND
r_cols.position = cols.position
SQL;
$conditions[] = 'cols.table_name = ' . $this->quoteStringLiteral(
$this->normalizeIdentifier($table)->getName()
);
}

$conditions[] = "alc.constraint_type = 'R'";

$sql .= ' WHERE ' . implode(' AND ', $conditions);
$sql .= ' ORDER BY cols.table_name, cols.constraint_name, cols.position';

return $sql;
}

/**
Expand All @@ -675,48 +731,55 @@ public function getListTableConstraintsSQL($table)
return 'SELECT * FROM user_constraints WHERE table_name = ' . $table;
}

public function getListDatabaseColumnsSQL(string $database): string
{
return $this->getListColumnsSQL($database);
}

/**
* {@inheritDoc}
*/
public function getListTableColumnsSQL($table, $database = null)
{
$table = $this->normalizeIdentifier($table);
$table = $this->quoteStringLiteral($table->getName());
return $this->getListColumnsSQL($database, $table);
}

private function getListColumnsSQL(?string $database, ?string $table = null): string
{
$conditions = [];

$tabColumnsTableName = 'user_tab_columns';
$colCommentsTableName = 'user_col_comments';
$tabColumnsOwnerCondition = '';
$colCommentsOwnerCondition = '';
$sql = 'SELECT c.table_name, c.*, d.comments AS comments ';

if ($database !== null && $database !== '/') {
$database = $this->normalizeIdentifier($database);
$database = $this->quoteStringLiteral($database->getName());
$tabColumnsTableName = 'all_tab_columns';
$colCommentsTableName = 'all_col_comments';
$tabColumnsOwnerCondition = ' AND c.owner = ' . $database;
$colCommentsOwnerCondition = ' AND d.OWNER = c.OWNER';
if (isset($database)) {
$sql .= <<<SQL
FROM all_tab_columns c
LEFT JOIN all_col_comments d ON d.OWNER = c.OWNER AND d.TABLE_NAME = c.TABLE_NAME AND
d.COLUMN_NAME = c.COLUMN_NAME
SQL;
$conditions[] = 'c.owner = ' . $this->quoteStringLiteral(
$this->normalizeIdentifier($database)->getName()
);
if (isset($table)) {
$conditions[] = 'c.table_name = ' . $this->quoteStringLiteral(
$this->normalizeIdentifier($table)->getName()
);
}
} else {
assert(isset($table));
$sql .= <<<SQL
FROM user_tab_columns c
LEFT JOIN user_col_comments d ON d.OWNER = c.OWNER AND d.TABLE_NAME = c.TABLE_NAME AND
d.COLUMN_NAME = c.COLUMN_NAME
SQL;
$conditions[] = 'c.table_name = ' . $this->quoteStringLiteral(
$this->normalizeIdentifier($table)->getName()
);
}

return sprintf(
<<<'SQL'
SELECT c.*,
(
SELECT d.comments
FROM %s d
WHERE d.TABLE_NAME = c.TABLE_NAME%s
AND d.COLUMN_NAME = c.COLUMN_NAME
) AS comments
FROM %s c
WHERE c.table_name = %s%s
ORDER BY c.column_id
SQL
,
$colCommentsTableName,
$colCommentsOwnerCondition,
$tabColumnsTableName,
$table,
$tabColumnsOwnerCondition
);
$sql .= ' WHERE ' . implode(' AND ', $conditions);
$sql .= ' ORDER BY c.table_name, c.column_id';

return $sql;
}

/**
Expand Down
Loading