Skip to content

Commit 8c288ee

Browse files
author
David Maechler
committed
fixing limit issue with different ways of writing a limit and adding some new unit test case
1 parent cc99a92 commit 8c288ee

File tree

5 files changed

+74
-11
lines changed

5 files changed

+74
-11
lines changed

src/SQLParser/Node/NodeFactory.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -713,12 +713,12 @@ public static function toSql($nodes, Connection $dbConnection = null, array $par
713713
$item = $nodes;
714714
if ($item instanceof SqlRenderInterface) {
715715
$itemSql = $item->toSql($parameters, $dbConnection, $indent, $conditionsMode);
716-
if ($itemSql == null) {
716+
if ($itemSql === null || $itemSql === '') {
717717
return;
718718
}
719719
$sql = str_repeat(' ', $indent).$itemSql;
720720
} else {
721-
if ($item == null) {
721+
if ($item === null || $item === '') {
722722
return;
723723
}
724724
$sql = str_repeat(' ', $indent).$item;

src/SQLParser/Node/UnquotedParameter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,6 @@ public function toSql(array $parameters = array(), Connection $dbConnection = nu
5858
{
5959
$name = parent::toSql($parameters, $dbConnection, $indent, $conditionsMode);
6060
$name = str_replace("'", "", $name);
61-
return is_numeric($name) ? (int)$name : $name;
61+
return $name;
6262
}
6363
}

src/SQLParser/Query/Select.php

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -232,19 +232,37 @@ public function setOptions($options)
232232
private $limit;
233233

234234
/**
235-
* @return NodeInterface[]|NodeInterface $limit
235+
* @return NodeInterface
236236
*/
237237
public function getLimit() {
238238
return $this->limit;
239239
}
240240

241241
/**
242-
* @param NodeInterface[]|NodeInterface $limit
242+
* @param NodeInterface $limit
243243
*/
244244
public function setLimit($limit) {
245245
$this->limit = $limit;
246246
}
247247

248+
private $offset;
249+
250+
/**
251+
* @return NodeInterface
252+
*/
253+
public function getOffset()
254+
{
255+
return $this->offset;
256+
}
257+
258+
/**
259+
* @param NodeInterface $offset
260+
*/
261+
public function setOffset($offset)
262+
{
263+
$this->offset = $offset;
264+
}
265+
248266
/**
249267
* @param MoufManager $moufManager
250268
*
@@ -260,6 +278,7 @@ public function toInstanceDescriptor(MoufManager $moufManager)
260278
$instanceDescriptor->getProperty('group')->setValue(NodeFactory::nodeToInstanceDescriptor($this->group, $moufManager));
261279
$instanceDescriptor->getProperty('having')->setValue(NodeFactory::nodeToInstanceDescriptor($this->having, $moufManager));
262280
$instanceDescriptor->getProperty('order')->setValue(NodeFactory::nodeToInstanceDescriptor($this->order, $moufManager));
281+
$instanceDescriptor->getProperty('offset')->setValue(NodeFactory::nodeToInstanceDescriptor($this->offset, $moufManager));
263282
$instanceDescriptor->getProperty('limit')->setValue(NodeFactory::nodeToInstanceDescriptor($this->limit, $moufManager));
264283
$instanceDescriptor->getProperty('options')->setValue($this->options);
265284

@@ -284,6 +303,7 @@ public function overwriteInstanceDescriptor($name, MoufManager $moufManager)
284303
$instanceDescriptor->getProperty('group')->setValue(NodeFactory::nodeToInstanceDescriptor($this->group, $moufManager));
285304
$instanceDescriptor->getProperty('having')->setValue(NodeFactory::nodeToInstanceDescriptor($this->having, $moufManager));
286305
$instanceDescriptor->getProperty('order')->setValue(NodeFactory::nodeToInstanceDescriptor($this->order, $moufManager));
306+
$instanceDescriptor->getProperty('offset')->setValue(NodeFactory::nodeToInstanceDescriptor($this->offset, $moufManager));
287307
$instanceDescriptor->getProperty('limit')->setValue(NodeFactory::nodeToInstanceDescriptor($this->limit, $moufManager));
288308
$instanceDescriptor->getProperty('options')->setValue($this->options);
289309

@@ -348,11 +368,31 @@ public function toSql(array $parameters = array(), Connection $dbConnection = nu
348368
}
349369
}
350370

351-
if (!empty($this->limit)) {
371+
if (!empty($this->offset) && empty($this->limit)) {
372+
throw new \Exception('There is no offset if no limit is provided. An error may have occurred during SQLParsing.');
373+
} else if (!empty($this->limit)) {
352374
$limit = NodeFactory::toSql($this->limit, $dbConnection, $parameters, ',', false, $indent + 2, $conditionsMode);
353-
if ($limit) {
354-
$sql .= "\nLIMIT ".$limit;
375+
if ($limit === '') {
376+
$limit = null;
377+
}
378+
if (!empty($this->offset)) {
379+
$offset = NodeFactory::toSql($this->offset, $dbConnection, $parameters, ',', false, $indent + 2, $conditionsMode);
380+
if ($offset === '') {
381+
$offset = null;
382+
}
383+
} else {
384+
$offset = null;
385+
}
386+
387+
388+
if ($limit === null && $offset !== null) {
389+
throw new \Exception('There is no offset if no limit is provided. An error may have occurred during SQLParsing.');
390+
}
391+
$sql .= "\nLIMIT ";
392+
if ($offset !== null) {
393+
$sql .= $offset.', ';
355394
}
395+
$sql .= $limit;
356396
}
357397

358398
return $sql;

src/SQLParser/Query/StatementFactory.php

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,17 +96,34 @@ public static function toObject(array $desc)
9696
}
9797

9898
if (isset($desc['LIMIT'])) {
99-
$limit = self::mapArrayToNodeObjectList($desc['LIMIT']);
100-
$limit = NodeFactory::simplify($limit);
99+
$descLimit = self::checkLimitDesc($desc['LIMIT']);
100+
101+
$limit = NodeFactory::toObject($descLimit['limit']);
102+
//$limit = NodeFactory::simplify($limit);
101103
$select->setLimit($limit);
102-
}
103104

105+
$offset = NodeFactory::toObject($descLimit['offset']);
106+
//$offset = NodeFactory::simplify($offset);
107+
$select->setOffset($offset);
108+
}
104109
return $select;
105110
} else {
106111
throw new \BadMethodCallException('Unknown query');
107112
}
108113
}
109114

115+
/**
116+
* @param array $descLimit
117+
* @return array
118+
* @throws \Exception
119+
*/
120+
private static function checkLimitDesc(array $descLimit) {
121+
if(count($descLimit) > 2) {
122+
throw new \Exception('The limit returned by the SQLParser contains more than 2 items, something might went wrong.');
123+
}
124+
return ['offset' => $descLimit[0], 'limit' => $descLimit[1]];
125+
}
126+
110127
/**
111128
* @param array $items An array of objects represented as SQLParser arrays.
112129
*/

tests/Mouf/Database/MagicQueryTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ public function testStandardSelect()
1212
{
1313
$magicQuery = new MagicQuery();
1414

15+
$sql = "SELECT id FROM users LIMIT 10";
16+
$this->assertEquals("SELECT id FROM users LIMIT 10", self::simplifySql($magicQuery->build($sql)));
17+
18+
$sql = "SELECT id FROM users LIMIT 10 OFFSET 20";
19+
$this->assertEquals("SELECT id FROM users LIMIT 20, 10", self::simplifySql($magicQuery->build($sql)));
20+
1521
$sql = "SELECT id FROM users WHERE name LIKE :name LIMIT :offset, :limit";
1622
$this->assertEquals("SELECT id FROM users WHERE name LIKE 'foo' LIMIT 0, 20", self::simplifySql($magicQuery->build($sql, ['name' => 'foo', 'offset' => 0, 'limit' => 20])));
1723

0 commit comments

Comments
 (0)