From 28b3c2ef342f2cffbc5137d8c474d8297fb3e26d Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 21 Oct 2020 23:20:35 +0900 Subject: [PATCH] Fix #1422 incorrect quoting of expressions in XML queries --- common/framework/parsers/dbquery/query.php | 12 +++++++----- .../{selectTest.xml => selectTest1.xml} | 2 +- tests/_data/dbquery/selectTest2.xml | 12 ++++++++++++ .../framework/parsers/DBQueryParserTest.php | 18 +++++++++++++++--- 4 files changed, 35 insertions(+), 9 deletions(-) rename tests/_data/dbquery/{selectTest.xml => selectTest1.xml} (94%) create mode 100644 tests/_data/dbquery/selectTest2.xml diff --git a/common/framework/parsers/dbquery/query.php b/common/framework/parsers/dbquery/query.php index 4142cf403..63aa039d1 100644 --- a/common/framework/parsers/dbquery/query.php +++ b/common/framework/parsers/dbquery/query.php @@ -581,11 +581,13 @@ class Query extends VariableBase */ public static function quoteName(string $column_name): string { - $columns = explode('.', $column_name); - $columns = array_map(function($str) { - return $str === '*' ? $str : ('`' . $str . '`'); - }, $columns); - return implode('.', $columns); + return preg_replace_callback('/[a-z][a-z0-9_.*]*(?!\\()\b/i', function($m) { + $columns = explode('.', $m[0]); + $columns = array_map(function($str) { + return $str === '*' ? $str : ('`' . $str . '`'); + }, $columns); + return implode('.', $columns); + }, $column_name); } /** diff --git a/tests/_data/dbquery/selectTest.xml b/tests/_data/dbquery/selectTest1.xml similarity index 94% rename from tests/_data/dbquery/selectTest.xml rename to tests/_data/dbquery/selectTest1.xml index 6ece56c98..244253090 100644 --- a/tests/_data/dbquery/selectTest.xml +++ b/tests/_data/dbquery/selectTest1.xml @@ -1,4 +1,4 @@ - + diff --git a/tests/_data/dbquery/selectTest2.xml b/tests/_data/dbquery/selectTest2.xml new file mode 100644 index 000000000..277a2d190 --- /dev/null +++ b/tests/_data/dbquery/selectTest2.xml @@ -0,0 +1,12 @@ + + +
+ + + + + + + + + diff --git a/tests/unit/framework/parsers/DBQueryParserTest.php b/tests/unit/framework/parsers/DBQueryParserTest.php index b69f7a920..736765375 100644 --- a/tests/unit/framework/parsers/DBQueryParserTest.php +++ b/tests/unit/framework/parsers/DBQueryParserTest.php @@ -4,9 +4,9 @@ class DBQueryParserTest extends \Codeception\TestCase\Test { public function testLoadXML() { - $query = Rhymix\Framework\Parsers\DBQueryParser::loadXML(\RX_BASEDIR . 'tests/_data/dbquery/selectTest.xml'); + $query = Rhymix\Framework\Parsers\DBQueryParser::loadXML(\RX_BASEDIR . 'tests/_data/dbquery/selectTest1.xml'); $this->assertTrue($query instanceof Rhymix\Framework\Parsers\DBQuery\Query); - $this->assertEquals('selectTest', $query->name); + $this->assertEquals('selectTest1', $query->name); $this->assertEquals('SELECT', $query->type); $this->assertTrue($query->select_distinct); @@ -47,7 +47,7 @@ class DBQueryParserTest extends \Codeception\TestCase\Test public function testSimpleSelect() { - $query = Rhymix\Framework\Parsers\DBQueryParser::loadXML(\RX_BASEDIR . 'tests/_data/dbquery/selectTest.xml'); + $query = Rhymix\Framework\Parsers\DBQueryParser::loadXML(\RX_BASEDIR . 'tests/_data/dbquery/selectTest1.xml'); $args = array('member_srl' => 1234, 'regdate_more' => '20200707120000', 'page' => 3); $sql = $query->getQueryString('rx_', $args); $params = $query->getQueryParams(); @@ -58,6 +58,18 @@ class DBQueryParserTest extends \Codeception\TestCase\Test $this->assertEquals(['1234', '20200707120000', 'PUBLIC'], $params); } + public function testSelectWithExpressions() + { + $query = Rhymix\Framework\Parsers\DBQueryParser::loadXML(\RX_BASEDIR . 'tests/_data/dbquery/selectTest2.xml'); + $args = array('voted_count' => 20, 'date' => '20201021'); + $sql = $query->getQueryString('rx_', $args); + $params = $query->getQueryParams(); + + $this->assertEquals('SELECT readed_count + trackback_count AS `count` ' . + 'FROM `rx_documents` AS `documents` WHERE `voted_count` + `blamed_count` >= ? AND LEFT(`regdate`, 8) = ?', $sql); + $this->assertEquals([20, '20201021'], $params); + } + public function testJoin1() { $query = Rhymix\Framework\Parsers\DBQueryParser::loadXML(\RX_BASEDIR . 'tests/_data/dbquery/selectJoinTest1.xml');