From db7e53161391ff6db5ad920bb75cea2572351eda Mon Sep 17 00:00:00 2001 From: Softarius Date: Fri, 15 Nov 2024 16:24:59 +0300 Subject: [PATCH 1/4] Using parse_ident --- src/Pgsql/PgsqlDriver.php | 58 +++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/src/Pgsql/PgsqlDriver.php b/src/Pgsql/PgsqlDriver.php index 86ee0872..a8fa4c6a 100644 --- a/src/Pgsql/PgsqlDriver.php +++ b/src/Pgsql/PgsqlDriver.php @@ -220,6 +220,31 @@ public function getTableCreate($tables) { return []; } + + /** + * Parses the fully qualified or bare name of the database object (table, view, procedure etc.) into object + * with fields "schema" and "table" respectively + * + * @param string $table Name of the database object with schema or without it + * + * @return object + */ + private function ParseIdent($table) + { + $query=$this->getQuery(1); + $query->select(['r[1]','r[2]']) + ->from("parse_ident(:t) as r") + ->bind(':t', $table); + $qn=$this->setQuery($query) + ->loadRow(); + if ($qn[1]) + { + return (object) ['schema' => $qn[0], 'table' => $qn[1]]; + } else + { + return (object) ['schema' => $this->getDefaultSchema(), 'table' => $qn[0]]; + } + } /** * Retrieves field information about a given table. @@ -238,7 +263,7 @@ public function getTableColumns($table, $typeOnly = true) $result = []; $tableSub = $this->replacePrefix($table); - $defaultSchema = $this->getDefaultSchema(); + $fullname = $this->ParseIdent($tableSub); $this->setQuery( ' @@ -259,9 +284,9 @@ public function getTableColumns($table, $typeOnly = true) LEFT JOIN pg_catalog.pg_attrdef adef ON a.attrelid=adef.adrelid AND a.attnum=adef.adnum LEFT JOIN pg_catalog.pg_type t ON a.atttypid=t.oid WHERE a.attrelid = - (SELECT oid FROM pg_catalog.pg_class WHERE relname=' . $this->quote($tableSub) . ' + (SELECT oid FROM pg_catalog.pg_class WHERE relname=' . $this->quote($fullname->table) . ' AND relnamespace = (SELECT oid FROM pg_catalog.pg_namespace WHERE - nspname = ' . $this->quote($defaultSchema) . ') + nspname = ' . $this->quote($fullname->schema) . ') ) AND a.attnum > 0 AND NOT a.attisdropped ORDER BY a.attnum' @@ -324,8 +349,9 @@ public function getTableKeys($table) // To check if table exists and prevent SQL injection $tableList = $this->getTableList(); $tableSub = $this->replacePrefix($table); + $fullname = $this->ParseIdent($tableSub); - if (\in_array($tableSub, $tableList, true)) { + if (\in_array($fullname->table, $tableList, true)) { // Get the details columns information. $this->setQuery( ' @@ -338,7 +364,7 @@ public function getTableKeys($table) FROM pg_indexes LEFT JOIN pg_class AS pgClassFirst ON indexname=pgClassFirst.relname LEFT JOIN pg_index AS pgIndex ON pgClassFirst.oid=pgIndex.indexrelid - WHERE tablename=' . $this->quote($tableSub) . ' ORDER BY indkey' + WHERE tablename=' . $this->quote($fullname->table) . ' ORDER BY indkey' ); return $this->loadObjectList(); @@ -363,6 +389,7 @@ public function getNamesKey($table, $indKey) $this->connect(); $tableSub = $this->replacePrefix($table); + $fullname = $this->ParseIdent($tableSub); $tabInd = explode(' ', $indKey); $colNames = []; @@ -371,7 +398,7 @@ public function getNamesKey($table, $indKey) $query = $this->createQuery() ->select('attname') ->from('pg_attribute') - ->join('LEFT', 'pg_class ON pg_class.relname=' . $this->quote($tableSub)) + ->join('LEFT', 'pg_class ON pg_class.relname=' . $this->quote($fullname->table)) ->where('attnum=' . $numCol . ' AND attrelid=pg_class.oid'); $this->setQuery($query); $colNames[] = $this->loadResult(); @@ -417,8 +444,9 @@ public function getTableSequences($table) // To check if table exists and prevent SQL injection $tableList = $this->getTableList(); $tableSub = $this->replacePrefix($table); + $fullname = $this->ParseIdent($tableSub); - if (\in_array($tableSub, $tableList, true)) { + if (\in_array($fullname->table, $tableList, true)) { $name = [ 's.relname', 'n.nspname', 't.relname', 'a.attname', 'info.data_type', 'info.minimum_value', 'info.maximum_value', 'info.increment', 'info.cycle_option', 'info.start_value', @@ -437,7 +465,7 @@ public function getTableSequences($table) ->leftJoin('pg_namespace n ON n.oid = t.relnamespace') ->leftJoin('pg_attribute a ON a.attrelid = t.oid AND a.attnum = d.refobjsubid') ->leftJoin('information_schema.sequences AS info ON info.sequence_name = s.relname') - ->where('s.relkind = ' . $this->quote('S') . ' AND d.deptype = ' . $this->quote('a') . ' AND t.relname = ' . $this->quote($tableSub)); + ->where('s.relkind = ' . $this->quote('S') . ' AND d.deptype = ' . $this->quote('a') . ' AND t.relname = ' . $this->quote($fullname->table)); $this->setQuery($query); return $this->loadObjectList(); @@ -529,12 +557,14 @@ public function renameTable($oldTable, $newTable, $backup = null, $prefix = null $oldTable = $this->replacePrefix($oldTable); $newTable = $this->replacePrefix($newTable); + $fullOldTable = $this->ParseIdent($oldTable); + $fullNewTable = $this->ParseIdent($newTable); // To check if table exists and prevent SQL injection $tableList = $this->getTableList(); // Origin Table does not exist - if (!\in_array($oldTable, $tableList, true)) { + if (!\in_array($fullOldTable->table, $tableList, true)) { // Origin Table not found throw new \RuntimeException('Table not found in Postgresql database.'); } @@ -543,7 +573,7 @@ public function renameTable($oldTable, $newTable, $backup = null, $prefix = null $subQuery = $this->createQuery() ->select('indexrelid') ->from('pg_index, pg_class') - ->where('pg_class.relname = ' . $this->quote($oldTable)) + ->where('pg_class.relname = ' . $this->quote($fullOldTable->table)) ->where('pg_class.oid = pg_index.indrelid'); $this->setQuery( @@ -556,7 +586,7 @@ public function renameTable($oldTable, $newTable, $backup = null, $prefix = null $oldIndexes = $this->loadColumn(); foreach ($oldIndexes as $oldIndex) { - $changedIdxName = str_replace($oldTable, $newTable, $oldIndex); + $changedIdxName = str_replace($fullOldTable->table, $fullNewTable->table, $oldIndex); $this->setQuery('ALTER INDEX ' . $this->escape($oldIndex) . ' RENAME TO ' . $this->escape($changedIdxName))->execute(); } @@ -573,18 +603,18 @@ public function renameTable($oldTable, $newTable, $backup = null, $prefix = null ->from('pg_class') ->where('relkind = ' . $this->quote('S')) ->where('relnamespace IN (' . (string) $subQuery . ')') - ->where('relname LIKE ' . $this->quote("%$oldTable%")) + ->where('relname LIKE ' . $this->quote("%{$fullOldTable->table}%")) ); $oldSequences = $this->loadColumn(); foreach ($oldSequences as $oldSequence) { - $changedSequenceName = str_replace($oldTable, $newTable, $oldSequence); + $changedSequenceName = str_replace($fullOldTable->table, $fullNewTable->table, $oldSequence); $this->setQuery('ALTER SEQUENCE ' . $this->escape($oldSequence) . ' RENAME TO ' . $this->escape($changedSequenceName))->execute(); } // Rename table - $this->setQuery('ALTER TABLE ' . $this->escape($oldTable) . ' RENAME TO ' . $this->escape($newTable))->execute(); + $this->setQuery('ALTER TABLE ' . $this->escape($fullOldTable->table) . ' RENAME TO ' . $this->escape($fullNewTable->table))->execute(); return $this; } From c0aea30d95fb3132cc2cf75860bc5f0c1412eae1 Mon Sep 17 00:00:00 2001 From: Richard Fath Date: Sun, 23 Mar 2025 14:45:22 +0100 Subject: [PATCH 2/4] Fix PHPCS --- src/Pgsql/PgsqlDriver.php | 48 +++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/src/Pgsql/PgsqlDriver.php b/src/Pgsql/PgsqlDriver.php index a8fa4c6a..6851636a 100644 --- a/src/Pgsql/PgsqlDriver.php +++ b/src/Pgsql/PgsqlDriver.php @@ -220,31 +220,29 @@ public function getTableCreate($tables) { return []; } - - /** - * Parses the fully qualified or bare name of the database object (table, view, procedure etc.) into object - * with fields "schema" and "table" respectively - * - * @param string $table Name of the database object with schema or without it - * - * @return object - */ - private function ParseIdent($table) - { - $query=$this->getQuery(1); - $query->select(['r[1]','r[2]']) - ->from("parse_ident(:t) as r") - ->bind(':t', $table); - $qn=$this->setQuery($query) - ->loadRow(); - if ($qn[1]) - { - return (object) ['schema' => $qn[0], 'table' => $qn[1]]; - } else - { - return (object) ['schema' => $this->getDefaultSchema(), 'table' => $qn[0]]; - } - } + + /** + * Parses the fully qualified or bare name of the database object (table, view, procedure etc.) into object + * with fields "schema" and "table" respectively + * + * @param string $table Name of the database object with schema or without it + * + * @return object + */ + private function ParseIdent($table) + { + $query = $this->getQuery(1); + $query->select(['r[1]','r[2]']) + ->from("parse_ident(:t) as r") + ->bind(':t', $table); + $qn = $this->setQuery($query) + ->loadRow(); + if ($qn[1]) { + return (object) ['schema' => $qn[0], 'table' => $qn[1]]; + } else { + return (object) ['schema' => $this->getDefaultSchema(), 'table' => $qn[0]]; + } + } /** * Retrieves field information about a given table. From 7d328009b024e72b7ee17b888e5938e8fdc25c7f Mon Sep 17 00:00:00 2001 From: Richard Fath Date: Sun, 23 Mar 2025 14:47:43 +0100 Subject: [PATCH 3/4] PHPCS Use camel case for method name --- src/Pgsql/PgsqlDriver.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Pgsql/PgsqlDriver.php b/src/Pgsql/PgsqlDriver.php index 6851636a..5c8d82e9 100644 --- a/src/Pgsql/PgsqlDriver.php +++ b/src/Pgsql/PgsqlDriver.php @@ -229,7 +229,7 @@ public function getTableCreate($tables) * * @return object */ - private function ParseIdent($table) + private function parseIdent($table) { $query = $this->getQuery(1); $query->select(['r[1]','r[2]']) @@ -261,7 +261,7 @@ public function getTableColumns($table, $typeOnly = true) $result = []; $tableSub = $this->replacePrefix($table); - $fullname = $this->ParseIdent($tableSub); + $fullname = $this->parseIdent($tableSub); $this->setQuery( ' @@ -347,7 +347,7 @@ public function getTableKeys($table) // To check if table exists and prevent SQL injection $tableList = $this->getTableList(); $tableSub = $this->replacePrefix($table); - $fullname = $this->ParseIdent($tableSub); + $fullname = $this->parseIdent($tableSub); if (\in_array($fullname->table, $tableList, true)) { // Get the details columns information. @@ -387,7 +387,7 @@ public function getNamesKey($table, $indKey) $this->connect(); $tableSub = $this->replacePrefix($table); - $fullname = $this->ParseIdent($tableSub); + $fullname = $this->parseIdent($tableSub); $tabInd = explode(' ', $indKey); $colNames = []; @@ -442,7 +442,7 @@ public function getTableSequences($table) // To check if table exists and prevent SQL injection $tableList = $this->getTableList(); $tableSub = $this->replacePrefix($table); - $fullname = $this->ParseIdent($tableSub); + $fullname = $this->parseIdent($tableSub); if (\in_array($fullname->table, $tableList, true)) { $name = [ @@ -555,8 +555,8 @@ public function renameTable($oldTable, $newTable, $backup = null, $prefix = null $oldTable = $this->replacePrefix($oldTable); $newTable = $this->replacePrefix($newTable); - $fullOldTable = $this->ParseIdent($oldTable); - $fullNewTable = $this->ParseIdent($newTable); + $fullOldTable = $this->parseIdent($oldTable); + $fullNewTable = $this->parseIdent($newTable); // To check if table exists and prevent SQL injection $tableList = $this->getTableList(); From 0f14ab04c930f1404b1ef6af3a8a43ae09cad865 Mon Sep 17 00:00:00 2001 From: Richard Fath Date: Sun, 23 Mar 2025 15:25:06 +0100 Subject: [PATCH 4/4] More code style suggestions from code review --- src/Pgsql/PgsqlDriver.php | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/Pgsql/PgsqlDriver.php b/src/Pgsql/PgsqlDriver.php index 5c8d82e9..6221f439 100644 --- a/src/Pgsql/PgsqlDriver.php +++ b/src/Pgsql/PgsqlDriver.php @@ -232,16 +232,19 @@ public function getTableCreate($tables) private function parseIdent($table) { $query = $this->getQuery(1); + $query->select(['r[1]','r[2]']) - ->from("parse_ident(:t) as r") - ->bind(':t', $table); + ->from("parse_ident(:t) as r") + ->bind(':t', $table); + $qn = $this->setQuery($query) - ->loadRow(); + ->loadRow(); + if ($qn[1]) { return (object) ['schema' => $qn[0], 'table' => $qn[1]]; - } else { - return (object) ['schema' => $this->getDefaultSchema(), 'table' => $qn[0]]; } + + return (object) ['schema' => $this->getDefaultSchema(), 'table' => $qn[0]]; } /** @@ -386,7 +389,7 @@ public function getNamesKey($table, $indKey) { $this->connect(); - $tableSub = $this->replacePrefix($table); + $tableSub = $this->replacePrefix($table); $fullname = $this->parseIdent($tableSub); $tabInd = explode(' ', $indKey); @@ -553,8 +556,8 @@ public function renameTable($oldTable, $newTable, $backup = null, $prefix = null { $this->connect(); - $oldTable = $this->replacePrefix($oldTable); - $newTable = $this->replacePrefix($newTable); + $oldTable = $this->replacePrefix($oldTable); + $newTable = $this->replacePrefix($newTable); $fullOldTable = $this->parseIdent($oldTable); $fullNewTable = $this->parseIdent($newTable);