Commit 22fce635 authored by romanb's avatar romanb

[2.0][DDC-339][DDC-340] Fixed.

parent ec880fe5
...@@ -159,7 +159,7 @@ class ClassMetadata extends ClassMetadataInfo ...@@ -159,7 +159,7 @@ class ClassMetadata extends ClassMetadataInfo
* with the same order as the field order in {@link identifier}. * with the same order as the field order in {@link identifier}.
* *
* @param object $entity * @param object $entity
* @return mixed * @return array
*/ */
public function getIdentifierValues($entity) public function getIdentifierValues($entity)
{ {
......
...@@ -220,8 +220,9 @@ final class Query extends AbstractQuery ...@@ -220,8 +220,9 @@ final class Query extends AbstractQuery
if (is_object($value)) { if (is_object($value)) {
$values = $this->_em->getClassMetadata(get_class($value))->getIdentifierValues($value); $values = $this->_em->getClassMetadata(get_class($value))->getIdentifierValues($value);
//var_dump($this->_em->getUnitOfWork()->getEntityIdentifier($value));
$sqlPositions = $paramMappings[$key]; $sqlPositions = $paramMappings[$key];
$sqlParams = array_merge($sqlParams, array_combine((array)$sqlPositions, (array)$values)); $sqlParams = array_merge($sqlParams, array_combine((array)$sqlPositions, $values));
} else if (is_bool($value)) { } else if (is_bool($value)) {
$boolValue = $this->_em->getConnection()->getDatabasePlatform()->convertBooleans($value); $boolValue = $this->_em->getConnection()->getDatabasePlatform()->convertBooleans($value);
foreach ($paramMappings[$key] as $position) { foreach ($paramMappings[$key] as $position) {
......
...@@ -417,10 +417,10 @@ class Parser ...@@ -417,10 +417,10 @@ class Parser
*/ */
private function _isFunction() private function _isFunction()
{ {
$peek = $this->_lexer->peek(); $peek = $this->_lexer->peek();
$nextpeek = $this->_lexer->peek(); $nextpeek = $this->_lexer->peek();
$this->_lexer->resetPeek(); $this->_lexer->resetPeek();
// We deny the COUNT(SELECT * FROM User u) here. COUNT won't be considered a function // We deny the COUNT(SELECT * FROM User u) here. COUNT won't be considered a function
return ($peek['value'] === '(' && $nextpeek['type'] !== Lexer::T_SELECT); return ($peek['value'] === '(' && $nextpeek['type'] !== Lexer::T_SELECT);
} }
...@@ -929,10 +929,9 @@ class Parser ...@@ -929,10 +929,9 @@ class Parser
$identVariable = $this->IdentificationVariable(); $identVariable = $this->IdentificationVariable();
$this->match(Lexer::T_DOT); $this->match(Lexer::T_DOT);
//TODO: $this->match($this->_lexer->lookahead['value']); $this->match($this->_lexer->lookahead['type']);
$this->match(Lexer::T_IDENTIFIER);
$field = $this->_lexer->token['value']; $field = $this->_lexer->token['value'];
// Validate association field // Validate association field
$qComp = $this->_queryComponents[$identVariable]; $qComp = $this->_queryComponents[$identVariable];
$class = $qComp['metadata']; $class = $qComp['metadata'];
...@@ -1878,17 +1877,7 @@ class Parser ...@@ -1878,17 +1877,7 @@ class Parser
if ($this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) { if ($this->_lexer->isNextToken(Lexer::T_OPEN_PARENTHESIS)) {
// Peek beyond the matching closing paranthesis ')' // Peek beyond the matching closing paranthesis ')'
$numUnmatched = 1; $peek = $this->_peekBeyondClosingParenthesis();
$peek = $this->_lexer->peek();
while ($numUnmatched > 0 && $peek !== null) {
if ($peek['value'] == ')') {
--$numUnmatched;
} else if ($peek['value'] == '(') {
++$numUnmatched;
}
$peek = $this->_lexer->peek();
}
$this->_lexer->resetPeek();
if (in_array($peek['value'], array("=", "<", "<=", "<>", ">", ">=", "!=")) || if (in_array($peek['value'], array("=", "<", "<=", "<>", ">", ">=", "!=")) ||
$peek['type'] === Lexer::T_NOT || $peek['type'] === Lexer::T_NOT ||
...@@ -1928,70 +1917,75 @@ class Parser ...@@ -1928,70 +1917,75 @@ class Parser
return $this->ExistsExpression(); return $this->ExistsExpression();
} }
$pathExprOrInputParam = false; $peek = $this->_lexer->glimpse();
if ($token['type'] === Lexer::T_IDENTIFIER || $token['type'] === Lexer::T_INPUT_PARAMETER) { if ($token['type'] === Lexer::T_IDENTIFIER || $token['type'] === Lexer::T_INPUT_PARAMETER) {
// Peek beyond the PathExpression if ($peek['value'] == '(') {
$pathExprOrInputParam = true; // Peek beyond the matching closing paranthesis ')'
$peek = $this->_lexer->peek();
while ($peek['value'] === '.') {
$this->_lexer->peek(); $this->_lexer->peek();
$token = $this->_peekBeyondClosingParenthesis();
} else {
// Peek beyond the PathExpression (or InputParameter)
$peek = $this->_lexer->peek(); $peek = $this->_lexer->peek();
}
// Also peek beyond a NOT if there is one while ($peek['value'] === '.') {
if ($peek['type'] === Lexer::T_NOT) { $this->_lexer->peek();
$peek = $this->_lexer->peek(); $peek = $this->_lexer->peek();
} }
$token = $peek;
// We need to go even further in case of IS (differenciate between NULL and EMPTY)
$lookahead = $this->_lexer->peek();
// Also peek beyond a NOT if there is one
if ($lookahead['type'] === Lexer::T_NOT) {
$lookahead = $this->_lexer->peek();
}
$this->_lexer->resetPeek();
}
if ($pathExprOrInputParam) {
switch ($token['type']) {
case Lexer::T_EQUALS:
case Lexer::T_LOWER_THAN:
case Lexer::T_GREATER_THAN:
case Lexer::T_NEGATE:
case Lexer::T_OPEN_PARENTHESIS:
return $this->ComparisonExpression();
case Lexer::T_BETWEEN: // Also peek beyond a NOT if there is one
return $this->BetweenExpression(); if ($peek['type'] === Lexer::T_NOT) {
$peek = $this->_lexer->peek();
}
case Lexer::T_LIKE: $token = $peek;
return $this->LikeExpression();
case Lexer::T_IN: // We need to go even further in case of IS (differenciate between NULL and EMPTY)
return $this->InExpression(); $lookahead = $this->_lexer->peek();
case Lexer::T_IS: // Also peek beyond a NOT if there is one
if ($lookahead['type'] == Lexer::T_NULL) { if ($lookahead['type'] === Lexer::T_NOT) {
return $this->NullComparisonExpression(); $lookahead = $this->_lexer->peek();
} }
return $this->EmptyCollectionComparisonExpression();
case Lexer::T_MEMBER: $this->_lexer->resetPeek();
return $this->CollectionMemberExpression(); }
}
default: switch ($token['type']) {
$this->syntaxError(); case Lexer::T_BETWEEN:
return $this->BetweenExpression();
case Lexer::T_LIKE:
return $this->LikeExpression();
case Lexer::T_IN:
return $this->InExpression();
case Lexer::T_IS:
if ($lookahead['type'] == Lexer::T_NULL) {
return $this->NullComparisonExpression();
}
return $this->EmptyCollectionComparisonExpression();
case Lexer::T_MEMBER:
return $this->CollectionMemberExpression();
default:
return $this->ComparisonExpression();
}
}
private function _peekBeyondClosingParenthesis()
{
$numUnmatched = 1;
$token = $this->_lexer->peek();
while ($numUnmatched > 0 && $token !== null) {
if ($token['value'] == ')') {
--$numUnmatched;
} else if ($token['value'] == '(') {
++$numUnmatched;
} }
$token = $this->_lexer->peek();
} }
$this->_lexer->resetPeek();
return $this->ComparisonExpression(); return $token;
} }
/** /**
......
...@@ -442,7 +442,7 @@ class SqlWalker implements TreeWalker ...@@ -442,7 +442,7 @@ class SqlWalker implements TreeWalker
throw QueryException::associationPathCompositeKeyNotSupported(); throw QueryException::associationPathCompositeKeyNotSupported();
} }
$sql .= $this->walkIdentificationVariable($dqlAlias) . '.' $sql .= $this->walkIdentificationVariable($dqlAlias) . '.'
. $assoc->getQuotedJoinColumnName(key($assoc->sourceToTargetKeyColumns), $this->_platform); . $assoc->getQuotedJoinColumnName(reset($assoc->targetToSourceKeyColumns), $this->_platform);
} else { } else {
// 2- Inverse side: NOT (YET?) SUPPORTED // 2- Inverse side: NOT (YET?) SUPPORTED
throw QueryException::associationPathInverseSideNotSupported(); throw QueryException::associationPathInverseSideNotSupported();
...@@ -466,7 +466,7 @@ class SqlWalker implements TreeWalker ...@@ -466,7 +466,7 @@ class SqlWalker implements TreeWalker
$sql = 'SELECT ' . (($selectClause->isDistinct) ? 'DISTINCT ' : '') . implode( $sql = 'SELECT ' . (($selectClause->isDistinct) ? 'DISTINCT ' : '') . implode(
', ', array_map(array($this, 'walkSelectExpression'), $selectClause->selectExpressions) ', ', array_map(array($this, 'walkSelectExpression'), $selectClause->selectExpressions)
); );
$addMetaColumns = ! $this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD) && $addMetaColumns = ! $this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD) &&
$this->_query->getHydrationMode() == Query::HYDRATE_OBJECT $this->_query->getHydrationMode() == Query::HYDRATE_OBJECT
|| ||
...@@ -521,7 +521,7 @@ class SqlWalker implements TreeWalker ...@@ -521,7 +521,7 @@ class SqlWalker implements TreeWalker
} }
} }
} else { } else {
// Add foreign key columns to SQL, if necessary // Add foreign key columns to SQL, if necessary
if ($addMetaColumns) { if ($addMetaColumns) {
$sqlTableAlias = $this->getSqlTableAlias($class->primaryTable['name'], $dqlAlias); $sqlTableAlias = $this->getSqlTableAlias($class->primaryTable['name'], $dqlAlias);
foreach ($class->associationMappings as $assoc) { foreach ($class->associationMappings as $assoc) {
......
...@@ -547,7 +547,6 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase ...@@ -547,7 +547,6 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
public function testFlushDoesNotIssueUnnecessaryUpdates() public function testFlushDoesNotIssueUnnecessaryUpdates()
{ {
$user = new CmsUser; $user = new CmsUser;
$user->name = 'Guilherme'; $user->name = 'Guilherme';
$user->username = 'gblanco'; $user->username = 'gblanco';
...@@ -613,6 +612,35 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase ...@@ -613,6 +612,35 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
//$this->_em->getConnection()->getConfiguration()->setSqlLogger(null); //$this->_em->getConnection()->getConfiguration()->setSqlLogger(null);
} }
/**
* @group ref
*/
/*public function testQueryEntityByReference()
{
$user = new CmsUser;
$user->name = 'Guilherme';
$user->username = 'gblanco';
$user->status = 'developer';
$address = new CmsAddress;
$address->country = 'Germany';
$address->city = 'Berlin';
$address->zip = '12345';
$user->setAddress($address);
$this->_em->persist($user);
$this->_em->flush();
$this->_em->clear();
$userRef = $this->_em->getReference('Doctrine\Tests\Models\CMS\CmsUser', $user->getId());
$address2 = $this->_em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsAddress a where a.user = :user')
->setParameter('user', $userRef)
->getSingleResult();
}*/
//DRAFT OF EXPECTED/DESIRED BEHAVIOR //DRAFT OF EXPECTED/DESIRED BEHAVIOR
/*public function testPersistentCollectionContainsDoesNeverInitialize() /*public function testPersistentCollectionContainsDoesNeverInitialize()
{ {
......
...@@ -346,10 +346,11 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase ...@@ -346,10 +346,11 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
{ {
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > SOME (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = u.name)'); $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > SOME (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = u.name)');
} }
public function testMemberOfExpression() public function testMemberOfExpression()
{ {
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.phonenumbers'); $this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.phonenumbers');
//$this->assertValidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE 'Joe' MEMBER OF u.nicknames");
} }
public function testSizeFunction() public function testSizeFunction()
...@@ -407,6 +408,11 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase ...@@ -407,6 +408,11 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
{ {
$this->assertValidDql('SELECT u, u.id + ?1 AS someNumber FROM Doctrine\Tests\Models\CMS\CmsUser u'); $this->assertValidDql('SELECT u, u.id + ?1 AS someNumber FROM Doctrine\Tests\Models\CMS\CmsUser u');
} }
public function testDQLKeywordInJoinIsAllowed()
{
$this->assertValidDql('SELECT u FROM ' . __NAMESPACE__ . '\DQLKeywordsModelUser u JOIN u.group g');
}
/* The exception is currently thrown in the SQLWalker, not earlier. /* The exception is currently thrown in the SQLWalker, not earlier.
public function testInverseSideSingleValuedAssociationPathNotAllowed() public function testInverseSideSingleValuedAssociationPathNotAllowed()
...@@ -414,4 +420,20 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase ...@@ -414,4 +420,20 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
$this->assertInvalidDql('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address = ?1'); $this->assertInvalidDql('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address = ?1');
} }
*/ */
} }
\ No newline at end of file
/** @Entity */
class DQLKeywordsModelUser
{
/** @Id @Column(type="integer") @GeneratedValue */
private $id;
/** @OneToOne(targetEntity="DQLKeywordsModelGroup") */
private $group;
}
/** @Entity */
class DQLKeywordsModelGroup
{
/** @Id @Column(type="integer") @GeneratedValue */
private $id;
}
...@@ -483,7 +483,6 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase ...@@ -483,7 +483,6 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
); );
} }
public function testBooleanLiteralInWhereOnSqlite() public function testBooleanLiteralInWhereOnSqlite()
{ {
$oldPlat = $this->_em->getConnection()->getDatabasePlatform(); $oldPlat = $this->_em->getConnection()->getDatabasePlatform();
...@@ -519,22 +518,14 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase ...@@ -519,22 +518,14 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
$this->_em->getConnection()->setDatabasePlatform($oldPlat); $this->_em->getConnection()->setDatabasePlatform($oldPlat);
} }
/* Not yet implemented, needs more thought */
public function testSingleValuedAssociationFieldInWhere() public function testSingleValuedAssociationFieldInWhere()
{ {
/*$this->assertSqlGeneration( $this->assertSqlGeneration(
"SELECT p FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.user = ?1", "SELECT p FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.user = ?1",
"SELECT c0_.id AS id0, c0_user_id AS user_id1, c0_.phonenumber AS phonenumber2 FROM cms_phonenumbers c0_ WHERE c0_.user_id = ?" "SELECT c0_.phonenumber AS phonenumber0 FROM cms_phonenumbers c0_ WHERE c0_.user_id = ?"
); );
$this->assertSqlGeneration(
"SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address = ?1",
//"SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.id = (SELECT c1_.user_id FROM cms_addresses c1_ WHERE c1_.id = ?)"
"SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_addresses c1_ WHERE c1_.user_id = c0_.id AND c1_.id = ?)"
);*/
} }
public function testSingleValuedAssociationNullCheckOnOwningSide() public function testSingleValuedAssociationNullCheckOnOwningSide()
{ {
...@@ -554,4 +545,23 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase ...@@ -554,4 +545,23 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
"SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ LEFT JOIN cms_addresses c1_ ON c0_.id = c1_.user_id WHERE c1_.id IS NULL" "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ LEFT JOIN cms_addresses c1_ ON c0_.id = c1_.user_id WHERE c1_.id IS NULL"
); );
} }
/**
* @group DDC-339
*/
public function testStringFunctionLikeExpression()
{
$this->assertSqlGeneration(
"SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE LOWER(u.name) LIKE '%foo OR bar%'",
"SELECT c0_.name AS name0 FROM cms_users c0_ WHERE LOWER(c0_.name) LIKE '%foo OR bar%'"
);
$this->assertSqlGeneration(
"SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE LOWER(u.name) LIKE :str",
"SELECT c0_.name AS name0 FROM cms_users c0_ WHERE LOWER(c0_.name) LIKE ?"
);
$this->assertSqlGeneration(
"SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(UPPER(u.name), '_moo') LIKE :str",
"SELECT c0_.name AS name0 FROM cms_users c0_ WHERE UPPER(c0_.name) || '_moo' LIKE ?"
);
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment