Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added support to CaseExpression. Added support to nest AndX and OrX Q…

…ueryBuilder composite expressions, since they do not mess with generated queries.
  • Loading branch information...
commit 816ce41f638d28934c79a12ef27f954124b2639e 1 parent 1666d59
@guilhermeblanco guilhermeblanco authored
View
48 lib/Doctrine/ORM/Query/AST/GeneralCaseExpression.php
@@ -0,0 +1,48 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * GeneralCaseExpression ::= "CASE" WhenClause {WhenClause}* "ELSE" ScalarExpression "END"
+ *
+ * @since 2.2
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link www.doctrine-project.org
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Jonathan Wage <jonwage@gmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ */
+class GeneralCaseExpression extends Node
+{
+ public $whenClauses = array();
+ public $elseScalarExpression = null;
+
+ public function __construct(array $whenClauses, $elseScalarExpression)
+ {
+ $this->whenClauses = $whenClauses;
+ $this->elseScalarExpression = $elseScalarExpression;
+ }
+
+ public function dispatch($sqlWalker)
+ {
+ return $sqlWalker->walkGeneralCaseExpression($this);
+ }
+}
View
50 lib/Doctrine/ORM/Query/AST/SimpleCaseExpression.php
@@ -0,0 +1,50 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * SimpleCaseExpression ::= "CASE" CaseOperand SimpleWhenClause {SimpleWhenClause}* "ELSE" ScalarExpression "END"
+ *
+ * @since 2.2
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link www.doctrine-project.org
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Jonathan Wage <jonwage@gmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ */
+class SimpleCaseExpression extends Node
+{
+ public $caseOperand = null;
+ public $simpleWhenClauses = array();
+ public $elseScalarExpression = null;
+
+ public function __construct($caseOperand, array $simpleWhenClauses, $elseScalarExpression)
+ {
+ $this->caseOperand = $caseOperand;
+ $this->simpleWhenClauses = $simpleWhenClauses;
+ $this->elseScalarExpression = $elseScalarExpression;
+ }
+
+ public function dispatch($sqlWalker)
+ {
+ return $sqlWalker->walkSimpleCaseExpression($this);
+ }
+}
View
48 lib/Doctrine/ORM/Query/AST/SimpleWhenClause.php
@@ -0,0 +1,48 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * SimpleWhenClause ::= "WHEN" ScalarExpression "THEN" ScalarExpression
+ *
+ * @since 2.2
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link www.doctrine-project.org
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Jonathan Wage <jonwage@gmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ */
+class SimpleWhenClause extends Node
+{
+ public $caseScalarExpression = null;
+ public $thenScalarExpression = null;
+
+ public function __construct($caseScalarExpression, $thenScalarExpression)
+ {
+ $this->caseScalarExpression = $caseScalarExpression;
+ $this->thenScalarExpression = $thenScalarExpression;
+ }
+
+ public function dispatch($sqlWalker)
+ {
+ return $sqlWalker->walkWhenClauseExpression($this);
+ }
+}
View
48 lib/Doctrine/ORM/Query/AST/WhenClause.php
@@ -0,0 +1,48 @@
+<?php
+/*
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.doctrine-project.org>.
+ */
+
+namespace Doctrine\ORM\Query\AST;
+
+/**
+ * WhenClause ::= "WHEN" ConditionalExpression "THEN" ScalarExpression
+ *
+ * @since 2.2
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link www.doctrine-project.org
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
+ * @author Jonathan Wage <jonwage@gmail.com>
+ * @author Roman Borschel <roman@code-factory.org>
+ */
+class WhenClause extends Node
+{
+ public $caseConditionExpression = null;
+ public $thenScalarExpression = null;
+
+ public function __construct($caseConditionExpression, $thenScalarExpression)
+ {
+ $this->caseConditionExpression = $caseConditionExpression;
+ $this->thenScalarExpression = $thenScalarExpression;
+ }
+
+ public function dispatch($sqlWalker)
+ {
+ return $sqlWalker->walkWhenClauseExpression($this);
+ }
+}
View
1  lib/Doctrine/ORM/Query/Expr/Andx.php
@@ -39,5 +39,6 @@ class Andx extends Composite
'Doctrine\ORM\Query\Expr\Comparison',
'Doctrine\ORM\Query\Expr\Func',
'Doctrine\ORM\Query\Expr\Orx',
+ 'Doctrine\ORM\Query\Expr\Andx',

Any chance of committing this change and the one in Orx.php to the 2.1.x branch? Thanks :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
);
}
View
3  lib/Doctrine/ORM/Query/Expr/Orx.php
@@ -36,8 +36,9 @@ class Orx extends Composite
{
protected $_separator = ' OR ';
protected $_allowedClasses = array(
- 'Doctrine\ORM\Query\Expr\Andx',
'Doctrine\ORM\Query\Expr\Comparison',
'Doctrine\ORM\Query\Expr\Func',
+ 'Doctrine\ORM\Query\Expr\Andx',
+ 'Doctrine\ORM\Query\Expr\Orx',
);
}
View
83 lib/Doctrine/ORM/Query/Lexer.php
@@ -67,46 +67,49 @@ class Lexer extends \Doctrine\Common\Lexer
const T_DELETE = 113;
const T_DESC = 114;
const T_DISTINCT = 115;
- const T_EMPTY = 116;
- const T_ESCAPE = 117;
- const T_EXISTS = 118;
- const T_FALSE = 119;
- const T_FROM = 120;
- const T_GROUP = 121;
- const T_HAVING = 122;
- const T_IN = 123;
- const T_INDEX = 124;
- const T_INNER = 125;
- const T_INSTANCE = 126;
- const T_IS = 127;
- const T_JOIN = 128;
- const T_LEADING = 129;
- const T_LEFT = 130;
- const T_LIKE = 131;
- const T_MAX = 132;
- const T_MEMBER = 133;
- const T_MIN = 134;
- const T_NOT = 135;
- const T_NULL = 136;
- const T_NULLIF = 137;
- const T_OF = 138;
- const T_OR = 139;
- const T_ORDER = 140;
- const T_OUTER = 141;
- const T_SELECT = 142;
- const T_SET = 143;
- const T_SIZE = 144;
- const T_SOME = 145;
- const T_SUM = 146;
- const T_TRAILING = 147;
- const T_TRUE = 148;
- const T_UPDATE = 149;
- const T_WHEN = 150;
- const T_WHERE = 151;
- const T_WITH = 153;
- const T_PARTIAL = 154;
- const T_MOD = 155;
-
+ const T_ELSE = 116;
+ const T_EMPTY = 117;
+ const T_END = 118;
+ const T_ESCAPE = 119;
+ const T_EXISTS = 120;
+ const T_FALSE = 121;
+ const T_FROM = 122;
+ const T_GROUP = 123;
+ const T_HAVING = 124;
+ const T_IN = 125;
+ const T_INDEX = 126;
+ const T_INNER = 127;
+ const T_INSTANCE = 128;
+ const T_IS = 129;
+ const T_JOIN = 130;
+ const T_LEADING = 131;
+ const T_LEFT = 132;
+ const T_LIKE = 133;
+ const T_MAX = 134;
+ const T_MEMBER = 135;
+ const T_MIN = 136;
+ const T_NOT = 137;
+ const T_NULL = 138;
+ const T_NULLIF = 139;
+ const T_OF = 140;
+ const T_OR = 141;
+ const T_ORDER = 142;
+ const T_OUTER = 143;
+ const T_SELECT = 144;
+ const T_SET = 145;
+ const T_SIZE = 146;
+ const T_SOME = 147;
+ const T_SUM = 148;
+ const T_THEN = 149;
+ const T_TRAILING = 150;
+ const T_TRUE = 151;
+ const T_UPDATE = 152;
+ const T_WHEN = 153;
+ const T_WHERE = 154;
+ const T_WITH = 155;
+ const T_PARTIAL = 156;
+ const T_MOD = 157;
+
/**
* Creates a new query scanner object.
*
View
133 lib/Doctrine/ORM/Query/Parser.php
@@ -1624,7 +1624,7 @@ public function IndexBy()
/**
* ScalarExpression ::= SimpleArithmeticExpression | StringPrimary | DateTimePrimary |
* StateFieldPathExpression | BooleanPrimary | CaseExpression |
- * EntityTypeExpression
+ * InstanceOfExpression
*
* @return mixed One of the possible expressions or subexpressions.
*/
@@ -1659,9 +1659,9 @@ public function ScalarExpression()
if ($this->_isAggregateFunction($this->_lexer->lookahead['type'])) {
return $this->AggregateExpression();
- } else {
- return $this->FunctionDeclaration();
}
+
+ return $this->FunctionDeclaration();
} else if ($lookahead == Lexer::T_STRING) {
return $this->StringPrimary();
} else if ($lookahead == Lexer::T_INPUT_PARAMETER) {
@@ -1674,25 +1674,42 @@ public function ScalarExpression()
}
}
+ /**
+ * CaseExpression ::= GeneralCaseExpression | SimpleCaseExpression | CoalesceExpression | NullifExpression
+ * GeneralCaseExpression ::= "CASE" WhenClause {WhenClause}* "ELSE" ScalarExpression "END"
+ * WhenClause ::= "WHEN" ConditionalExpression "THEN" ScalarExpression
+ * SimpleCaseExpression ::= "CASE" CaseOperand SimpleWhenClause {SimpleWhenClause}* "ELSE" ScalarExpression "END"
+ * CaseOperand ::= StateFieldPathExpression | TypeDiscriminator
+ * SimpleWhenClause ::= "WHEN" ScalarExpression "THEN" ScalarExpression
+ * CoalesceExpression ::= "COALESCE" "(" ScalarExpression {"," ScalarExpression}* ")"
+ * NullifExpression ::= "NULLIF" "(" ScalarExpression "," ScalarExpression ")"
+ *
+ * @return mixed One of the possible expressions or subexpressions.
+ */
public function CaseExpression()
{
$lookahead = $this->_lexer->lookahead['type'];
- // if "CASE" "WHEN" => GeneralCaseExpression
- // else if "CASE" => SimpleCaseExpression
- // [DONE] else if "COALESCE" => CoalesceExpression
- // [DONE] else if "NULLIF" => NullifExpression
switch ($lookahead) {
case Lexer::T_NULLIF:
return $this->NullIfExpression();
case Lexer::T_COALESCE:
return $this->CoalesceExpression();
+
+ case Lexer::T_CASE:
+ $peek = $this->_lexer->peek();
+
+ return ($peek['type'] === Lexer::T_WHEN)
+ ? $this->GeneralCaseExpression()
+ : $this->SimpleCaseExpression();
default:
- $this->semanticalError('CaseExpression not yet supported.');
- return null;
+ // Do nothing
+ break;
}
+
+ $this->syntaxError();
}
/**
@@ -1722,7 +1739,7 @@ public function CoalesceExpression()
/**
* NullIfExpression ::= "NULLIF" "(" ScalarExpression "," ScalarExpression ")"
*
- * @return Doctrine\ORM\Query\AST\ExistsExpression
+ * @return Doctrine\ORM\Query\AST\NullIfExpression
*/
public function NullIfExpression()
{
@@ -1737,6 +1754,80 @@ public function NullIfExpression()
return new AST\NullIfExpression($firstExpression, $secondExpression);
}
+
+ /**
+ * GeneralCaseExpression ::= "CASE" WhenClause {WhenClause}* "ELSE" ScalarExpression "END"
+ *
+ * @return Doctrine\ORM\Query\AST\GeneralExpression
+ */
+ public function GeneralCaseExpression()
+ {
+ $this->match(Lexer::T_CASE);
+
+ // Process WhenClause (1..N)
+ $whenClauses = array();
+
+ do {
+ $whenClauses[] = $this->WhenClause();
+ } while ($this->_lexer->isNextToken(Lexer::T_WHEN));
+
+ $this->match(Lexer::T_ELSE);
+ $scalarExpression = $this->ScalarExpression();
+ $this->match(Lexer::T_END);
+
+ return new AST\GeneralCaseExpression($whenClauses, $scalarExpression);
+ }
+
+ /**
+ * SimpleCaseExpression ::= "CASE" CaseOperand SimpleWhenClause {SimpleWhenClause}* "ELSE" ScalarExpression "END"
+ * CaseOperand ::= StateFieldPathExpression | TypeDiscriminator
+ */
+ public function SimpleCaseExpression()
+ {
+ $this->match(Lexer::T_CASE);
+ $caseOperand = $this->StateFieldPathExpression();
+
+ // Process SimpleWhenClause (1..N)
+ $simpleWhenClauses = array();
+
+ do {
+ $simpleWhenClauses[] = $this->SimpleWhenClause();
+ } while ($this->_lexer->isNextToken(Lexer::T_WHEN));
+
+ $this->match(Lexer::T_ELSE);
+ $scalarExpression = $this->ScalarExpression();
+ $this->match(Lexer::T_END);
+
+ return new AST\SimpleCaseExpression($caseOperand, $simpleWhenClauses, $scalarExpression);
+ }
+
+ /**
+ * WhenClause ::= "WHEN" ConditionalExpression "THEN" ScalarExpression
+ *
+ * @return Doctrine\ORM\Query\AST\WhenExpression
+ */
+ public function WhenClause()
+ {
+ $this->match(Lexer::T_WHEN);
+ $conditionalExpression = $this->ConditionalExpression();
+ $this->match(Lexer::T_THEN);
+
+ return new AST\WhenClause($conditionalExpression, $this->ScalarExpression());
+ }
+
+ /**
+ * SimpleWhenClause ::= "WHEN" ScalarExpression "THEN" ScalarExpression
+ *
+ * @return Doctrine\ORM\Query\AST\SimpleWhenExpression
+ */
+ public function SimpleWhenClause()
+ {
+ $this->match(Lexer::T_WHEN);
+ $conditionalExpression = $this->ScalarExpression();
+ $this->match(Lexer::T_THEN);
+
+ return new AST\SimpleWhenClause($conditionalExpression, $this->ScalarExpression());
+ }
/**
* SelectExpression ::=
@@ -1782,7 +1873,7 @@ public function SelectExpression()
$expression = $this->ScalarExpression();
} else if ($this->_isAggregateFunction($this->_lexer->lookahead['type'])) {
$expression = $this->AggregateExpression();
- } else if (in_array ($lookaheadType, array(Lexer::T_CASE, Lexer::T_COALESCE, Lexer::T_NULLIF))) {
+ } else if (in_array($lookaheadType, array(Lexer::T_COALESCE, Lexer::T_NULLIF))) {
$expression = $this->CaseExpression();
} else {
// Shortcut: ScalarExpression => Function
@@ -1797,10 +1888,13 @@ public function SelectExpression()
$this->_lexer->lookahead['type'] == Lexer::T_STRING) {
// Shortcut: ScalarExpression => SimpleArithmeticExpression
$expression = $this->SimpleArithmeticExpression();
+ } else if ($this->_lexer->lookahead['type'] == Lexer::T_CASE) {
+ $expression = $this->CaseExpression();
} else {
- $this->syntaxError('IdentificationVariable | StateFieldPathExpression'
- . ' | AggregateExpression | "(" Subselect ")" | ScalarExpression',
- $this->_lexer->lookahead);
+ $this->syntaxError(
+ 'IdentificationVariable | StateFieldPathExpression | AggregateExpression | "(" Subselect ")" | ScalarExpression',
+ $this->_lexer->lookahead
+ );
}
if ($supportsAlias) {
@@ -2290,7 +2384,7 @@ public function ArithmeticFactor()
/**
* ArithmeticPrimary ::= SingleValuedPathExpression | Literal | "(" SimpleArithmeticExpression ")"
* | FunctionsReturningNumerics | AggregateExpression | FunctionsReturningStrings
- * | FunctionsReturningDatetime | IdentificationVariable
+ * | FunctionsReturningDatetime | IdentificationVariable | CaseExpression
*/
public function ArithmeticPrimary()
{
@@ -2304,6 +2398,11 @@ public function ArithmeticPrimary()
}
switch ($this->_lexer->lookahead['type']) {
+ case Lexer::T_COALESCE:
+ case Lexer::T_NULLIF:
+ case Lexer::T_CASE:
+ return $this->CaseExpression();
+
case Lexer::T_IDENTIFIER:
$peek = $this->_lexer->glimpse();
@@ -2359,7 +2458,7 @@ public function StringExpression()
}
/**
- * StringPrimary ::= StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression
+ * StringPrimary ::= StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression | CaseExpression
*/
public function StringPrimary()
{
@@ -2382,6 +2481,8 @@ public function StringPrimary()
return $this->InputParameter();
} else if ($this->_isAggregateFunction($this->_lexer->lookahead['type'])) {
return $this->AggregateExpression();
+ } else if (in_array($this->_lexer->lookahead['type'], array(Lexer::T_CASE, Lexer::T_COALESCE, Lexer::T_NULLIF))) {
+ return $this->CaseExpression();
}
$this->syntaxError('StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression');
View
140 lib/Doctrine/ORM/Query/SqlWalker.php
@@ -859,6 +859,32 @@ public function walkJoinVariableDeclaration($joinVarDecl)
}
/**
+ * Walks down a CaseExpression AST node and generates the corresponding SQL.
+ *
+ * @param CoalesceExpression|NullIfExpression|GeneralCaseExpression|SimpleCaseExpression $expression
+ * @return string The SQL.
+ */
+ public function walkCaseExpression($expression)
+ {
+ switch (true) {
+ case ($expression instanceof AST\CoalesceExpression):
+ return $this->walkCoalesceExpression($expression);
+
+ case ($expression instanceof AST\NullIfExpression):
+ return $this->walkNullIfExpression($expression);
+
+ case ($expression instanceof AST\GeneralCaseExpression):
+ return $this->walkGeneralCaseExpression($expression);
+
+ case ($expression instanceof AST\SimpleCaseExpression):
+ return $this->walkSimpleCaseExpression($expression);
+
+ default:
+ return '';
+ }
+ }
+
+ /**
* Walks down a CoalesceExpression AST node and generates the corresponding SQL.
*
* @param CoalesceExpression $coalesceExpression
@@ -879,20 +905,6 @@ public function walkCoalesceExpression($coalesceExpression)
return $sql;
}
- public function walkCaseExpression($expression)
- {
- switch (true) {
- case ($expression instanceof AST\CoalesceExpression):
- return $this->walkCoalesceExpression($expression);
-
- case ($expression instanceof AST\NullIfExpression):
- return $this->walkNullIfExpression($expression);
-
- default:
- return '';
- }
- }
-
/**
* Walks down a NullIfExpression AST node and generates the corresponding SQL.
*
@@ -911,6 +923,46 @@ public function walkNullIfExpression($nullIfExpression)
return 'NULLIF(' . $firstExpression . ', ' . $secondExpression . ')';
}
+
+ /**
+ * Walks down a GeneralCaseExpression AST node and generates the corresponding SQL.
+ *
+ * @param GeneralCaseExpression $generalCaseExpression
+ * @return string The SQL.
+ */
+ public function walkGeneralCaseExpression(AST\GeneralCaseExpression $generalCaseExpression)
+ {
+ $sql = 'CASE';
+
+ foreach ($generalCaseExpression->whenClauses as $whenClause) {
+ $sql .= ' WHEN ' . $this->walkConditionalExpression($whenClause->caseConditionExpression);
+ $sql .= ' THEN ' . $this->walkSimpleArithmeticExpression($whenClause->thenScalarExpression);
+ }
+
+ $sql .= ' ELSE ' . $this->walkSimpleArithmeticExpression($generalCaseExpression->elseScalarExpression) . ' END';
+
+ return $sql;
+ }
+
+ /**
+ * Walks down a SimpleCaseExpression AST node and generates the corresponding SQL.
+ *
+ * @param SimpleCaseExpression $simpleCaseExpression
+ * @return string The SQL.
+ */
+ public function walkSimpleCaseExpression($simpleCaseExpression)
+ {
+ $sql = 'CASE ' . $this->walkStateFieldPathExpression($simpleCaseExpression->caseOperand);
+
+ foreach ($simpleCaseExpression->simpleWhenClauses as $simpleWhenClause) {
+ $sql .= ' WHEN ' . $this->walkSimpleArithmeticExpression($simpleWhenClause->caseScalarExpression);
+ $sql .= ' THEN ' . $this->walkSimpleArithmeticExpression($simpleWhenClause->thenScalarExpression);
+ }
+
+ $sql .= ' ELSE ' . $this->walkSimpleArithmeticExpression($simpleCaseExpression->elseScalarExpression) . ' END';
+
+ return $sql;
+ }
/**
* Walks down a SelectExpression AST node and generates the corresponding SQL.
@@ -924,36 +976,35 @@ public function walkSelectExpression($selectExpression)
$expr = $selectExpression->expression;
if ($expr instanceof AST\PathExpression) {
- if ($expr->type == AST\PathExpression::TYPE_STATE_FIELD) {
- $fieldName = $expr->field;
- $dqlAlias = $expr->identificationVariable;
- $qComp = $this->_queryComponents[$dqlAlias];
- $class = $qComp['metadata'];
-
- if ( ! $selectExpression->fieldIdentificationVariable) {
- $resultAlias = $fieldName;
- } else {
- $resultAlias = $selectExpression->fieldIdentificationVariable;
- }
-
- if ($class->isInheritanceTypeJoined()) {
- $tableName = $this->_em->getUnitOfWork()->getEntityPersister($class->name)->getOwningTable($fieldName);
- } else {
- $tableName = $class->getTableName();
- }
+ if ($expr->type !== AST\PathExpression::TYPE_STATE_FIELD) {
+ throw QueryException::invalidPathExpression($expr->type);
+ }
+
+ $fieldName = $expr->field;
+ $dqlAlias = $expr->identificationVariable;
+ $qComp = $this->_queryComponents[$dqlAlias];
+ $class = $qComp['metadata'];
- $sqlTableAlias = $this->getSQLTableAlias($tableName, $dqlAlias);
- $columnName = $class->getQuotedColumnName($fieldName, $this->_platform);
+ if ( ! $selectExpression->fieldIdentificationVariable) {
+ $resultAlias = $fieldName;
+ } else {
+ $resultAlias = $selectExpression->fieldIdentificationVariable;
+ }
- $columnAlias = $this->getSQLColumnAlias($columnName);
- $sql .= $sqlTableAlias . '.' . $columnName . ' AS ' . $columnAlias;
- $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
- $this->_rsm->addScalarResult($columnAlias, $resultAlias);
+ if ($class->isInheritanceTypeJoined()) {
+ $tableName = $this->_em->getUnitOfWork()->getEntityPersister($class->name)->getOwningTable($fieldName);
} else {
- throw QueryException::invalidPathExpression($expr->type);
+ $tableName = $class->getTableName();
}
- }
- else if ($expr instanceof AST\AggregateExpression) {
+
+ $sqlTableAlias = $this->getSQLTableAlias($tableName, $dqlAlias);
+ $columnName = $class->getQuotedColumnName($fieldName, $this->_platform);
+
+ $columnAlias = $this->getSQLColumnAlias($columnName);
+ $sql .= $sqlTableAlias . '.' . $columnName . ' AS ' . $columnAlias;
+ $columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
+ $this->_rsm->addScalarResult($columnAlias, $resultAlias);
+ } else if ($expr instanceof AST\AggregateExpression) {
if ( ! $selectExpression->fieldIdentificationVariable) {
$resultAlias = $this->_scalarResultCounter++;
} else {
@@ -966,8 +1017,7 @@ public function walkSelectExpression($selectExpression)
$columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
$this->_rsm->addScalarResult($columnAlias, $resultAlias);
- }
- else if ($expr instanceof AST\Subselect) {
+ } else if ($expr instanceof AST\Subselect) {
if ( ! $selectExpression->fieldIdentificationVariable) {
$resultAlias = $this->_scalarResultCounter++;
} else {
@@ -980,8 +1030,7 @@ public function walkSelectExpression($selectExpression)
$columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
$this->_rsm->addScalarResult($columnAlias, $resultAlias);
- }
- else if ($expr instanceof AST\Functions\FunctionNode) {
+ } else if ($expr instanceof AST\Functions\FunctionNode) {
if ( ! $selectExpression->fieldIdentificationVariable) {
$resultAlias = $this->_scalarResultCounter++;
} else {
@@ -1022,7 +1071,8 @@ public function walkSelectExpression($selectExpression)
} else if (
$expr instanceof AST\NullIfExpression ||
$expr instanceof AST\CoalesceExpression ||
- $expr instanceof AST\CaseExpression
+ $expr instanceof AST\GeneralCaseExpression ||
+ $expr instanceof AST\SimpleCaseExpression
) {
if ( ! $selectExpression->fieldIdentificationVariable) {
$resultAlias = $this->_scalarResultCounter++;
2  lib/vendor/doctrine-common
@@ -1 +1 @@
-Subproject commit 40f1bf16e84ddc5291a6a63aa00b9879c40e3500
+Subproject commit 74a2c924cd08b30785877808b1fb519b4b2e60b1
2  lib/vendor/doctrine-dbal
@@ -1 +1 @@
-Subproject commit 0127ee98a4301f2f6e3463c824adc3a3687f901f
+Subproject commit be3790059cc43b674a55548eb42d5d25846ea6a9
View
36 tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
@@ -976,6 +976,38 @@ public function testSelectForeignKeyPKWithoutFields()
"SELECT d0_.article_id AS article_id0, d0_.title AS title1, d1_.article_id AS article_id2, d1_.title AS title3 FROM DDC117Link d2_ INNER JOIN DDC117Article d0_ ON d2_.target_id = d0_.article_id INNER JOIN DDC117Article d1_ ON d2_.source_id = d1_.article_id"
);
}
+
+ public function testGeneralCaseWithSingleWhenClause()
+ {
+ $this->assertSqlGeneration(
+ "SELECT g.id, CASE WHEN ((g.id / 2) > 18) THEN 1 ELSE 0 END AS test FROM Doctrine\Tests\Models\CMS\CmsGroup g",
+ "SELECT c0_.id AS id0, CASE WHEN (c0_.id / 2 > 18) THEN 1 ELSE 0 END AS sclr1 FROM cms_groups c0_"
+ );
+ }
+
+ public function testGeneralCaseWithMultipleWhenClause()
+ {
+ $this->assertSqlGeneration(
+ "SELECT g.id, CASE WHEN (g.id / 2 < 10) THEN 2 WHEN ((g.id / 2) > 20) THEN 1 ELSE 0 END AS test FROM Doctrine\Tests\Models\CMS\CmsGroup g",
+ "SELECT c0_.id AS id0, CASE WHEN (c0_.id / 2 < 10) THEN 2 WHEN (c0_.id / 2 > 20) THEN 1 ELSE 0 END AS sclr1 FROM cms_groups c0_"
+ );
+ }
+
+ public function testSimpleCaseWithSingleWhenClause()
+ {
+ $this->assertSqlGeneration(
+ "SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id = CASE g.name WHEN 'admin' THEN 1 ELSE 2 END",
+ "SELECT c0_.id AS id0, c0_.name AS name1 FROM cms_groups c0_ WHERE c0_.id = CASE c0_.name WHEN admin THEN 1 ELSE 2 END"
+ );
+ }
+
+ public function testSimpleCaseWithMultipleWhenClause()
+ {
+ $this->assertSqlGeneration(
+ "SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id = (CASE g.name WHEN 'admin' THEN 1 WHEN 'moderator' THEN 2 ELSE 3 END)",
+ "SELECT c0_.id AS id0, c0_.name AS name1 FROM cms_groups c0_ WHERE c0_.id = CASE c0_.name WHEN admin THEN 1 WHEN moderator THEN 2 ELSE 3 END"
+ );
+ }
}
@@ -988,9 +1020,7 @@ class MyAbsFunction extends \Doctrine\ORM\Query\AST\Functions\FunctionNode
*/
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
- return 'ABS(' . $sqlWalker->walkSimpleArithmeticExpression(
- $this->simpleArithmeticExpression
- ) . ')';
+ return 'ABS(' . $sqlWalker->walkSimpleArithmeticExpression($this->simpleArithmeticExpression) . ')';
}
/**
Please sign in to comment.
Something went wrong with that request. Please try again.