From 1d6020c454ed3f3df072c68c393a2a8baf1fe207 Mon Sep 17 00:00:00 2001 From: zYne Date: Tue, 30 Oct 2007 19:10:18 +0000 Subject: [PATCH] fixes #533, using DQL identifier aliases before column names is now optional when selecting from single component --- lib/Doctrine/Query.php | 101 ++++++++++++++++++++++++++++++++- lib/Doctrine/Query/Groupby.php | 9 ++- lib/Doctrine/Query/Orderby.php | 25 +------- 3 files changed, 106 insertions(+), 29 deletions(-) diff --git a/lib/Doctrine/Query.php b/lib/Doctrine/Query.php index acab42891..44081bba7 100644 --- a/lib/Doctrine/Query.php +++ b/lib/Doctrine/Query.php @@ -40,6 +40,57 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable const STATE_LOCKED = 4; + protected static $_keywords = array('ALL', + 'AND', + 'ANY', + 'AS', + 'ASC', + 'AVG', + 'BETWEEN', + 'BIT_LENGTH', + 'BY', + 'CHARACTER_LENGTH', + 'CHAR_LENGTH', + 'CURRENT_DATE', + 'CURRENT_TIME', + 'CURRENT_TIMESTAMP', + 'DELETE', + 'DESC', + 'DISTINCT', + 'EMPTY', + 'EXISTS', + 'FALSE', + 'FETCH', + 'FROM', + 'GROUP', + 'HAVING', + 'IN', + 'INDEXBY', + 'INNER', + 'IS', + 'JOIN', + 'LEFT', + 'LIKE', + 'LOWER', + 'MEMBER', + 'MOD', + 'NEW', + 'NOT', + 'NULL', + 'OBJECT', + 'OF', + 'OR', + 'ORDER', + 'OUTER', + 'POSITION', + 'SELECT', + 'SOME', + 'TRIM', + 'TRUE', + 'UNKNOWN', + 'UPDATE', + 'WHERE'); + protected $subqueryAliases = array(); @@ -576,6 +627,8 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable */ public function parseClause($clause) { + $clause = trim($clause); + if (is_numeric($clause)) { return $clause; } @@ -585,7 +638,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable $str = ''; foreach ($terms as $term) { $pos = strpos($term[0], '('); - + if ($pos !== false) { $name = substr($term[0], 0, $pos); if ($name !== '') { @@ -621,6 +674,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable } } else { if (substr($term[0], 0, 1) !== "'" && substr($term[0], -1) !== "'") { + if (strpos($term[0], '.') !== false) { if ( ! is_numeric($term[0])) { $e = explode('.', $term[0]); @@ -638,7 +692,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable if ( ! isset($this->_aliasMap[$componentAlias])) { throw new Doctrine_Query_Exception('Unknown component alias ' . $componentAlias); } - + $table = $this->_aliasMap[$componentAlias]['table']; // get the actual field name from alias @@ -650,7 +704,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable } $tableAlias = $this->getTableAlias($componentAlias); - + // build sql expression $term[0] = $this->_conn->quoteIdentifier($tableAlias) . '.' @@ -660,6 +714,47 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable $term[0] = $this->_conn->quoteIdentifier($field); } } + } else { + + if ( ! empty($term[0]) && + ! in_array(strtoupper($term[0]), self::$_keywords) && + ! is_numeric($term[0])) { + + $componentAlias = $this->getRootAlias(); + + $found = false; + + if ($componentAlias !== false && + $componentAlias !== null) { + $table = $this->_aliasMap[$componentAlias]['table']; + + // check column existence + if ($table->hasColumn($term[0])) { + $found = true; + + // get the actual field name from alias + $term[0] = $table->getColumnName($term[0]); + + $tableAlias = $this->getTableAlias($componentAlias); + + if ($this->getType() === Doctrine_Query::SELECT) { + // build sql expression + $term[0] = $this->_conn->quoteIdentifier($tableAlias) + . '.' + . $this->_conn->quoteIdentifier($term[0]); + } else { + // build sql expression + $term[0] = $this->_conn->quoteIdentifier($term[0]); + } + } else { + $found = false; + } + } + + if ( ! $found) { + $term[0] = $this->getAggregateAlias($term[0]); + } + } } } } diff --git a/lib/Doctrine/Query/Groupby.php b/lib/Doctrine/Query/Groupby.php index 1f1810da8..7eb9bacd4 100644 --- a/lib/Doctrine/Query/Groupby.php +++ b/lib/Doctrine/Query/Groupby.php @@ -44,19 +44,22 @@ class Doctrine_Query_Groupby extends Doctrine_Query_Part $r = array(); foreach (explode(',', $str) as $reference) { $reference = trim($reference); - $e = explode('.', $reference); + /** if (count($e) > 1) { $field = array_pop($e); $ref = implode('.', $e); $this->query->load($ref); - + $r[] = $this->query->getTableAlias($ref) . '.' . $field; } else { $alias = end($e); + $r[] = $this->query->getAggregateAlias($alias); } + */ + $r[] = $this->query->parseClause($reference); } return implode(', ', $r); } -} \ No newline at end of file +} diff --git a/lib/Doctrine/Query/Orderby.php b/lib/Doctrine/Query/Orderby.php index d57825fa4..14211a12f 100644 --- a/lib/Doctrine/Query/Orderby.php +++ b/lib/Doctrine/Query/Orderby.php @@ -44,31 +44,10 @@ class Doctrine_Query_Orderby extends Doctrine_Query_Part $ret = array(); foreach (explode(',', trim($str)) as $r) { - $r = trim($r); - $e = explode(' ', $r); - $a = explode('.', $e[0]); + $r = $this->query->parseClause($r); - if (count($a) > 1) { - $field = array_pop($a); - $reference = implode('.', $a); - $name = end($a); - - $map = $this->query->load($reference, false); - $tableAlias = $this->query->getTableAlias($reference); - - $r = $tableAlias . '.' . $field; - - - } else { - $field = $this->query->getAggregateAlias($e[0]); - - $r = $field; - } - if (isset($e[1])) { - $r .= ' ' . $e[1]; - } $ret[] = $r; } return $ret; } -} \ No newline at end of file +}