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() 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) 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); $column = $this->getIdentifier($column);
if (count($values) == 0) { 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) . ')'; return $column . ' IN (' . implode(', ', $values) . ')';
} }
@ -784,7 +784,7 @@ abstract class AbstractPlatform
*/ */
public function getGuidExpression() 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() 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() 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() 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() 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() 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() 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() 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() 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() 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() 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) 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) 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()) public function getCreateTableSql($table, array $columns, array $options = array())
{ {
if ( ! $table) { if ( ! $table) {
throw \Doctrine\Common\DoctrineException::updateMe('no valid table name specified'); throw DoctrineException::updateMe('no valid table name specified');
} }
if (empty($columns)) { 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); $queryFields = $this->getFieldDeclarationListSql($columns);
@ -1043,7 +1043,7 @@ abstract class AbstractPlatform
*/ */
public function getCreateSequenceSql($sequenceName, $start = 1, array $options) 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']) . ' '; $type = strtoupper($definition['type']) . ' ';
break; break;
default: 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) 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 * @return string
*/ */
abstract public function getTinyIntTypeDeclarationSql(array $columnDef); //abstract public function getTinyIntTypeDeclarationSql(array $columnDef);
/** /**
* Gets the SQL snippet that declares a SMALLINT column. * Gets the SQL snippet that declares a SMALLINT column.
@ -1325,7 +1325,7 @@ abstract class AbstractPlatform
* *
* @return string * @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. * Gets the SQL snippet that declares common properties of an integer column.
@ -1408,12 +1408,12 @@ abstract class AbstractPlatform
if (strtolower($definition['type']) == 'unique') { if (strtolower($definition['type']) == 'unique') {
$type = strtoupper($definition['type']) . ' '; $type = strtoupper($definition['type']) . ' ';
} else { } 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'])) { 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; $query = $type . 'INDEX ' . $name;
@ -1469,7 +1469,7 @@ abstract class AbstractPlatform
*/ */
public function getShowDatabasesSql() 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; return $upper;
break; break;
default: 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 ('; $sql .= 'FOREIGN KEY (';
if ( ! isset($definition['local'])) { 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'])) { 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'])) { 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'])) { if ( ! is_array($definition['local'])) {
@ -1663,7 +1663,7 @@ abstract class AbstractPlatform
*/ */
public function getMatchPatternExpression($pattern, $operator = null, $field = null) 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: case Connection::TRANSACTION_SERIALIZABLE:
return 'SERIALIZABLE'; return 'SERIALIZABLE';
default: 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) 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 * This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see * and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.org>. * <http://www.doctrine-project.org>.
*/ */
namespace Doctrine\DBAL\Platforms; namespace Doctrine\DBAL\Platforms;
@ -185,7 +185,7 @@ class MySqlPlatform extends AbstractPlatform
$match = $field.'LIKE BINARY '; $match = $field.'LIKE BINARY ';
break; break;
default: default:
throw \Doctrine\Common\DoctrineException::updateMe('not a supported operator type:'. $operator); throw DoctrineException::updateMe('not a supported operator type:'. $operator);
} }
} }
$match.= "'"; $match.= "'";
@ -520,7 +520,7 @@ class MySqlPlatform extends AbstractPlatform
$length = null; $length = null;
break; break;
default: 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; $length = ((int) $length == 0) ? null : (int) $length;
@ -678,10 +678,10 @@ class MySqlPlatform extends AbstractPlatform
public function getCreateTableSql($name, array $fields, array $options = array()) public function getCreateTableSql($name, array $fields, array $options = array())
{ {
if ( ! $name) { if ( ! $name) {
throw \Doctrine\Common\DoctrineException::updateMe('no valid table name specified'); throw DoctrineException::updateMe('no valid table name specified');
} }
if (empty($fields)) { 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); $queryFields = $this->getFieldDeclarationListSql($fields);
@ -866,7 +866,7 @@ class MySqlPlatform extends AbstractPlatform
public function getAlterTableSql($name, array $changes, $check = false) public function getAlterTableSql($name, array $changes, $check = false)
{ {
if ( ! $name) { 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) { foreach ($changes as $changeName => $change) {
switch ($changeName) { switch ($changeName) {
@ -877,7 +877,7 @@ class MySqlPlatform extends AbstractPlatform
case 'name': case 'name':
break; break;
default: 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']) . ' '; $type = strtoupper($definition['type']) . ' ';
break; break;
default: 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; $query = 'CREATE ' . $type . 'INDEX ' . $name . ' ON ' . $table;
@ -1050,10 +1050,10 @@ class MySqlPlatform extends AbstractPlatform
} }
/** @override */ /** @override */
public function getTinyIntTypeDeclarationSql(array $field) /*public function getTinyIntTypeDeclarationSql(array $field)
{ {
return 'TINYINT' . $this->_getCommonIntegerTypeDeclarationSql($field); return 'TINYINT' . $this->_getCommonIntegerTypeDeclarationSql($field);
} }*/
/** @override */ /** @override */
public function getSmallIntTypeDeclarationSql(array $field) public function getSmallIntTypeDeclarationSql(array $field)
@ -1062,10 +1062,10 @@ class MySqlPlatform extends AbstractPlatform
} }
/** @override */ /** @override */
public function getMediumIntTypeDeclarationSql(array $field) /*public function getMediumIntTypeDeclarationSql(array $field)
{ {
return 'MEDIUMINT' . $this->_getCommonIntegerTypeDeclarationSql($field); return 'MEDIUMINT' . $this->_getCommonIntegerTypeDeclarationSql($field);
} }*/
/** @override */ /** @override */
protected function _getCommonIntegerTypeDeclarationSql(array $columnDef) protected function _getCommonIntegerTypeDeclarationSql(array $columnDef)

View File

@ -101,7 +101,7 @@ class PostgreSqlPlatform extends AbstractPlatform
public function getNativeDeclaration(array $field) public function getNativeDeclaration(array $field)
{ {
if ( ! isset($field['type'])) { if ( ! isset($field['type'])) {
throw \Doctrine\Common\DoctrineException::updateMe('Missing column type.'); throw DoctrineException::updateMe('Missing column type.');
} }
switch ($field['type']) { switch ($field['type']) {
case 'char': case 'char':
@ -161,7 +161,7 @@ class PostgreSqlPlatform extends AbstractPlatform
$scale = !empty($field['scale']) ? $field['scale'] : $this->conn->getAttribute(Doctrine::ATTR_DECIMAL_PLACES); $scale = !empty($field['scale']) ? $field['scale'] : $this->conn->getAttribute(Doctrine::ATTR_DECIMAL_PLACES);
return 'NUMERIC('.$length.','.$scale.')'; 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; $length = null;
break; break;
default: default:
throw \Doctrine\Common\DoctrineException::updateMe('unknown database attribute type: '.$dbType); throw DoctrineException::updateMe('unknown database attribute type: '.$dbType);
} }
return array('type' => $type, return array('type' => $type,
@ -461,7 +461,7 @@ class PostgreSqlPlatform extends AbstractPlatform
$match = $field.'LIKE '; $match = $field.'LIKE ';
break; break;
default: default:
throw \Doctrine\Common\DoctrineException::updateMe('not a supported operator type:'. $operator); throw DoctrineException::updateMe('not a supported operator type:'. $operator);
} }
} }
$match.= "'"; $match.= "'";
@ -766,7 +766,7 @@ class PostgreSqlPlatform extends AbstractPlatform
case 'rename': case 'rename':
break; break;
default: 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(); $serverInfo = $this->getServerVersion();
if (is_array($serverInfo) && $serverInfo['major'] < 8) { 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']); $query = 'ALTER ' . $fieldName . ' TYPE ' . $this->getTypeDeclarationSql($field['definition']);
$sql[] = 'ALTER TABLE ' . $name . ' ' . $query; $sql[] = 'ALTER TABLE ' . $name . ' ' . $query;
@ -875,10 +875,10 @@ class PostgreSqlPlatform extends AbstractPlatform
public function getCreateTableSql($name, array $fields, array $options = array()) public function getCreateTableSql($name, array $fields, array $options = array())
{ {
if ( ! $name) { if ( ! $name) {
throw \Doctrine\Common\DoctrineException::updateMe('no valid table name specified'); throw DoctrineException::updateMe('no valid table name specified');
} }
if (empty($fields)) { 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); $queryFields = $this->getFieldDeclarationListSql($fields);
@ -1001,4 +1001,65 @@ class PostgreSqlPlatform extends AbstractPlatform
return 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL ' return 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL '
. $this->_getTransactionIsolationLevelSql($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) public function getNativeDeclaration(array $field)
{ {
if ( ! isset($field['type'])) { if ( ! isset($field['type'])) {
throw \Doctrine\Common\DoctrineException::updateMe('Missing column type.'); throw DoctrineException::updateMe('Missing column type.');
} }
switch ($field['type']) { switch ($field['type']) {
case 'text': case 'text':
@ -254,7 +254,7 @@ class SqlitePlatform extends AbstractPlatform
$scale = !empty($field['scale']) ? $field['scale'] : $this->conn->getAttribute(Doctrine::ATTR_DECIMAL_PLACES); $scale = !empty($field['scale']) ? $field['scale'] : $this->conn->getAttribute(Doctrine::ATTR_DECIMAL_PLACES);
return 'DECIMAL('.$length.','.$scale.')'; 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; $length = null;
break; break;
default: default:
throw \Doctrine\Common\DoctrineException::updateMe('unknown database attribute type: '.$dbType); throw DoctrineException::updateMe('unknown database attribute type: '.$dbType);
} }
return array('type' => $type, 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; namespace Doctrine\ORM;
/** /**
* Doctrine_EntityManager_Exception * EntityManagerException
* *
* @author Konsta Vesterinen <kvesteri@cc.hut.fi> * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Roman Borschel <roman@code-factory.org> * @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) 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(' . $sql = 'CONCAT(' .
$sqlWalker->walkStringPrimary($this->_firstStringPrimary) $sqlWalker->walkStringPrimary($this->_firstStringPrimary)
. ', ' . . ', ' .
$sqlWalker->walkStringPrimary($this->_secondStringPrimary) $sqlWalker->walkStringPrimary($this->_secondStringPrimary)
. ')'; . ')';
return $sql; return $sql;*/
} }
/** /**

View File

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

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() public function resetPeek()
{ {
@ -351,6 +351,12 @@ class Lexer
$this->_position = $position; $this->_position = $position;
} }
/**
* Gets the literal for a given token.
*
* @param mixed $token
* @return string
*/
public function getLiteral($token) public function getLiteral($token)
{ {
if ( ! $this->_keywordsTable) { if ( ! $this->_keywordsTable) {

View File

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

View File

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

View File

@ -89,7 +89,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
public function testFunctionalExpressionsSupportedInWherePart() 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() 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"); $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() public function testCustomJoinsAndWithKeywordSupported()
{ {
// We need existant classes here, otherwise semantical will always fail $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');
$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);
} }
public function testAnyExpressionWithCorrelatedSubquery() public function testAnyExpressionWithCorrelatedSubquery()
{ {
// We need existant classes here, otherwise semantical will always fail $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)');
$this->assertValidDql('SELECT * FROM Employee e WHERE e.salary > ANY (SELECT m.salary FROM Manager m WHERE m.department = e.department)');
} }
public function testSomeExpressionWithCorrelatedSubquery() public function testSomeExpressionWithCorrelatedSubquery()
{ {
// We need existant classes here, otherwise semantical will always fail $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 * FROM Employee e WHERE e.salary > SOME (SELECT m.salary FROM Manager m WHERE m.department = e.department)');
} }
*/
} }

View File

@ -26,7 +26,6 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
} }
} }
public function testPlainFromClauseWithoutAlias() public function testPlainFromClauseWithoutAlias()
{ {
$this->assertSqlGeneration( $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 // Ticket 894
public function testBetweenDeclarationWithInputParameter() public function testBetweenDeclarationWithInputParameter()
{ {
$this->assertSqlGeneration( $this->assertSqlGeneration(
"SELECT u.name FROM CmsUser u WHERE u.id BETWEEN ? AND ?", "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id BETWEEN ?1 AND ?2",
"SELECT cu.name AS cu__name FROM cms_user cu WHERE cu.id BETWEEN ? AND ?" "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() public function testInExpressionSupportedInWherePart()
{ {
$this->assertSqlGeneration( $this->assertSqlGeneration(
'SELECT * FROM CmsUser WHERE CmsUser.id IN (1, 2)', 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.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 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() public function testNotInExpressionSupportedInWherePart()
{ {
$this->assertSqlGeneration( $this->assertSqlGeneration(
'SELECT * FROM CmsUser WHERE CmsUser.id NOT IN (1)', 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.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 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);
}
} }