Skip to content

Commit 3424082

Browse files
committed
Merge pull request #18 from dmaechler/fix_simple_functions
fixing reserved sql names that where considered as expression nodes and never outputed. Add a new node Reserved.php to handle it. Add also the unit test to this case with group_concat
2 parents def185f + bbfaccd commit 3424082

File tree

3 files changed

+169
-3
lines changed

3 files changed

+169
-3
lines changed

src/SQLParser/Node/NodeFactory.php

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -292,14 +292,29 @@ public static function toObject(array $desc)
292292
}
293293

294294
return $expr;
295+
case ExpressionType::RESERVED:
296+
$res = new Reserved();
297+
$res->setBaseExpression($desc['base_expr']);
295298

299+
if ($desc['expr_type'] == ExpressionType::BRACKET_EXPRESSION) {
300+
$res->setBrackets(true);
301+
}
302+
303+
// Debug:
304+
unset($desc['base_expr']);
305+
unset($desc['expr_type']);
306+
unset($desc['sub_tree']);
307+
unset($desc['alias']);
308+
unset($desc['direction']);
309+
if (!empty($desc)) {
310+
throw new \InvalidArgumentException('Unexpected parameters in exception: '.var_export($desc, true));
311+
}
312+
313+
return $res;
296314
case ExpressionType::USER_VARIABLE:
297315
case ExpressionType::SESSION_VARIABLE:
298316
case ExpressionType::GLOBAL_VARIABLE:
299317
case ExpressionType::LOCAL_VARIABLE:
300-
301-
case ExpressionType::RESERVED:
302-
303318
case ExpressionType::EXPRESSION:
304319
case ExpressionType::BRACKET_EXPRESSION:
305320
case ExpressionType::TABLE_EXPRESSION:

src/SQLParser/Node/Reserved.php

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
<?php
2+
3+
/**
4+
* expression-types.php.
5+
*
6+
*
7+
* Copyright (c) 2010-2013, Justin Swanhart
8+
* with contributions by André Rothe <[email protected], [email protected]>
9+
* and David Négrier <[email protected]>
10+
*
11+
* All rights reserved.
12+
*
13+
* Redistribution and use in source and binary forms, with or without modification,
14+
* are permitted provided that the following conditions are met:
15+
*
16+
* * Redistributions of source code must retain the above copyright notice,
17+
* this list of conditions and the following disclaimer.
18+
* * Redistributions in binary form must reproduce the above copyright notice,
19+
* this list of conditions and the following disclaimer in the documentation
20+
* and/or other materials provided with the distribution.
21+
*
22+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
23+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25+
* SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27+
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28+
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30+
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31+
* DAMAGE.
32+
*/
33+
34+
namespace SQLParser\Node;
35+
36+
use Doctrine\DBAL\Connection;
37+
use Mouf\MoufInstanceDescriptor;
38+
use Mouf\MoufManager;
39+
use SQLParser\Node\Traverser\NodeTraverser;
40+
use SQLParser\Node\Traverser\VisitorInterface;
41+
42+
/**
43+
* This class represents a node that is an SQL expression.
44+
*
45+
* @author David Négrier <[email protected]>
46+
*/
47+
class Reserved implements NodeInterface
48+
{
49+
private $baseExpression;
50+
51+
/**
52+
* Returns the base expression (the string that generated this expression).
53+
*
54+
* @return string
55+
*/
56+
public function getBaseExpression()
57+
{
58+
return $this->baseExpression;
59+
}
60+
61+
/**
62+
* Sets the base expression (the string that generated this expression).
63+
*
64+
* @param string $baseExpression
65+
*/
66+
public function setBaseExpression($baseExpression)
67+
{
68+
$this->baseExpression = $baseExpression;
69+
}
70+
71+
private $brackets = false;
72+
73+
/**
74+
* Returns true if the expression is between brackets.
75+
*
76+
* @return bool
77+
*/
78+
public function hasBrackets()
79+
{
80+
return $this->brackets;
81+
}
82+
83+
/**
84+
* Sets to true if the expression is between brackets.
85+
*
86+
* @Important
87+
*
88+
* @param bool $brackets
89+
*/
90+
public function setBrackets($brackets)
91+
{
92+
$this->brackets = $brackets;
93+
}
94+
95+
/**
96+
* Returns a Mouf instance descriptor describing this object.
97+
*
98+
* @param MoufManager $moufManager
99+
*
100+
* @return MoufInstanceDescriptor
101+
*/
102+
public function toInstanceDescriptor(MoufManager $moufManager)
103+
{
104+
$instanceDescriptor = $moufManager->createInstance(get_called_class());
105+
$instanceDescriptor->getProperty('baseExpression')->setValue(NodeFactory::nodeToInstanceDescriptor($this->baseExpression, $moufManager));
106+
$instanceDescriptor->getProperty('brackets')->setValue(NodeFactory::nodeToInstanceDescriptor($this->brackets, $moufManager));
107+
108+
return $instanceDescriptor;
109+
}
110+
111+
/**
112+
* Renders the object as a SQL string.
113+
*
114+
* @param array $parameters
115+
* @param Connection $dbConnection
116+
* @param int|number $indent
117+
* @param int $conditionsMode
118+
* @return string
119+
*/
120+
public function toSql(array $parameters = array(), Connection $dbConnection = null, $indent = 0, $conditionsMode = self::CONDITION_APPLY)
121+
{
122+
$sql = '';
123+
124+
if($this->baseExpression) {
125+
$sql .= ' '.$this->baseExpression.' ';
126+
}
127+
128+
if ($this->brackets) {
129+
$sql = '('.$sql.')';
130+
}
131+
132+
return $sql;
133+
}
134+
135+
/**
136+
* Walks the tree of nodes, calling the visitor passed in parameter.
137+
*
138+
* @param VisitorInterface $visitor
139+
*/
140+
public function walk(VisitorInterface $visitor) {
141+
$node = $this;
142+
$result = $visitor->enterNode($node);
143+
if ($result instanceof NodeInterface) {
144+
$node = $result;
145+
}
146+
return $visitor->leaveNode($node);
147+
}
148+
}

tests/Mouf/Database/MagicQueryTest.php

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

15+
$sql = "SELECT GROUP_CONCAT(id SEPARATOR ', ') AS ids FROM users";
16+
$this->assertEquals("SELECT GROUP_CONCAT(id SEPARATOR ', ') AS ids FROM users", self::simplifySql($magicQuery->build($sql)));
17+
1518
$sql = "SELECT id FROM users WHERE name LIKE :name LIMIT :offset, :limit";
1619
$this->assertEquals("SELECT id FROM users WHERE name LIKE 'foo'", self::simplifySql($magicQuery->build($sql, ['name' => 'foo'])));
1720

0 commit comments

Comments
 (0)