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

[2.0] Parser work. Added support for functions in SelectExpressions.

This commit is contained in:
romanb 2009-03-28 17:10:41 +00:00
parent 5ebaa6504c
commit 705199e897
15 changed files with 597 additions and 155 deletions

View File

@ -131,7 +131,7 @@ abstract class AbstractPlatform
*/
public function getRegexpExpression()
{
throw \Doctrine\Common\DoctrineException::updateMe('Regular expression operator is not supported by this database driver.');
throw DoctrineException::updateMe('Regular expression operator is not supported by this database driver.');
}
/**
@ -351,7 +351,7 @@ abstract class AbstractPlatform
*/
public function getSoundexExpression($value)
{
throw \Doctrine\Common\DoctrineException::updateMe('SQL soundex function not supported by this driver.');
throw DoctrineException::updateMe('SQL soundex function not supported by this driver.');
}
/**
@ -701,7 +701,7 @@ abstract class AbstractPlatform
$column = $this->getIdentifier($column);
if (count($values) == 0) {
throw \Doctrine\Common\DoctrineException::updateMe('Values array for IN operator should not be empty.');
throw DoctrineException::updateMe('Values array for IN operator should not be empty.');
}
return $column . ' IN (' . implode(', ', $values) . ')';
}
@ -784,7 +784,7 @@ abstract class AbstractPlatform
*/
public function getGuidExpression()
{
throw \Doctrine\Common\DoctrineException::updateMe('method not implemented');
throw DoctrineException::updateMe('method not implemented');
}
/**
@ -847,7 +847,7 @@ abstract class AbstractPlatform
*/
public function getListDatabasesSql()
{
throw \Doctrine\Common\DoctrineException::updateMe('List databases not supported by this driver.');
throw DoctrineException::updateMe('List databases not supported by this driver.');
}
/**
@ -857,7 +857,7 @@ abstract class AbstractPlatform
*/
public function getListFunctionsSql()
{
throw \Doctrine\Common\DoctrineException::updateMe('List functions not supported by this driver.');
throw DoctrineException::updateMe('List functions not supported by this driver.');
}
/**
@ -867,7 +867,7 @@ abstract class AbstractPlatform
*/
public function getListTriggersSql()
{
throw \Doctrine\Common\DoctrineException::updateMe('List triggers not supported by this driver.');
throw DoctrineException::updateMe('List triggers not supported by this driver.');
}
/**
@ -877,7 +877,7 @@ abstract class AbstractPlatform
*/
public function getListSequencesSql()
{
throw \Doctrine\Common\DoctrineException::updateMe('List sequences not supported by this driver.');
throw DoctrineException::updateMe('List sequences not supported by this driver.');
}
/**
@ -887,7 +887,7 @@ abstract class AbstractPlatform
*/
public function getListTableConstraintsSql()
{
throw \Doctrine\Common\DoctrineException::updateMe('List table constraints not supported by this driver.');
throw DoctrineException::updateMe('List table constraints not supported by this driver.');
}
/**
@ -897,7 +897,7 @@ abstract class AbstractPlatform
*/
public function getListTableColumnsSql()
{
throw \Doctrine\Common\DoctrineException::updateMe('List table columns not supported by this driver.');
throw DoctrineException::updateMe('List table columns not supported by this driver.');
}
/**
@ -907,7 +907,7 @@ abstract class AbstractPlatform
*/
public function getListTablesSql()
{
throw \Doctrine\Common\DoctrineException::updateMe('List tables not supported by this driver.');
throw DoctrineException::updateMe('List tables not supported by this driver.');
}
/**
@ -917,7 +917,7 @@ abstract class AbstractPlatform
*/
public function getListUsersSql()
{
throw \Doctrine\Common\DoctrineException::updateMe('List users not supported by this driver.');
throw DoctrineException::updateMe('List users not supported by this driver.');
}
/**
@ -927,7 +927,7 @@ abstract class AbstractPlatform
*/
public function getListViewsSql()
{
throw \Doctrine\Common\DoctrineException::updateMe('List views not supported by this driver.');
throw DoctrineException::updateMe('List views not supported by this driver.');
}
/**
@ -967,7 +967,7 @@ abstract class AbstractPlatform
*/
public function getDropSequenceSql()
{
throw \Doctrine\Common\DoctrineException::updateMe('Drop sequence not supported by this driver.');
throw DoctrineException::updateMe('Drop sequence not supported by this driver.');
}
/**
@ -975,7 +975,7 @@ abstract class AbstractPlatform
*/
public function getSequenceNextValSql($sequenceName)
{
throw \Doctrine\Common\DoctrineException::updateMe('Sequences not supported by this driver.');
throw DoctrineException::updateMe('Sequences not supported by this driver.');
}
/**
@ -985,7 +985,7 @@ abstract class AbstractPlatform
*/
public function getCreateDatabaseSql($database)
{
throw \Doctrine\Common\DoctrineException::updateMe('Create database not supported by this driver.');
throw DoctrineException::updateMe('Create database not supported by this driver.');
}
/**
@ -996,10 +996,10 @@ abstract class AbstractPlatform
public function getCreateTableSql($table, array $columns, array $options = array())
{
if ( ! $table) {
throw \Doctrine\Common\DoctrineException::updateMe('no valid table name specified');
throw DoctrineException::updateMe('no valid table name specified');
}
if (empty($columns)) {
throw \Doctrine\Common\DoctrineException::updateMe('no fields specified for table ' . $name);
throw DoctrineException::updateMe('no fields specified for table ' . $name);
}
$queryFields = $this->getFieldDeclarationListSql($columns);
@ -1043,7 +1043,7 @@ abstract class AbstractPlatform
*/
public function getCreateSequenceSql($sequenceName, $start = 1, array $options)
{
throw \Doctrine\Common\DoctrineException::updateMe('Create sequence not supported by this driver.');
throw DoctrineException::updateMe('Create sequence not supported by this driver.');
}
/**
@ -1104,7 +1104,7 @@ abstract class AbstractPlatform
$type = strtoupper($definition['type']) . ' ';
break;
default:
throw \Doctrine\Common\DoctrineException::updateMe('Unknown index type ' . $definition['type']);
throw DoctrineException::updateMe('Unknown index type ' . $definition['type']);
}
}
@ -1200,7 +1200,7 @@ abstract class AbstractPlatform
*/
public function getAlterTableSql($name, array $changes, $check = false)
{
throw \Doctrine\Common\DoctrineException::updateMe('Alter table not supported by this driver.');
throw DoctrineException::updateMe('Alter table not supported by this driver.');
}
/**
@ -1311,7 +1311,7 @@ abstract class AbstractPlatform
*
* @return string
*/
abstract public function getTinyIntTypeDeclarationSql(array $columnDef);
//abstract public function getTinyIntTypeDeclarationSql(array $columnDef);
/**
* Gets the SQL snippet that declares a SMALLINT column.
@ -1325,7 +1325,7 @@ abstract class AbstractPlatform
*
* @return string
*/
abstract public function getMediumIntTypeDeclarationSql(array $columnDef);
//abstract public function getMediumIntTypeDeclarationSql(array $columnDef);
/**
* Gets the SQL snippet that declares common properties of an integer column.
@ -1408,12 +1408,12 @@ abstract class AbstractPlatform
if (strtolower($definition['type']) == 'unique') {
$type = strtoupper($definition['type']) . ' ';
} else {
throw \Doctrine\Common\DoctrineException::updateMe('Unknown index type ' . $definition['type']);
throw DoctrineException::updateMe('Unknown index type ' . $definition['type']);
}
}
if ( ! isset($definition['fields']) || ! is_array($definition['fields'])) {
throw \Doctrine\Common\DoctrineException::updateMe('No index columns given.');
throw DoctrineException::updateMe('No index columns given.');
}
$query = $type . 'INDEX ' . $name;
@ -1469,7 +1469,7 @@ abstract class AbstractPlatform
*/
public function getShowDatabasesSql()
{
throw \Doctrine\Common\DoctrineException::updateMe('Show databases not supported by this driver.');
throw DoctrineException::updateMe('Show databases not supported by this driver.');
}
/**
@ -1562,7 +1562,7 @@ abstract class AbstractPlatform
return $upper;
break;
default:
throw \Doctrine\Common\DoctrineException::updateMe('Unknown foreign key referential action \'' . $upper . '\' given.');
throw DoctrineException::updateMe('Unknown foreign key referential action \'' . $upper . '\' given.');
}
}
@ -1582,13 +1582,13 @@ abstract class AbstractPlatform
$sql .= 'FOREIGN KEY (';
if ( ! isset($definition['local'])) {
throw \Doctrine\Common\DoctrineException::updateMe('Local reference field missing from definition.');
throw DoctrineException::updateMe('Local reference field missing from definition.');
}
if ( ! isset($definition['foreign'])) {
throw \Doctrine\Common\DoctrineException::updateMe('Foreign reference field missing from definition.');
throw DoctrineException::updateMe('Foreign reference field missing from definition.');
}
if ( ! isset($definition['foreignTable'])) {
throw \Doctrine\Common\DoctrineException::updateMe('Foreign reference table missing from definition.');
throw DoctrineException::updateMe('Foreign reference table missing from definition.');
}
if ( ! is_array($definition['local'])) {
@ -1663,7 +1663,7 @@ abstract class AbstractPlatform
*/
public function getMatchPatternExpression($pattern, $operator = null, $field = null)
{
throw \Doctrine\Common\DoctrineException::updateMe("Method not implemented.");
throw DoctrineException::updateMe("Method not implemented.");
}
/**
@ -1832,7 +1832,7 @@ abstract class AbstractPlatform
case Connection::TRANSACTION_SERIALIZABLE:
return 'SERIALIZABLE';
default:
throw \Doctrine\Common\DoctrineException::updateMe('isolation level is not supported: ' . $isolation);
throw DoctrineException::updateMe('isolation level is not supported: ' . $isolation);
}
}
@ -1843,7 +1843,7 @@ abstract class AbstractPlatform
*/
public function getSetTransactionIsolationSql($level)
{
throw \Doctrine\Common\DoctrineException::updateMe('Set transaction isolation not supported by this platform.');
throw DoctrineException::updateMe('Set transaction isolation not supported by this platform.');
}
/**

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\DBAL\Platforms;
@ -185,7 +185,7 @@ class MySqlPlatform extends AbstractPlatform
$match = $field.'LIKE BINARY ';
break;
default:
throw \Doctrine\Common\DoctrineException::updateMe('not a supported operator type:'. $operator);
throw DoctrineException::updateMe('not a supported operator type:'. $operator);
}
}
$match.= "'";
@ -520,7 +520,7 @@ class MySqlPlatform extends AbstractPlatform
$length = null;
break;
default:
throw \Doctrine\Common\DoctrineException::updateMe('unknown database attribute type: ' . $dbType);
throw DoctrineException::updateMe('unknown database attribute type: ' . $dbType);
}
$length = ((int) $length == 0) ? null : (int) $length;
@ -678,10 +678,10 @@ class MySqlPlatform extends AbstractPlatform
public function getCreateTableSql($name, array $fields, array $options = array())
{
if ( ! $name) {
throw \Doctrine\Common\DoctrineException::updateMe('no valid table name specified');
throw DoctrineException::updateMe('no valid table name specified');
}
if (empty($fields)) {
throw \Doctrine\Common\DoctrineException::updateMe('no fields specified for table "'.$name.'"');
throw DoctrineException::updateMe('no fields specified for table "'.$name.'"');
}
$queryFields = $this->getFieldDeclarationListSql($fields);
@ -866,7 +866,7 @@ class MySqlPlatform extends AbstractPlatform
public function getAlterTableSql($name, array $changes, $check = false)
{
if ( ! $name) {
throw \Doctrine\Common\DoctrineException::updateMe('no valid table name specified');
throw DoctrineException::updateMe('no valid table name specified');
}
foreach ($changes as $changeName => $change) {
switch ($changeName) {
@ -877,7 +877,7 @@ class MySqlPlatform extends AbstractPlatform
case 'name':
break;
default:
throw \Doctrine\Common\DoctrineException::updateMe('change type "' . $changeName . '" not yet supported');
throw DoctrineException::updateMe('change type "' . $changeName . '" not yet supported');
}
}
@ -1003,7 +1003,7 @@ class MySqlPlatform extends AbstractPlatform
$type = strtoupper($definition['type']) . ' ';
break;
default:
throw \Doctrine\Common\DoctrineException::updateMe('Unknown index type ' . $definition['type']);
throw DoctrineException::updateMe('Unknown index type ' . $definition['type']);
}
}
$query = 'CREATE ' . $type . 'INDEX ' . $name . ' ON ' . $table;
@ -1050,10 +1050,10 @@ class MySqlPlatform extends AbstractPlatform
}
/** @override */
public function getTinyIntTypeDeclarationSql(array $field)
/*public function getTinyIntTypeDeclarationSql(array $field)
{
return 'TINYINT' . $this->_getCommonIntegerTypeDeclarationSql($field);
}
}*/
/** @override */
public function getSmallIntTypeDeclarationSql(array $field)
@ -1062,10 +1062,10 @@ class MySqlPlatform extends AbstractPlatform
}
/** @override */
public function getMediumIntTypeDeclarationSql(array $field)
/*public function getMediumIntTypeDeclarationSql(array $field)
{
return 'MEDIUMINT' . $this->_getCommonIntegerTypeDeclarationSql($field);
}
}*/
/** @override */
protected function _getCommonIntegerTypeDeclarationSql(array $columnDef)

View File

@ -101,7 +101,7 @@ class PostgreSqlPlatform extends AbstractPlatform
public function getNativeDeclaration(array $field)
{
if ( ! isset($field['type'])) {
throw \Doctrine\Common\DoctrineException::updateMe('Missing column type.');
throw DoctrineException::updateMe('Missing column type.');
}
switch ($field['type']) {
case 'char':
@ -161,7 +161,7 @@ class PostgreSqlPlatform extends AbstractPlatform
$scale = !empty($field['scale']) ? $field['scale'] : $this->conn->getAttribute(Doctrine::ATTR_DECIMAL_PLACES);
return 'NUMERIC('.$length.','.$scale.')';
}
throw \Doctrine\Common\DoctrineException::updateMe('Unknown field type \'' . $field['type'] . '\'.');
throw DoctrineException::updateMe('Unknown field type \'' . $field['type'] . '\'.');
}
/**
@ -293,7 +293,7 @@ class PostgreSqlPlatform extends AbstractPlatform
$length = null;
break;
default:
throw \Doctrine\Common\DoctrineException::updateMe('unknown database attribute type: '.$dbType);
throw DoctrineException::updateMe('unknown database attribute type: '.$dbType);
}
return array('type' => $type,
@ -461,7 +461,7 @@ class PostgreSqlPlatform extends AbstractPlatform
$match = $field.'LIKE ';
break;
default:
throw \Doctrine\Common\DoctrineException::updateMe('not a supported operator type:'. $operator);
throw DoctrineException::updateMe('not a supported operator type:'. $operator);
}
}
$match.= "'";
@ -766,7 +766,7 @@ class PostgreSqlPlatform extends AbstractPlatform
case 'rename':
break;
default:
throw \Doctrine\Common\DoctrineException::updateMe('change type "' . $changeName . '\" not yet supported');
throw DoctrineException::updateMe('change type "' . $changeName . '\" not yet supported');
}
}
@ -798,7 +798,7 @@ class PostgreSqlPlatform extends AbstractPlatform
$serverInfo = $this->getServerVersion();
if (is_array($serverInfo) && $serverInfo['major'] < 8) {
throw \Doctrine\Common\DoctrineException::updateMe('changing column type for "'.$field['type'].'\" requires PostgreSQL 8.0 or above');
throw DoctrineException::updateMe('changing column type for "'.$field['type'].'\" requires PostgreSQL 8.0 or above');
}
$query = 'ALTER ' . $fieldName . ' TYPE ' . $this->getTypeDeclarationSql($field['definition']);
$sql[] = 'ALTER TABLE ' . $name . ' ' . $query;
@ -875,10 +875,10 @@ class PostgreSqlPlatform extends AbstractPlatform
public function getCreateTableSql($name, array $fields, array $options = array())
{
if ( ! $name) {
throw \Doctrine\Common\DoctrineException::updateMe('no valid table name specified');
throw DoctrineException::updateMe('no valid table name specified');
}
if (empty($fields)) {
throw \Doctrine\Common\DoctrineException::updateMe('no fields specified for table ' . $name);
throw DoctrineException::updateMe('no fields specified for table ' . $name);
}
$queryFields = $this->getFieldDeclarationListSql($fields);
@ -1001,4 +1001,65 @@ class PostgreSqlPlatform extends AbstractPlatform
return 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL '
. $this->_getTransactionIsolationLevelSql($level);
}
/**
* @override
*/
public function getIntegerTypeDeclarationSql(array $field)
{
if ( ! empty($field['autoincrement'])) {
return 'SERIAL';
}
return 'INT';
}
/**
* @override
*/
public function getBigIntTypeDeclarationSql(array $field)
{
if ( ! empty($field['autoincrement'])) {
return 'BIGSERIAL';
}
return 'BIGINT';
}
/**
* @override
*/
public function getSmallIntTypeDeclarationSql(array $field)
{
return 'SMALLINT';
}
/**
* @override
*/
protected function _getCommonIntegerTypeDeclarationSql(array $columnDef)
{
return '';
}
/**
* Gets the SQL snippet used to declare a VARCHAR column on the MySql platform.
*
* @params array $field
* @override
*/
public function getVarcharDeclarationSql(array $field)
{
if ( ! isset($field['length'])) {
if (array_key_exists('default', $field)) {
$field['length'] = $this->getVarcharMaxLength();
} else {
$field['length'] = false;
}
}
$length = ($field['length'] <= $this->getVarcharMaxLength()) ? $field['length'] : false;
$fixed = (isset($field['fixed'])) ? $field['fixed'] : false;
return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)')
: ($length ? 'VARCHAR(' . $length . ')' : 'TEXT');
}
}

View File

@ -194,7 +194,7 @@ class SqlitePlatform extends AbstractPlatform
public function getNativeDeclaration(array $field)
{
if ( ! isset($field['type'])) {
throw \Doctrine\Common\DoctrineException::updateMe('Missing column type.');
throw DoctrineException::updateMe('Missing column type.');
}
switch ($field['type']) {
case 'text':
@ -254,7 +254,7 @@ class SqlitePlatform extends AbstractPlatform
$scale = !empty($field['scale']) ? $field['scale'] : $this->conn->getAttribute(Doctrine::ATTR_DECIMAL_PLACES);
return 'DECIMAL('.$length.','.$scale.')';
}
throw \Doctrine\Common\DoctrineException::updateMe('Unknown field type \'' . $field['type'] . '\'.');
throw DoctrineException::updateMe('Unknown field type \'' . $field['type'] . '\'.');
}
/**
@ -371,7 +371,7 @@ class SqlitePlatform extends AbstractPlatform
$length = null;
break;
default:
throw \Doctrine\Common\DoctrineException::updateMe('unknown database attribute type: '.$dbType);
throw DoctrineException::updateMe('unknown database attribute type: '.$dbType);
}
return array('type' => $type,

View File

@ -1,13 +0,0 @@
<?php
namespace Doctrine\DBAL\Types;
/**
* Description of MediumIntType
*
* @author robo
*/
class MediumIntType
{
//put your code here
}

View File

@ -1,13 +0,0 @@
<?php
namespace Doctrine\DBAL\Types;
/**
* Description of TinyIntType
*
* @author robo
*/
class TinyIntType
{
//put your code here
}

View File

@ -22,7 +22,7 @@
namespace Doctrine\ORM;
/**
* Doctrine_EntityManager_Exception
* EntityManagerException
*
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Roman Borschel <roman@code-factory.org>

View File

@ -31,13 +31,18 @@ class ConcatFunction extends FunctionNode
*/
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
//TODO: Use platform to get SQL
$platform = $sqlWalker->getConnection()->getDatabasePlatform();
return $platform->getConcatExpression(
$sqlWalker->walkStringPrimary($this->_firstStringPrimary),
$sqlWalker->walkStringPrimary($this->_secondStringPrimary)
);
/*
$sql = 'CONCAT(' .
$sqlWalker->walkStringPrimary($this->_firstStringPrimary)
. ', ' .
$sqlWalker->walkStringPrimary($this->_secondStringPrimary)
. ')';
return $sql;
return $sql;*/
}
/**

View File

@ -50,17 +50,5 @@ abstract class FunctionNode extends Node
return $sqlWalker->walkFunction($this);
}
//abstract public function parse(\Doctrine\ORM\Query\Parser $parser);
/*
public function getExpressions()
{
return $this->_expressions;
}
public function setExpressions(array $expressions)
{
$this->_expressions = $expressions;
}
*/
abstract public function parse(\Doctrine\ORM\Query\Parser $parser);
}

View File

@ -0,0 +1,69 @@
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
namespace Doctrine\ORM\Query\AST;
/**
* QuantifiedExpression ::= ("ALL" | "ANY" | "SOME") "(" Subselect ")"
*
* @author robo
*/
class QuantifiedExpression extends Node
{
private $_all;
private $_any;
private $_some;
private $_subselect;
public function __construct($subselect)
{
$this->_subselect = $subselect;
}
public function getSubselect()
{
return $this->_subselect;
}
public function isAll()
{
return $this->_all;
}
public function isAny()
{
return $this->_any;
}
public function isSome()
{
return $this->_some;
}
public function setAll($bool)
{
$this->_all = $bool;
}
public function setAny($bool)
{
$this->_any = $bool;
}
public function setSome($bool)
{
$this->_some = $bool;
}
/**
* @override
*/
public function dispatch($sqlWalker)
{
return $sqlWalker->walkQuantifiedExpression($this);
}
}

View File

@ -336,7 +336,7 @@ class Lexer
}
/**
* @todo Doc
* Resets the peek pointer to 0.
*/
public function resetPeek()
{
@ -351,6 +351,12 @@ class Lexer
$this->_position = $position;
}
/**
* Gets the literal for a given token.
*
* @param mixed $token
* @return string
*/
public function getLiteral($token)
{
if ( ! $this->_keywordsTable) {

View File

@ -626,7 +626,8 @@ class Parser
/**
* SelectExpression ::=
* IdentificationVariable | StateFieldPathExpression |
* (AggregateExpression | "(" Subselect ")") [["AS"] FieldAliasIdentificationVariable]
* (AggregateExpression | "(" Subselect ")") [["AS"] FieldAliasIdentificationVariable] |
* Function
*/
public function _SelectExpression()
{
@ -634,11 +635,15 @@ class Parser
$fieldIdentificationVariable = null;
$peek = $this->_lexer->glimpse();
// First we recognize for an IdentificationVariable (DQL class alias)
if ($peek['value'] != '.' && $this->_lexer->lookahead['type'] === Lexer::T_IDENTIFIER) {
if ($peek['value'] != '.' && $peek['value'] != '(' && $this->_lexer->lookahead['type'] === Lexer::T_IDENTIFIER) {
$expression = $this->_IdentificationVariable();
} else if (($isFunction = $this->_isFunction()) !== false || $this->_isSubselect()) {
if ($isFunction) {
if ($this->_isAggregateFunction($this->_lexer->lookahead['type'])) {
$expression = $this->_AggregateExpression();
} else {
$expression = $this->_Function();
}
} else {
$this->match('(');
$expression = $this->_Subselect();
@ -1290,7 +1295,7 @@ class Parser
}
}
}
else if ($this->_isAggregateFunction($this->_lexer->lookahead)) {
/*else if ($this->_isAggregateFunction($this->_lexer->lookahead['type'])) {
$leftExpr = $this->_StringExpression();
$operator = $this->_ComparisonOperator();
if ($this->_lexer->lookahead['type'] === Lexer::T_ALL ||
@ -1300,7 +1305,7 @@ class Parser
} else {
$rightExpr = $this->_StringExpression();
}
}
}*/
else {
$leftExpr = $this->_ArithmeticExpression();
$operator = $this->_ComparisonOperator();
@ -1316,6 +1321,20 @@ class Parser
return new AST\ComparisonExpression($leftExpr, $operator, $rightExpr);
}
public function _Function()
{
$funcName = $this->_lexer->lookahead['value'];
if ($this->_isStringFunction($funcName)) {
return $this->_FunctionsReturningStrings();
} else if ($this->_isNumericFunction($funcName)) {
return $this->_FunctionsReturningNumerics();
} else if ($this->_isDatetimeFunction($funcName)) {
return $this->_FunctionsReturningDatetime();
} else {
$this->syntaxError('Known function.');
}
}
public function _isStringFunction($funcName)
{
return isset(self::$_STRING_FUNCTIONS[strtolower($funcName)]);
@ -1468,6 +1487,33 @@ class Parser
return $existsExpression;
}
/**
* QuantifiedExpression ::= ("ALL" | "ANY" | "SOME") "(" Subselect ")"
*/
public function _QuantifiedExpression()
{
$all = $any = $some = false;
if ($this->_lexer->isNextToken(Lexer::T_ALL)) {
$this->match(Lexer::T_ALL);
$all = true;
} else if ($this->_lexer->isNextToken(Lexer::T_ANY)) {
$this->match(Lexer::T_ANY);
$any = true;
} else if ($this->_lexer->isNextToken(Lexer::T_SOME)) {
$this->match(Lexer::T_SOME);
$some = true;
} else {
$this->syntaxError('ALL, ANY or SOME');
}
$this->match('(');
$qExpr = new AST\QuantifiedExpression($this->_Subselect());
$this->match(')');
$qExpr->setAll($all);
$qExpr->setAny($any);
$qExpr->setSome($some);
return $qExpr;
}
/**
* Subselect ::= SimpleSelectClause SubselectFromClause [WhereClause] [GroupByClause] [HavingClause] [OrderByClause]
*/
@ -1805,7 +1851,7 @@ class Parser
if ($peek['value'] == '.') {
return $this->_StateFieldPathExpression();
} else if ($peek['value'] == '(') {
//TODO... FunctionsReturningStrings or AggregateExpression
return $this->_FunctionsReturningStrings();
} else {
$this->syntaxError("'.' or '('");
}
@ -1815,6 +1861,8 @@ class Parser
} else if ($this->_lexer->lookahead['type'] === Lexer::T_INPUT_PARAMETER) {
$this->match(Lexer::T_INPUT_PARAMETER);
return new AST\InputParameter($this->_lexer->token['value']);
} else if ($this->_isAggregateFunction($this->_lexer->lookahead['type'])) {
return $this->_AggregateExpression();
} else {
$this->syntaxError('StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression');
}

View File

@ -64,17 +64,34 @@ class SqlWalker
$this->_dqlToSqlAliasMap = array_flip($sqlToDqlAliasMap);
}
public function getConnection()
{
return $this->_em->getConnection();
}
/**
* Walks down a SelectStatement AST node, thereby generating the appropriate SQL.
*
* @return string The SQL.
*/
public function walkSelectStatement(AST\SelectStatement $AST)
{
$sql = $this->walkSelectClause($AST->getSelectClause());
$sql .= $this->walkFromClause($AST->getFromClause());
$sql .= $AST->getWhereClause() ? $this->walkWhereClause($AST->getWhereClause()) : '';
$sql .= $AST->getGroupByClause() ? $this->walkGroupByClause($AST->getGroupByClause()) : '';
$sql .= $AST->getHavingClause() ? $this->walkHavingClause($AST->getHavingClause()) : '';
$sql .= $AST->getOrderByClause() ? $this->walkOrderByClause($AST->getOrderByClause()) : '';
//... more clauses
return $sql;
}
/**
* Walks down a SelectClause AST node, thereby generating the appropriate SQL.
*
* @return string The SQL.
*/
public function walkSelectClause($selectClause)
{
return 'SELECT ' . (($selectClause->isDistinct()) ? 'DISTINCT ' : '')
@ -82,6 +99,11 @@ class SqlWalker
$selectClause->getSelectExpressions()));
}
/**
* Walks down a FromClause AST node, thereby generating the appropriate SQL.
*
* @return string The SQL.
*/
public function walkFromClause($fromClause)
{
$sql = ' FROM ';
@ -98,11 +120,61 @@ class SqlWalker
return $sql;
}
/**
* Walks down a FunctionNode AST node, thereby generating the appropriate SQL.
*
* @return string The SQL.
*/
public function walkFunction($function)
{
return $function->getSql($this);
}
/**
* Walks down an OrderByClause AST node, thereby generating the appropriate SQL.
*
* @param OrderByClause
* @return string The SQL.
*/
public function walkOrderByClause($orderByClause)
{
// OrderByClause ::= "ORDER" "BY" OrderByItem {"," OrderByItem}*
return ' ORDER BY '
. implode(', ', array_map(array($this, 'walkOrderByItem'),
$orderByClause->getOrderByItems()));
}
/**
* Walks down an OrderByItem AST node, thereby generating the appropriate SQL.
*
* @param OrderByItem
* @return string The SQL.
*/
public function walkOrderByItem($orderByItem)
{
//TODO: support general SingleValuedPathExpression, not just state field
$pathExpr = $orderByItem->getStateFieldPathExpression();
$parts = $pathExpr->getParts();
$qComp = $this->_parserResult->getQueryComponent($parts[0]);
$columnName = $qComp['metadata']->getColumnName($parts[1]);
$sql = $this->_dqlToSqlAliasMap[$parts[0]] . '.' . $columnName;
$sql .= $orderByItem->isAsc() ? ' ASC' : ' DESC';
return $sql;
}
/**
* Walks down a HavingClause AST node, thereby generating the appropriate SQL.
*
* @param HavingClause
* @return string The SQL.
*/
public function walkHavingClause($havingClause)
{
// HavingClause ::= "HAVING" ConditionalExpression
return ' HAVING ' . implode(' OR ', array_map(array($this, 'walkConditionalTerm'),
$havingClause->getConditionalExpression()->getConditionalTerms()));
}
/**
* Walks down a JoinVariableDeclaration AST node and creates the corresponding SQL.
*
@ -155,8 +227,8 @@ class SqlWalker
/**
* Walks down a SelectExpression AST node and generates the corresponding SQL.
*
* @param <type> $selectExpression
* @return string
* @param SelectExpression $selectExpression
* @return string The SQL.
*/
public function walkSelectExpression($selectExpression)
{
@ -197,6 +269,14 @@ class SqlWalker
}
else if ($selectExpression->getExpression() instanceof AST\Subselect) {
$sql .= $this->walkSubselect($selectExpression->getExpression());
} else if ($selectExpression->getExpression() instanceof AST\Functions\FunctionNode) {
$funcExpr = $selectExpression->getExpression();
if ( ! $selectExpression->getFieldIdentificationVariable()) {
$alias = $this->_scalarAliasCounter++;
} else {
$alias = $selectExpression->getFieldIdentificationVariable();
}
$sql .= $this->walkFunction($selectExpression->getExpression()) . ' AS dctrn__' . $alias;
} else {
$dqlAlias = $selectExpression->getExpression();
$queryComp = $this->_parserResult->getQueryComponent($dqlAlias);
@ -217,17 +297,45 @@ class SqlWalker
return $sql;
}
/**
* Walks down a QuantifiedExpression AST node, thereby generating the appropriate SQL.
*
* @param QuantifiedExpression
* @return string The SQL.
*/
public function walkQuantifiedExpression($qExpr)
{
$sql = '';
if ($qExpr->isAll()) $sql .= ' ALL';
else if ($qExpr->isAny()) $sql .= ' ANY';
else if ($qExpr->isSome()) $sql .= ' SOME';
return $sql .= '(' . $this->walkSubselect($qExpr->getSubselect()) . ')';
}
/**
* Walks down a Subselect AST node, thereby generating the appropriate SQL.
*
* @param Subselect
* @return string The SQL.
*/
public function walkSubselect($subselect)
{
$sql = $this->walkSimpleSelectClause($subselect->getSimpleSelectClause());
$sql .= $this->walkSubselectFromClause($subselect->getSubselectFromClause());
$sql .= $subselect->getWhereClause() ? $this->walkWhereClause($subselect->getWhereClause()) : '';
$sql .= $subselect->getGroupByClause() ? $this->walkGroupByClause($subselect->getGroupByClause()) : '';
$sql .= $subselect->getHavingClause() ? $this->walkHavingClause($subselect->getHavingClause()) : '';
$sql .= $subselect->getOrderByClause() ? $this->walkOrderByClause($subselect->getOrderByClause()) : '';
//... more clauses
return $sql;
}
/**
* Walks down a SubselectFromClause AST node, thereby generating the appropriate SQL.
*
* @param SubselectFromClause
* @return string The SQL.
*/
public function walkSubselectFromClause($subselectFromClause)
{
$sql = ' FROM ';
@ -244,6 +352,12 @@ class SqlWalker
return $sql;
}
/**
* Walks down a SimpleSelectClause AST node, thereby generating the appropriate SQL.
*
* @param SimpleSelectClause
* @return string The SQL.
*/
public function walkSimpleSelectClause($simpleSelectClause)
{
$sql = 'SELECT';
@ -254,11 +368,18 @@ class SqlWalker
return $sql;
}
/**
* Walks down a SimpleSelectExpression AST node, thereby generating the appropriate SQL.
*
* @param SimpleSelectExpression
* @return string The SQL.
*/
public function walkSimpleSelectExpression($simpleSelectExpression)
{
$sql = '';
$expr = $simpleSelectExpression->getExpression();
if ($expr instanceof AST\StateFieldPathExpression) {
$sql .= ' ' . $this->walkPathExpression($expr);
//...
} else if ($expr instanceof AST\AggregateExpression) {
if ( ! $simpleSelectExpression->getFieldIdentificationVariable()) {
@ -274,6 +395,12 @@ class SqlWalker
return $sql;
}
/**
* Walks down an AggregateExpression AST node, thereby generating the appropriate SQL.
*
* @param AggregateExpression
* @return string The SQL.
*/
public function walkAggregateExpression($aggExpression)
{
$sql = '';
@ -291,13 +418,25 @@ class SqlWalker
return $sql;
}
/**
* Walks down a GroupByClause AST node, thereby generating the appropriate SQL.
*
* @param GroupByClause
* @return string The SQL.
*/
public function walkGroupByClause($groupByClause)
{
return ' GROUP BY '
. implode(', ', array_map(array(&$this, 'walkGroupByItem'),
. implode(', ', array_map(array($this, 'walkGroupByItem'),
$groupByClause->getGroupByItems()));
}
/**
* Walks down a GroupByItem AST node, thereby generating the appropriate SQL.
*
* @param GroupByItem
* @return string The SQL.
*/
public function walkGroupByItem($pathExpr)
{
//TODO: support general SingleValuedPathExpression, not just state field
@ -307,6 +446,12 @@ class SqlWalker
return $this->_dqlToSqlAliasMap[$parts[0]] . '.' . $columnName;
}
/**
* Walks down an UpdateStatement AST node, thereby generating the appropriate SQL.
*
* @param UpdateStatement
* @return string The SQL.
*/
public function walkUpdateStatement(AST\UpdateStatement $AST)
{
$sql = $this->walkUpdateClause($AST->getUpdateClause());
@ -314,6 +459,12 @@ class SqlWalker
return $sql;
}
/**
* Walks down a DeleteStatement AST node, thereby generating the appropriate SQL.
*
* @param DeleteStatement
* @return string The SQL.
*/
public function walkDeleteStatement(AST\DeleteStatement $AST)
{
$sql = $this->walkDeleteClause($AST->getDeleteClause());
@ -321,6 +472,12 @@ class SqlWalker
return $sql;
}
/**
* Walks down a DeleteClause AST node, thereby generating the appropriate SQL.
*
* @param DeleteClause
* @return string The SQL.
*/
public function walkDeleteClause(AST\DeleteClause $deleteClause)
{
$sql = 'DELETE FROM ';
@ -332,6 +489,12 @@ class SqlWalker
return $sql;
}
/**
* Walks down an UpdateClause AST node, thereby generating the appropriate SQL.
*
* @param UpdateClause
* @return string The SQL.
*/
public function walkUpdateClause($updateClause)
{
$sql = 'UPDATE ';
@ -346,6 +509,12 @@ class SqlWalker
return $sql;
}
/**
* Walks down an UpdateItem AST node, thereby generating the appropriate SQL.
*
* @param UpdateItem
* @return string The SQL.
*/
public function walkUpdateItem($updateItem)
{
$sql = '';
@ -373,6 +542,12 @@ class SqlWalker
return $sql;
}
/**
* Walks down a WhereClause AST node, thereby generating the appropriate SQL.
*
* @param WhereClause
* @return string The SQL.
*/
public function walkWhereClause($whereClause)
{
$sql = ' WHERE ';
@ -382,12 +557,24 @@ class SqlWalker
return $sql;
}
/**
* Walks down a ConditionalTerm AST node, thereby generating the appropriate SQL.
*
* @param ConditionalTerm
* @return string The SQL.
*/
public function walkConditionalTerm($condTerm)
{
return implode(' AND ', array_map(array($this, 'walkConditionalFactor'),
$condTerm->getConditionalFactors()));
}
/**
* Walks down a ConditionalFactor AST node, thereby generating the appropriate SQL.
*
* @param ConditionalFactor
* @return string The SQL.
*/
public function walkConditionalFactor($factor)
{
$sql = '';
@ -402,6 +589,12 @@ class SqlWalker
return $sql;
}
/**
* Walks down an ExistsExpression AST node, thereby generating the appropriate SQL.
*
* @param ExistsExpression
* @return string The SQL.
*/
public function walkExistsExpression($existsExpr)
{
$sql = '';
@ -410,6 +603,12 @@ class SqlWalker
return $sql;
}
/**
* Walks down a NullComparisonExpression AST node, thereby generating the appropriate SQL.
*
* @param NullComparisonExpression
* @return string The SQL.
*/
public function walkNullComparisonExpression($nullCompExpr)
{
$sql = '';
@ -423,6 +622,12 @@ class SqlWalker
return $sql;
}
/**
* Walks down an InExpression AST node, thereby generating the appropriate SQL.
*
* @param InExpression
* @return string The SQL.
*/
public function walkInExpression($inExpr)
{
$sql = $this->walkPathExpression($inExpr->getPathExpression());
@ -437,6 +642,12 @@ class SqlWalker
return $sql;
}
/**
* Walks down a literal that represents an AST node, thereby generating the appropriate SQL.
*
* @param mixed
* @return string The SQL.
*/
public function walkLiteral($literal)
{
if ($literal instanceof AST\InputParameter) {
@ -446,6 +657,12 @@ class SqlWalker
}
}
/**
* Walks down a BetweenExpression AST node, thereby generating the appropriate SQL.
*
* @param BetweenExpression
* @return string The SQL.
*/
public function walkBetweenExpression($betweenExpr)
{
$sql = $this->walkArithmeticExpression($betweenExpr->getBaseExpression());
@ -455,6 +672,12 @@ class SqlWalker
return $sql;
}
/**
* Walks down a LikeExpression AST node, thereby generating the appropriate SQL.
*
* @param LikeExpression
* @return string The SQL.
*/
public function walkLikeExpression($likeExpr)
{
$sql = '';
@ -477,11 +700,23 @@ class SqlWalker
return $sql;
}
/**
* Walks down a StateFieldPathExpression AST node, thereby generating the appropriate SQL.
*
* @param StateFieldPathExpression
* @return string The SQL.
*/
public function walkStateFieldPathExpression($stateFieldPathExpression)
{
return $this->walkPathExpression($stateFieldPathExpression);
}
/**
* Walks down a ComparisonExpression AST node, thereby generating the appropriate SQL.
*
* @param ComparisonExpression
* @return string The SQL.
*/
public function walkComparisonExpression($compExpr)
{
$sql = '';
@ -505,11 +740,23 @@ class SqlWalker
return $sql;
}
/**
* Walks down an InputParameter AST node, thereby generating the appropriate SQL.
*
* @param InputParameter
* @return string The SQL.
*/
public function walkInputParameter($inputParam)
{
return $inputParam->isNamed() ? ':' . $inputParam->getName() : '?';
}
/**
* Walks down an ArithmeticExpression AST node, thereby generating the appropriate SQL.
*
* @param ArithmeticExpression
* @return string The SQL.
*/
public function walkArithmeticExpression($arithmeticExpr)
{
$sql = '';
@ -523,6 +770,12 @@ class SqlWalker
return $sql;
}
/**
* Walks down an ArithmeticTerm AST node, thereby generating the appropriate SQL.
*
* @param mixed
* @return string The SQL.
*/
public function walkArithmeticTerm($term)
{
if (is_string($term)) return $term;
@ -531,6 +784,12 @@ class SqlWalker
$term->getArithmeticFactors()));
}
/**
* Walks down a StringPrimary that represents an AST node, thereby generating the appropriate SQL.
*
* @param mixed
* @return string The SQL.
*/
public function walkStringPrimary($stringPrimary)
{
if (is_string($stringPrimary)) {
@ -540,6 +799,12 @@ class SqlWalker
}
}
/**
* Walks down an ArithmeticFactor that represents an AST node, thereby generating the appropriate SQL.
*
* @param mixed
* @return string The SQL.
*/
public function walkArithmeticFactor($factor)
{
if (is_string($factor)) return $factor;
@ -560,12 +825,24 @@ class SqlWalker
return $sql;
}
/**
* Walks down an SimpleArithmeticExpression AST node, thereby generating the appropriate SQL.
*
* @param SimpleArithmeticExpression
* @return string The SQL.
*/
public function walkSimpleArithmeticExpression($simpleArithmeticExpr)
{
return implode(' ', array_map(array($this, 'walkArithmeticTerm'),
$simpleArithmeticExpr->getArithmeticTerms()));
}
/**
* Walks down an PathExpression AST node, thereby generating the appropriate SQL.
*
* @param mixed
* @return string The SQL.
*/
public function walkPathExpression($pathExpr)
{
$sql = '';

View File

@ -89,7 +89,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
public function testFunctionalExpressionsSupportedInWherePart()
{
//$this->assertValidDql("SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(u.name) = 'someone'");
$this->assertValidDql("SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(u.name) = 'someone'");
}
public function testArithmeticExpressionsSupportedInWherePart()
@ -300,29 +300,23 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
$this->assertValidDql("SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a WHERE u.name = a.topic");
}
/*
public function testAllExpressionWithCorrelatedSubquery()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > ALL (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = u.name)');
}
public function testCustomJoinsAndWithKeywordSupported()
{
// We need existant classes here, otherwise semantical will always fail
$this->assertValidDql('SELECT c.*, c2.*, d.* FROM Record_Country c INNER JOIN c.City c2 WITH c2.id = 2 WHERE c.id = 1');
}
*/
/* public function testAllExpressionWithCorrelatedSubquery()
{
// We need existant classes here, otherwise semantical will always fail
$this->assertValidDql('SELECT * FROM CompanyEmployee e WHERE e.salary > ALL (SELECT m.salary FROM CompanyManager m WHERE m.department = e.department)', true);
$this->assertValidDql('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.phonenumbers p WITH p.phonenumber = 123 WHERE u.id = 1');
}
public function testAnyExpressionWithCorrelatedSubquery()
{
// We need existant classes here, otherwise semantical will always fail
$this->assertValidDql('SELECT * FROM Employee e WHERE e.salary > ANY (SELECT m.salary FROM Manager m WHERE m.department = e.department)');
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > ANY (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = u.name)');
}
public function testSomeExpressionWithCorrelatedSubquery()
{
// We need existant classes here, otherwise semantical will always fail
$this->assertValidDql('SELECT * FROM Employee e WHERE e.salary > SOME (SELECT m.salary FROM Manager m WHERE m.department = e.department)');
$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)');
}
*/
}

View File

@ -26,7 +26,6 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
}
}
public function testPlainFromClauseWithoutAlias()
{
$this->assertSqlGeneration(
@ -165,54 +164,75 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
);
}
/*public function testFunctionalExpressionsSupportedInWherePart()
{
$this->assertSqlGeneration(
"SELECT u.name FROM CmsUser u WHERE TRIM(u.name) = 'someone'",
// String quoting in the SQL usually depends on the database platform.
// This test works with a mock connection which uses ' for string quoting.
"SELECT cu.name AS cu__name FROM CmsUser cu WHERE TRIM(cu.name) = 'someone'"
);
}*/
/*
// Ticket #973
public function testSingleInValueWithoutSpace()
{
$this->assertSqlGeneration(
"SELECT u.name FROM CmsUser u WHERE u.id IN(46)",
"SELECT cu.name AS cu__name FROM cms_user cu WHERE cu.id IN (46)"
);
}
// Ticket 894
public function testBetweenDeclarationWithInputParameter()
{
$this->assertSqlGeneration(
"SELECT u.name FROM CmsUser u WHERE u.id BETWEEN ? AND ?",
"SELECT cu.name AS cu__name FROM cms_user cu WHERE cu.id BETWEEN ? AND ?"
"SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id BETWEEN ?1 AND ?2",
"SELECT c0.name AS c0__name FROM cms_users c0 WHERE c0.id BETWEEN ? AND ?"
);
}
public function testFunctionalExpressionsSupportedInWherePart()
{
$this->assertSqlGeneration(
"SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(u.name) = 'someone'",
// String quoting in the SQL usually depends on the database platform.
// This test works with a mock connection which uses ' for string quoting.
"SELECT c0.name AS c0__name FROM cms_users c0 WHERE TRIM(FROM c0.name) = 'someone'"
);
}
// Ticket #973
public function testSingleInValueWithoutSpace()
{
$this->assertSqlGeneration(
"SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN(46)",
"SELECT c0.name AS c0__name FROM cms_users c0 WHERE c0.id IN (46)"
);
}
public function testInExpressionSupportedInWherePart()
{
$this->assertSqlGeneration(
'SELECT * FROM CmsUser WHERE CmsUser.id IN (1, 2)',
'SELECT cu.id AS cu__id, cu.status AS cu__status, cu.username AS cu__username, cu.name AS cu__name FROM cms_user cu WHERE cu.id IN (1, 2)'
'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN (1, 2)',
'SELECT c0.id AS c0__id, c0.status AS c0__status, c0.username AS c0__username, c0.name AS c0__name FROM cms_users c0 WHERE c0.id IN (1, 2)'
);
}
public function testNotInExpressionSupportedInWherePart()
{
$this->assertSqlGeneration(
'SELECT * FROM CmsUser WHERE CmsUser.id NOT IN (1)',
'SELECT cu.id AS cu__id, cu.status AS cu__status, cu.username AS cu__username, cu.name AS cu__name FROM cms_user cu WHERE cu.id NOT IN (1)'
'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id NOT IN (1)',
'SELECT c0.id AS c0__id, c0.status AS c0__status, c0.username AS c0__username, c0.name AS c0__name FROM cms_users c0 WHERE c0.id NOT IN (1)'
);
}
*/
public function testConcatFunction()
{
$connMock = $this->_em->getConnection();
$orgPlatform = $connMock->getDatabasePlatform();
$connMock->setDatabasePlatform(new \Doctrine\DBAL\Platforms\MySqlPlatform);
$this->assertSqlGeneration(
"SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, 's') = ?1",
"SELECT c0.id AS c0__id FROM cms_users c0 WHERE CONCAT(c0.name, 's') = ?"
);
$this->assertSqlGeneration(
"SELECT CONCAT(u.id, u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1",
"SELECT CONCAT(c0.id, c0.name) AS dctrn__0 FROM cms_users c0 WHERE c0.id = ?"
);
$connMock->setDatabasePlatform(new \Doctrine\DBAL\Platforms\PostgreSqlPlatform);
$this->assertSqlGeneration(
"SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, 's') = ?1",
"SELECT c0.id AS c0__id FROM cms_users c0 WHERE c0.name || 's' = ?"
);
$this->assertSqlGeneration(
"SELECT CONCAT(u.id, u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1",
"SELECT c0.id || c0.name AS dctrn__0 FROM cms_users c0 WHERE c0.id = ?"
);
$connMock->setDatabasePlatform($orgPlatform);
}
}