1
0
mirror of synced 2024-12-13 06:46:03 +03:00

[2.0] Parser work. Drafted logic for multi-table deletes through DQL (for Class/Concrete Table Inheritance)

This commit is contained in:
romanb 2009-03-21 12:49:58 +00:00
parent c7dbde9f89
commit d833ee1464
13 changed files with 277 additions and 94 deletions

View File

@ -63,6 +63,11 @@ abstract class AbstractEntityPersister
*/
protected $_em;
/**
* Queued inserts.
*
* @var array
*/
protected $_queuedInserts = array();
/**
@ -150,13 +155,21 @@ abstract class AbstractEntityPersister
/**
*
* @return Doctrine\ORM\ClassMetadata
* @return Doctrine\ORM\Mapping\ClassMetadata
*/
public function getClassMetadata()
{
return $this->_classMetadata;
}
/**
* Gets the table name to use for temporary identifier tables.
*/
public function getTemporaryIdTableName()
{
//...
}
/**
* Gets the name of the class in the entity hierarchy that owns the field with
* the given name. The owning class is the one that defines the field.

View File

@ -22,7 +22,7 @@
namespace Doctrine\ORM\Persisters;
/**
* Persister for collections of basic elements / value objects.
* Persister for collections of basic elements / value types.
*
* @author robo
*/

View File

@ -1,7 +1,22 @@
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
/*
* $Id$
*
* 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;

View File

@ -48,9 +48,14 @@ class InExpression extends Node
$this->_not = $bool;
}
public function getNot()
public function isNot()
{
return $this->_not;
}
public function getPathExpression()
{
return $this->_pathExpression;
}
}

View File

@ -10,6 +10,7 @@ namespace Doctrine\ORM\Query\AST;
* Description of JoinCollectionValuedPathExpression
*
* @author robo
* @todo Rename: JoinAssociationPathExpression
*/
class JoinPathExpression extends Node
{

View File

@ -0,0 +1,39 @@
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
namespace Doctrine\ORM\Query\AST;
/**
* NullComparisonExpression ::= (SingleValuedPathExpression | InputParameter) "IS" ["NOT"] "NULL"
*
* @author robo
*/
class NullComparisonExpression extends Node
{
private $_expression;
private $_not;
public function __construct($expression)
{
$this->_expression = $expression;
}
public function getExpression()
{
return $this->_expression;
}
public function setNot($bool)
{
$this->_not = $bool;
}
public function isNot()
{
return $this->_not;
}
}

View File

@ -16,7 +16,7 @@
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>.
* <http://www.doctrine-project.org>.
*/
namespace Doctrine\ORM\Query\AST;
@ -26,14 +26,14 @@ namespace Doctrine\ORM\Query\AST;
*
* @author Guilherme Blanco <guilhermeblanco@hotmail.com>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link http://www.phpdoctrine.org
* @link http://www.doctrine-project.org
* @since 2.0
* @version $Revision$
*/
class SimpleStateFieldPathExpression extends Node
{
protected $_identificationVariable = null;
protected $_simpleStateField = null;
private $_identificationVariable = null;
private $_simpleStateField = null;
public function __construct($identificationVariable, $simpleStateField)
{

View File

@ -7,11 +7,11 @@
namespace Doctrine\ORM\Query\AST;
/**
* Description of PathExpression
* StateFieldPathExpression ::= SimpleStateFieldPathExpression | SimpleStateFieldAssociationPathExpression
*
* @author robo
*/
class PathExpression extends Node
class StateFieldPathExpression extends Node
{
private $_parts;
// Information that is attached during semantical analysis.

View File

@ -43,7 +43,16 @@ class MultiTableDeleteExecutor extends AbstractExecutor
*/
public function __construct(\Doctrine\ORM\Query\AST $AST)
{
// TODO: Inspect the AST, create the necessary SQL queries and store them
// 1. Create a INSERT ... SELECT statement where the SELECT statement
// selects the identifiers from the temporary ID table and uses the WhereClause of the $AST.
// 2. Create ID subselect statement used in DELETE .... WHERE ... IN (subselect)
// 3. Create and store DELETE statements
/*$subselect = 'SELECT id1, id2 FROM temptable';
foreach ($tableNames as $tableName) {
$this->_sqlStatements[] = 'DELETE FROM ' . $tableName . ' WHERE (id1, id2) IN (subselect)';
}*/
// in $this->_sqlStatements
}
@ -56,6 +65,8 @@ class MultiTableDeleteExecutor extends AbstractExecutor
*/
public function execute(\Doctrine\DBAL\Connection $conn, array $params)
{
// 1. Create temporary id table if necessary
//...
}
}

View File

@ -1,5 +1,4 @@
<?php
/*
* $Id$
*
@ -53,7 +52,7 @@ class Parser
*
* @var array
*/
private $_pendingPathExpressionsInSelect = array();
private $_deferredPathExpressionStacks = array();
/**
* A scanner object.
@ -127,7 +126,6 @@ class Parser
}
if ( ! $isMatch) {
// No definition for value checking.
$this->syntaxError($this->_lexer->getLiteral($token));
}
@ -159,7 +157,6 @@ class Parser
$this->_lexer->token = null;
$this->_lexer->lookahead = null;
//$this->_errorDistance = self::MIN_ERROR_DISTANCE;
}
@ -340,9 +337,10 @@ class Parser
*/
private function _SelectStatement()
{
$this->_beginDeferredPathExpressionStack();
$selectClause = $this->_SelectClause();
$fromClause = $this->_FromClause();
$this->_processPendingPathExpressionsInSelect();
$this->_processDeferredPathExpressionStack();
$whereClause = $this->_lexer->isNextToken(Lexer::T_WHERE) ?
$this->_WhereClause() : null;
@ -361,16 +359,25 @@ class Parser
);
}
/**
*
*/
private function _beginDeferredPathExpressionStack()
{
$this->_deferredPathExpressionStacks[] = array();
}
/**
* Processes pending path expressions that were encountered while parsing
* select expressions. These will be validated to make sure they are indeed
* valid <tt>StateFieldPathExpression</tt>s and additional information
* is attached to their AST nodes.
*/
private function _processPendingPathExpressionsInSelect()
private function _processDeferredPathExpressionStack()
{
$exprStack = array_pop($this->_deferredPathExpressionStacks);
$qComps = $this->_parserResult->getQueryComponents();
foreach ($this->_pendingPathExpressionsInSelect as $expr) {
foreach ($exprStack as $expr) {
$parts = $expr->getParts();
$numParts = count($parts);
$dqlAlias = $parts[0];
@ -511,7 +518,7 @@ class Parser
//TODO: Can be StringPrimary or EnumPrimary
return $this->_StringPrimary();
} else {
$this->syntaxError('Not yet implemented.');
$this->syntaxError('Not yet implemented-1.');
//echo "UH OH ...";
}
}
@ -629,7 +636,7 @@ class Parser
$fieldIdentificationVariable = $this->_lexer->token['value'];
}
} else {
$expression = $this->_PathExpressionInSelect();
$expression = $this->_StateFieldPathExpression();
}
return new AST\SelectExpression($expression, $fieldIdentificationVariable);
}
@ -714,7 +721,7 @@ class Parser
/**
* Special rule that acceps all kinds of path expressions.
*/
private function _PathExpression()
/*private function _StateFieldPathExpression()
{
$this->match(Lexer::T_IDENTIFIER);
$parts = array($this->_lexer->token['value']);
@ -723,21 +730,28 @@ class Parser
$this->match(Lexer::T_IDENTIFIER);
$parts[] = $this->_lexer->token['value'];
}
$pathExpression = new AST\PathExpression($parts);
$pathExpression = new AST\StateFieldPathExpression($parts);
return $pathExpression;
}
}*/
/**
* Special rule that acceps all kinds of path expressions. and defers their
* semantical checking until the FROM part has been parsed completely (joins inclusive).
* Mainly used for path expressions in the SelectExpressions.
*/
private function _PathExpressionInSelect()
/*private function _PathExpressionInSelect()
{
$expr = $this->_PathExpression();
$this->match(Lexer::T_IDENTIFIER);
$parts = array($this->_lexer->token['value']);
while ($this->_lexer->isNextToken('.')) {
$this->match('.');
$this->match(Lexer::T_IDENTIFIER);
$parts[] = $this->_lexer->token['value'];
}
$expr = new AST\StateFieldPathExpression($parts);
$this->_pendingPathExpressionsInSelect[] = $expr;
return $expr;
}
}*/
/**
* JoinVariableDeclaration ::= Join [IndexBy]
@ -818,14 +832,6 @@ class Parser
return $join;
}
/*private function _JoinAssociationPathExpression() {
if ($this->_isSingleValuedPathExpression()) {
return $this->_JoinSingleValuedAssociationPathExpression();
} else {
return $this->_JoinCollectionValuedPathExpression();
}
}*/
/*private function _isSingleValuedPathExpression()
{
$parserResult = $this->_parserResult;
@ -894,6 +900,21 @@ class Parser
*/
private function _StateFieldPathExpression()
{
if ( ! empty($this->_deferredPathExpressionStacks)) {
$exprStack = array_pop($this->_deferredPathExpressionStacks);
$this->match(Lexer::T_IDENTIFIER);
$parts = array($this->_lexer->token['value']);
while ($this->_lexer->isNextToken('.')) {
$this->match('.');
$this->match(Lexer::T_IDENTIFIER);
$parts[] = $this->_lexer->token['value'];
}
$expr = new AST\StateFieldPathExpression($parts);
$exprStack[] = $expr;
array_push($this->_deferredPathExpressionStacks, $exprStack);
return $expr; // EARLY EXIT!
}
$parts = array();
$stateFieldSeen = false;
$assocSeen = false;
@ -928,7 +949,7 @@ class Parser
$parts[] = $part;
}
$pathExpr = new AST\PathExpression($parts);
$pathExpr = new AST\StateFieldPathExpression($parts);
if ($assocSeen) {
$pathExpr->setIsSimpleStateFieldAssociationPathExpression(true);
@ -939,6 +960,28 @@ class Parser
return $pathExpr;
}
/**
* NullComparisonExpression ::= (SingleValuedPathExpression | InputParameter) "IS" ["NOT"] "NULL"
*/
private function _NullComparisonExpression()
{
if ($this->_lexer->isNextToken(Lexer::T_INPUT_PARAMETER)) {
$this->match(Lexer::T_INPUT_PARAMETER);
$expr = new AST\InputParameter($this->_lexer->token['value']);
} else {
//TODO: Support SingleValuedAssociationPathExpression
$expr = $this->_StateFieldPathExpression();
}
$nullCompExpr = new AST\NullComparisonExpression($expr);
$this->match(Lexer::T_IS);
if ($this->_lexer->isNextToken(Lexer::T_NOT)) {
$this->match(Lexer::T_NOT);
$nullCompExpr->setNot(true);
}
$this->match(Lexer::T_NULL);
return $nullCompExpr;
}
/**
* AggregateExpression ::=
* ("AVG" | "MAX" | "MIN" | "SUM") "(" ["DISTINCT"] StateFieldPathExpression ")" |
@ -957,7 +1000,7 @@ class Parser
$isDistinct = true;
}
// For now we only support a PathExpression here...
$pathExp = $this->_PathExpression();
$pathExp = $this->_StateFieldPathExpression();
$this->match(')');
} else {
if ($this->_lexer->isNextToken(Lexer::T_AVG)) {
@ -988,10 +1031,10 @@ class Parser
$this->match(Lexer::T_GROUP);
$this->match(Lexer::T_BY);
$groupByItems = array();
$groupByItems[] = $this->_PathExpression();
$groupByItems[] = $this->_StateFieldPathExpression();
while ($this->_lexer->isNextToken(',')) {
$this->match(',');
$groupByItems[] = $this->_PathExpression();
$groupByItems[] = $this->_StateFieldPathExpression();
}
return new AST\GroupByClause($groupByItems);
}
@ -1286,7 +1329,7 @@ class Parser
*/
private function _InExpression()
{
$inExpression = new AST\InExpression($this->_PathExpression());
$inExpression = new AST\InExpression($this->_StateFieldPathExpression());
if ($this->_lexer->isNextToken(Lexer::T_NOT)) {
$this->match(Lexer::T_NOT);
$inExpression->setNot(true);
@ -1331,7 +1374,9 @@ class Parser
*/
private function _Subselect()
{
$this->_beginDeferredPathExpressionStack();
$subselect = new AST\Subselect($this->_SimpleSelectClause(), $this->_SubselectFromClause());
$this->_processDeferredPathExpressionStack();
$subselect->setWhereClause(
$this->_lexer->isNextToken(Lexer::T_WHERE) ? $this->_WhereClause() : null
@ -1410,7 +1455,7 @@ class Parser
// SingleValuedPathExpression | IdentificationVariable
$peek = $this->_lexer->glimpse();
if ($peek['value'] == '.') {
return new AST\SimpleSelectExpression($this->_PathExpressionInSelect());
return new AST\SimpleSelectExpression($this->_StateFieldPathExpression());
} else {
$this->match($this->_lexer->lookahead['value']);
return new AST\SimpleSelectExpression($this->_lexer->token['value']);
@ -1507,7 +1552,7 @@ class Parser
$this->syntaxError();
}
}
throw \Doctrine\Common\DoctrineException::updateMe("Not yet implemented.");
throw \Doctrine\Common\DoctrineException::updateMe("Not yet implemented2.");
//TODO...
}
@ -1598,7 +1643,7 @@ class Parser
}
/**
* LikeExpression ::= StringExpression ["NOT"] "LIKE" string ["ESCAPE" char]
* LikeExpression ::= StringExpression ["NOT"] "LIKE" (string | input_parameter) ["ESCAPE" char]
*/
private function _LikeExpression()
{
@ -1609,8 +1654,13 @@ class Parser
$isNot = true;
}
$this->match(Lexer::T_LIKE);
$this->match(Lexer::T_STRING);
$stringPattern = $this->_lexer->token['value'];
if ($this->_lexer->isNextToken(Lexer::T_INPUT_PARAMETER)) {
$this->match(Lexer::T_INPUT_PARAMETER);
$stringPattern = new AST\InputParameter($this->_lexer->token['value']);
} else {
$this->match(Lexer::T_STRING);
$stringPattern = $this->_lexer->token['value'];
}
$escapeChar = null;
if ($this->_lexer->lookahead['type'] === Lexer::T_ESCAPE) {
$this->match(Lexer::T_ESCAPE);

View File

@ -154,7 +154,7 @@ class SqlWalker
public function walkSelectExpression($selectExpression)
{
$sql = '';
if ($selectExpression->getExpression() instanceof AST\PathExpression) {
if ($selectExpression->getExpression() instanceof AST\StateFieldPathExpression) {
$pathExpression = $selectExpression->getExpression();
if ($pathExpression->isSimpleStateFieldPathExpression()) {
$parts = $pathExpression->getParts();
@ -251,7 +251,7 @@ class SqlWalker
{
$sql = '';
$expr = $simpleSelectExpression->getExpression();
if ($expr instanceof AST\PathExpression) {
if ($expr instanceof AST\StateFieldPathExpression) {
//...
} else if ($expr instanceof AST\AggregateExpression) {
if ( ! $simpleSelectExpression->getFieldIdentificationVariable()) {
@ -351,6 +351,14 @@ class SqlWalker
else if ($simpleCond instanceof AST\LikeExpression) {
$sql .= $this->walkLikeExpression($simpleCond);
}
else if ($simpleCond instanceof AST\BetweenExpression) {
$sql .= $this->walkBetweenExpression($simpleCond);
}
else if ($simpleCond instanceof AST\InExpression) {
$sql .= $this->walkInExpression($simpleCond);
} else if ($simpleCond instanceof AST\NullComparisonExpression) {
$sql .= $this->walkNullComparisonExpression($simpleCond);
}
// else if ...
} else if ($primary->isConditionalExpression()) {
$sql .= '(' . implode(' OR ', array_map(array(&$this, 'walkConditionalTerm'),
@ -359,14 +367,60 @@ class SqlWalker
return $sql;
}
public function walkNullComparisonExpression($nullCompExpr)
{
$sql = '';
if ($nullCompExpr->getExpression() instanceof AST\InputParameter) {
$inputParam = $nullCompExpr->getExpression();
$sql .= ' ' . ($inputParam->isNamed() ? ':' . $inputParam->getName() : '?');
} else {
$sql .= $this->walkPathExpression($nullCompExpr->getExpression());
}
$sql .= ' IS' . ($nullCompExpr->isNot() ? ' NOT' : '') . ' NULL';
return $sql;
}
public function walkInExpression($inExpr)
{
$sql = $this->walkPathExpression($inExpr->getPathExpression());
if ($inExpr->isNot()) $sql .= ' NOT';
$sql .= ' IN (';
if ($inExpr->getSubselect()) {
$sql .= $this->walkSubselect($inExpr->getSubselect());
} else {
//$sql .= implode(', ', array_map(array($this, 'walkLiteral'), $inExpr->getLiterals()));
}
$sql .= ')';
return $sql;
}
public function walkBetweenExpression($betweenExpr)
{
$sql = $this->walkArithmeticExpression($betweenExpr->getBaseExpression());
if ($betweenExpr->getNot()) $sql .= ' NOT';
$sql .= ' BETWEEN ' . $this->walkArithmeticExpression($betweenExpr->getLeftBetweenExpression())
. ' AND ' . $this->walkArithmeticExpression($betweenExpr->getRightBetweenExpression());
return $sql;
}
public function walkLikeExpression($likeExpr)
{
$sql = '';
$stringExpr = $likeExpr->getStringExpression();
if ($stringExpr instanceof AST\PathExpression) {
if ($stringExpr instanceof AST\StateFieldPathExpression) {
$sql .= $this->walkPathExpression($stringExpr);
} //TODO else...
$sql .= ' LIKE ' . $likeExpr->getStringPattern();
if ($likeExpr->isNot()) $sql .= ' NOT';
$sql .= ' LIKE ';
if ($likeExpr->getStringPattern() instanceof AST\InputParameter) {
$inputParam = $likeExpr->getStringPattern();
$sql .= $inputParam->isNamed() ? ':' . $inputParam->getName() : '?';
} else {
$sql .= $likeExpr->getStringPattern();
}
if ($likeExpr->getEscapeChar()) {
$sql .= ' ESCAPE ' . $likeExpr->getEscapeChar();
}
return $sql;
}
@ -413,7 +467,7 @@ class SqlWalker
} else if (is_string($primary)) {
//TODO: quote string according to platform
$sql .= $primary;
} else if ($primary instanceof AST\PathExpression) {
} else if ($primary instanceof AST\StateFieldPathExpression) {
$sql .= $this->walkPathExpression($primary);
} else if ($primary instanceof AST\InputParameter) {
if ($primary->isNamed()) {
@ -456,9 +510,9 @@ class SqlWalker
$sqlTableAlias = $this->_dqlToSqlAliasMap[$dqlAlias];
$sql .= $sqlTableAlias . '.' . $class->getColumnName($fieldName);
} else if ($pathExpr->isSimpleStateFieldAssociationPathExpression()) {
\Doctrine\Common\DoctrineException::updateMe("Not yet implemented.");
throw \Doctrine\Common\DoctrineException::updateMe("Not yet implemented.");
} else {
\Doctrine\Common\DoctrineException::updateMe("Encountered invalid PathExpression during SQL construction.");
throw \Doctrine\Common\DoctrineException::updateMe("Encountered invalid PathExpression during SQL construction.");
}
return $sql;
}

View File

@ -88,10 +88,10 @@ class DeleteSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
'DELETE FROM cms_users c0 WHERE c0.id = ? OR (c0.username = ? OR c0.name = ?)'
);
/*$this->assertSqlGeneration(
'DELETE FROM Doctrine\Tests\Models\CMS\CmsUser WHERE id = ?1',
'DELETE FROM cms_users WHERE id = ?'
);*/
//$this->assertSqlGeneration(
// 'DELETE FROM Doctrine\Tests\Models\CMS\CmsUser WHERE id = ?1',
// 'DELETE FROM cms_users WHERE id = ?'
//);
}
public function testParserIsCaseAgnostic()
@ -163,7 +163,7 @@ class DeleteSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
"DELETE FROM cms_users c0 WHERE c0.id <> ?"
);
}
/*
public function testWithExprAndBetween()
{
$this->assertSqlGeneration(
@ -181,60 +181,55 @@ class DeleteSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
{
// "WHERE" Expression LikeExpression
$this->assertSqlGeneration(
'DELETE CmsUser u WHERE u.username NOT LIKE ?',
'DELETE FROM cms_user cu WHERE cu.username NOT LIKE ?'
'DELETE Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username NOT LIKE ?1',
'DELETE FROM cms_users c0 WHERE c0.username NOT LIKE ?'
);
$this->assertSqlGeneration(
"DELETE CmsUser u WHERE u.username LIKE ? ESCAPE '\\'",
"DELETE FROM cms_user cu WHERE cu.username LIKE ? ESCAPE '\\'"
"DELETE Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username LIKE ?1 ESCAPE '\\'",
"DELETE FROM cms_users c0 WHERE c0.username LIKE ? ESCAPE '\\'"
);
}
public function testWithExprAndIn()
{
// "WHERE" Expression InExpression
$this->assertSqlGeneration(
'DELETE CmsUser u WHERE u.id IN ( ?, ?, ?, ? )',
'DELETE FROM cms_user cu WHERE cu.id IN (?, ?, ?, ?)'
);
$this->assertSqlGeneration(
'DELETE CmsUser u WHERE u.id NOT IN ( ?, ? )',
'DELETE FROM cms_user cu WHERE cu.id NOT IN (?, ?)'
);
}
public function testWithExprAndNull()
{
// "WHERE" Expression NullComparisonExpression
$this->assertSqlGeneration(
'DELETE CmsUser u WHERE u.name IS NULL',
'DELETE FROM cms_user cu WHERE cu.name IS NULL'
'DELETE Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name IS NULL',
'DELETE FROM cms_users c0 WHERE c0.name IS NULL'
);
$this->assertSqlGeneration(
'DELETE CmsUser u WHERE u.name IS NOT NULL',
'DELETE FROM cms_user cu WHERE cu.name IS NOT NULL'
'DELETE Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name IS NOT NULL',
'DELETE FROM cms_users c0 WHERE c0.name IS NOT NULL'
);
}
// All previously defined tests used Primary as PathExpression. No need to check it again.
public function testWithPrimaryAsAtom()
{
// Atom = string | integer | float | boolean | input_parameter
$this->assertSqlGeneration(
'DELETE CmsUser u WHERE 1 = 1',
'DELETE FROM cms_user cu WHERE 1 = 1'
'DELETE Doctrine\Tests\Models\CMS\CmsUser u WHERE 1 = 1',
'DELETE FROM cms_users c0 WHERE 1 = 1'
);
$this->assertSqlGeneration(
'DELETE CmsUser u WHERE ? = 1',
'DELETE FROM cms_user cu WHERE ? = 1'
'DELETE Doctrine\Tests\Models\CMS\CmsUser u WHERE ?1 = 1',
'DELETE FROM cms_users c0 WHERE ? = 1'
);
}
/*
public function testWithExprAndIn()
{
// "WHERE" Expression InExpression
$this->assertSqlGeneration(
'DELETE Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN ( ?, ?, ?, ? )',
'DELETE FROM cms_users c0 WHERE c0.id IN (?, ?, ?, ?)'
);
$this->assertSqlGeneration(
'DELETE Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id NOT IN ( ?, ? )',
'DELETE FROM cms_users c0 WHERE c0.id NOT IN (?, ?)'
);
}
*/

View File

@ -110,12 +110,12 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
public function testExistsExpressionSupportedInWherePart()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE EXISTS (SELECT p.id FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234)');
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE EXISTS (SELECT p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234)');
}
public function testNotExistsExpressionSupportedInWherePart()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE NOT EXISTS (SELECT p.id FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234)');
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE NOT EXISTS (SELECT p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234)');
}
public function testAggregateFunctionInHavingClause()
@ -239,14 +239,14 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
{
$this->assertValidDql("SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name LIKE 'z|%' ESCAPE '|'");
}
/*
public function testImplicitJoinInWhereOnSingleValuedAssociationPathExpression()
{
// This should be allowed because avatar is a single-value association.
// SQL: SELECT ... FROM forum_user fu INNER JOIN forum_avatar fa ON fu.avatar_id = fa.id WHERE fa.id = ?
$this->assertValidDql("SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u WHERE u.avatar.id = ?");
}
*/
public function testImplicitJoinInWhereOnCollectionValuedPathExpression()
{
// This should be forbidden, because articles is a collection