Skip to content

Commit

Permalink
Merge pull request #47 from TheoBiron/between_issue
Browse files Browse the repository at this point in the history
Issue with between and parenthesis
  • Loading branch information
moufmouf committed Jun 26, 2019
2 parents 3eb2186 + 7ad8b0f commit d5fcdd8
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 37 deletions.
34 changes: 27 additions & 7 deletions src/SQLParser/Node/NodeFactory.php
Expand Up @@ -452,19 +452,39 @@ private static function buildFromSubtree($subTree)
if (!empty($subTree) && !isset($subTree[0])) {
$subTree = StatementFactory::toObject($subTree);
} else {
$subTree = array_map(function ($item) {
if (is_array($item)) {
return self::toObject($item);
} else {
return $item;
}
}, $subTree);
$subTree = self::mapArrayToNodeObjectList($subTree);
}
}

return $subTree;
}

/**
* @param array $items An array of objects represented as SQLParser arrays.
*/
public static function mapArrayToNodeObjectList(array $items)
{
$list = [];

$nextAndPartOfBetween = false;

// Special case, let's replace the AND of a between with a ANDBETWEEN object.
foreach ($items as $item) {
$obj = NodeFactory::toObject($item);
if ($obj instanceof Operator) {
if ($obj->getValue() == 'BETWEEN') {
$nextAndPartOfBetween = true;
} elseif ($nextAndPartOfBetween && $obj->getValue() == 'AND') {
$nextAndPartOfBetween = false;
$obj->setValue('AND_FROM_BETWEEN');
}
}
$list[] = $obj;
}

return $list;
}

private static $PRECEDENCE = array(
array('INTERVAL'),
array('BINARY', 'COLLATE'),
Expand Down
35 changes: 5 additions & 30 deletions src/SQLParser/Query/StatementFactory.php
Expand Up @@ -39,30 +39,30 @@ public static function toObject(array $desc)
$select->setColumns($columns);

if (isset($desc['FROM'])) {
$from = self::mapArrayToNodeObjectList($desc['FROM']);
$from = NodeFactory::mapArrayToNodeObjectList($desc['FROM']);
$select->setFrom($from);
}

if (isset($desc['WHERE'])) {
$where = self::mapArrayToNodeObjectList($desc['WHERE']);
$where = NodeFactory::mapArrayToNodeObjectList($desc['WHERE']);
$where = NodeFactory::simplify($where);
$select->setWhere($where);
}

if (isset($desc['GROUP'])) {
$group = self::mapArrayToNodeObjectList($desc['GROUP']);
$group = NodeFactory::mapArrayToNodeObjectList($desc['GROUP']);
$group = NodeFactory::simplify($group);
$select->setGroup($group);
}

if (isset($desc['HAVING'])) {
$having = self::mapArrayToNodeObjectList($desc['HAVING']);
$having = NodeFactory::mapArrayToNodeObjectList($desc['HAVING']);
$having = NodeFactory::simplify($having);
$select->setHaving($having);
}

if (isset($desc['ORDER'])) {
$order = self::mapArrayToNodeObjectList($desc['ORDER']);
$order = NodeFactory::mapArrayToNodeObjectList($desc['ORDER']);
$order = NodeFactory::simplify($order);
$select->setOrder($order);
}
Expand Down Expand Up @@ -112,29 +112,4 @@ public static function toObject(array $desc)
return ['offset' => $descLimit['offset'], 'limit' => $descLimit['rowcount']];
}*/

/**
* @param array $items An array of objects represented as SQLParser arrays.
*/
private static function mapArrayToNodeObjectList(array $items)
{
$list = [];

$nextAndPartOfBetween = false;

// Special case, let's replace the AND of a between with a ANDBETWEEN object.
foreach ($items as $item) {
$obj = NodeFactory::toObject($item);
if ($obj instanceof Operator) {
if ($obj->getValue() == 'BETWEEN') {
$nextAndPartOfBetween = true;
} elseif ($nextAndPartOfBetween && $obj->getValue() == 'AND') {
$nextAndPartOfBetween = false;
$obj->setValue('AND_FROM_BETWEEN');
}
}
$list[] = $obj;
}

return $list;
}
}
4 changes: 4 additions & 0 deletions tests/Mouf/Database/MagicQueryTest.php
Expand Up @@ -78,6 +78,10 @@ public function testStandardSelect()
$this->assertEquals("SELECT * FROM myTable WHERE someField <= '4'", self::simplifySql($magicQuery->build($sql, ['value2' => 4])));
$this->assertEquals('SELECT * FROM myTable', self::simplifySql($magicQuery->build($sql, [])));

$sql = 'SELECT * FROM myTable where (someField BETWEEN :value1 AND :value2) AND otherField = :value3';
$this->assertEquals("SELECT * FROM myTable WHERE ((someField BETWEEN '2' AND '4')) AND (otherField = '8')", self::simplifySql($magicQuery->build($sql, ['value1' => 2, 'value2' => 4, 'value3' => 8])));


// Triggers an "expression"
// TODO: find why it fails!
//$sql = 'SELECT * FROM (users) WHERE name LIKE :name';
Expand Down

0 comments on commit d5fcdd8

Please sign in to comment.