mirror of
https://github.com/phpbb/phpbb.git
synced 2025-06-28 14:18:52 +00:00
Short story: Oracle does not like sub queries that contain columns that have the same name
Long story: Expanding the implicitly defined columns to explicitly defined columns lets us determine which columns we are actually grabbing. This lets us avoid the problem of having two columns having the same name even though one is implicit and the other is explicit. What does this mean? It means that when doing a limit on Oracle with an implicit column and a bunch of explicit columns, the explicit columns are the ones that "win". git-svn-id: file:///svn/phpbb/trunk@6159 89ea8834-ac86-4346-8a33-228a782c2dd0
This commit is contained in:
parent
9ab98d0d79
commit
0424200ac6
1 changed files with 46 additions and 0 deletions
|
@ -155,6 +155,52 @@ class dbal_oracle extends dbal
|
||||||
{
|
{
|
||||||
$this->query_result = false;
|
$this->query_result = false;
|
||||||
|
|
||||||
|
// Any implicit columns exist?
|
||||||
|
if (strpos($query, '.*') !== false)
|
||||||
|
{
|
||||||
|
// This sucker does a few things for us. It grabs all the explicitly named columns and what tables are being used
|
||||||
|
preg_match('/SELECT (?:DISTINCT )?(.*?)FROM(.*?)(?:WHERE|(ORDER|GROUP) BY|$)/s', $query, $tables);
|
||||||
|
|
||||||
|
// The prefixes of the explicit columns don't matter, they simply get in the way
|
||||||
|
preg_match_all('/\.(\w+)/', trim($tables[1]), $columns);
|
||||||
|
|
||||||
|
// Flip lets us do an easy isset() call
|
||||||
|
$columns = array_flip($columns[1]);
|
||||||
|
|
||||||
|
$table_data = trim($tables[2]);
|
||||||
|
|
||||||
|
// Grab the implicitly named columns, they need expanding...
|
||||||
|
preg_match_all('/(\w)\.\*/', $query, $info);
|
||||||
|
|
||||||
|
$cols = array();
|
||||||
|
|
||||||
|
foreach ($info[1] as $table_alias)
|
||||||
|
{
|
||||||
|
// We need to get the name of the aliased table
|
||||||
|
preg_match('/(\w+) ' . $table_alias . '/', $table_data, $table_name);
|
||||||
|
$table_name = $table_name[1];
|
||||||
|
|
||||||
|
$sql = "SELECT column_name
|
||||||
|
FROM all_tab_cols
|
||||||
|
WHERE table_name = '" . strtoupper($table_name) . "'";
|
||||||
|
|
||||||
|
$result = $this->sql_query($sql);
|
||||||
|
while ($row = $this->sql_fetchrow($result))
|
||||||
|
{
|
||||||
|
if (!isset($columns[strtolower($row['column_name'])]))
|
||||||
|
{
|
||||||
|
$cols[] = $table_alias . '.' . strtolower($row['column_name']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->sql_freeresult($result);
|
||||||
|
|
||||||
|
// Remove the implicity .* with it's full expansion
|
||||||
|
$query = str_replace($table_alias . '.*', implode(', ', $cols), $query);
|
||||||
|
|
||||||
|
unset($cols);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$query = 'SELECT * FROM (SELECT /*+ FIRST_ROWS */ rownum AS xrownum, a.* FROM (' . $query . ') a WHERE rownum <= ' . ($offset + $total) . ') WHERE xrownum >= ' . $offset;
|
$query = 'SELECT * FROM (SELECT /*+ FIRST_ROWS */ rownum AS xrownum, a.* FROM (' . $query . ') a WHERE rownum <= ' . ($offset + $total) . ') WHERE xrownum >= ' . $offset;
|
||||||
|
|
||||||
return $this->sql_query($query, $cache_ttl);
|
return $this->sql_query($query, $cache_ttl);
|
||||||
|
|
Loading…
Add table
Reference in a new issue