diff options
author | Meik Sievertsen <acydburn@phpbb.com> | 2008-12-05 11:18:59 +0000 |
---|---|---|
committer | Meik Sievertsen <acydburn@phpbb.com> | 2008-12-05 11:18:59 +0000 |
commit | 5c7dcec0738c8c99535a0789a357e4f92a8dad9f (patch) | |
tree | 32e2c47f75061e0991637327667f990cf1dc3745 /phpBB/includes/db/dbal.php | |
parent | 00d870676574b7555625f1573c73d4a22f16be38 (diff) | |
download | forums-5c7dcec0738c8c99535a0789a357e4f92a8dad9f.tar forums-5c7dcec0738c8c99535a0789a357e4f92a8dad9f.tar.gz forums-5c7dcec0738c8c99535a0789a357e4f92a8dad9f.tar.bz2 forums-5c7dcec0738c8c99535a0789a357e4f92a8dad9f.tar.xz forums-5c7dcec0738c8c99535a0789a357e4f92a8dad9f.zip |
Enforce a requirement for some DBMS (Oracle, PostgreSQL, MSSQL) where the table order is quite important in some situations. ;) Since this does not affect the operation of the other DBMS the code is placed into dbal.php.
git-svn-id: file:///svn/phpbb/branches/phpBB-3_0_0@9175 89ea8834-ac86-4346-8a33-228a782c2dd0
Diffstat (limited to 'phpBB/includes/db/dbal.php')
-rw-r--r-- | phpBB/includes/db/dbal.php | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/phpBB/includes/db/dbal.php b/phpBB/includes/db/dbal.php index 179eff65d2..c4ae50dea0 100644 --- a/phpBB/includes/db/dbal.php +++ b/phpBB/includes/db/dbal.php @@ -500,7 +500,8 @@ class dbal $sql = str_replace('_', ' ', $query) . ' ' . $array['SELECT'] . ' FROM '; - $table_array = array(); + // Build table array. We also build an alias array for later checks. + $table_array = $aliases = array(); foreach ($array['FROM'] as $table_name => $alias) { if (is_array($alias)) @@ -508,14 +509,58 @@ class dbal foreach ($alias as $multi_alias) { $table_array[] = $table_name . ' ' . $multi_alias; + $aliases[] = $multi_alias; } } else { $table_array[] = $table_name . ' ' . $alias; + $aliases[] = $alias; } } + // We run the following code to determine if we need to re-order the table array. ;) + // The reason for this is that for multiple tables in the FROM statement the last table need to match the first LEFT JOIN'ed table. + // DBMS who rely on this (at the moment i only spotted it on multi-aliases): Oracle, PostgreSQL and MSSQL + $first_join_match = false; + + if (!empty($array['LEFT_JOIN']) && sizeof($array['FROM']) > 1) + { + // Take first LEFT JOIN + $join = current($array['LEFT_JOIN']); + + // Determine the table used there (even if there are more than one used, we only want to have one + preg_match('/(' . implode('|', $aliases) . ')\.[^\s]+/U', str_replace(array('(', ')', 'AND', 'OR', ' '), '', $join['ON']), $matches); + + if (!empty($matches[1])) + { + $first_join_match = trim($matches[1]); + } + } + + // If there is a first join match, we need to make sure the table order is correct + if ($first_join_match !== false) + { + $table_array = $last = array(); + + foreach ($array['FROM'] as $table_name => $alias) + { + if (is_array($alias)) + { + foreach ($alias as $multi_alias) + { + ($multi_alias === $first_join_match) ? $last[] = $table_name . ' ' . $multi_alias : $table_array[] = $table_name . ' ' . $multi_alias; + } + } + else + { + ($alias === $first_join_match) ? $last[] = $table_name . ' ' . $alias : $table_array[] = $table_name . ' ' . $alias; + } + } + + $table_array = array_merge($table_array, $last); + } + $sql .= $this->_sql_custom_build('FROM', implode(', ', $table_array)); if (!empty($array['LEFT_JOIN'])) |