No longer treat aggregate functions as a special case.
This commit is contained in:
parent
e4ff7a35a8
commit
866418e40f
@ -425,10 +425,6 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
|||||||
*/
|
*/
|
||||||
public function addCustomStringFunction($name, $className)
|
public function addCustomStringFunction($name, $className)
|
||||||
{
|
{
|
||||||
if (Query\Parser::isInternalFunction($name)) {
|
|
||||||
throw ORMException::overwriteInternalDQLFunctionNotAllowed($name);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->_attributes['customStringFunctions'][strtolower($name)] = $className;
|
$this->_attributes['customStringFunctions'][strtolower($name)] = $className;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,10 +479,6 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
|||||||
*/
|
*/
|
||||||
public function addCustomNumericFunction($name, $className)
|
public function addCustomNumericFunction($name, $className)
|
||||||
{
|
{
|
||||||
if (Query\Parser::isInternalFunction($name)) {
|
|
||||||
throw ORMException::overwriteInternalDQLFunctionNotAllowed($name);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->_attributes['customNumericFunctions'][strtolower($name)] = $className;
|
$this->_attributes['customNumericFunctions'][strtolower($name)] = $className;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,10 +533,6 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
|||||||
*/
|
*/
|
||||||
public function addCustomDatetimeFunction($name, $className)
|
public function addCustomDatetimeFunction($name, $className)
|
||||||
{
|
{
|
||||||
if (Query\Parser::isInternalFunction($name)) {
|
|
||||||
throw ORMException::overwriteInternalDQLFunctionNotAllowed($name);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->_attributes['customDatetimeFunctions'][strtolower($name)] = $className;
|
$this->_attributes['customDatetimeFunctions'][strtolower($name)] = $className;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,16 +323,6 @@ class ORMException extends Exception
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $functionName
|
|
||||||
*
|
|
||||||
* @return ORMException
|
|
||||||
*/
|
|
||||||
public static function overwriteInternalDQLFunctionNotAllowed($functionName)
|
|
||||||
{
|
|
||||||
return new self("It is not allowed to overwrite internal function '$functionName' in the DQL parser through user-defined functions.");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return ORMException
|
* @return ORMException
|
||||||
*/
|
*/
|
||||||
|
55
lib/Doctrine/ORM/Query/AST/Functions/AvgFunction.php
Normal file
55
lib/Doctrine/ORM/Query/AST/Functions/AvgFunction.php
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?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 MIT license. For more information, see
|
||||||
|
* <http://www.doctrine-project.org>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Doctrine\ORM\Query\AST\Functions;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Query\Parser;
|
||||||
|
use Doctrine\ORM\Query\SqlWalker;
|
||||||
|
use Doctrine\ORM\Query\AST\AggregateExpression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "AVG" "(" ["DISTINCT"] StringPrimary ")"
|
||||||
|
*
|
||||||
|
* @link www.doctrine-project.org
|
||||||
|
* @since 2.0
|
||||||
|
* @author Mathew Davies <thepixeldeveloper@icloud.com>
|
||||||
|
*/
|
||||||
|
class AvgFunction extends FunctionNode
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var AggregateExpression
|
||||||
|
*/
|
||||||
|
public $aggregateExpression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getSql(SqlWalker $sqlWalker)
|
||||||
|
{
|
||||||
|
return $this->aggregateExpression->dispatch($sqlWalker);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function parse(Parser $parser)
|
||||||
|
{
|
||||||
|
$this->aggregateExpression = $parser->AggregateExpression();
|
||||||
|
}
|
||||||
|
}
|
55
lib/Doctrine/ORM/Query/AST/Functions/CountFunction.php
Normal file
55
lib/Doctrine/ORM/Query/AST/Functions/CountFunction.php
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?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 MIT license. For more information, see
|
||||||
|
* <http://www.doctrine-project.org>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Doctrine\ORM\Query\AST\Functions;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Query\Parser;
|
||||||
|
use Doctrine\ORM\Query\SqlWalker;
|
||||||
|
use Doctrine\ORM\Query\AST\AggregateExpression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "COUNT" "(" ["DISTINCT"] StringPrimary ")"
|
||||||
|
*
|
||||||
|
* @link www.doctrine-project.org
|
||||||
|
* @since 2.0
|
||||||
|
* @author Mathew Davies <thepixeldeveloper@icloud.com>
|
||||||
|
*/
|
||||||
|
class CountFunction extends FunctionNode
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var AggregateExpression
|
||||||
|
*/
|
||||||
|
public $aggregateExpression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getSql(SqlWalker $sqlWalker)
|
||||||
|
{
|
||||||
|
return $this->aggregateExpression->dispatch($sqlWalker);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function parse(Parser $parser)
|
||||||
|
{
|
||||||
|
$this->aggregateExpression = $parser->AggregateExpression();
|
||||||
|
}
|
||||||
|
}
|
55
lib/Doctrine/ORM/Query/AST/Functions/MaxFunction.php
Normal file
55
lib/Doctrine/ORM/Query/AST/Functions/MaxFunction.php
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?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 MIT license. For more information, see
|
||||||
|
* <http://www.doctrine-project.org>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Doctrine\ORM\Query\AST\Functions;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Query\Parser;
|
||||||
|
use Doctrine\ORM\Query\SqlWalker;
|
||||||
|
use Doctrine\ORM\Query\AST\AggregateExpression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "MAX" "(" ["DISTINCT"] StringPrimary ")"
|
||||||
|
*
|
||||||
|
* @link www.doctrine-project.org
|
||||||
|
* @since 2.0
|
||||||
|
* @author Mathew Davies <thepixeldeveloper@icloud.com>
|
||||||
|
*/
|
||||||
|
class MaxFunction extends FunctionNode
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var AggregateExpression
|
||||||
|
*/
|
||||||
|
public $aggregateExpression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getSql(SqlWalker $sqlWalker)
|
||||||
|
{
|
||||||
|
return $this->aggregateExpression->dispatch($sqlWalker);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function parse(Parser $parser)
|
||||||
|
{
|
||||||
|
$this->aggregateExpression = $parser->AggregateExpression();
|
||||||
|
}
|
||||||
|
}
|
55
lib/Doctrine/ORM/Query/AST/Functions/MinFunction.php
Normal file
55
lib/Doctrine/ORM/Query/AST/Functions/MinFunction.php
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?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 MIT license. For more information, see
|
||||||
|
* <http://www.doctrine-project.org>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Doctrine\ORM\Query\AST\Functions;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Query\Parser;
|
||||||
|
use Doctrine\ORM\Query\SqlWalker;
|
||||||
|
use Doctrine\ORM\Query\AST\AggregateExpression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "MIN" "(" ["DISTINCT"] StringPrimary ")"
|
||||||
|
*
|
||||||
|
* @link www.doctrine-project.org
|
||||||
|
* @since 2.0
|
||||||
|
* @author Mathew Davies <thepixeldeveloper@icloud.com>
|
||||||
|
*/
|
||||||
|
class MinFunction extends FunctionNode
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var AggregateExpression
|
||||||
|
*/
|
||||||
|
public $aggregateExpression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getSql(SqlWalker $sqlWalker)
|
||||||
|
{
|
||||||
|
return $this->aggregateExpression->dispatch($sqlWalker);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function parse(Parser $parser)
|
||||||
|
{
|
||||||
|
$this->aggregateExpression = $parser->AggregateExpression();
|
||||||
|
}
|
||||||
|
}
|
55
lib/Doctrine/ORM/Query/AST/Functions/SumFunction.php
Normal file
55
lib/Doctrine/ORM/Query/AST/Functions/SumFunction.php
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?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 MIT license. For more information, see
|
||||||
|
* <http://www.doctrine-project.org>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Doctrine\ORM\Query\AST\Functions;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Query\Parser;
|
||||||
|
use Doctrine\ORM\Query\SqlWalker;
|
||||||
|
use Doctrine\ORM\Query\AST\AggregateExpression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "SUM" "(" ["DISTINCT"] StringPrimary ")"
|
||||||
|
*
|
||||||
|
* @link www.doctrine-project.org
|
||||||
|
* @since 2.0
|
||||||
|
* @author Mathew Davies <thepixeldeveloper@icloud.com>
|
||||||
|
*/
|
||||||
|
class SumFunction extends FunctionNode
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var AggregateExpression
|
||||||
|
*/
|
||||||
|
public $aggregateExpression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function getSql(SqlWalker $sqlWalker)
|
||||||
|
{
|
||||||
|
return $this->aggregateExpression->dispatch($sqlWalker);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function parse(Parser $parser)
|
||||||
|
{
|
||||||
|
$this->aggregateExpression = $parser->AggregateExpression();
|
||||||
|
}
|
||||||
|
}
|
@ -65,6 +65,13 @@ class Parser
|
|||||||
'date_diff' => Functions\DateDiffFunction::class,
|
'date_diff' => Functions\DateDiffFunction::class,
|
||||||
'bit_and' => Functions\BitAndFunction::class,
|
'bit_and' => Functions\BitAndFunction::class,
|
||||||
'bit_or' => Functions\BitOrFunction::class,
|
'bit_or' => Functions\BitOrFunction::class,
|
||||||
|
|
||||||
|
// Aggregate functions
|
||||||
|
'min' => Functions\MinFunction::class,
|
||||||
|
'max' => Functions\MaxFunction::class,
|
||||||
|
'avg' => Functions\AvgFunction::class,
|
||||||
|
'sum' => Functions\SumFunction::class,
|
||||||
|
'count' => Functions\CountFunction::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -171,23 +178,6 @@ class Parser
|
|||||||
*/
|
*/
|
||||||
private $identVariableExpressions = [];
|
private $identVariableExpressions = [];
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if a function is internally defined. Used to prevent overwriting
|
|
||||||
* of built-in functions through user-defined functions.
|
|
||||||
*
|
|
||||||
* @param string $functionName
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
static public function isInternalFunction($functionName)
|
|
||||||
{
|
|
||||||
$functionName = strtolower($functionName);
|
|
||||||
|
|
||||||
return isset(self::$_STRING_FUNCTIONS[$functionName])
|
|
||||||
|| isset(self::$_DATETIME_FUNCTIONS[$functionName])
|
|
||||||
|| isset(self::$_NUMERIC_FUNCTIONS[$functionName]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new query parser object.
|
* Creates a new query parser object.
|
||||||
*
|
*
|
||||||
@ -1978,9 +1968,6 @@ class Parser
|
|||||||
// SUM(u.id) + COUNT(u.id)
|
// SUM(u.id) + COUNT(u.id)
|
||||||
return $this->SimpleArithmeticExpression();
|
return $this->SimpleArithmeticExpression();
|
||||||
|
|
||||||
case ($this->isAggregateFunction($this->lexer->lookahead['type'])):
|
|
||||||
return $this->AggregateExpression();
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// IDENTITY(u)
|
// IDENTITY(u)
|
||||||
return $this->FunctionDeclaration();
|
return $this->FunctionDeclaration();
|
||||||
@ -2209,11 +2196,6 @@ class Parser
|
|||||||
$expression = $this->ScalarExpression();
|
$expression = $this->ScalarExpression();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ($this->isAggregateFunction($lookaheadType)):
|
|
||||||
// COUNT(u.id)
|
|
||||||
$expression = $this->AggregateExpression();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// IDENTITY(u)
|
// IDENTITY(u)
|
||||||
$expression = $this->FunctionDeclaration();
|
$expression = $this->FunctionDeclaration();
|
||||||
@ -2858,10 +2840,6 @@ class Parser
|
|||||||
$peek = $this->lexer->glimpse();
|
$peek = $this->lexer->glimpse();
|
||||||
|
|
||||||
if ($peek['value'] == '(') {
|
if ($peek['value'] == '(') {
|
||||||
if ($this->isAggregateFunction($this->lexer->lookahead['type'])) {
|
|
||||||
return $this->AggregateExpression();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->FunctionDeclaration();
|
return $this->FunctionDeclaration();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2932,11 +2910,6 @@ class Parser
|
|||||||
case Lexer::T_COALESCE:
|
case Lexer::T_COALESCE:
|
||||||
case Lexer::T_NULLIF:
|
case Lexer::T_NULLIF:
|
||||||
return $this->CaseExpression();
|
return $this->CaseExpression();
|
||||||
|
|
||||||
default:
|
|
||||||
if ($this->isAggregateFunction($lookaheadType)) {
|
|
||||||
return $this->AggregateExpression();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->syntaxError(
|
$this->syntaxError(
|
||||||
@ -3236,10 +3209,6 @@ class Parser
|
|||||||
$expr = $this->CoalesceExpression();
|
$expr = $this->CoalesceExpression();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case $this->isAggregateFunction($this->lexer->lookahead['type']):
|
|
||||||
$expr = $this->AggregateExpression();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case $this->isFunction():
|
case $this->isFunction():
|
||||||
$expr = $this->FunctionDeclaration();
|
$expr = $this->FunctionDeclaration();
|
||||||
break;
|
break;
|
||||||
|
@ -1579,10 +1579,14 @@ class SqlWalker implements TreeWalker
|
|||||||
$sql .= $this->walkPathExpression($expr);
|
$sql .= $this->walkPathExpression($expr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ($expr instanceof AST\AggregateExpression):
|
case ($expr instanceof AST\Functions\AvgFunction):
|
||||||
|
case ($expr instanceof AST\Functions\CountFunction):
|
||||||
|
case ($expr instanceof AST\Functions\MaxFunction):
|
||||||
|
case ($expr instanceof AST\Functions\MinFunction):
|
||||||
|
case ($expr instanceof AST\Functions\SumFunction):
|
||||||
$alias = $simpleSelectExpression->fieldIdentificationVariable ?: $this->scalarResultCounter++;
|
$alias = $simpleSelectExpression->fieldIdentificationVariable ?: $this->scalarResultCounter++;
|
||||||
|
|
||||||
$sql .= $this->walkAggregateExpression($expr) . ' AS dctrn__' . $alias;
|
$sql .= $expr->dispatch($this) . ' AS dctrn__' . $alias;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ($expr instanceof AST\Subselect):
|
case ($expr instanceof AST\Subselect):
|
||||||
|
@ -265,8 +265,6 @@ class ConfigurationTest extends TestCase
|
|||||||
$this->assertSame(null, $this->configuration->getCustomStringFunction('NonExistingFunction'));
|
$this->assertSame(null, $this->configuration->getCustomStringFunction('NonExistingFunction'));
|
||||||
$this->configuration->setCustomStringFunctions(['OtherFunctionName' => __CLASS__]);
|
$this->configuration->setCustomStringFunctions(['OtherFunctionName' => __CLASS__]);
|
||||||
$this->assertSame(__CLASS__, $this->configuration->getCustomStringFunction('OtherFunctionName'));
|
$this->assertSame(__CLASS__, $this->configuration->getCustomStringFunction('OtherFunctionName'));
|
||||||
$this->expectException(ORMException::class);
|
|
||||||
$this->configuration->addCustomStringFunction('concat', __CLASS__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAddGetCustomNumericFunction()
|
public function testAddGetCustomNumericFunction()
|
||||||
@ -276,8 +274,6 @@ class ConfigurationTest extends TestCase
|
|||||||
$this->assertSame(null, $this->configuration->getCustomNumericFunction('NonExistingFunction'));
|
$this->assertSame(null, $this->configuration->getCustomNumericFunction('NonExistingFunction'));
|
||||||
$this->configuration->setCustomNumericFunctions(['OtherFunctionName' => __CLASS__]);
|
$this->configuration->setCustomNumericFunctions(['OtherFunctionName' => __CLASS__]);
|
||||||
$this->assertSame(__CLASS__, $this->configuration->getCustomNumericFunction('OtherFunctionName'));
|
$this->assertSame(__CLASS__, $this->configuration->getCustomNumericFunction('OtherFunctionName'));
|
||||||
$this->expectException(ORMException::class);
|
|
||||||
$this->configuration->addCustomNumericFunction('abs', __CLASS__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAddGetCustomDatetimeFunction()
|
public function testAddGetCustomDatetimeFunction()
|
||||||
@ -287,8 +283,6 @@ class ConfigurationTest extends TestCase
|
|||||||
$this->assertSame(null, $this->configuration->getCustomDatetimeFunction('NonExistingFunction'));
|
$this->assertSame(null, $this->configuration->getCustomDatetimeFunction('NonExistingFunction'));
|
||||||
$this->configuration->setCustomDatetimeFunctions(['OtherFunctionName' => __CLASS__]);
|
$this->configuration->setCustomDatetimeFunctions(['OtherFunctionName' => __CLASS__]);
|
||||||
$this->assertSame(__CLASS__, $this->configuration->getCustomDatetimeFunction('OtherFunctionName'));
|
$this->assertSame(__CLASS__, $this->configuration->getCustomDatetimeFunction('OtherFunctionName'));
|
||||||
$this->expectException(ORMException::class);
|
|
||||||
$this->configuration->addCustomDatetimeFunction('date_add', __CLASS__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAddGetCustomHydrationMode()
|
public function testAddGetCustomHydrationMode()
|
||||||
|
@ -58,12 +58,11 @@ class CustomFunctionsTest extends OrmFunctionalTestCase
|
|||||||
|
|
||||||
$this->_em->getConfiguration()->addCustomStringFunction('COUNT', 'Doctrine\Tests\ORM\Functional\CustomCount');
|
$this->_em->getConfiguration()->addCustomStringFunction('COUNT', 'Doctrine\Tests\ORM\Functional\CustomCount');
|
||||||
|
|
||||||
$query = $this->_em->createQuery('SELECT COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u');
|
$query = $this->_em->createQuery('SELECT COUNT(DISTINCT u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u');
|
||||||
|
|
||||||
$users = $query->getResult();
|
$usersCount = $query->getSingleScalarResult();
|
||||||
|
|
||||||
$this->assertEquals(1, count($users));
|
$this->assertEquals(1, $usersCount);
|
||||||
$this->assertSame($user, $users[0]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,20 +90,17 @@ class NoOp extends FunctionNode
|
|||||||
class CustomCount extends FunctionNode
|
class CustomCount extends FunctionNode
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var PathExpression
|
* @var Query\AST\AggregateExpression
|
||||||
*/
|
*/
|
||||||
private $field;
|
private $aggregateExpression;
|
||||||
|
|
||||||
public function parse(Parser $parser)
|
public function parse(Parser $parser)
|
||||||
{
|
{
|
||||||
$parser->match(Lexer::T_IDENTIFIER);
|
$this->aggregateExpression = $parser->AggregateExpression();
|
||||||
$parser->match(Lexer::T_OPEN_PARENTHESIS);
|
|
||||||
$this->field = $parser->StringExpression();
|
|
||||||
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSql(SqlWalker $sqlWalker)
|
public function getSql(SqlWalker $sqlWalker)
|
||||||
{
|
{
|
||||||
return $this->field->dispatch($sqlWalker);
|
return $this->aggregateExpression->dispatch($sqlWalker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user