From 339bf90ec25bf3b8dd38735d742fcd01b5077b73 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 7 Aug 2014 18:43:48 +0200 Subject: [PATCH 01/14] [ticket/12710] Prepare get_existing_indexes() for other DBMS PHPBB3-12710 --- phpBB/phpbb/db/tools.php | 185 ++++++++++++++++++++++++--------------- 1 file changed, 112 insertions(+), 73 deletions(-) diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index 5d93eb8246..53225fb997 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -2289,12 +2289,14 @@ class tools $old_return_statements = $this->return_statements; $this->return_statements = true; - $indexes = $this->mssql_get_existing_indexes($table_name, $column_name); + $indexes = $this->get_existing_indexes($table_name, $column_name); + $unique_indexes = $this->get_existing_indexes($table_name, $column_name, true); // Drop any indexes - if (!empty($indexes)) + if (!empty($indexes) || !empty($unique_indexes)) { - foreach ($indexes as $index_name => $index_data) + $drop_indexes = array_merge(array_keys($indexes), array_keys($unique_indexes)); + foreach ($drop_indexes as $index_name) { $result = $this->sql_index_drop($table_name, $index_name); $statements = array_merge($statements, $result); @@ -2324,6 +2326,16 @@ class tools } } + if (!empty($unique_indexes)) + { + // Recreate unique indexes after we changed the column + foreach ($unique_indexes as $index_name => $index_data) + { + $result = $this->sql_create_unique_index($table_name, $index_name, $index_data); + $statements = array_merge($statements, $result); + } + } + $this->return_statements = $old_return_statements; break; @@ -2517,87 +2529,114 @@ class tools * * @param string $table_name * @param string $column_name + * @param bool $unique Should we get unique indexes or normal ones * @return array Array with Index name => columns */ - protected function mssql_get_existing_indexes($table_name, $column_name) + public function get_existing_indexes($table_name, $column_name, $unique = false) { $existing_indexes = array(); - if ($this->mssql_is_sql_server_2000()) - { - // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx - // Deprecated in SQL Server 2005 - $sql = "SELECT DISTINCT ix.name AS phpbb_index_name - FROM sysindexes ix - INNER JOIN sysindexkeys ixc - ON ixc.id = ix.id - AND ixc.indid = ix.indid - INNER JOIN syscolumns cols - ON cols.colid = ixc.colid - AND cols.id = ix.id - WHERE ix.id = object_id('{$table_name}') - AND cols.name = '{$column_name}'"; - } - else - { - $sql = "SELECT DISTINCT ix.name AS phpbb_index_name - FROM sys.indexes ix - INNER JOIN sys.index_columns ixc - ON ixc.object_id = ix.object_id - AND ixc.index_id = ix.index_id - INNER JOIN sys.columns cols - ON cols.column_id = ixc.column_id - AND cols.object_id = ix.object_id - WHERE ix.object_id = object_id('{$table_name}') - AND cols.name = '{$column_name}'"; - } - $result = $this->db->sql_query($sql); - $existing_indexes = array(); - while ($row = $this->db->sql_fetchrow($result)) + switch ($this->sql_layer) { - $existing_indexes[$row['phpbb_index_name']] = array(); - } - $this->db->sql_freeresult($result); + case 'mssql': + case 'mssqlnative': + if ($unique) + { + // TODO fix me + throw new \Exception('FIX ME mssql treats unique and normal indexes the same'); + } - if (empty($existing_indexes)) - { - return array(); - } + if ($this->mssql_is_sql_server_2000()) + { + // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx + // Deprecated in SQL Server 2005 + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name + FROM sysindexes ix + INNER JOIN sysindexkeys ixc + ON ixc.id = ix.id + AND ixc.indid = ix.indid + INNER JOIN syscolumns cols + ON cols.colid = ixc.colid + AND cols.id = ix.id + WHERE ix.id = object_id('{$table_name}') + AND cols.name = '{$column_name}'"; + } + else + { + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name + FROM sys.indexes ix + INNER JOIN sys.index_columns ixc + ON ixc.object_id = ix.object_id + AND ixc.index_id = ix.index_id + INNER JOIN sys.columns cols + ON cols.column_id = ixc.column_id + AND cols.object_id = ix.object_id + WHERE ix.object_id = object_id('{$table_name}') + AND cols.name = '{$column_name}'"; + } - if ($this->mssql_is_sql_server_2000()) - { - $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name - FROM sysindexes ix - INNER JOIN sysindexkeys ixc - ON ixc.id = ix.id - AND ixc.indid = ix.indid - INNER JOIN syscolumns cols - ON cols.colid = ixc.colid - AND cols.id = ix.id - WHERE ix.id = object_id('{$table_name}') - AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); - } - else - { - $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name - FROM sys.indexes ix - INNER JOIN sys.index_columns ixc - ON ixc.object_id = ix.object_id - AND ixc.index_id = ix.index_id - INNER JOIN sys.columns cols - ON cols.column_id = ixc.column_id - AND cols.object_id = ix.object_id - WHERE ix.object_id = object_id('{$table_name}') - AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); - } + $result = $this->db->sql_query($sql); + $existing_indexes = array(); + while ($row = $this->db->sql_fetchrow($result)) + { + $existing_indexes[$row['phpbb_index_name']] = array(); + } + $this->db->sql_freeresult($result); - $result = $this->db->sql_query($sql); + if (empty($existing_indexes)) + { + return array(); + } - while ($row = $this->db->sql_fetchrow($result)) - { - $existing_indexes[$row['phpbb_index_name']][] = $row['phpbb_column_name']; + if ($this->mssql_is_sql_server_2000()) + { + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name + FROM sysindexes ix + INNER JOIN sysindexkeys ixc + ON ixc.id = ix.id + AND ixc.indid = ix.indid + INNER JOIN syscolumns cols + ON cols.colid = ixc.colid + AND cols.id = ix.id + WHERE ix.id = object_id('{$table_name}') + AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); + } + else + { + $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name + FROM sys.indexes ix + INNER JOIN sys.index_columns ixc + ON ixc.object_id = ix.object_id + AND ixc.index_id = ix.index_id + INNER JOIN sys.columns cols + ON cols.column_id = ixc.column_id + AND cols.object_id = ix.object_id + WHERE ix.object_id = object_id('{$table_name}') + AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); + } + + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $existing_indexes[$row['phpbb_index_name']][] = $row['phpbb_column_name']; + } + $this->db->sql_freeresult($result); + break; + + case 'oracle': + throw new \Exception('Needs implementing'); + break; + + case 'mysql_40': + case 'mysql_41': + case 'postgres': + case 'sqlite': + case 'sqlite3': + // Not supported + throw new \Exception('DBMS is not supported'); + break; } - $this->db->sql_freeresult($result); return $existing_indexes; } From b39305b9f6e9871f3e5ba63e7a62396a05dbb712 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 7 Aug 2014 19:45:34 +0200 Subject: [PATCH 02/14] [ticket/12710] Fix changing the column type on oracle PHPBB3-12710 --- phpBB/phpbb/db/tools.php | 178 ++++++++++++++++++++++++++++----------- 1 file changed, 130 insertions(+), 48 deletions(-) diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index 53225fb997..b1927f4302 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -2345,7 +2345,69 @@ class tools break; case 'oracle': - $statements[] = 'ALTER TABLE ' . $table_name . ' MODIFY ' . $column_name . ' ' . $column_data['column_type_sql']; + // We need the data here + $old_return_statements = $this->return_statements; + $this->return_statements = true; + + // Get list of existing indexes + $indexes = $this->get_existing_indexes($table_name, $column_name); + $unique_indexes = $this->get_existing_indexes($table_name, $column_name, true); + + // Drop any indexes + if (!empty($indexes) || !empty($unique_indexes)) + { + $drop_indexes = array_merge(array_keys($indexes), array_keys($unique_indexes)); + foreach ($drop_indexes as $index_name => $index_data) + { + $result = $this->sql_index_drop($table_name, $index_name); + $statements = array_merge($statements, $result); + } + } + + $temp_column_name = substr(md5($column_name), 0, 30); + // Add a temporary table with the new type + $result = $this->sql_column_add($table_name, $temp_column_name, $column_data); + $statements = array_merge($statements, $result); + + // Copy the data to the new column + $statements[] = 'UPDATE ' . $table_name . ' SET ' . $temp_column_name . ' = ' . $column_name; + + // Drop the original column + $result = $this->sql_column_remove($table_name, $column_name); + $statements = array_merge($statements, $result); + + // Recreate the original column with the new type + $result = $this->sql_column_add($table_name, $column_name, $column_data); + $statements = array_merge($statements, $result); + + if (!empty($indexes)) + { + // Recreate indexes after we changed the column + foreach ($indexes as $index_name => $index_data) + { + $result = $this->sql_create_index($table_name, $index_name, $index_data); + $statements = array_merge($statements, $result); + } + } + + if (!empty($unique_indexes)) + { + // Recreate unique indexes after we changed the column + foreach ($unique_indexes as $index_name => $index_data) + { + $result = $this->sql_create_unique_index($table_name, $index_name, $index_data); + $statements = array_merge($statements, $result); + } + } + + // Copy the data to the original column + $statements[] = 'UPDATE ' . $table_name . ' SET ' . $column_name . ' = ' . $temp_column_name; + + // Drop the temporary column again + $result = $this->sql_column_remove($table_name, $temp_column_name); + $statements = array_merge($statements, $result); + + $this->return_statements = $old_return_statements; break; case 'postgres': @@ -2534,6 +2596,19 @@ class tools */ public function get_existing_indexes($table_name, $column_name, $unique = false) { + switch ($this->sql_layer) + { + case 'mysql_40': + case 'mysql_41': + case 'postgres': + case 'sqlite': + case 'sqlite3': + // Not supported + throw new \Exception('DBMS is not supported'); + break; + } + + $sql = ''; $existing_indexes = array(); switch ($this->sql_layer) @@ -2574,70 +2649,77 @@ class tools WHERE ix.object_id = object_id('{$table_name}') AND cols.name = '{$column_name}'"; } + break; - $result = $this->db->sql_query($sql); - $existing_indexes = array(); - while ($row = $this->db->sql_fetchrow($result)) - { - $existing_indexes[$row['phpbb_index_name']] = array(); - } - $this->db->sql_freeresult($result); + case 'oracle': + $sql = "SELECT ixc.column_name AS phpbb_index_name + FROM all_ind_columns ixc, all_indexes ix + WHERE ix.index_name = ixc.index_name + AND ixc.table_name = UPPER('{$table_name}') + AND ixc.index_name = UPPER('{$column_name}') + AND ix.uniqueness = " . ($unique) ? "'UNIQUE'" : "'NONUNIQUE'"; + break; + } - if (empty($existing_indexes)) - { - return array(); - } + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $existing_indexes[$row['phpbb_index_name']] = array(); + } + $this->db->sql_freeresult($result); + if (empty($existing_indexes)) + { + return array(); + } + + switch ($this->sql_layer) + { + case 'mssql': + case 'mssqlnative': if ($this->mssql_is_sql_server_2000()) { $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name - FROM sysindexes ix - INNER JOIN sysindexkeys ixc - ON ixc.id = ix.id - AND ixc.indid = ix.indid - INNER JOIN syscolumns cols - ON cols.colid = ixc.colid - AND cols.id = ix.id - WHERE ix.id = object_id('{$table_name}') - AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); + FROM sysindexes ix + INNER JOIN sysindexkeys ixc + ON ixc.id = ix.id + AND ixc.indid = ix.indid + INNER JOIN syscolumns cols + ON cols.colid = ixc.colid + AND cols.id = ix.id + WHERE ix.id = object_id('{$table_name}') + AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); } else { $sql = "SELECT DISTINCT ix.name AS phpbb_index_name, cols.name AS phpbb_column_name - FROM sys.indexes ix - INNER JOIN sys.index_columns ixc - ON ixc.object_id = ix.object_id - AND ixc.index_id = ix.index_id - INNER JOIN sys.columns cols - ON cols.column_id = ixc.column_id - AND cols.object_id = ix.object_id - WHERE ix.object_id = object_id('{$table_name}') - AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); + FROM sys.indexes ix + INNER JOIN sys.index_columns ixc + ON ixc.object_id = ix.object_id + AND ixc.index_id = ix.index_id + INNER JOIN sys.columns cols + ON cols.column_id = ixc.column_id + AND cols.object_id = ix.object_id + WHERE ix.object_id = object_id('{$table_name}') + AND " . $this->db->sql_in_set('ix.name', array_keys($existing_indexes)); } - - $result = $this->db->sql_query($sql); - - while ($row = $this->db->sql_fetchrow($result)) - { - $existing_indexes[$row['phpbb_index_name']][] = $row['phpbb_column_name']; - } - $this->db->sql_freeresult($result); break; case 'oracle': - throw new \Exception('Needs implementing'); - break; - - case 'mysql_40': - case 'mysql_41': - case 'postgres': - case 'sqlite': - case 'sqlite3': - // Not supported - throw new \Exception('DBMS is not supported'); + $sql = "SELECT index_name AS phpbb_index_name, column_name AS phpbb_column_name + FROM all_ind_columns + WHERE table_name = UPPER('{$table_name}') + AND " . $this->db->sql_in_set('index_name', array_keys($existing_indexes)); break; } + $result = $this->db->sql_query($sql); + while ($row = $this->db->sql_fetchrow($result)) + { + $existing_indexes[$row['phpbb_index_name']][] = $row['phpbb_column_name']; + } + $this->db->sql_freeresult($result); + return $existing_indexes; } From 96fc29eeccf4988aee3e949110d356fec722887e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 7 Aug 2014 19:56:31 +0200 Subject: [PATCH 03/14] [ticket/12710] Correctly fetch unique and normal indexes only in MSSQL PHPBB3-12710 --- phpBB/phpbb/db/tools.php | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index b1927f4302..c4b2399aff 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -1816,7 +1816,8 @@ class tools $old_return_statements = $this->return_statements; $this->return_statements = true; - $indexes = $this->mssql_get_existing_indexes($table_name, $column_name); + $indexes = $this->get_existing_indexes($table_name, $column_name); + $indexes = array_merge($indexes, $this->get_existing_indexes($table_name, $column_name, true)); // Drop any indexes $recreate_indexes = array(); @@ -2615,12 +2616,6 @@ class tools { case 'mssql': case 'mssqlnative': - if ($unique) - { - // TODO fix me - throw new \Exception('FIX ME mssql treats unique and normal indexes the same'); - } - if ($this->mssql_is_sql_server_2000()) { // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx @@ -2634,7 +2629,8 @@ class tools ON cols.colid = ixc.colid AND cols.id = ix.id WHERE ix.id = object_id('{$table_name}') - AND cols.name = '{$column_name}'"; + AND cols.name = '{$column_name}' + AND INDEXPROPERTY(ix.id, ix.name, 'IsUnique') = " . ($unique) ? '1' : '0'; } else { @@ -2647,7 +2643,8 @@ class tools ON cols.column_id = ixc.column_id AND cols.object_id = ix.object_id WHERE ix.object_id = object_id('{$table_name}') - AND cols.name = '{$column_name}'"; + AND cols.name = '{$column_name}' + AND ix.is_unique = " . ($unique) ? '1' : '0'; } break; From cdcfd1fe1ef5680333348f0ea49cdf21ffdd9e3a Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 9 Aug 2014 08:28:44 +0200 Subject: [PATCH 04/14] [ticket/12710] Fix problems with creating unique indexes on oracle PHPBB3-12710 --- phpBB/phpbb/db/tools.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index c4b2399aff..38655018e1 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -2039,7 +2039,7 @@ class tools break; case 'oracle': - $statements[] = 'ALTER TABLE ' . $table_name . 'add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')'; + $statements[] = 'ALTER TABLE ' . $table_name . ' add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')'; break; case 'sqlite': From 4e4ea681be7939ba70db492331164ed024adae8e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 9 Aug 2014 08:33:15 +0200 Subject: [PATCH 05/14] [ticket/12710] Fix "ORA-00972: identifier is too long [972]" on oracle PHPBB3-12710 --- tests/dbal/db_tools_test.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/dbal/db_tools_test.php b/tests/dbal/db_tools_test.php index 6cc2f8ec0f..51f9daacfb 100644 --- a/tests/dbal/db_tools_test.php +++ b/tests/dbal/db_tools_test.php @@ -288,13 +288,13 @@ class phpbb_dbal_db_tools_test extends phpbb_database_test_case $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012_2')); // Create index over the column - $this->assertFalse($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012_2')); - $this->assertTrue($this->tools->sql_create_index('prefix_table_name', 'i_bug_12012_2', array('c_bug_12012_2', 'c_bool'))); - $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012_2')); + $this->assertFalse($this->tools->sql_index_exists('prefix_table_name', 'bug_12012_2')); + $this->assertTrue($this->tools->sql_create_index('prefix_table_name', 'bug_12012_2', array('c_bug_12012_2', 'c_bool'))); + $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', 'bug_12012_2')); - $this->assertFalse($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012_3')); - $this->assertTrue($this->tools->sql_create_index('prefix_table_name', 'i_bug_12012_3', array('c_bug_12012_2'))); - $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', 'i_bug_12012_3')); + $this->assertFalse($this->tools->sql_index_exists('prefix_table_name', 'bug_12012_3')); + $this->assertTrue($this->tools->sql_create_index('prefix_table_name', 'bug_12012_3', array('c_bug_12012_2'))); + $this->assertTrue($this->tools->sql_index_exists('prefix_table_name', 'bug_12012_3')); // Remove the column $this->assertTrue($this->tools->sql_column_exists('prefix_table_name', 'c_bug_12012_2')); From 12eb993d230e0be0d0c1c70e5ebe6379bacecc0d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 9 Aug 2014 08:54:40 +0200 Subject: [PATCH 06/14] [ticket/12710] Correctly select index name and compare to column name PHPBB3-12710 --- phpBB/phpbb/db/tools.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index 38655018e1..05bba0ba84 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -2649,11 +2649,11 @@ class tools break; case 'oracle': - $sql = "SELECT ixc.column_name AS phpbb_index_name + $sql = "SELECT ix.index_name AS phpbb_index_name FROM all_ind_columns ixc, all_indexes ix WHERE ix.index_name = ixc.index_name AND ixc.table_name = UPPER('{$table_name}') - AND ixc.index_name = UPPER('{$column_name}') + AND ixc.column_name = UPPER('{$column_name}') AND ix.uniqueness = " . ($unique) ? "'UNIQUE'" : "'NONUNIQUE'"; break; } From 078c68da6360f0f55acf887b31394ae69553d52e Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 9 Aug 2014 12:46:59 +0200 Subject: [PATCH 07/14] [ticket/12710] Can not use upper in oracles where claus PHPBB3-12710 --- phpBB/phpbb/db/tools.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index 05bba0ba84..d5b8d4fad7 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -2652,8 +2652,8 @@ class tools $sql = "SELECT ix.index_name AS phpbb_index_name FROM all_ind_columns ixc, all_indexes ix WHERE ix.index_name = ixc.index_name - AND ixc.table_name = UPPER('{$table_name}') - AND ixc.column_name = UPPER('{$column_name}') + AND ixc.table_name = '" . strtoupper($table_name) . "' + AND ixc.column_name = '" . strtoupper($column_name) . "' AND ix.uniqueness = " . ($unique) ? "'UNIQUE'" : "'NONUNIQUE'"; break; } @@ -2705,7 +2705,7 @@ class tools case 'oracle': $sql = "SELECT index_name AS phpbb_index_name, column_name AS phpbb_column_name FROM all_ind_columns - WHERE table_name = UPPER('{$table_name}') + WHERE table_name = '" . strtoupper($table_name) . "' AND " . $this->db->sql_in_set('index_name', array_keys($existing_indexes)); break; } From 7d44995f1659cf654bf8d05b5f6315de2eda7925 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 9 Aug 2014 12:53:15 +0200 Subject: [PATCH 08/14] [ticket/12710] Remove table_name from index_name before deleting and recreating them PHPBB3-12710 --- phpBB/phpbb/db/tools.php | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index d5b8d4fad7..434568d01a 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -2274,6 +2274,18 @@ class tools return array_map('strtolower', $index_array); } + /** + * Removes table_name from the index_name if it is at the beginning + * + * @param $table_name + * @param $index_name + * @return string + */ + protected function strip_table_name_from_index_name($table_name, $index_name) + { + return (strpos($index_name, $table_name) === 0) ? substr($index_name, strlen($table_name) + 1) : $index_name; + } + /** * Change column type (not name!) */ @@ -2360,7 +2372,7 @@ class tools $drop_indexes = array_merge(array_keys($indexes), array_keys($unique_indexes)); foreach ($drop_indexes as $index_name => $index_data) { - $result = $this->sql_index_drop($table_name, $index_name); + $result = $this->sql_index_drop($table_name, $this->strip_table_name_from_index_name($table_name, $index_name)); $statements = array_merge($statements, $result); } } @@ -2386,7 +2398,7 @@ class tools // Recreate indexes after we changed the column foreach ($indexes as $index_name => $index_data) { - $result = $this->sql_create_index($table_name, $index_name, $index_data); + $result = $this->sql_create_index($table_name, $this->strip_table_name_from_index_name($table_name, $index_name), $index_data); $statements = array_merge($statements, $result); } } @@ -2396,7 +2408,7 @@ class tools // Recreate unique indexes after we changed the column foreach ($unique_indexes as $index_name => $index_data) { - $result = $this->sql_create_unique_index($table_name, $index_name, $index_data); + $result = $this->sql_create_unique_index($table_name, $this->strip_table_name_from_index_name($table_name, $index_name), $index_data); $statements = array_merge($statements, $result); } } From f03a003bea0071617fe11d9313e117c33100c570 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 9 Aug 2014 13:14:08 +0200 Subject: [PATCH 09/14] [ticket/12710] Do not try to match the uniqueness in the query PHPBB3-12710 --- phpBB/phpbb/db/tools.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index 434568d01a..556b162061 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -2661,19 +2661,21 @@ class tools break; case 'oracle': - $sql = "SELECT ix.index_name AS phpbb_index_name + $sql = "SELECT ix.index_name AS phpbb_index_name, ix.uniqueness AS is_unique FROM all_ind_columns ixc, all_indexes ix WHERE ix.index_name = ixc.index_name AND ixc.table_name = '" . strtoupper($table_name) . "' - AND ixc.column_name = '" . strtoupper($column_name) . "' - AND ix.uniqueness = " . ($unique) ? "'UNIQUE'" : "'NONUNIQUE'"; + AND ixc.column_name = '" . strtoupper($column_name) . "'"; break; } $result = $this->db->sql_query($sql); while ($row = $this->db->sql_fetchrow($result)) { - $existing_indexes[$row['phpbb_index_name']] = array(); + if (!isset($row['is_unique']) || ($unique && $row['is_unique'] == 'UNIQUE') || (!$unique && $row['is_unique'] == 'NONUNIQUE')) + { + $existing_indexes[$row['phpbb_index_name']] = array(); + } } $this->db->sql_freeresult($result); From c8e7db60ba0edbee1dffb4b0687adf702cf49e62 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 9 Aug 2014 13:34:22 +0200 Subject: [PATCH 10/14] [ticket/12710] Compare to uppercase version PHPBB3-12710 --- phpBB/phpbb/db/tools.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index 556b162061..000f0681cb 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -2283,7 +2283,7 @@ class tools */ protected function strip_table_name_from_index_name($table_name, $index_name) { - return (strpos($index_name, $table_name) === 0) ? substr($index_name, strlen($table_name) + 1) : $index_name; + return (strpos(strtoupper($index_name), strtoupper($table_name) === 0) ? substr($index_name, strlen($table_name) + 1) : $index_name; } /** From 37a1874782629286cb3c7750b2dc1ffa8427e73c Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 9 Aug 2014 14:02:24 +0200 Subject: [PATCH 11/14] [ticket/12710] Fix foreach generation PHPBB3-12710 --- phpBB/phpbb/db/tools.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index 000f0681cb..69c6f17416 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -2370,7 +2370,7 @@ class tools if (!empty($indexes) || !empty($unique_indexes)) { $drop_indexes = array_merge(array_keys($indexes), array_keys($unique_indexes)); - foreach ($drop_indexes as $index_name => $index_data) + foreach ($drop_indexes as $index_name) { $result = $this->sql_index_drop($table_name, $this->strip_table_name_from_index_name($table_name, $index_name)); $statements = array_merge($statements, $result); From ef9360d28532cf04b99a7c352b8897b79587ba37 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 9 Aug 2014 14:13:42 +0200 Subject: [PATCH 12/14] [ticket/12710] Pass the original column data to the create function PHPBB3-12710 --- phpBB/phpbb/db/tools.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index 69c6f17416..72bc7d72f1 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -2291,6 +2291,7 @@ class tools */ function sql_column_change($table_name, $column_name, $column_data, $inline = false) { + $original_column_data = $column_data; $column_data = $this->sql_prepare_column_data($table_name, $column_name, $column_data); $statements = array(); @@ -2379,7 +2380,7 @@ class tools $temp_column_name = substr(md5($column_name), 0, 30); // Add a temporary table with the new type - $result = $this->sql_column_add($table_name, $temp_column_name, $column_data); + $result = $this->sql_column_add($table_name, $temp_column_name, $original_column_data); $statements = array_merge($statements, $result); // Copy the data to the new column @@ -2390,7 +2391,7 @@ class tools $statements = array_merge($statements, $result); // Recreate the original column with the new type - $result = $this->sql_column_add($table_name, $column_name, $column_data); + $result = $this->sql_column_add($table_name, $column_name, $original_column_data); $statements = array_merge($statements, $result); if (!empty($indexes)) From 0806c74084086d778c54ea6e87ab582deb9ecf43 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 9 Aug 2014 14:29:59 +0200 Subject: [PATCH 13/14] [ticket/12710] Prefix column so it does not start with a number PHPBB3-12710 --- phpBB/phpbb/db/tools.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index 72bc7d72f1..fccc731026 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -2378,7 +2378,7 @@ class tools } } - $temp_column_name = substr(md5($column_name), 0, 30); + $temp_column_name = 'temp_' . substr(md5($column_name), 0, 25); // Add a temporary table with the new type $result = $this->sql_column_add($table_name, $temp_column_name, $original_column_data); $statements = array_merge($statements, $result); From f87831aee511071c96a77124cacde33fe69869f2 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Sat, 9 Aug 2014 14:49:30 +0200 Subject: [PATCH 14/14] [ticket/12710] Fix missing closing bracket PHPBB3-12710 --- phpBB/phpbb/db/tools.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index fccc731026..3567570137 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -2283,7 +2283,7 @@ class tools */ protected function strip_table_name_from_index_name($table_name, $index_name) { - return (strpos(strtoupper($index_name), strtoupper($table_name) === 0) ? substr($index_name, strlen($table_name) + 1) : $index_name; + return (strpos(strtoupper($index_name), strtoupper($table_name)) === 0) ? substr($index_name, strlen($table_name) + 1) : $index_name; } /**