1
0
mirror of synced 2025-01-31 04:21:44 +03:00

Made SimpleSelectExpression (Literal) be included as a scalar result. More general SQL Walker optimizations.

This commit is contained in:
Guilherme Blanco 2011-10-28 14:25:12 -02:00
parent 1f06e9fca5
commit 3745e948c6
2 changed files with 114 additions and 126 deletions

View File

@ -157,32 +157,24 @@ class SqlWalker implements TreeWalker
*/
public function getExecutor($AST)
{
$isDeleteStatement = $AST instanceof AST\DeleteStatement;
$isUpdateStatement = $AST instanceof AST\UpdateStatement;
if ($isDeleteStatement) {
$primaryClass = $this->_em->getClassMetadata(
$AST->deleteClause->abstractSchemaName
);
if ($primaryClass->isInheritanceTypeJoined()) {
return new Exec\MultiTableDeleteExecutor($AST, $this);
} else {
return new Exec\SingleTableDeleteUpdateExecutor($AST, $this);
}
} else if ($isUpdateStatement) {
$primaryClass = $this->_em->getClassMetadata(
$AST->updateClause->abstractSchemaName
);
if ($primaryClass->isInheritanceTypeJoined()) {
return new Exec\MultiTableUpdateExecutor($AST, $this);
} else {
return new Exec\SingleTableDeleteUpdateExecutor($AST, $this);
}
switch (true) {
case ($AST instanceof AST\DeleteStatement):
$primaryClass = $this->_em->getClassMetadata($AST->deleteClause->abstractSchemaName);
return ($primaryClass->isInheritanceTypeJoined())
? new Exec\MultiTableDeleteExecutor($AST, $this)
: new Exec\SingleTableDeleteUpdateExecutor($AST, $this);
case ($AST instanceof AST\UpdateStatement):
$primaryClass = $this->_em->getClassMetadata($AST->updateClause->abstractSchemaName);
return ($primaryClass->isInheritanceTypeJoined())
? new Exec\MultiTableUpdateExecutor($AST, $this)
: new Exec\SingleTableDeleteUpdateExecutor($AST, $this);
default:
return new Exec\SingleSelectExecutor($AST, $this);
}
return new Exec\SingleSelectExecutor($AST, $this);
}
/**
@ -1324,14 +1316,11 @@ class SqlWalker implements TreeWalker
$sql .= $this->walkFunction($expr) . ' AS ' . $columnAlias;
break;
case ($expr instanceof AST\Literal):
$sql .= $this->walkLiteral($expr);
break;
case ($expr instanceof AST\SimpleArithmeticExpression):
case ($expr instanceof AST\ArithmeticTerm):
case ($expr instanceof AST\ArithmeticFactor):
case ($expr instanceof AST\ArithmeticPrimary):
case ($expr instanceof AST\Literal):
$alias = $simpleSelectExpression->fieldIdentificationVariable ?: $this->_scalarResultCounter++;
$columnAlias = 'sclr' . $this->_aliasCounter++;
@ -1388,25 +1377,24 @@ class SqlWalker implements TreeWalker
*/
public function walkGroupByClause($groupByClause)
{
$sql = '';
$sqlParts = array();
foreach ($groupByClause->groupByItems AS $groupByItem) {
if (is_string($groupByItem)) {
foreach ($this->_queryComponents[$groupByItem]['metadata']->identifier AS $idField) {
if ($sql != '') {
$sql .= ', ';
}
$groupByItem = new AST\PathExpression(AST\PathExpression::TYPE_STATE_FIELD, $groupByItem, $idField);
$groupByItem->type = AST\PathExpression::TYPE_STATE_FIELD;
$sql .= $this->walkGroupByItem($groupByItem);
}
} else {
if ($sql != '') {
$sql .= ', ';
}
$sql .= $this->walkGroupByItem($groupByItem);
if ( ! is_string($groupByItem)) {
$sqlParts[] = $this->walkGroupByItem($groupByItem);
continue;
}
foreach ($this->_queryComponents[$groupByItem]['metadata']->identifier AS $idField) {
$groupByItem = new AST\PathExpression(AST\PathExpression::TYPE_STATE_FIELD, $groupByItem, $idField);
$groupByItem->type = AST\PathExpression::TYPE_STATE_FIELD;
$sqlParts[] = $this->walkGroupByItem($groupByItem);
}
}
return ' GROUP BY ' . $sql;
return ' GROUP BY ' . implode(', ', $sqlParts);
}
/**
@ -1428,12 +1416,11 @@ class SqlWalker implements TreeWalker
*/
public function walkDeleteClause(AST\DeleteClause $deleteClause)
{
$sql = 'DELETE FROM ';
$class = $this->_em->getClassMetadata($deleteClause->abstractSchemaName);
$sql .= $class->getQuotedTableName($this->_platform);
$this->setSQLTableAlias($class->getTableName(), $class->getTableName(), $deleteClause->aliasIdentificationVariable);
$class = $this->_em->getClassMetadata($deleteClause->abstractSchemaName);
$tableName = $class->getTableName();
$sql = 'DELETE FROM ' . $class->getQuotedTableName($this->_platform);
$this->setSQLTableAlias($tableName, $tableName, $deleteClause->aliasIdentificationVariable);
$this->_rootAliases[] = $deleteClause->aliasIdentificationVariable;
return $sql;
@ -1447,17 +1434,14 @@ class SqlWalker implements TreeWalker
*/
public function walkUpdateClause($updateClause)
{
$sql = 'UPDATE ';
$class = $this->_em->getClassMetadata($updateClause->abstractSchemaName);
$sql .= $class->getQuotedTableName($this->_platform);
$this->setSQLTableAlias($class->getTableName(), $class->getTableName(), $updateClause->aliasIdentificationVariable);
$class = $this->_em->getClassMetadata($updateClause->abstractSchemaName);
$tableName = $class->getTableName();
$sql = 'UPDATE ' . $class->getQuotedTableName($this->_platform);
$this->setSQLTableAlias($tableName, $tableName, $updateClause->aliasIdentificationVariable);
$this->_rootAliases[] = $updateClause->aliasIdentificationVariable;
$sql .= ' SET ' . implode(
', ', array_map(array($this, 'walkUpdateItem'), $updateClause->updateItems)
);
$sql .= ' SET ' . implode(', ', array_map(array($this, 'walkUpdateItem'), $updateClause->updateItems));
return $sql;
}
@ -1473,16 +1457,21 @@ class SqlWalker implements TreeWalker
$useTableAliasesBefore = $this->_useSqlTableAliases;
$this->_useSqlTableAliases = false;
$sql = $this->walkPathExpression($updateItem->pathExpression) . ' = ';
$sql = $this->walkPathExpression($updateItem->pathExpression) . ' = ';
$newValue = $updateItem->newValue;
if ($newValue === null) {
$sql .= 'NULL';
} else if ($newValue instanceof AST\Node) {
$sql .= $newValue->dispatch($this);
} else {
$sql .= $this->_conn->quote($newValue);
switch (true) {
case ($newValue instanceof AST\Node):
$sql .= $newValue->dispatch($this);
break;
case ($newValue === null):
$sql .= 'NULL';
break;
default:
$sql .= $this->_conn->quote($newValue);
break;
}
$this->_useSqlTableAliases = $useTableAliasesBefore;
@ -1499,12 +1488,14 @@ class SqlWalker implements TreeWalker
*/
public function walkWhereClause($whereClause)
{
$condSql = null !== $whereClause ? $this->walkConditionalExpression($whereClause->conditionalExpression) : '';
$condSql = null !== $whereClause ? $this->walkConditionalExpression($whereClause->conditionalExpression) : '';
$discrSql = $this->_generateDiscriminatorColumnConditionSql($this->_rootAliases);
if ($condSql) {
return ' WHERE ' . (( ! $discrSql) ? $condSql : '(' . $condSql . ') AND ' . $discrSql);
} else if ($discrSql) {
}
if ($discrSql) {
return ' WHERE ' . $discrSql;
}
@ -1521,11 +1512,11 @@ class SqlWalker implements TreeWalker
{
// Phase 2 AST optimization: Skip processment of ConditionalExpression
// if only one ConditionalTerm is defined
return ( ! ($condExpr instanceof AST\ConditionalExpression))
? $this->walkConditionalTerm($condExpr)
: implode(
' OR ', array_map(array($this, 'walkConditionalTerm'), $condExpr->conditionalTerms)
);
if ( ! ($condExpr instanceof AST\ConditionalExpression)) {
return $this->walkConditionalTerm($condExpr);
}
return implode(' OR ', array_map(array($this, 'walkConditionalTerm'), $condExpr->conditionalTerms));
}
/**
@ -1538,11 +1529,11 @@ class SqlWalker implements TreeWalker
{
// Phase 2 AST optimization: Skip processment of ConditionalTerm
// if only one ConditionalFactor is defined
return ( ! ($condTerm instanceof AST\ConditionalTerm))
? $this->walkConditionalFactor($condTerm)
: implode(
' AND ', array_map(array($this, 'walkConditionalFactor'), $condTerm->conditionalFactors)
);
if ( ! ($condTerm instanceof AST\ConditionalTerm)) {
return $this->walkConditionalFactor($condTerm);
}
return implode(' AND ', array_map(array($this, 'walkConditionalFactor'), $condTerm->conditionalFactors));
}
/**
@ -1570,7 +1561,9 @@ class SqlWalker implements TreeWalker
{
if ($primary->isSimpleConditionalExpression()) {
return $primary->simpleConditionalExpression->dispatch($this);
} else if ($primary->isConditionalExpression()) {
}
if ($primary->isConditionalExpression()) {
$condExpr = $primary->conditionalExpression;
return '(' . $this->walkConditionalExpression($condExpr) . ')';
@ -1749,14 +1742,12 @@ class SqlWalker implements TreeWalker
*/
public function walkInExpression($inExpr)
{
$sql = $this->walkPathExpression($inExpr->pathExpression)
$sql = $this->walkPathExpression($inExpr->pathExpression)
. ($inExpr->not ? ' NOT' : '') . ' IN (';
if ($inExpr->subselect) {
$sql .= $this->walkSubselect($inExpr->subselect);
} else {
$sql .= implode(', ', array_map(array($this, 'walkInParameter'), $inExpr->literals));
}
$sql .= ($inExpr->subselect)
? $this->walkSubselect($inExpr->subselect)
: implode(', ', array_map(array($this, 'walkInParameter'), $inExpr->literals));
$sql .= ')';
@ -1831,9 +1822,9 @@ class SqlWalker implements TreeWalker
*/
public function walkInParameter($inParam)
{
return $inParam instanceof AST\InputParameter ?
$this->walkInputParameter($inParam) :
$this->walkLiteral($inParam);
return $inParam instanceof AST\InputParameter
? $this->walkInputParameter($inParam)
: $this->walkLiteral($inParam);
}
/**
@ -1926,23 +1917,19 @@ class SqlWalker implements TreeWalker
*/
public function walkComparisonExpression($compExpr)
{
$sql = '';
$leftExpr = $compExpr->leftExpression;
$leftExpr = $compExpr->leftExpression;
$rightExpr = $compExpr->rightExpression;
if ($leftExpr instanceof AST\Node) {
$sql .= $leftExpr->dispatch($this);
} else {
$sql .= is_numeric($leftExpr) ? $leftExpr : $this->_conn->quote($leftExpr);
}
$sql = '';
$sql .= ($leftExpr instanceof AST\Node)
? $leftExpr->dispatch($this)
: (is_numeric($leftExpr) ? $leftExpr : $this->_conn->quote($leftExpr));
$sql .= ' ' . $compExpr->operator . ' ';
if ($rightExpr instanceof AST\Node) {
$sql .= $rightExpr->dispatch($this);
} else {
$sql .= is_numeric($rightExpr) ? $rightExpr : $this->_conn->quote($rightExpr);
}
$sql .= ($rightExpr instanceof AST\Node)
? $rightExpr->dispatch($this)
: (is_numeric($rightExpr) ? $rightExpr : $this->_conn->quote($rightExpr));
return $sql;
}
@ -1981,11 +1968,11 @@ class SqlWalker implements TreeWalker
*/
public function walkSimpleArithmeticExpression($simpleArithmeticExpr)
{
return ( ! ($simpleArithmeticExpr instanceof AST\SimpleArithmeticExpression))
? $this->walkArithmeticTerm($simpleArithmeticExpr)
: implode(
' ', array_map(array($this, 'walkArithmeticTerm'), $simpleArithmeticExpr->arithmeticTerms)
);
if ( ! ($simpleArithmeticExpr instanceof AST\SimpleArithmeticExpression)) {
return $this->walkArithmeticTerm($simpleArithmeticExpr);
}
return implode(' ', array_map(array($this, 'walkArithmeticTerm'), $simpleArithmeticExpr->arithmeticTerms));
}
/**
@ -1997,22 +1984,18 @@ class SqlWalker implements TreeWalker
public function walkArithmeticTerm($term)
{
if (is_string($term)) {
if (isset($this->_queryComponents[$term])) {
$columnName = $this->_queryComponents[$term]['token']['value'];
return $this->_scalarResultAliasMap[$columnName];
}
return $term;
return (isset($this->_queryComponents[$term]))
? $this->_scalarResultAliasMap[$this->_queryComponents[$term]['token']['value']]
: $term;
}
// Phase 2 AST optimization: Skip processment of ArithmeticTerm
// if only one ArithmeticFactor is defined
return ( ! ($term instanceof AST\ArithmeticTerm))
? $this->walkArithmeticFactor($term)
: implode(
' ', array_map(array($this, 'walkArithmeticFactor'), $term->arithmeticFactors)
);
if ( ! ($term instanceof AST\ArithmeticTerm)) {
return $this->walkArithmeticFactor($term);
}
return implode(' ', array_map(array($this, 'walkArithmeticFactor'), $term->arithmeticFactors));
}
/**
@ -2029,10 +2012,13 @@ class SqlWalker implements TreeWalker
// Phase 2 AST optimization: Skip processment of ArithmeticFactor
// if only one ArithmeticPrimary is defined
return ( ! ($factor instanceof AST\ArithmeticFactor))
? $this->walkArithmeticPrimary($factor)
: ($factor->isNegativeSigned() ? '-' : ($factor->isPositiveSigned() ? '+' : ''))
. $this->walkArithmeticPrimary($factor->arithmeticPrimary);
if ( ! ($factor instanceof AST\ArithmeticFactor)) {
return $this->walkArithmeticPrimary($factor);
}
$sign = $factor->isNegativeSigned() ? '-' : ($factor->isPositiveSigned() ? '+' : '');
return $sign . $this->walkArithmeticPrimary($factor->arithmeticPrimary);
}
/**
@ -2045,7 +2031,9 @@ class SqlWalker implements TreeWalker
{
if ($primary instanceof AST\SimpleArithmeticExpression) {
return '(' . $this->walkSimpleArithmeticExpression($primary) . ')';
} else if ($primary instanceof AST\Node) {
}
if ($primary instanceof AST\Node) {
return $primary->dispatch($this);
}

View File

@ -620,7 +620,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
// SQL
'SELECT DISTINCT c0_.id AS id0, c0_.name AS name1 FROM cms_employees c0_'
. ' WHERE EXISTS ('
. 'SELECT 1 FROM cms_employees c1_ WHERE c1_.id = c0_.spouse_id'
. 'SELECT 1 AS sclr2 FROM cms_employees c1_ WHERE c1_.id = c0_.spouse_id'
. ')'
);
}