mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
EQL - Simplify nested query where expressions after parsing
This commit is contained in:
@@ -21,6 +21,11 @@ public abstract class AbstractExpression implements SpiExpression {
|
||||
this.propName = propName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void simplify() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getIdEqualTo(String idName) {
|
||||
// override on SimpleExpression
|
||||
|
||||
@@ -88,6 +88,11 @@ public class DefaultExampleExpression implements SpiExpression, ExampleExpressio
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void simplify() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDocQuery(DocQueryContext context) throws IOException {
|
||||
if (!list.isEmpty()) {
|
||||
|
||||
@@ -97,6 +97,16 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
|
||||
}
|
||||
}
|
||||
|
||||
void simplifyEntries() {
|
||||
for (SpiExpression element : list) {
|
||||
element.simplify();
|
||||
}
|
||||
}
|
||||
|
||||
public void simplify() {
|
||||
simplifyEntries();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write being aware if it is the Top level "text" expressions.
|
||||
* <p>
|
||||
|
||||
@@ -36,6 +36,11 @@ class ExistsQueryExpression implements SpiExpression, UnsupportedDocStoreExpress
|
||||
this.subQuery = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void simplify() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDocQuery(DocQueryContext context) throws IOException {
|
||||
throw new IllegalStateException("Not supported");
|
||||
|
||||
@@ -38,6 +38,11 @@ class InQueryExpression extends AbstractExpression implements UnsupportedDocStor
|
||||
this.bindParams = bindParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void simplify() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDocQuery(DocQueryContext context) throws IOException {
|
||||
throw new IllegalStateException("Not supported");
|
||||
|
||||
@@ -39,9 +39,9 @@ import java.util.Set;
|
||||
*/
|
||||
class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, ExpressionList<T> {
|
||||
|
||||
protected final DefaultExpressionList<T> exprList;
|
||||
protected DefaultExpressionList<T> exprList;
|
||||
|
||||
protected final Junction.Type type;
|
||||
protected Junction.Type type;
|
||||
|
||||
JunctionExpression(Junction.Type type, Query<T> query, ExpressionList<T> parent) {
|
||||
this.type = type;
|
||||
@@ -56,6 +56,31 @@ class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expression
|
||||
this.exprList = exprList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplify nested expressions where possible.
|
||||
* <p>
|
||||
* This is expected to only used after expressions are built via query language parsing.
|
||||
* </p>
|
||||
*/
|
||||
public void simplify() {
|
||||
exprList.simplifyEntries();
|
||||
|
||||
List<SpiExpression> list = exprList.list;
|
||||
if (list.size() == 1 && list.get(0) instanceof JunctionExpression) {
|
||||
JunctionExpression nested = (JunctionExpression)list.get(0);
|
||||
if (type == Type.AND && !nested.type.isText()) {
|
||||
// and (and (a, b, c)) -> and (a, b, c)
|
||||
// and (not (a, b, c)) -> not (a, b, c)
|
||||
// and (or (a, b, c)) -> or (a, b, c)
|
||||
this.exprList = nested.exprList;
|
||||
this.type = nested.type;
|
||||
} else if (type == Type.NOT && nested.type == Type.AND) {
|
||||
// not (and (a, b, c)) -> not (a, b, c)
|
||||
this.exprList = nested.exprList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SpiExpression copyForPlanKey() {
|
||||
return new JunctionExpression<T>(type, exprList.copyForPlanKey());
|
||||
}
|
||||
|
||||
@@ -57,6 +57,11 @@ abstract class LogicExpression implements SpiExpression {
|
||||
this.expTwo = (SpiExpression) expTwo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void simplify() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDocQuery(DocQueryContext context) throws IOException {
|
||||
|
||||
|
||||
+5
@@ -24,6 +24,11 @@ class NestedPathWrapperExpression implements SpiExpression {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void simplify() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDocQuery(DocQueryContext context) throws IOException {
|
||||
context.startNested(nestedPath);
|
||||
|
||||
@@ -8,6 +8,11 @@ import com.avaje.ebeaninternal.api.SpiExpression;
|
||||
*/
|
||||
abstract class NonPrepareExpression implements SpiExpression {
|
||||
|
||||
@Override
|
||||
public void simplify() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareExpression(BeanQueryRequest<?> request) {
|
||||
// do nothing
|
||||
|
||||
@@ -17,6 +17,11 @@ class NoopExpression implements SpiExpression {
|
||||
|
||||
protected static final NoopExpression INSTANCE = new NoopExpression();
|
||||
|
||||
@Override
|
||||
public void simplify() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpiExpression copyForPlanKey() {
|
||||
return this;
|
||||
|
||||
@@ -22,6 +22,11 @@ final class NotExpression implements SpiExpression {
|
||||
this.exp = (SpiExpression) exp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void simplify() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeDocQuery(DocQueryContext context) throws IOException {
|
||||
context.startBoolMustNot();
|
||||
|
||||
@@ -27,8 +27,8 @@ class EqlAdapter<T> extends EQLBaseListener {
|
||||
|
||||
private boolean textMode;
|
||||
|
||||
public EqlAdapter(Query<T> query) {
|
||||
this.query = (SpiQuery<T>)query;
|
||||
public EqlAdapter(SpiQuery<T> query) {
|
||||
this.query = query;
|
||||
this.helper = new EqlAdapterHelper(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.avaje.ebeaninternal.server.grammer;
|
||||
|
||||
import com.avaje.ebean.Query;
|
||||
import com.avaje.ebeaninternal.api.SpiQuery;
|
||||
import com.avaje.ebeaninternal.server.grammer.antlr.EQLLexer;
|
||||
import com.avaje.ebeaninternal.server.grammer.antlr.EQLParser;
|
||||
import org.antlr.v4.runtime.ANTLRInputStream;
|
||||
@@ -9,7 +9,7 @@ import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||
|
||||
public class EqlParser {
|
||||
|
||||
public static <T> void parse(String raw, Query<T> query) {
|
||||
public static <T> void parse(String raw, SpiQuery<T> query) {
|
||||
|
||||
EQLLexer lexer = new EQLLexer(new ANTLRInputStream(raw));
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||
@@ -20,5 +20,7 @@ public class EqlParser {
|
||||
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(adapter, context);
|
||||
|
||||
query.simplifyExpressions();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1349,6 +1349,13 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
return whereExpressions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void simplifyExpressions() {
|
||||
if (whereExpressions != null) {
|
||||
whereExpressions.simplify();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultOrmQuery<T> having(Expression expression) {
|
||||
having().add(expression);
|
||||
|
||||
Reference in New Issue
Block a user