Fix incorrect prefixing when CTE has an alias #2587

This commit is contained in:
Kijin Sung 2025-07-23 01:07:25 +09:00
parent 393c847cee
commit 64ca8e775a
2 changed files with 11 additions and 12 deletions

View file

@ -1133,13 +1133,12 @@ class DB
return preg_replace_callback('/\b((?:DELETE\s+)?FROM|JOIN|INTO|(?<!KEY\s)UPDATE)(?i)\s+((?:`?\w+`?)(?:\s+AS\s+`?\w+`?)?(?:\s*,\s*(?:`?\w+\`?)(?:\s+AS\s+`?\w+`?)?)*)/', function($m) use($exceptions) { return preg_replace_callback('/\b((?:DELETE\s+)?FROM|JOIN|INTO|(?<!KEY\s)UPDATE)(?i)\s+((?:`?\w+`?)(?:\s+AS\s+`?\w+`?)?(?:\s*,\s*(?:`?\w+\`?)(?:\s+AS\s+`?\w+`?)?)*)/', function($m) use($exceptions) {
$type = strtoupper($m[1]); $type = strtoupper($m[1]);
$tables = array_map(function($str) use($type, $exceptions) { $tables = array_map(function($str) use($type, $exceptions) {
$str = trim($str); return preg_replace_callback('/`?(\w+)`?(?:\s+AS\s+`?(\w+)`?)?/i', function($m) use($type, $exceptions) {
if (count($exceptions) && in_array(trim($str, '`'), $exceptions)) if (count($exceptions) && in_array($m[1], $exceptions))
{ {
return $str; return isset($m[2]) ? sprintf('`%s` AS `%s`', $m[1], $m[2]) : sprintf('`%s`', $m[1]);
} }
return preg_replace_callback('/`?(\w+)`?(?:\s+AS\s+`?(\w+)`?)?/i', function($m) use($type) { elseif ($type === 'FROM' || $type === 'JOIN')
if ($type === 'FROM' || $type === 'JOIN')
{ {
return isset($m[2]) ? sprintf('`%s%s` AS `%s`', $this->_prefix, $m[1], $m[2]) : sprintf('`%s%s` AS `%s`', $this->_prefix, $m[1], $m[1]); return isset($m[2]) ? sprintf('`%s%s` AS `%s`', $this->_prefix, $m[1], $m[2]) : sprintf('`%s%s` AS `%s`', $this->_prefix, $m[1], $m[1]);
} }
@ -1147,7 +1146,7 @@ class DB
{ {
return isset($m[2]) ? sprintf('`%s%s` AS `%s`', $this->_prefix, $m[1], $m[2]) : sprintf('`%s%s`', $this->_prefix, $m[1]); return isset($m[2]) ? sprintf('`%s%s` AS `%s`', $this->_prefix, $m[1], $m[2]) : sprintf('`%s%s`', $this->_prefix, $m[1]);
} }
}, $str); }, trim($str));
}, explode(',', $m[2])); }, explode(',', $m[2]));
return $m[1] . ' ' . implode(', ', $tables); return $m[1] . ' ' . implode(', ', $tables);
}, $query_string); }, $query_string);

View file

@ -160,15 +160,15 @@ class DBTest extends \Codeception\Test\Unit
$this->assertEquals($target, $oDB->addPrefixes($source)); $this->assertEquals($target, $oDB->addPrefixes($source));
$source = 'WITH cte AS (SELECT * FROM documents) SELECT * FROM cte WHERE document_srl = ?'; $source = 'WITH cte AS (SELECT * FROM documents) SELECT * FROM cte WHERE document_srl = ?';
$target = 'WITH cte AS (SELECT * FROM `' . $prefix . 'documents` AS `documents`) SELECT * FROM cte WHERE document_srl = ?'; $target = 'WITH cte AS (SELECT * FROM `' . $prefix . 'documents` AS `documents`) SELECT * FROM `cte` WHERE document_srl = ?';
$this->assertEquals($target, $oDB->addPrefixes($source)); $this->assertEquals($target, $oDB->addPrefixes($source));
$source = 'WITH RECURSIVE cte AS (SELECT * FROM documents INNER JOIN `cte`) SELECT * FROM cte JOIN member on cte.member_srl = member.member_srl'; $source = 'WITH RECURSIVE cte AS (SELECT * FROM documents INNER JOIN `cte`) SELECT * FROM cte JOIN member on cte.member_srl = member.member_srl';
$target = 'WITH RECURSIVE cte AS (SELECT * FROM `' . $prefix . 'documents` AS `documents` INNER JOIN `cte`) SELECT * FROM cte JOIN `rx_member` AS `member` on cte.member_srl = member.member_srl'; $target = 'WITH RECURSIVE cte AS (SELECT * FROM `' . $prefix . 'documents` AS `documents` INNER JOIN `cte`) SELECT * FROM `cte` JOIN `rx_member` AS `member` on cte.member_srl = member.member_srl';
$this->assertEquals($target, $oDB->addPrefixes($source)); $this->assertEquals($target, $oDB->addPrefixes($source));
$source = 'WITH RECURSIVE `cte` AS (SELECT * FROM cte) SELECT * FROM cte WHERE a = ?'; $source = 'WITH RECURSIVE `cte` AS (SELECT * FROM tbl INNER JOIN cte AS h) SELECT * FROM cte WHERE a = ?';
$target = 'WITH RECURSIVE `cte` AS (SELECT * FROM cte) SELECT * FROM cte WHERE a = ?'; $target = 'WITH RECURSIVE `cte` AS (SELECT * FROM `' . $prefix . 'tbl` AS `tbl` INNER JOIN `cte` AS `h`) SELECT * FROM `cte` WHERE a = ?';
$this->assertEquals($target, $oDB->addPrefixes($source)); $this->assertEquals($target, $oDB->addPrefixes($source));
$source = 'INSERT INTO documents (a, b, c) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE b = ?, c = ?'; $source = 'INSERT INTO documents (a, b, c) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE b = ?, c = ?';