Permalink
Browse files

Remove optimization to a separate Optimizer (much cleaner!)

  • Loading branch information...
1 parent 30b151c commit 156e43a4f1cd1446f8b7fa6c2cd687e9625bcbd5 @relaxnow committed Jun 3, 2012
@@ -0,0 +1,61 @@
+<?php
+
+namespace QueryLang\v3;
+
+use \QueryLang\v3\Node as Node;
+
+/**
+ * Query Optimizer removes unnecessary sub-queries
+ */
+class Optimizer
+{
+ private $_query;
+
+ public function __construct(Node\Query $query)
+ {
+ $this->_query = $query;
+ }
+
+ public function optimize()
+ {
+ $optimizedQuery = $this->_optimize($this->_query);
+
+ if ($optimizedQuery instanceof Node\Term) {
+ $query = new Node\Query();
+ $query->add($optimizedQuery);
+ $optimizedQuery = $query;
+ }
+
+ return $optimizedQuery;
+ }
+
+ protected function _optimize(Node\Query $query)
+ {
+ $terms = $query->getTerms();
+ $termCount = count($terms);
+ $subQueries = $query->getSubQueries();
+ $subQueryCount = count($subQueries);
+
+ // Only contains a single term
+ if ($subQueryCount === 0 && $termCount === 1) {
+ return $terms[0];
+ }
+ // Only contains a single sub-query
+ else if ($subQueryCount == 1 && $termCount === 0) {
+ return $this->_optimize($subQueries[0]);
+ }
+ else {
+ $newQuery = new Node\Query($query->getOperator());
+
+ foreach ($terms as $term) {
+ $newQuery->addTerm($term);
+ }
+
+ foreach ($subQueries as $subQuery) {
+ $newQuery->add($this->_optimize($subQuery));
+ }
+
+ return $newQuery;
+ }
+ }
+}
@@ -2,6 +2,8 @@
namespace QueryLang\v3;
+use \QueryLang\v3\Node as Node;
+
/**
* Query: OrQuery
* OrQuery: AndQuery ([ OR ] AndQuery)*
@@ -26,49 +28,39 @@ public function parse()
protected function _query()
{
- $result = $this->_orQuery();
-
- if (!($result instanceof \QueryLang\v3\Node\Query)) {
- $query = new \QueryLang\v3\Node\Query();
- $query->add($result);
- $result = $query;
- }
-
- return $result;
+ return $this->_orQuery();
}
protected function _orQuery()
{
+ $query = new Node\Query('OR');
+
$leftTerm = $this->_andQuery();
- $query = new \QueryLang\v3\Node\Query('OR');
$query->add($leftTerm);
- $parsed = false;
while ($this->_predict()->getType() === 'OR') {
$this->_accept('OR');
$rightTerm = $this->_andQuery();
$query->add($rightTerm);
- $parsed = true;
}
- return $parsed ? $query : $leftTerm;
+ return $query;
}
protected function _andQuery()
{
+ $query = new Node\Query('AND');
+
$leftTerm = $this->_term();
- $query = new \QueryLang\v3\Node\Query('AND');
$query->add($leftTerm);
- $parsed = false;
while ($this->_predict()->getType() === 'AND') {
$this->_accept('AND');
$rightTerm = $this->_term();
$query->add($rightTerm);
- $parsed = true;
}
- return $parsed ? $query : $leftTerm;
+ return $query;
}
protected function _term()
@@ -83,7 +75,7 @@ protected function _term()
}
else if ($nextTokenType === 'TermValue') {
$termValue = $this->_accept('TermValue');
- return new \QueryLang\v3\Node\Term($termValue);
+ return new Node\Term($termValue);
}
else {
throw new SyntaxException(
Oops, something went wrong.

0 comments on commit 156e43a

Please sign in to comment.