[15x] Remove Named queries, ANTLR, Query language parser

This commit is contained in:
Rob Bygrave
2023-10-11 22:54:00 +13:00
parent 91ecc074a7
commit 8473f9fd39
38 changed files with 23 additions and 7812 deletions
@@ -155,10 +155,4 @@ public abstract class BeanFinder<I,T> {
return db().findNative(type, nativeSql);
}
/**
* Creates a query using the ORM query language.
*/
protected Query<T> query(String ormQuery) {
return db().createQuery(type, ormQuery);
}
}
-52
View File
@@ -790,21 +790,6 @@ public final class DB {
return getDefault().createUpdate(beanType, ormUpdate);
}
/**
* Create a named query.
* <p>
* For RawSql the named query is expected to be in ebean.xml.
*
* @param beanType The type of entity bean
* @param namedQuery The name of the query
* @param <T> The type of entity bean
* @return The query
*/
public static <T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery) {
return getDefault().createNamedQuery(beanType, namedQuery);
}
/**
* Create a query for a type of entity bean.
* <p>
@@ -824,43 +809,6 @@ public final class DB {
return getDefault().createQuery(beanType);
}
/**
* Parse the Ebean query language statement returning the query which can then
* be modified (add expressions, change order by clause, change maxRows, change
* fetch and select paths etc).
* <p>
* <h3>Example</h3>
* <pre>{@code
*
* // Find order additionally fetching the customer, details and details.product name.
*
* String eql = "fetch customer fetch details fetch details.product (name) where id = :orderId ";
*
* Query<Order> query = DB.createQuery(Order.class, eql);
* query.setParameter("orderId", 2);
*
* Order order = query.findOne();
*
* // This is the same as:
*
* Order order = DB.find(Order.class)
* .fetch("customer")
* .fetch("details")
* .fetch("detail.product", "name")
* .setId(2)
* .findOne();
*
* }</pre>
*
* @param beanType The type of bean to fetch
* @param eql The Ebean query
* @param <T> The type of the entity bean
* @return The query with expressions defined as per the parsed query statement
*/
public static <T> Query<T> createQuery(Class<T> beanType, String eql) {
return getDefault().createQuery(beanType, eql);
}
/**
* Create a query for a type of entity bean.
* <p>
@@ -225,18 +225,6 @@ public interface Database {
*/
<T> UpdateQuery<T> update(Class<T> beanType);
/**
* Create a named query.
* <p>
* For RawSql the named query is expected to be in ebean.xml.
*
* @param beanType The type of entity bean
* @param namedQuery The name of the query
* @param <T> The type of entity bean
* @return The query
*/
<T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery);
/**
* Create a query for an entity bean and synonym for {@link #find(Class)}.
*
@@ -244,41 +232,6 @@ public interface Database {
*/
<T> Query<T> createQuery(Class<T> beanType);
/**
* Parse the Ebean query language statement returning the query which can then
* be modified (add expressions, change order by clause, change maxRows, change
* fetch and select paths etc).
* <p>
* <h3>Example</h3>
* <pre>{@code
*
* // Find order additionally fetching the customer, details and details.product name.
*
* String ormQuery = "fetch customer fetch details fetch details.product (name) where id = :orderId ";
*
* Query<Order> query = DB.createQuery(Order.class, ormQuery);
* query.setParameter("orderId", 2);
*
* Order order = query.findOne();
*
* // This is the same as:
*
* Order order = DB.find(Order.class)
* .fetch("customer")
* .fetch("details")
* .fetch("detail.product", "name")
* .setId(2)
* .findOne();
*
* }</pre>
*
* @param beanType The type of bean to fetch
* @param ormQuery The Ebean ORM query
* @param <T> The type of the entity bean
* @return The query with expressions defined as per the parsed query statement
*/
<T> Query<T> createQuery(Class<T> beanType, String ormQuery);
/**
* Create a query for a type of entity bean.
* <p>
@@ -693,12 +693,4 @@ public interface ExpressionFactory {
*/
<T> Junction<T> junction(Junction.Type type, Query<T> query, ExpressionList<T> parent);
/**
* Add the expressions to the given expression list.
*
* @param where The expression list to add the expressions to
* @param expressions The expressions that are parsed
* @param params Bind parameters to match ? or ?1 bind positions.
*/
<T> void where(ExpressionList<T> where, String expressions, Object[] params);
}
@@ -507,28 +507,6 @@ public interface ExpressionList<T> {
*/
ExpressionList<T> filterMany(String manyProperty);
/**
* Deprecated for removal - migrate to filterManyRaw()
* <p>
* Add filter expressions to the many property.
*
* <pre>{@code
*
* DB.find(Customer.class)
* .where()
* .eq("name", "Rob")
* .filterMany("orders", "status = ?", Status.NEW)
* .findList();
*
* }</pre>
*
* @param manyProperty The many property
* @param expressions Filter expressions with and, or and ? or ?1 type bind parameters
* @param params Bind parameters used in the expressions
*/
@Deprecated(forRemoval = true)
ExpressionList<T> filterMany(String manyProperty, String expressions, Object... params);
/**
* Add filter expressions for the many path. The expressions can include SQL functions if
* desired and the property names are translated to column names.
@@ -721,14 +699,6 @@ public interface ExpressionList<T> {
*/
ExpressionList<T> where();
/**
* Add the expressions to this expression list.
*
* @param expressions The expressions that are parsed and added to this expression list
* @param params Bind parameters to match ? or ?1 bind positions.
*/
ExpressionList<T> where(String expressions, Object... params);
/**
* Path exists - for the given path in a JSON document.
* <pre>{@code
@@ -213,11 +213,4 @@ public class Finder<I, T> {
return db().findNative(type, nativeSql);
}
/**
* Creates a query using the ORM query language.
*/
public Query<T> query(String ormQuery) {
return db().createQuery(type, ormQuery);
}
}
-6
View File
@@ -55,12 +55,6 @@
<version>13.18.0</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.8-1</version>
</dependency>
<!--
Class retention Nonnull and Nullable annotations
to assist with IDE auto-completion with Ebean API
@@ -34,7 +34,6 @@ import io.ebeaninternal.server.deploy.InheritInfo;
import io.ebeaninternal.server.dto.DtoBeanDescriptor;
import io.ebeaninternal.server.dto.DtoBeanManager;
import io.ebeaninternal.server.el.ElFilter;
import io.ebeaninternal.server.grammer.EqlParser;
import io.ebeaninternal.server.query.*;
import io.ebeaninternal.server.querydefn.*;
import io.ebeaninternal.server.rawsql.SpiRawSql;
@@ -848,29 +847,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
return query;
}
@Override
public <T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery) {
BeanDescriptor<T> desc = desc(beanType);
String named = desc.namedQuery(namedQuery);
if (named != null) {
return createQuery(beanType, named);
}
SpiRawSql rawSql = desc.namedRawSql(namedQuery);
if (rawSql != null) {
DefaultOrmQuery<T> query = createQuery(beanType);
query.setRawSql(rawSql);
return query;
}
throw new PersistenceException("No named query called " + namedQuery + " for bean:" + beanType.getName());
}
@Override
public <T> DefaultOrmQuery<T> createQuery(Class<T> beanType, String eql) {
DefaultOrmQuery<T> query = createQuery(beanType);
EqlParser.parse(eql, query);
return query;
}
@Override
public <T> DefaultOrmQuery<T> createQuery(Class<T> beanType) {
return new DefaultOrmQuery<>(desc(beanType), this, expressionFactory);
@@ -5,7 +5,6 @@ import io.ebean.bean.EntityBean;
import io.ebean.search.*;
import io.ebeaninternal.api.SpiExpressionFactory;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.server.grammer.EqlParser;
import java.util.Arrays;
import java.util.Collection;
@@ -146,11 +145,6 @@ public class DefaultExpressionFactory implements SpiExpressionFactory {
return new BitwiseExpression(propertyName, BitwiseOp.AND, flags, "=", match);
}
@Override
public <T> void where(ExpressionList<T> list, String expressions, Object[] params) {
EqlParser.parseWhere(expressions, list, this, params);
}
@Override
public Expression eq(String propertyName, Query<?> subQuery) {
return new SubQueryExpression(SubQueryOp.EQ, propertyName, (SpiQuery<?>) subQuery);
@@ -439,11 +439,6 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
return query.filterMany(manyProperty);
}
@Override
public ExpressionList<T> filterMany(String manyProperty, String expressions, Object... params) {
return query.filterMany(manyProperty).where(expressions, params);
}
@Override
public ExpressionList<T> filterManyRaw(String manyProperty, String rawExpression, Object... params) {
return query.filterMany(manyProperty).raw(rawExpression, params);
@@ -718,12 +713,6 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
return add(expr.jsonBetween(propertyName, path, lowerValue, upperValue));
}
@Override
public ExpressionList<T> where(String expressions, Object... params) {
expr.where(this, expressions, params);
return this;
}
@Override
public ExpressionList<T> bitwiseAny(String propertyName, long flags) {
return add(expr.bitwiseAny(propertyName, flags));
@@ -302,21 +302,11 @@ final class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expr
return exprList.exampleLike(example);
}
@Override
public ExpressionList<T> where(String expressions, Object... params) {
throw new IllegalStateException("where not allowed on Junction expression list");
}
@Override
public ExpressionList<T> filterMany(String prop) {
throw new IllegalStateException("filterMany not allowed on Junction expression list");
}
@Override
public ExpressionList<T> filterMany(String manyProperty, String expressions, Object... params) {
throw new IllegalStateException("filterMany not allowed on Junction expression list");
}
@Override
public ExpressionList<T> filterManyRaw(String manyProperty, String rawExpression, Object... params) {
throw new IllegalStateException("filterMany not allowed on Junction expression list");
@@ -1,176 +0,0 @@
package io.ebeaninternal.server.grammer;
import io.ebean.ExpressionFactory;
import io.ebean.ExpressionList;
import io.ebean.FetchConfig;
import io.ebean.OrderBy;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.server.grammer.antlr.EQLParser;
import io.ebeaninternal.server.util.ArrayStack;
import org.antlr.v4.runtime.tree.ParseTree;
class EqlAdapter<T> extends EqlWhereListener<T> {
private static final String DISTINCT = "distinct";
private static final String NULLS = "nulls";
private static final String ASC = "asc";
private final SpiQuery<T> query;
private final ExpressionFactory expressionFactory;
EqlAdapter(SpiQuery<T> query) {
this.query = query;
this.expressionFactory = query.getExpressionFactory();
}
@Override
ExpressionFactory expressionFactory() {
return expressionFactory;
}
@Override
Object namedParam(String parameterName) {
return query.createNamedParameter(parameterName);
}
@Override
Object positionParam(String paramPosition) {
return query.createNamedParameter(paramPosition);
}
/**
* Return the current expression list that expressions should be added to.
*/
@Override
ExpressionList<T> peekExprList() {
if (textMode) {
// return the current text expression list
return _peekText();
}
if (whereStack == null) {
whereStack = new ArrayStack<>();
whereStack.push(query.where());
}
// return the current expression list
return whereStack.peek();
}
private ExpressionList<T> _peekText() {
if (textStack == null) {
textStack = new ArrayStack<>();
// empty so push on the queries base expression list
textStack.push(query.text());
}
// return the current expression list
return textStack.peek();
}
@Override
public void enterSelect_clause(EQLParser.Select_clauseContext ctx) {
// with or without surrounding ( and )
int childCount = ctx.getChildCount();
String clause = trimParenthesis(child(ctx, childCount - 1));
if (DISTINCT.equals(child(ctx, 1))) {
query.setDistinct(true);
}
query.select(clause);
}
@Override
public void enterFetch_path(EQLParser.Fetch_pathContext ctx) {
int childCount = ctx.getChildCount();
checkChildren(ctx, 2);
String maybePath = child(ctx, 1);
FetchConfig fetchConfig = ParseFetchConfig.parse(maybePath);
int propsIndex = 2;
String path;
if (fetchConfig == null) {
path = trimQuotes(maybePath);
} else {
propsIndex = 3;
path = trimQuotes(child(ctx, 2));
}
if (childCount == propsIndex) {
query.fetch(path, fetchConfig);
} else {
String properties = trimParenthesis(ctx.getChild(propsIndex).getText());
query.fetch(path, properties, fetchConfig);
}
}
/**
* Trim leading '(' and trailing ')'
*/
private String trimParenthesis(String text) {
if (text.charAt(0) == '(') {
return text.substring(1, text.length() - 1);
}
return text;
}
private String trimQuotes(String path) {
if (path.charAt(0) == '\'' || path.charAt(0) == '`') {
return path.substring(1, path.length() - 1);
}
return path;
}
@Override
public void enterOrderby_property(EQLParser.Orderby_propertyContext ctx) {
int childCount = ctx.getChildCount();
String path = child(ctx, 0);
boolean asc = true;
String nulls = null;
String nullsFirstLast = null;
if (childCount == 3) {
asc = child(ctx, 1).startsWith(ASC);
nullsFirstLast = ctx.getChild(2).getChild(1).getText();
nulls = NULLS;
} else if (childCount == 2) {
String firstChild = child(ctx, 1);
if (firstChild.startsWith(NULLS)) {
nullsFirstLast = ctx.getChild(1).getChild(1).getText();
nulls = NULLS;
} else {
asc = firstChild.startsWith(ASC);
}
}
query.order().add(new OrderBy.Property(path, asc, nulls, nullsFirstLast));
}
@Override
public void enterLimit_clause(EQLParser.Limit_clauseContext ctx) {
try {
String limitValue = child(ctx, 1);
query.setMaxRows(Integer.parseInt(limitValue));
int childCount = ctx.getChildCount();
if (childCount == 3) {
ParseTree offsetTree = ctx.getChild(2);
String offsetValue = offsetTree.getChild(1).getText();
query.setFirstRow(Integer.parseInt(offsetValue));
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Error parsing limit or offset parameter - not an integer", e);
}
}
}
@@ -1,29 +0,0 @@
package io.ebeaninternal.server.grammer;
enum EqlOperator {
EQ,
IEQ,
NE,
INE,
LT,
LTE,
GT,
GTE,
EQORNULL,
LTORNULL,
GTORNULL,
LEORNULL,
GEORNULL,
CONTAINS,
STARTS_WITH,
ENDS_WITH,
LIKE,
ICONTAINS,
ISTARTS_WITH,
IENDS_WITH,
ILIKE,
INRANGE,
BETWEEN
}
@@ -1,51 +0,0 @@
package io.ebeaninternal.server.grammer;
import io.ebean.ExpressionFactory;
import io.ebean.ExpressionList;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.server.grammer.antlr.EQLLexer;
import io.ebeaninternal.server.grammer.antlr.EQLParser;
import org.antlr.v4.runtime.BaseErrorListener;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.RecognitionException;
import org.antlr.v4.runtime.Recognizer;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
/**
* Parse EQL query language applying it to an ORM query object.
*/
public class EqlParser {
private static final ErrorListener errorListener = new ErrorListener();
/**
* Parse the raw EQL query and apply it to the supplied query.
*/
public static <T> void parse(String raw, SpiQuery<T> query) {
EQLParser parser = new EQLParser(new CommonTokenStream(new EQLLexer(CharStreams.fromString(raw))));
parser.addErrorListener(errorListener);
new ParseTreeWalker().walk(new EqlAdapter<>(query), parser.select_statement());
query.simplifyExpressions();
}
public static <T> void parseWhere(String raw, ExpressionList<T> where, ExpressionFactory expr, Object[] params) {
EQLParser parser = new EQLParser(new CommonTokenStream(new EQLLexer(CharStreams.fromString(raw))));
parser.addErrorListener(errorListener);
new ParseTreeWalker().walk(new EqlWhereAdapter<>(where, expr, params), parser.conditional_expression());
}
static class ErrorListener extends BaseErrorListener {
@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
String reportMsg = "line " + line + ":" + charPositionInLine + " " + msg;
throw new IllegalArgumentException(reportMsg);
}
}
}
@@ -1,9 +0,0 @@
package io.ebeaninternal.server.grammer;
enum EqlValueType {
POS_PARAM,
NAMED_PARAM,
STRING,
BOOL,
NUMBER
}
@@ -1,48 +0,0 @@
package io.ebeaninternal.server.grammer;
import io.ebean.ExpressionFactory;
import io.ebean.ExpressionList;
import io.ebeaninternal.server.util.ArrayStack;
class EqlWhereAdapter<T> extends EqlWhereListener<T> {
private final ExpressionList<T> where;
private final ExpressionFactory expr;
private final Object[] params;
private int paramIndex;
EqlWhereAdapter(ExpressionList<T> where, ExpressionFactory expr, Object[] params) {
this.where = where;
this.expr = expr;
this.params = params;
}
@Override
ExpressionList<T> peekExprList() {
if (whereStack == null) {
whereStack = new ArrayStack<>();
whereStack.push(where);
}
return whereStack.peek();
}
@Override
ExpressionFactory expressionFactory() {
return expr;
}
@Override
Object positionParam(String paramPosition) {
if ("?".equals(paramPosition)) {
return params[paramIndex++];
}
final int pos = Integer.parseInt(paramPosition.substring(1));
return params[pos -1];
}
@Override
Object namedParam(String substring) {
throw new RuntimeException("Not supported");
}
}
@@ -1,468 +0,0 @@
package io.ebeaninternal.server.grammer;
import io.ebean.Expression;
import io.ebean.ExpressionFactory;
import io.ebean.ExpressionList;
import io.ebean.LikeType;
import io.ebeaninternal.server.grammer.antlr.EQLBaseListener;
import io.ebeaninternal.server.grammer.antlr.EQLLexer;
import io.ebeaninternal.server.grammer.antlr.EQLParser;
import io.ebeaninternal.server.util.ArrayStack;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNode;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
abstract class EqlWhereListener<T> extends EQLBaseListener {
private static final OperatorMapping operatorMapping = new OperatorMapping();
ArrayStack<ExpressionList<T>> textStack;
ArrayStack<ExpressionList<T>> whereStack;
boolean textMode;
private boolean inWithEmpty;
private List<Object> inValues;
private String inPropertyName;
/**
* Return the current expression list that expressions should be added to.
*/
abstract ExpressionList<T> peekExprList();
abstract ExpressionFactory expressionFactory();
abstract Object namedParam(String paramName);
abstract Object positionParam(String paramPosition);
/**
* Push the expression list onto the appropriate stack.
*/
private void pushExprList(ExpressionList<T> list) {
if (textMode) {
textStack.push(list);
} else {
whereStack.push(list);
}
}
/**
* End a list of expressions added by 'OR'.
*/
private void popJunction() {
if (textMode) {
textStack.pop();
} else {
whereStack.pop();
}
}
private String getLeftHandSidePath(ParserRuleContext ctx) {
TerminalNode pathToken = ctx.getToken(EQLLexer.PATH_VARIABLE, 0);
return pathToken.getText();
}
@Override
public void enterInrange_expression(EQLParser.Inrange_expressionContext ctx) {
checkChildren(ctx, 5);
String path = getLeftHandSidePath(ctx);
EqlOperator op = getOperator(ctx);
if (op != EqlOperator.INRANGE) {
throw new IllegalStateException("Expecting INRANGE operator but got " + op);
}
addInRange(path, child(ctx, 2), child(ctx, 4));
}
@Override
public void enterBetween_expression(EQLParser.Between_expressionContext ctx) {
checkChildren(ctx, 5);
String path = getLeftHandSidePath(ctx);
EqlOperator op = getOperator(ctx);
if (op != EqlOperator.BETWEEN) {
throw new IllegalStateException("Expecting BETWEEN operator but got " + op);
}
addBetween(path, child(ctx, 2), child(ctx, 4));
}
@Override
public void enterPropertyBetween_expression(EQLParser.PropertyBetween_expressionContext ctx) {
checkChildren(ctx, 5);
String rawValue = child(ctx, 0);
EqlOperator op = getOperator(ctx);
if (op != EqlOperator.BETWEEN) {
throw new IllegalStateException("Expecting BETWEEN operator but got " + op);
}
addBetweenProperty(rawValue, child(ctx, 2), child(ctx, 4));
}
@Override
public void enterInOrEmpty_expression(EQLParser.InOrEmpty_expressionContext ctx) {
this.inWithEmpty = true;
this.inValues = new ArrayList<>();
this.inPropertyName = getLeftHandSidePath(ctx);
}
@Override
public void enterIn_expression(EQLParser.In_expressionContext ctx) {
this.inValues = new ArrayList<>();
this.inPropertyName = getLeftHandSidePath(ctx);
}
@Override
public void enterIn_value(EQLParser.In_valueContext ctx) {
int childCount = ctx.getChildCount();
for (int i = 0; i < childCount; i++) {
String text = child(ctx, i);
if (text.startsWith("?")) {
inValues = toList(getBindValue(EqlValueType.POS_PARAM, text));
} else {
if (inWithEmpty) {
throw new IllegalArgumentException("Sorry, can only use inOrEmpty with positioned parameters");
}
if (isValue(text)) {
inValues.add(bind(text));
}
}
}
}
@SuppressWarnings({"unchecked", "rawtypes"})
private List<Object> toList(Object value) {
if (value == null) return null;
if (value instanceof List) {
return (List<Object>)value;
}
if (value instanceof Set) {
return new ArrayList<>((Set)value);
}
throw new IllegalArgumentException("Expected List of Set but got " + value);
}
@Override
public void exitIn_expression(EQLParser.In_expressionContext ctx) {
peekExprList().in(inPropertyName, inValues);
}
@Override
public void exitInOrEmpty_expression(EQLParser.InOrEmpty_expressionContext ctx) {
inWithEmpty = false;
peekExprList().inOrEmpty(inPropertyName, inValues);
}
String child(ParserRuleContext ctx, int position) {
ParseTree child = ctx.getChild(position);
return child.getText();
}
private boolean isValue(String text) {
return text.length() != 1 || (!text.equals("(") && !text.equals(")") && !text.equals(","));
}
@Override
public void enterIsNull_expression(EQLParser.IsNull_expressionContext ctx) {
String path = getLeftHandSidePath(ctx);
peekExprList().isNull(path);
}
@Override
public void enterIsNotNull_expression(EQLParser.IsNotNull_expressionContext ctx) {
String path = getLeftHandSidePath(ctx);
peekExprList().isNotNull(path);
}
@Override
public void enterIsEmpty_expression(EQLParser.IsEmpty_expressionContext ctx) {
String path = getLeftHandSidePath(ctx);
peekExprList().isEmpty(path);
}
@Override
public void enterIsNotEmpty_expression(EQLParser.IsNotEmpty_expressionContext ctx) {
String path = getLeftHandSidePath(ctx);
peekExprList().isNotEmpty(path);
}
@Override
public void enterLike_expression(EQLParser.Like_expressionContext ctx) {
addExpression(ctx);
}
@Override
public void enterComparison_expression(EQLParser.Comparison_expressionContext ctx) {
addExpression(ctx);
}
private void addExpression(ParserRuleContext ctx) {
int childCount = ctx.getChildCount();
if (childCount < 3) {
throw new IllegalStateException("expecting 3 children for comparison? " + ctx);
}
String operator = child(ctx, 1);
EqlOperator op = operatorMapping.get(operator);
if (op == null) {
throw new IllegalStateException("No operator found for " + operator);
}
String path = getLeftHandSidePath(ctx);
String rhs = child(ctx, 2);
if (path.equals(rhs)) {
// the 'value operator path' form
// invert the operator and use LHS as RHS
op = invert(op);
rhs = child(ctx, 0);
}
// RHS is Path, Literal or Named input parameter
addExpression(path, op, rhs);
}
private EqlOperator invert(EqlOperator op) {
switch (op) {
// no change
case EQ:
return EqlOperator.EQ;
case IEQ:
return EqlOperator.IEQ;
case INE:
return EqlOperator.INE;
case NE:
return EqlOperator.NE;
// invert
case LT:
return EqlOperator.GT;
case LTE:
return EqlOperator.GTE;
case GT:
return EqlOperator.LT;
case GTE:
return EqlOperator.LTE;
case EQORNULL:
return EqlOperator.EQORNULL;
case GTORNULL:
return EqlOperator.LEORNULL;
case LTORNULL:
return EqlOperator.GEORNULL;
case GEORNULL:
return EqlOperator.LTORNULL;
case LEORNULL:
return EqlOperator.GTORNULL;
default:
throw new IllegalStateException("Can not invert operator " + op);
}
}
@Override
public void enterConditional_term(EQLParser.Conditional_termContext ctx) {
int childCount = ctx.getChildCount();
if (childCount > 1) {
pushExprList(peekExprList().and());
}
}
@Override
public void exitConditional_term(EQLParser.Conditional_termContext ctx) {
if (ctx.getChildCount() > 1) {
popJunction();
}
}
@Override
public void enterConditional_expression(EQLParser.Conditional_expressionContext ctx) {
if (ctx.getChildCount() > 1) {
pushExprList(peekExprList().or());
}
}
@Override
public void exitConditional_expression(EQLParser.Conditional_expressionContext ctx) {
if (ctx.getChildCount() > 1) {
popJunction();
}
}
@Override
public void enterConditional_factor(EQLParser.Conditional_factorContext ctx) {
if (ctx.getChildCount() > 1) {
pushExprList(peekExprList().not());
}
}
@Override
public void exitConditional_factor(EQLParser.Conditional_factorContext ctx) {
if (ctx.getChildCount() > 1) {
popJunction();
}
}
private EqlOperator getOperator(ParserRuleContext ctx) {
String operator = child(ctx, 1);
EqlOperator op = operatorMapping.get(operator);
if (op == null) {
throw new IllegalStateException("No operator found for " + operator);
}
return op;
}
/**
* Check for the minimum number of children.
*/
void checkChildren(ParserRuleContext ctx, int min) {
if (ctx.getChildCount() < min) {
throw new IllegalStateException("expecting " + min + " children for comparison but got " + ctx.getChildCount());
}
}
private Expression like(boolean caseInsensitive, LikeType likeType, String property, Object bindValue) {
return expressionFactory().like(property, bindValue, caseInsensitive, likeType);
}
private Expression ieq(String property, Object bindValue) {
return expressionFactory().ieqObject(property, bindValue);
}
private Expression ine(String property, Object bindValue) {
return expressionFactory().ineObject(property, bindValue);
}
private EqlValueType getValueType(String valueAsText) {
char firstChar = Character.toLowerCase(valueAsText.charAt(0));
switch (firstChar) {
case '?':
return EqlValueType.POS_PARAM;
case ':':
return EqlValueType.NAMED_PARAM;
case 't':
case 'f':
return EqlValueType.BOOL;
case '\'':
return EqlValueType.STRING;
default:
if (Character.isDigit(firstChar)) {
return EqlValueType.NUMBER;
}
throw new IllegalArgumentException("Unexpected first character in value " + valueAsText);
}
}
private void addBetweenProperty(String rawValue, String lowProperty, String highProperty) {
peekExprList().betweenProperties(lowProperty, highProperty, bind(rawValue));
}
private void addBetween(String path, String value1, String value2) {
peekExprList().between(path, bind(value1), bind(value2));
}
private void addInRange(String path, String value1, String value2) {
peekExprList().inRange(path, bind(value1), bind(value2));
}
private void addExpression(String path, EqlOperator op, String value) {
switch (op) {
case EQ:
peekExprList().eq(path, bind(value));
break;
case IEQ:
peekExprList().add(ieq(path, bind(value)));
break;
case NE:
peekExprList().ne(path, bind(value));
break;
case INE:
peekExprList().add(ine(path, bind(value)));
break;
case GT:
peekExprList().gt(path, bind(value));
break;
case LT:
peekExprList().lt(path, bind(value));
break;
case GTE:
peekExprList().ge(path, bind(value));
break;
case LTE:
peekExprList().le(path, bind(value));
break;
case LIKE:
addLike(false, LikeType.RAW, path, bind(value));
break;
case CONTAINS:
addLike(false, LikeType.CONTAINS, path, bind(value));
break;
case STARTS_WITH:
addLike(false, LikeType.STARTS_WITH, path, bind(value));
break;
case ENDS_WITH:
addLike(false, LikeType.ENDS_WITH, path, bind(value));
break;
case ILIKE:
addLike(true, LikeType.RAW, path, bind(value));
break;
case ICONTAINS:
addLike(true, LikeType.CONTAINS, path, bind(value));
break;
case ISTARTS_WITH:
addLike(true, LikeType.STARTS_WITH, path, bind(value));
break;
case IENDS_WITH:
addLike(true, LikeType.ENDS_WITH, path, bind(value));
break;
case EQORNULL:
peekExprList().eqOrNull(path, bind(value));
break;
case GTORNULL:
peekExprList().gtOrNull(path, bind(value));
break;
case LTORNULL:
peekExprList().ltOrNull(path, bind(value));
break;
case GEORNULL:
peekExprList().geOrNull(path, bind(value));
break;
case LEORNULL:
peekExprList().leOrNull(path, bind(value));
break;
default:
throw new IllegalStateException("Unhandled operator " + op);
}
}
private void addLike(boolean caseInsensitive, LikeType likeType, String path, Object bindValue) {
peekExprList().add(like(caseInsensitive, likeType, path, bindValue));
}
private Object bind(String value) {
return getBindValue(getValueType(value), value);
}
private Object getBindValue(EqlValueType valueType, String value) {
switch (valueType) {
case BOOL:
return Boolean.parseBoolean(value);
case NUMBER:
return new BigDecimal(value);
case STRING:
return unquote(value);
case POS_PARAM:
return positionParam(value);
case NAMED_PARAM:
return namedParam(value.substring(1));
default:
throw new IllegalArgumentException("Unhandled valueType " + valueType);
}
}
private String unquote(String value) {
return value.substring(1, value.length() - 1);
}
}
@@ -1,16 +0,0 @@
package io.ebeaninternal.server.grammer;
public class NamedParameter {
public static final String PREFIX = "$namedParam$";
private final String name;
public NamedParameter(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
@@ -1,57 +0,0 @@
package io.ebeaninternal.server.grammer;
import java.util.HashMap;
import java.util.Map;
class OperatorMapping {
private final Map<String, EqlOperator> map = new HashMap<>();
OperatorMapping() {
map.put("eq", EqlOperator.EQ);
map.put("=", EqlOperator.EQ);
map.put("ieq", EqlOperator.IEQ);
map.put("ne", EqlOperator.NE);
map.put("ine", EqlOperator.INE);
map.put("<>", EqlOperator.NE);
map.put("!=", EqlOperator.NE);
map.put(">", EqlOperator.GT);
map.put("gt", EqlOperator.GT);
map.put(">=", EqlOperator.GTE);
map.put("gte", EqlOperator.GTE);
map.put("ge", EqlOperator.GTE);
map.put("<", EqlOperator.LT);
map.put("lt", EqlOperator.LT);
map.put("<=", EqlOperator.LTE);
map.put("lte", EqlOperator.LTE);
map.put("le", EqlOperator.LTE);
map.put("contains", EqlOperator.CONTAINS);
map.put("startsWith", EqlOperator.STARTS_WITH);
map.put("endsWith", EqlOperator.ENDS_WITH);
map.put("like", EqlOperator.LIKE);
map.put("icontains", EqlOperator.ICONTAINS);
map.put("istartsWith", EqlOperator.ISTARTS_WITH);
map.put("iendsWith", EqlOperator.IENDS_WITH);
map.put("ilike", EqlOperator.ILIKE);
map.put("inrange", EqlOperator.INRANGE);
map.put("inRange", EqlOperator.INRANGE);
map.put("between", EqlOperator.BETWEEN);
map.put("eqOrNull", EqlOperator.EQORNULL);
map.put("gtOrNull", EqlOperator.GTORNULL);
map.put("ltOrNull", EqlOperator.LTORNULL);
map.put("geOrNull", EqlOperator.GEORNULL);
map.put("leOrNull", EqlOperator.LEORNULL);
}
public EqlOperator get(String key) {
return map.get(key);
}
}
File diff suppressed because one or more lines are too long
@@ -1,146 +0,0 @@
T__0=1
T__1=2
T__2=3
T__3=4
T__4=5
T__5=6
T__6=7
T__7=8
T__8=9
T__9=10
T__10=11
T__11=12
T__12=13
T__13=14
T__14=15
T__15=16
T__16=17
T__17=18
T__18=19
T__19=20
T__20=21
T__21=22
T__22=23
T__23=24
T__24=25
T__25=26
T__26=27
T__27=28
T__28=29
T__29=30
T__30=31
T__31=32
T__32=33
T__33=34
T__34=35
T__35=36
T__36=37
T__37=38
T__38=39
T__39=40
T__40=41
T__41=42
T__42=43
T__43=44
T__44=45
T__45=46
T__46=47
T__47=48
T__48=49
T__49=50
T__50=51
T__51=52
T__52=53
T__53=54
T__54=55
T__55=56
T__56=57
T__57=58
T__58=59
T__59=60
T__60=61
T__61=62
T__62=63
T__63=64
T__64=65
T__65=66
T__66=67
INPUT_VARIABLE=68
PATH_VARIABLE=69
QUOTED_PATH_VARIABLE=70
PROP_FORMULA=71
BOOLEAN_LITERAL=72
NUMBER_LITERAL=73
DOUBLE=74
INT=75
ZERO=76
STRING_LITERAL=77
WS=78
'('=1
')'=2
'select'=3
'distinct'=4
'where'=5
'order'=6
'by'=7
','=8
'nulls'=9
'first'=10
'last'=11
'asc'=12
'desc'=13
'limit'=14
'offset'=15
'fetch'=16
'+'=17
'query'=18
'lazy'=19
'or'=20
'and'=21
'not'=22
'inOrEmpty'=23
'in'=24
'between'=25
'to'=26
'inrange'=27
'inRange'=28
'is'=29
'null'=30
'isNull'=31
'isNotNull'=32
'notNull'=33
'empty'=34
'isEmpty'=35
'isNotEmpty'=36
'notEmpty'=37
'like'=38
'ilike'=39
'contains'=40
'icontains'=41
'startsWith'=42
'istartsWith'=43
'endsWith'=44
'iendsWith'=45
'='=46
'eq'=47
'>'=48
'gt'=49
'>='=50
'ge'=51
'gte'=52
'<'=53
'lt'=54
'<='=55
'le'=56
'lte'=57
'<>'=58
'!='=59
'ne'=60
'ieq'=61
'ine'=62
'eqOrNull'=63
'gtOrNull'=64
'ltOrNull'=65
'geOrNull'=66
'leOrNull'=67
'0'=76
@@ -1,579 +0,0 @@
// Generated from /home/rob/github/ebean-dir/ebean/src/test/resources/EQL.g4 by ANTLR 4.8
package io.ebeaninternal.server.grammer.antlr;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ErrorNode;
import org.antlr.v4.runtime.tree.TerminalNode;
/**
* This class provides an empty implementation of {@link EQLListener},
* which can be extended to create a listener which only needs to handle a subset
* of the available methods.
*/
public class EQLBaseListener implements EQLListener {
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterSelect_statement(EQLParser.Select_statementContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitSelect_statement(EQLParser.Select_statementContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterSelect_properties(EQLParser.Select_propertiesContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitSelect_properties(EQLParser.Select_propertiesContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterSelect_clause(EQLParser.Select_clauseContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitSelect_clause(EQLParser.Select_clauseContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterDistinct(EQLParser.DistinctContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitDistinct(EQLParser.DistinctContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterFetch_clause(EQLParser.Fetch_clauseContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitFetch_clause(EQLParser.Fetch_clauseContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterWhere_clause(EQLParser.Where_clauseContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitWhere_clause(EQLParser.Where_clauseContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterOrderby_clause(EQLParser.Orderby_clauseContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitOrderby_clause(EQLParser.Orderby_clauseContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterOrderby_property(EQLParser.Orderby_propertyContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitOrderby_property(EQLParser.Orderby_propertyContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterNulls_firstlast(EQLParser.Nulls_firstlastContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitNulls_firstlast(EQLParser.Nulls_firstlastContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterAsc_desc(EQLParser.Asc_descContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitAsc_desc(EQLParser.Asc_descContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterLimit_clause(EQLParser.Limit_clauseContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitLimit_clause(EQLParser.Limit_clauseContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterOffset_clause(EQLParser.Offset_clauseContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitOffset_clause(EQLParser.Offset_clauseContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterFetch_path(EQLParser.Fetch_pathContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitFetch_path(EQLParser.Fetch_pathContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterFetch_property_set(EQLParser.Fetch_property_setContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitFetch_property_set(EQLParser.Fetch_property_setContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterFetch_property_group(EQLParser.Fetch_property_groupContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitFetch_property_group(EQLParser.Fetch_property_groupContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterFetch_path_path(EQLParser.Fetch_path_pathContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitFetch_path_path(EQLParser.Fetch_path_pathContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterFetch_property(EQLParser.Fetch_propertyContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitFetch_property(EQLParser.Fetch_propertyContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterFetch_query_hint(EQLParser.Fetch_query_hintContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitFetch_query_hint(EQLParser.Fetch_query_hintContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterFetch_lazy_hint(EQLParser.Fetch_lazy_hintContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitFetch_lazy_hint(EQLParser.Fetch_lazy_hintContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterFetch_option(EQLParser.Fetch_optionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitFetch_option(EQLParser.Fetch_optionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterFetch_query_option(EQLParser.Fetch_query_optionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitFetch_query_option(EQLParser.Fetch_query_optionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterFetch_lazy_option(EQLParser.Fetch_lazy_optionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitFetch_lazy_option(EQLParser.Fetch_lazy_optionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterFetch_batch_size(EQLParser.Fetch_batch_sizeContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitFetch_batch_size(EQLParser.Fetch_batch_sizeContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterConditional_expression(EQLParser.Conditional_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitConditional_expression(EQLParser.Conditional_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterConditional_term(EQLParser.Conditional_termContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitConditional_term(EQLParser.Conditional_termContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterConditional_factor(EQLParser.Conditional_factorContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitConditional_factor(EQLParser.Conditional_factorContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterConditional_primary(EQLParser.Conditional_primaryContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitConditional_primary(EQLParser.Conditional_primaryContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterAny_expression(EQLParser.Any_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitAny_expression(EQLParser.Any_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterInOrEmpty_expression(EQLParser.InOrEmpty_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitInOrEmpty_expression(EQLParser.InOrEmpty_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterIn_expression(EQLParser.In_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitIn_expression(EQLParser.In_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterIn_value(EQLParser.In_valueContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitIn_value(EQLParser.In_valueContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterBetween_expression(EQLParser.Between_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitBetween_expression(EQLParser.Between_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterInrange_expression(EQLParser.Inrange_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitInrange_expression(EQLParser.Inrange_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterInrange_op(EQLParser.Inrange_opContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitInrange_op(EQLParser.Inrange_opContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterPropertyBetween_expression(EQLParser.PropertyBetween_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitPropertyBetween_expression(EQLParser.PropertyBetween_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterIsNull_expression(EQLParser.IsNull_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitIsNull_expression(EQLParser.IsNull_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterIsNotNull_expression(EQLParser.IsNotNull_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitIsNotNull_expression(EQLParser.IsNotNull_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterIsEmpty_expression(EQLParser.IsEmpty_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitIsEmpty_expression(EQLParser.IsEmpty_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterIsNotEmpty_expression(EQLParser.IsNotEmpty_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitIsNotEmpty_expression(EQLParser.IsNotEmpty_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterLike_expression(EQLParser.Like_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitLike_expression(EQLParser.Like_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterLike_op(EQLParser.Like_opContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitLike_op(EQLParser.Like_opContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterComparison_expression(EQLParser.Comparison_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitComparison_expression(EQLParser.Comparison_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterComparison_operator(EQLParser.Comparison_operatorContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitComparison_operator(EQLParser.Comparison_operatorContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterValue_expression(EQLParser.Value_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitValue_expression(EQLParser.Value_expressionContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterLiteral(EQLParser.LiteralContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitLiteral(EQLParser.LiteralContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void enterEveryRule(ParserRuleContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void exitEveryRule(ParserRuleContext ctx) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void visitTerminal(TerminalNode node) { }
/**
* {@inheritDoc}
*
* <p>The default implementation does nothing.</p>
*/
@Override public void visitErrorNode(ErrorNode node) { }
}
@@ -1,329 +0,0 @@
// Generated from /home/rob/github/ebean-dir/ebean/src/test/resources/EQL.g4 by ANTLR 4.8
package io.ebeaninternal.server.grammer.antlr;
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
/**
* This class provides an empty implementation of {@link EQLVisitor},
* which can be extended to create a visitor which only needs to handle a subset
* of the available methods.
*
* @param <T> The return type of the visit operation. Use {@link Void} for
* operations with no return type.
*/
public class EQLBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements EQLVisitor<T> {
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitSelect_statement(EQLParser.Select_statementContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitSelect_properties(EQLParser.Select_propertiesContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitSelect_clause(EQLParser.Select_clauseContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitDistinct(EQLParser.DistinctContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFetch_clause(EQLParser.Fetch_clauseContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitWhere_clause(EQLParser.Where_clauseContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitOrderby_clause(EQLParser.Orderby_clauseContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitOrderby_property(EQLParser.Orderby_propertyContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitNulls_firstlast(EQLParser.Nulls_firstlastContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitAsc_desc(EQLParser.Asc_descContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitLimit_clause(EQLParser.Limit_clauseContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitOffset_clause(EQLParser.Offset_clauseContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFetch_path(EQLParser.Fetch_pathContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFetch_property_set(EQLParser.Fetch_property_setContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFetch_property_group(EQLParser.Fetch_property_groupContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFetch_path_path(EQLParser.Fetch_path_pathContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFetch_property(EQLParser.Fetch_propertyContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFetch_query_hint(EQLParser.Fetch_query_hintContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFetch_lazy_hint(EQLParser.Fetch_lazy_hintContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFetch_option(EQLParser.Fetch_optionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFetch_query_option(EQLParser.Fetch_query_optionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFetch_lazy_option(EQLParser.Fetch_lazy_optionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitFetch_batch_size(EQLParser.Fetch_batch_sizeContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitConditional_expression(EQLParser.Conditional_expressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitConditional_term(EQLParser.Conditional_termContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitConditional_factor(EQLParser.Conditional_factorContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitConditional_primary(EQLParser.Conditional_primaryContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitAny_expression(EQLParser.Any_expressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitInOrEmpty_expression(EQLParser.InOrEmpty_expressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitIn_expression(EQLParser.In_expressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitIn_value(EQLParser.In_valueContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitBetween_expression(EQLParser.Between_expressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitInrange_expression(EQLParser.Inrange_expressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitInrange_op(EQLParser.Inrange_opContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitPropertyBetween_expression(EQLParser.PropertyBetween_expressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitIsNull_expression(EQLParser.IsNull_expressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitIsNotNull_expression(EQLParser.IsNotNull_expressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitIsEmpty_expression(EQLParser.IsEmpty_expressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitIsNotEmpty_expression(EQLParser.IsNotEmpty_expressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitLike_expression(EQLParser.Like_expressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitLike_op(EQLParser.Like_opContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitComparison_expression(EQLParser.Comparison_expressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitComparison_operator(EQLParser.Comparison_operatorContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitValue_expression(EQLParser.Value_expressionContext ctx) { return visitChildren(ctx); }
/**
* {@inheritDoc}
*
* <p>The default implementation returns the result of calling
* {@link #visitChildren} on {@code ctx}.</p>
*/
@Override public T visitLiteral(EQLParser.LiteralContext ctx) { return visitChildren(ctx); }
}
File diff suppressed because one or more lines are too long
@@ -1,374 +0,0 @@
// Generated from /home/rob/github/ebean-dir/ebean/src/test/resources/EQL.g4 by ANTLR 4.8
package io.ebeaninternal.server.grammer.antlr;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.RuntimeMetaData;
import org.antlr.v4.runtime.Vocabulary;
import org.antlr.v4.runtime.VocabularyImpl;
import org.antlr.v4.runtime.atn.ATN;
import org.antlr.v4.runtime.atn.ATNDeserializer;
import org.antlr.v4.runtime.atn.LexerATNSimulator;
import org.antlr.v4.runtime.atn.PredictionContextCache;
import org.antlr.v4.runtime.dfa.DFA;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class EQLLexer extends Lexer {
static { RuntimeMetaData.checkVersion("4.8", RuntimeMetaData.VERSION); }
protected static final DFA[] _decisionToDFA;
protected static final PredictionContextCache _sharedContextCache =
new PredictionContextCache();
public static final int
T__0=1, T__1=2, T__2=3, T__3=4, T__4=5, T__5=6, T__6=7, T__7=8, T__8=9,
T__9=10, T__10=11, T__11=12, T__12=13, T__13=14, T__14=15, T__15=16, T__16=17,
T__17=18, T__18=19, T__19=20, T__20=21, T__21=22, T__22=23, T__23=24,
T__24=25, T__25=26, T__26=27, T__27=28, T__28=29, T__29=30, T__30=31,
T__31=32, T__32=33, T__33=34, T__34=35, T__35=36, T__36=37, T__37=38,
T__38=39, T__39=40, T__40=41, T__41=42, T__42=43, T__43=44, T__44=45,
T__45=46, T__46=47, T__47=48, T__48=49, T__49=50, T__50=51, T__51=52,
T__52=53, T__53=54, T__54=55, T__55=56, T__56=57, T__57=58, T__58=59,
T__59=60, T__60=61, T__61=62, T__62=63, T__63=64, T__64=65, T__65=66,
T__66=67, INPUT_VARIABLE=68, PATH_VARIABLE=69, QUOTED_PATH_VARIABLE=70,
PROP_FORMULA=71, BOOLEAN_LITERAL=72, NUMBER_LITERAL=73, DOUBLE=74, INT=75,
ZERO=76, STRING_LITERAL=77, WS=78;
public static String[] channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
};
public static String[] modeNames = {
"DEFAULT_MODE"
};
private static String[] makeRuleNames() {
return new String[] {
"T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8",
"T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "T__16",
"T__17", "T__18", "T__19", "T__20", "T__21", "T__22", "T__23", "T__24",
"T__25", "T__26", "T__27", "T__28", "T__29", "T__30", "T__31", "T__32",
"T__33", "T__34", "T__35", "T__36", "T__37", "T__38", "T__39", "T__40",
"T__41", "T__42", "T__43", "T__44", "T__45", "T__46", "T__47", "T__48",
"T__49", "T__50", "T__51", "T__52", "T__53", "T__54", "T__55", "T__56",
"T__57", "T__58", "T__59", "T__60", "T__61", "T__62", "T__63", "T__64",
"T__65", "T__66", "INPUT_VARIABLE", "PATH_VARIABLE", "QUOTED_PATH_VARIABLE",
"PROP_FORMULA", "BOOLEAN_LITERAL", "NUMBER_LITERAL", "DOUBLE", "INT",
"ZERO", "STRING_LITERAL", "WS"
};
}
public static final String[] ruleNames = makeRuleNames();
private static String[] makeLiteralNames() {
return new String[] {
null, "'('", "')'", "'select'", "'distinct'", "'where'", "'order'", "'by'",
"','", "'nulls'", "'first'", "'last'", "'asc'", "'desc'", "'limit'",
"'offset'", "'fetch'", "'+'", "'query'", "'lazy'", "'or'", "'and'", "'not'",
"'inOrEmpty'", "'in'", "'between'", "'to'", "'inrange'", "'inRange'",
"'is'", "'null'", "'isNull'", "'isNotNull'", "'notNull'", "'empty'",
"'isEmpty'", "'isNotEmpty'", "'notEmpty'", "'like'", "'ilike'", "'contains'",
"'icontains'", "'startsWith'", "'istartsWith'", "'endsWith'", "'iendsWith'",
"'='", "'eq'", "'>'", "'gt'", "'>='", "'ge'", "'gte'", "'<'", "'lt'",
"'<='", "'le'", "'lte'", "'<>'", "'!='", "'ne'", "'ieq'", "'ine'", "'eqOrNull'",
"'gtOrNull'", "'ltOrNull'", "'geOrNull'", "'leOrNull'", null, null, null,
null, null, null, null, null, "'0'"
};
}
private static final String[] _LITERAL_NAMES = makeLiteralNames();
private static String[] makeSymbolicNames() {
return new String[] {
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null, null,
null, null, null, null, null, null, null, null, "INPUT_VARIABLE", "PATH_VARIABLE",
"QUOTED_PATH_VARIABLE", "PROP_FORMULA", "BOOLEAN_LITERAL", "NUMBER_LITERAL",
"DOUBLE", "INT", "ZERO", "STRING_LITERAL", "WS"
};
}
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
/**
* @deprecated Use {@link #VOCABULARY} instead.
*/
@Deprecated
public static final String[] tokenNames;
static {
tokenNames = new String[_SYMBOLIC_NAMES.length];
for (int i = 0; i < tokenNames.length; i++) {
tokenNames[i] = VOCABULARY.getLiteralName(i);
if (tokenNames[i] == null) {
tokenNames[i] = VOCABULARY.getSymbolicName(i);
}
if (tokenNames[i] == null) {
tokenNames[i] = "<INVALID>";
}
}
}
@Override
@Deprecated
public String[] getTokenNames() {
return tokenNames;
}
@Override
public Vocabulary getVocabulary() {
return VOCABULARY;
}
public EQLLexer(CharStream input) {
super(input);
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
}
@Override
public String getGrammarFileName() { return "EQL.g4"; }
@Override
public String[] getRuleNames() { return ruleNames; }
@Override
public String getSerializedATN() { return _serializedATN; }
@Override
public String[] getChannelNames() { return channelNames; }
@Override
public String[] getModeNames() { return modeNames; }
@Override
public ATN getATN() { return _ATN; }
public static final String _serializedATN =
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2P\u029f\b\1\4\2\t"+
"\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
"\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+
"\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+
",\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64\t"+
"\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t="+
"\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4I"+
"\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\3\2\3\2\3\3\3\3\3\4\3\4\3\4\3"+
"\4\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6"+
"\3\6\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3"+
"\n\3\13\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3"+
"\16\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3"+
"\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\23\3\23\3"+
"\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\25\3\25\3\25\3\26\3\26\3"+
"\26\3\26\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3"+
"\30\3\30\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\33\3"+
"\33\3\33\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3"+
"\35\3\35\3\35\3\35\3\36\3\36\3\36\3\37\3\37\3\37\3\37\3\37\3 \3 \3 \3"+
" \3 \3 \3 \3!\3!\3!\3!\3!\3!\3!\3!\3!\3!\3\"\3\"\3\"\3\"\3\"\3\"\3\"\3"+
"\"\3#\3#\3#\3#\3#\3#\3$\3$\3$\3$\3$\3$\3$\3$\3%\3%\3%\3%\3%\3%\3%\3%\3"+
"%\3%\3%\3&\3&\3&\3&\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3\'\3(\3(\3(\3(\3("+
"\3(\3)\3)\3)\3)\3)\3)\3)\3)\3)\3*\3*\3*\3*\3*\3*\3*\3*\3*\3*\3+\3+\3+"+
"\3+\3+\3+\3+\3+\3+\3+\3+\3,\3,\3,\3,\3,\3,\3,\3,\3,\3,\3,\3,\3-\3-\3-"+
"\3-\3-\3-\3-\3-\3-\3.\3.\3.\3.\3.\3.\3.\3.\3.\3.\3/\3/\3\60\3\60\3\60"+
"\3\61\3\61\3\62\3\62\3\62\3\63\3\63\3\63\3\64\3\64\3\64\3\65\3\65\3\65"+
"\3\65\3\66\3\66\3\67\3\67\3\67\38\38\38\39\39\39\3:\3:\3:\3:\3;\3;\3;"+
"\3<\3<\3<\3=\3=\3=\3>\3>\3>\3>\3?\3?\3?\3?\3@\3@\3@\3@\3@\3@\3@\3@\3@"+
"\3A\3A\3A\3A\3A\3A\3A\3A\3A\3B\3B\3B\3B\3B\3B\3B\3B\3B\3C\3C\3C\3C\3C"+
"\3C\3C\3C\3C\3D\3D\3D\3D\3D\3D\3D\3D\3D\3E\3E\3E\7E\u0221\nE\fE\16E\u0224"+
"\13E\3E\3E\7E\u0228\nE\fE\16E\u022b\13E\5E\u022d\nE\3F\3F\7F\u0231\nF"+
"\fF\16F\u0234\13F\3G\3G\3G\3G\3H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3"+
"H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3H\3"+
"H\3H\3H\3H\3H\3H\5H\u0264\nH\3I\3I\3I\3I\3I\3I\3I\3I\3I\5I\u026f\nI\3"+
"J\5J\u0272\nJ\3J\3J\5J\u0276\nJ\3J\3J\5J\u027a\nJ\3K\6K\u027d\nK\rK\16"+
"K\u027e\3K\3K\7K\u0283\nK\fK\16K\u0286\13K\3L\3L\7L\u028a\nL\fL\16L\u028d"+
"\13L\3M\3M\3N\3N\3N\3N\7N\u0295\nN\fN\16N\u0298\13N\3N\3N\3O\3O\3O\3O"+
"\2\2P\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35"+
"\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36"+
";\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67"+
"m8o9q:s;u<w=y>{?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG\u008d"+
"H\u008fI\u0091J\u0093K\u0095L\u0097M\u0099N\u009bO\u009dP\3\2\t\5\2C\\"+
"aac|\6\2\62;C\\aac|\7\2\60\60\62;C\\aac|\3\2\62;\3\2\63;\3\2))\5\2\13"+
"\f\17\17\"\"\2\u02b0\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2"+
"\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3"+
"\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2"+
"\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2"+
"\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2"+
"\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2"+
"\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q"+
"\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2"+
"\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2i\3\2\2\2"+
"\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2s\3\2\2\2\2u\3\2\2\2\2w"+
"\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3\2\2\2\2\u0081\3\2\2"+
"\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087\3\2\2\2\2\u0089\3\2\2\2\2\u008b"+
"\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2\2\2\u0091\3\2\2\2\2\u0093\3\2\2"+
"\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\2\u0099\3\2\2\2\2\u009b\3\2\2\2\2\u009d"+
"\3\2\2\2\3\u009f\3\2\2\2\5\u00a1\3\2\2\2\7\u00a3\3\2\2\2\t\u00aa\3\2\2"+
"\2\13\u00b3\3\2\2\2\r\u00b9\3\2\2\2\17\u00bf\3\2\2\2\21\u00c2\3\2\2\2"+
"\23\u00c4\3\2\2\2\25\u00ca\3\2\2\2\27\u00d0\3\2\2\2\31\u00d5\3\2\2\2\33"+
"\u00d9\3\2\2\2\35\u00de\3\2\2\2\37\u00e4\3\2\2\2!\u00eb\3\2\2\2#\u00f1"+
"\3\2\2\2%\u00f3\3\2\2\2\'\u00f9\3\2\2\2)\u00fe\3\2\2\2+\u0101\3\2\2\2"+
"-\u0105\3\2\2\2/\u0109\3\2\2\2\61\u0113\3\2\2\2\63\u0116\3\2\2\2\65\u011e"+
"\3\2\2\2\67\u0121\3\2\2\29\u0129\3\2\2\2;\u0131\3\2\2\2=\u0134\3\2\2\2"+
"?\u0139\3\2\2\2A\u0140\3\2\2\2C\u014a\3\2\2\2E\u0152\3\2\2\2G\u0158\3"+
"\2\2\2I\u0160\3\2\2\2K\u016b\3\2\2\2M\u0174\3\2\2\2O\u0179\3\2\2\2Q\u017f"+
"\3\2\2\2S\u0188\3\2\2\2U\u0192\3\2\2\2W\u019d\3\2\2\2Y\u01a9\3\2\2\2["+
"\u01b2\3\2\2\2]\u01bc\3\2\2\2_\u01be\3\2\2\2a\u01c1\3\2\2\2c\u01c3\3\2"+
"\2\2e\u01c6\3\2\2\2g\u01c9\3\2\2\2i\u01cc\3\2\2\2k\u01d0\3\2\2\2m\u01d2"+
"\3\2\2\2o\u01d5\3\2\2\2q\u01d8\3\2\2\2s\u01db\3\2\2\2u\u01df\3\2\2\2w"+
"\u01e2\3\2\2\2y\u01e5\3\2\2\2{\u01e8\3\2\2\2}\u01ec\3\2\2\2\177\u01f0"+
"\3\2\2\2\u0081\u01f9\3\2\2\2\u0083\u0202\3\2\2\2\u0085\u020b\3\2\2\2\u0087"+
"\u0214\3\2\2\2\u0089\u022c\3\2\2\2\u008b\u022e\3\2\2\2\u008d\u0235\3\2"+
"\2\2\u008f\u0263\3\2\2\2\u0091\u026e\3\2\2\2\u0093\u0279\3\2\2\2\u0095"+
"\u027c\3\2\2\2\u0097\u0287\3\2\2\2\u0099\u028e\3\2\2\2\u009b\u0290\3\2"+
"\2\2\u009d\u029b\3\2\2\2\u009f\u00a0\7*\2\2\u00a0\4\3\2\2\2\u00a1\u00a2"+
"\7+\2\2\u00a2\6\3\2\2\2\u00a3\u00a4\7u\2\2\u00a4\u00a5\7g\2\2\u00a5\u00a6"+
"\7n\2\2\u00a6\u00a7\7g\2\2\u00a7\u00a8\7e\2\2\u00a8\u00a9\7v\2\2\u00a9"+
"\b\3\2\2\2\u00aa\u00ab\7f\2\2\u00ab\u00ac\7k\2\2\u00ac\u00ad\7u\2\2\u00ad"+
"\u00ae\7v\2\2\u00ae\u00af\7k\2\2\u00af\u00b0\7p\2\2\u00b0\u00b1\7e\2\2"+
"\u00b1\u00b2\7v\2\2\u00b2\n\3\2\2\2\u00b3\u00b4\7y\2\2\u00b4\u00b5\7j"+
"\2\2\u00b5\u00b6\7g\2\2\u00b6\u00b7\7t\2\2\u00b7\u00b8\7g\2\2\u00b8\f"+
"\3\2\2\2\u00b9\u00ba\7q\2\2\u00ba\u00bb\7t\2\2\u00bb\u00bc\7f\2\2\u00bc"+
"\u00bd\7g\2\2\u00bd\u00be\7t\2\2\u00be\16\3\2\2\2\u00bf\u00c0\7d\2\2\u00c0"+
"\u00c1\7{\2\2\u00c1\20\3\2\2\2\u00c2\u00c3\7.\2\2\u00c3\22\3\2\2\2\u00c4"+
"\u00c5\7p\2\2\u00c5\u00c6\7w\2\2\u00c6\u00c7\7n\2\2\u00c7\u00c8\7n\2\2"+
"\u00c8\u00c9\7u\2\2\u00c9\24\3\2\2\2\u00ca\u00cb\7h\2\2\u00cb\u00cc\7"+
"k\2\2\u00cc\u00cd\7t\2\2\u00cd\u00ce\7u\2\2\u00ce\u00cf\7v\2\2\u00cf\26"+
"\3\2\2\2\u00d0\u00d1\7n\2\2\u00d1\u00d2\7c\2\2\u00d2\u00d3\7u\2\2\u00d3"+
"\u00d4\7v\2\2\u00d4\30\3\2\2\2\u00d5\u00d6\7c\2\2\u00d6\u00d7\7u\2\2\u00d7"+
"\u00d8\7e\2\2\u00d8\32\3\2\2\2\u00d9\u00da\7f\2\2\u00da\u00db\7g\2\2\u00db"+
"\u00dc\7u\2\2\u00dc\u00dd\7e\2\2\u00dd\34\3\2\2\2\u00de\u00df\7n\2\2\u00df"+
"\u00e0\7k\2\2\u00e0\u00e1\7o\2\2\u00e1\u00e2\7k\2\2\u00e2\u00e3\7v\2\2"+
"\u00e3\36\3\2\2\2\u00e4\u00e5\7q\2\2\u00e5\u00e6\7h\2\2\u00e6\u00e7\7"+
"h\2\2\u00e7\u00e8\7u\2\2\u00e8\u00e9\7g\2\2\u00e9\u00ea\7v\2\2\u00ea "+
"\3\2\2\2\u00eb\u00ec\7h\2\2\u00ec\u00ed\7g\2\2\u00ed\u00ee\7v\2\2\u00ee"+
"\u00ef\7e\2\2\u00ef\u00f0\7j\2\2\u00f0\"\3\2\2\2\u00f1\u00f2\7-\2\2\u00f2"+
"$\3\2\2\2\u00f3\u00f4\7s\2\2\u00f4\u00f5\7w\2\2\u00f5\u00f6\7g\2\2\u00f6"+
"\u00f7\7t\2\2\u00f7\u00f8\7{\2\2\u00f8&\3\2\2\2\u00f9\u00fa\7n\2\2\u00fa"+
"\u00fb\7c\2\2\u00fb\u00fc\7|\2\2\u00fc\u00fd\7{\2\2\u00fd(\3\2\2\2\u00fe"+
"\u00ff\7q\2\2\u00ff\u0100\7t\2\2\u0100*\3\2\2\2\u0101\u0102\7c\2\2\u0102"+
"\u0103\7p\2\2\u0103\u0104\7f\2\2\u0104,\3\2\2\2\u0105\u0106\7p\2\2\u0106"+
"\u0107\7q\2\2\u0107\u0108\7v\2\2\u0108.\3\2\2\2\u0109\u010a\7k\2\2\u010a"+
"\u010b\7p\2\2\u010b\u010c\7Q\2\2\u010c\u010d\7t\2\2\u010d\u010e\7G\2\2"+
"\u010e\u010f\7o\2\2\u010f\u0110\7r\2\2\u0110\u0111\7v\2\2\u0111\u0112"+
"\7{\2\2\u0112\60\3\2\2\2\u0113\u0114\7k\2\2\u0114\u0115\7p\2\2\u0115\62"+
"\3\2\2\2\u0116\u0117\7d\2\2\u0117\u0118\7g\2\2\u0118\u0119\7v\2\2\u0119"+
"\u011a\7y\2\2\u011a\u011b\7g\2\2\u011b\u011c\7g\2\2\u011c\u011d\7p\2\2"+
"\u011d\64\3\2\2\2\u011e\u011f\7v\2\2\u011f\u0120\7q\2\2\u0120\66\3\2\2"+
"\2\u0121\u0122\7k\2\2\u0122\u0123\7p\2\2\u0123\u0124\7t\2\2\u0124\u0125"+
"\7c\2\2\u0125\u0126\7p\2\2\u0126\u0127\7i\2\2\u0127\u0128\7g\2\2\u0128"+
"8\3\2\2\2\u0129\u012a\7k\2\2\u012a\u012b\7p\2\2\u012b\u012c\7T\2\2\u012c"+
"\u012d\7c\2\2\u012d\u012e\7p\2\2\u012e\u012f\7i\2\2\u012f\u0130\7g\2\2"+
"\u0130:\3\2\2\2\u0131\u0132\7k\2\2\u0132\u0133\7u\2\2\u0133<\3\2\2\2\u0134"+
"\u0135\7p\2\2\u0135\u0136\7w\2\2\u0136\u0137\7n\2\2\u0137\u0138\7n\2\2"+
"\u0138>\3\2\2\2\u0139\u013a\7k\2\2\u013a\u013b\7u\2\2\u013b\u013c\7P\2"+
"\2\u013c\u013d\7w\2\2\u013d\u013e\7n\2\2\u013e\u013f\7n\2\2\u013f@\3\2"+
"\2\2\u0140\u0141\7k\2\2\u0141\u0142\7u\2\2\u0142\u0143\7P\2\2\u0143\u0144"+
"\7q\2\2\u0144\u0145\7v\2\2\u0145\u0146\7P\2\2\u0146\u0147\7w\2\2\u0147"+
"\u0148\7n\2\2\u0148\u0149\7n\2\2\u0149B\3\2\2\2\u014a\u014b\7p\2\2\u014b"+
"\u014c\7q\2\2\u014c\u014d\7v\2\2\u014d\u014e\7P\2\2\u014e\u014f\7w\2\2"+
"\u014f\u0150\7n\2\2\u0150\u0151\7n\2\2\u0151D\3\2\2\2\u0152\u0153\7g\2"+
"\2\u0153\u0154\7o\2\2\u0154\u0155\7r\2\2\u0155\u0156\7v\2\2\u0156\u0157"+
"\7{\2\2\u0157F\3\2\2\2\u0158\u0159\7k\2\2\u0159\u015a\7u\2\2\u015a\u015b"+
"\7G\2\2\u015b\u015c\7o\2\2\u015c\u015d\7r\2\2\u015d\u015e\7v\2\2\u015e"+
"\u015f\7{\2\2\u015fH\3\2\2\2\u0160\u0161\7k\2\2\u0161\u0162\7u\2\2\u0162"+
"\u0163\7P\2\2\u0163\u0164\7q\2\2\u0164\u0165\7v\2\2\u0165\u0166\7G\2\2"+
"\u0166\u0167\7o\2\2\u0167\u0168\7r\2\2\u0168\u0169\7v\2\2\u0169\u016a"+
"\7{\2\2\u016aJ\3\2\2\2\u016b\u016c\7p\2\2\u016c\u016d\7q\2\2\u016d\u016e"+
"\7v\2\2\u016e\u016f\7G\2\2\u016f\u0170\7o\2\2\u0170\u0171\7r\2\2\u0171"+
"\u0172\7v\2\2\u0172\u0173\7{\2\2\u0173L\3\2\2\2\u0174\u0175\7n\2\2\u0175"+
"\u0176\7k\2\2\u0176\u0177\7m\2\2\u0177\u0178\7g\2\2\u0178N\3\2\2\2\u0179"+
"\u017a\7k\2\2\u017a\u017b\7n\2\2\u017b\u017c\7k\2\2\u017c\u017d\7m\2\2"+
"\u017d\u017e\7g\2\2\u017eP\3\2\2\2\u017f\u0180\7e\2\2\u0180\u0181\7q\2"+
"\2\u0181\u0182\7p\2\2\u0182\u0183\7v\2\2\u0183\u0184\7c\2\2\u0184\u0185"+
"\7k\2\2\u0185\u0186\7p\2\2\u0186\u0187\7u\2\2\u0187R\3\2\2\2\u0188\u0189"+
"\7k\2\2\u0189\u018a\7e\2\2\u018a\u018b\7q\2\2\u018b\u018c\7p\2\2\u018c"+
"\u018d\7v\2\2\u018d\u018e\7c\2\2\u018e\u018f\7k\2\2\u018f\u0190\7p\2\2"+
"\u0190\u0191\7u\2\2\u0191T\3\2\2\2\u0192\u0193\7u\2\2\u0193\u0194\7v\2"+
"\2\u0194\u0195\7c\2\2\u0195\u0196\7t\2\2\u0196\u0197\7v\2\2\u0197\u0198"+
"\7u\2\2\u0198\u0199\7Y\2\2\u0199\u019a\7k\2\2\u019a\u019b\7v\2\2\u019b"+
"\u019c\7j\2\2\u019cV\3\2\2\2\u019d\u019e\7k\2\2\u019e\u019f\7u\2\2\u019f"+
"\u01a0\7v\2\2\u01a0\u01a1\7c\2\2\u01a1\u01a2\7t\2\2\u01a2\u01a3\7v\2\2"+
"\u01a3\u01a4\7u\2\2\u01a4\u01a5\7Y\2\2\u01a5\u01a6\7k\2\2\u01a6\u01a7"+
"\7v\2\2\u01a7\u01a8\7j\2\2\u01a8X\3\2\2\2\u01a9\u01aa\7g\2\2\u01aa\u01ab"+
"\7p\2\2\u01ab\u01ac\7f\2\2\u01ac\u01ad\7u\2\2\u01ad\u01ae\7Y\2\2\u01ae"+
"\u01af\7k\2\2\u01af\u01b0\7v\2\2\u01b0\u01b1\7j\2\2\u01b1Z\3\2\2\2\u01b2"+
"\u01b3\7k\2\2\u01b3\u01b4\7g\2\2\u01b4\u01b5\7p\2\2\u01b5\u01b6\7f\2\2"+
"\u01b6\u01b7\7u\2\2\u01b7\u01b8\7Y\2\2\u01b8\u01b9\7k\2\2\u01b9\u01ba"+
"\7v\2\2\u01ba\u01bb\7j\2\2\u01bb\\\3\2\2\2\u01bc\u01bd\7?\2\2\u01bd^\3"+
"\2\2\2\u01be\u01bf\7g\2\2\u01bf\u01c0\7s\2\2\u01c0`\3\2\2\2\u01c1\u01c2"+
"\7@\2\2\u01c2b\3\2\2\2\u01c3\u01c4\7i\2\2\u01c4\u01c5\7v\2\2\u01c5d\3"+
"\2\2\2\u01c6\u01c7\7@\2\2\u01c7\u01c8\7?\2\2\u01c8f\3\2\2\2\u01c9\u01ca"+
"\7i\2\2\u01ca\u01cb\7g\2\2\u01cbh\3\2\2\2\u01cc\u01cd\7i\2\2\u01cd\u01ce"+
"\7v\2\2\u01ce\u01cf\7g\2\2\u01cfj\3\2\2\2\u01d0\u01d1\7>\2\2\u01d1l\3"+
"\2\2\2\u01d2\u01d3\7n\2\2\u01d3\u01d4\7v\2\2\u01d4n\3\2\2\2\u01d5\u01d6"+
"\7>\2\2\u01d6\u01d7\7?\2\2\u01d7p\3\2\2\2\u01d8\u01d9\7n\2\2\u01d9\u01da"+
"\7g\2\2\u01dar\3\2\2\2\u01db\u01dc\7n\2\2\u01dc\u01dd\7v\2\2\u01dd\u01de"+
"\7g\2\2\u01det\3\2\2\2\u01df\u01e0\7>\2\2\u01e0\u01e1\7@\2\2\u01e1v\3"+
"\2\2\2\u01e2\u01e3\7#\2\2\u01e3\u01e4\7?\2\2\u01e4x\3\2\2\2\u01e5\u01e6"+
"\7p\2\2\u01e6\u01e7\7g\2\2\u01e7z\3\2\2\2\u01e8\u01e9\7k\2\2\u01e9\u01ea"+
"\7g\2\2\u01ea\u01eb\7s\2\2\u01eb|\3\2\2\2\u01ec\u01ed\7k\2\2\u01ed\u01ee"+
"\7p\2\2\u01ee\u01ef\7g\2\2\u01ef~\3\2\2\2\u01f0\u01f1\7g\2\2\u01f1\u01f2"+
"\7s\2\2\u01f2\u01f3\7Q\2\2\u01f3\u01f4\7t\2\2\u01f4\u01f5\7P\2\2\u01f5"+
"\u01f6\7w\2\2\u01f6\u01f7\7n\2\2\u01f7\u01f8\7n\2\2\u01f8\u0080\3\2\2"+
"\2\u01f9\u01fa\7i\2\2\u01fa\u01fb\7v\2\2\u01fb\u01fc\7Q\2\2\u01fc\u01fd"+
"\7t\2\2\u01fd\u01fe\7P\2\2\u01fe\u01ff\7w\2\2\u01ff\u0200\7n\2\2\u0200"+
"\u0201\7n\2\2\u0201\u0082\3\2\2\2\u0202\u0203\7n\2\2\u0203\u0204\7v\2"+
"\2\u0204\u0205\7Q\2\2\u0205\u0206\7t\2\2\u0206\u0207\7P\2\2\u0207\u0208"+
"\7w\2\2\u0208\u0209\7n\2\2\u0209\u020a\7n\2\2\u020a\u0084\3\2\2\2\u020b"+
"\u020c\7i\2\2\u020c\u020d\7g\2\2\u020d\u020e\7Q\2\2\u020e\u020f\7t\2\2"+
"\u020f\u0210\7P\2\2\u0210\u0211\7w\2\2\u0211\u0212\7n\2\2\u0212\u0213"+
"\7n\2\2\u0213\u0086\3\2\2\2\u0214\u0215\7n\2\2\u0215\u0216\7g\2\2\u0216"+
"\u0217\7Q\2\2\u0217\u0218\7t\2\2\u0218\u0219\7P\2\2\u0219\u021a\7w\2\2"+
"\u021a\u021b\7n\2\2\u021b\u021c\7n\2\2\u021c\u0088\3\2\2\2\u021d\u021e"+
"\7<\2\2\u021e\u0222\t\2\2\2\u021f\u0221\t\3\2\2\u0220\u021f\3\2\2\2\u0221"+
"\u0224\3\2\2\2\u0222\u0220\3\2\2\2\u0222\u0223\3\2\2\2\u0223\u022d\3\2"+
"\2\2\u0224\u0222\3\2\2\2\u0225\u0229\7A\2\2\u0226\u0228\4\62;\2\u0227"+
"\u0226\3\2\2\2\u0228\u022b\3\2\2\2\u0229\u0227\3\2\2\2\u0229\u022a\3\2"+
"\2\2\u022a\u022d\3\2\2\2\u022b\u0229\3\2\2\2\u022c\u021d\3\2\2\2\u022c"+
"\u0225\3\2\2\2\u022d\u008a\3\2\2\2\u022e\u0232\t\2\2\2\u022f\u0231\t\4"+
"\2\2\u0230\u022f\3\2\2\2\u0231\u0234\3\2\2\2\u0232\u0230\3\2\2\2\u0232"+
"\u0233\3\2\2\2\u0233\u008c\3\2\2\2\u0234\u0232\3\2\2\2\u0235\u0236\7b"+
"\2\2\u0236\u0237\5\u008bF\2\u0237\u0238\7b\2\2\u0238\u008e\3\2\2\2\u0239"+
"\u023a\7u\2\2\u023a\u023b\7w\2\2\u023b\u023c\7o\2\2\u023c\u023d\7*\2\2"+
"\u023d\u023e\3\2\2\2\u023e\u023f\5\u008bF\2\u023f\u0240\7+\2\2\u0240\u0264"+
"\3\2\2\2\u0241\u0242\7o\2\2\u0242\u0243\7c\2\2\u0243\u0244\7z\2\2\u0244"+
"\u0245\7*\2\2\u0245\u0246\3\2\2\2\u0246\u0247\5\u008bF\2\u0247\u0248\7"+
"+\2\2\u0248\u0264\3\2\2\2\u0249\u024a\7o\2\2\u024a\u024b\7k\2\2\u024b"+
"\u024c\7p\2\2\u024c\u024d\7*\2\2\u024d\u024e\3\2\2\2\u024e\u024f\5\u008b"+
"F\2\u024f\u0250\7+\2\2\u0250\u0264\3\2\2\2\u0251\u0252\7c\2\2\u0252\u0253"+
"\7x\2\2\u0253\u0254\7i\2\2\u0254\u0255\7*\2\2\u0255\u0256\3\2\2\2\u0256"+
"\u0257\5\u008bF\2\u0257\u0258\7+\2\2\u0258\u0264\3\2\2\2\u0259\u025a\7"+
"e\2\2\u025a\u025b\7q\2\2\u025b\u025c\7w\2\2\u025c\u025d\7p\2\2\u025d\u025e"+
"\7v\2\2\u025e\u025f\7*\2\2\u025f\u0260\3\2\2\2\u0260\u0261\5\u008bF\2"+
"\u0261\u0262\7+\2\2\u0262\u0264\3\2\2\2\u0263\u0239\3\2\2\2\u0263\u0241"+
"\3\2\2\2\u0263\u0249\3\2\2\2\u0263\u0251\3\2\2\2\u0263\u0259\3\2\2\2\u0264"+
"\u0090\3\2\2\2\u0265\u0266\7v\2\2\u0266\u0267\7t\2\2\u0267\u0268\7w\2"+
"\2\u0268\u026f\7g\2\2\u0269\u026a\7h\2\2\u026a\u026b\7c\2\2\u026b\u026c"+
"\7n\2\2\u026c\u026d\7u\2\2\u026d\u026f\7g\2\2\u026e\u0265\3\2\2\2\u026e"+
"\u0269\3\2\2\2\u026f\u0092\3\2\2\2\u0270\u0272\7/\2\2\u0271\u0270\3\2"+
"\2\2\u0271\u0272\3\2\2\2\u0272\u0273\3\2\2\2\u0273\u027a\5\u0095K\2\u0274"+
"\u0276\7/\2\2\u0275\u0274\3\2\2\2\u0275\u0276\3\2\2\2\u0276\u0277\3\2"+
"\2\2\u0277\u027a\5\u0097L\2\u0278\u027a\5\u0099M\2\u0279\u0271\3\2\2\2"+
"\u0279\u0275\3\2\2\2\u0279\u0278\3\2\2\2\u027a\u0094\3\2\2\2\u027b\u027d"+
"\t\5\2\2\u027c\u027b\3\2\2\2\u027d\u027e\3\2\2\2\u027e\u027c\3\2\2\2\u027e"+
"\u027f\3\2\2\2\u027f\u0280\3\2\2\2\u0280\u0284\7\60\2\2\u0281\u0283\t"+
"\5\2\2\u0282\u0281\3\2\2\2\u0283\u0286\3\2\2\2\u0284\u0282\3\2\2\2\u0284"+
"\u0285\3\2\2\2\u0285\u0096\3\2\2\2\u0286\u0284\3\2\2\2\u0287\u028b\t\6"+
"\2\2\u0288\u028a\t\5\2\2\u0289\u0288\3\2\2\2\u028a\u028d\3\2\2\2\u028b"+
"\u0289\3\2\2\2\u028b\u028c\3\2\2\2\u028c\u0098\3\2\2\2\u028d\u028b\3\2"+
"\2\2\u028e\u028f\7\62\2\2\u028f\u009a\3\2\2\2\u0290\u0296\7)\2\2\u0291"+
"\u0295\n\7\2\2\u0292\u0293\7)\2\2\u0293\u0295\7)\2\2\u0294\u0291\3\2\2"+
"\2\u0294\u0292\3\2\2\2\u0295\u0298\3\2\2\2\u0296\u0294\3\2\2\2\u0296\u0297"+
"\3\2\2\2\u0297\u0299\3\2\2\2\u0298\u0296\3\2\2\2\u0299\u029a\7)\2\2\u029a"+
"\u009c\3\2\2\2\u029b\u029c\t\b\2\2\u029c\u029d\3\2\2\2\u029d\u029e\bO"+
"\2\2\u029e\u009e\3\2\2\2\21\2\u0222\u0229\u022c\u0232\u0263\u026e\u0271"+
"\u0275\u0279\u027e\u0284\u028b\u0294\u0296\3\b\2\2";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
}
}
}
@@ -1,146 +0,0 @@
T__0=1
T__1=2
T__2=3
T__3=4
T__4=5
T__5=6
T__6=7
T__7=8
T__8=9
T__9=10
T__10=11
T__11=12
T__12=13
T__13=14
T__14=15
T__15=16
T__16=17
T__17=18
T__18=19
T__19=20
T__20=21
T__21=22
T__22=23
T__23=24
T__24=25
T__25=26
T__26=27
T__27=28
T__28=29
T__29=30
T__30=31
T__31=32
T__32=33
T__33=34
T__34=35
T__35=36
T__36=37
T__37=38
T__38=39
T__39=40
T__40=41
T__41=42
T__42=43
T__43=44
T__44=45
T__45=46
T__46=47
T__47=48
T__48=49
T__49=50
T__50=51
T__51=52
T__52=53
T__53=54
T__54=55
T__55=56
T__56=57
T__57=58
T__58=59
T__59=60
T__60=61
T__61=62
T__62=63
T__63=64
T__64=65
T__65=66
T__66=67
INPUT_VARIABLE=68
PATH_VARIABLE=69
QUOTED_PATH_VARIABLE=70
PROP_FORMULA=71
BOOLEAN_LITERAL=72
NUMBER_LITERAL=73
DOUBLE=74
INT=75
ZERO=76
STRING_LITERAL=77
WS=78
'('=1
')'=2
'select'=3
'distinct'=4
'where'=5
'order'=6
'by'=7
','=8
'nulls'=9
'first'=10
'last'=11
'asc'=12
'desc'=13
'limit'=14
'offset'=15
'fetch'=16
'+'=17
'query'=18
'lazy'=19
'or'=20
'and'=21
'not'=22
'inOrEmpty'=23
'in'=24
'between'=25
'to'=26
'inrange'=27
'inRange'=28
'is'=29
'null'=30
'isNull'=31
'isNotNull'=32
'notNull'=33
'empty'=34
'isEmpty'=35
'isNotEmpty'=36
'notEmpty'=37
'like'=38
'ilike'=39
'contains'=40
'icontains'=41
'startsWith'=42
'istartsWith'=43
'endsWith'=44
'iendsWith'=45
'='=46
'eq'=47
'>'=48
'gt'=49
'>='=50
'ge'=51
'gte'=52
'<'=53
'lt'=54
'<='=55
'le'=56
'lte'=57
'<>'=58
'!='=59
'ne'=60
'ieq'=61
'ine'=62
'eqOrNull'=63
'gtOrNull'=64
'ltOrNull'=65
'geOrNull'=66
'leOrNull'=67
'0'=76
@@ -1,460 +0,0 @@
// Generated from /home/rob/github/ebean-dir/ebean/src/test/resources/EQL.g4 by ANTLR 4.8
package io.ebeaninternal.server.grammer.antlr;
import org.antlr.v4.runtime.tree.ParseTreeListener;
/**
* This interface defines a complete listener for a parse tree produced by
* {@link EQLParser}.
*/
public interface EQLListener extends ParseTreeListener {
/**
* Enter a parse tree produced by {@link EQLParser#select_statement}.
* @param ctx the parse tree
*/
void enterSelect_statement(EQLParser.Select_statementContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#select_statement}.
* @param ctx the parse tree
*/
void exitSelect_statement(EQLParser.Select_statementContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#select_properties}.
* @param ctx the parse tree
*/
void enterSelect_properties(EQLParser.Select_propertiesContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#select_properties}.
* @param ctx the parse tree
*/
void exitSelect_properties(EQLParser.Select_propertiesContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#select_clause}.
* @param ctx the parse tree
*/
void enterSelect_clause(EQLParser.Select_clauseContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#select_clause}.
* @param ctx the parse tree
*/
void exitSelect_clause(EQLParser.Select_clauseContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#distinct}.
* @param ctx the parse tree
*/
void enterDistinct(EQLParser.DistinctContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#distinct}.
* @param ctx the parse tree
*/
void exitDistinct(EQLParser.DistinctContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#fetch_clause}.
* @param ctx the parse tree
*/
void enterFetch_clause(EQLParser.Fetch_clauseContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#fetch_clause}.
* @param ctx the parse tree
*/
void exitFetch_clause(EQLParser.Fetch_clauseContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#where_clause}.
* @param ctx the parse tree
*/
void enterWhere_clause(EQLParser.Where_clauseContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#where_clause}.
* @param ctx the parse tree
*/
void exitWhere_clause(EQLParser.Where_clauseContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#orderby_clause}.
* @param ctx the parse tree
*/
void enterOrderby_clause(EQLParser.Orderby_clauseContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#orderby_clause}.
* @param ctx the parse tree
*/
void exitOrderby_clause(EQLParser.Orderby_clauseContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#orderby_property}.
* @param ctx the parse tree
*/
void enterOrderby_property(EQLParser.Orderby_propertyContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#orderby_property}.
* @param ctx the parse tree
*/
void exitOrderby_property(EQLParser.Orderby_propertyContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#nulls_firstlast}.
* @param ctx the parse tree
*/
void enterNulls_firstlast(EQLParser.Nulls_firstlastContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#nulls_firstlast}.
* @param ctx the parse tree
*/
void exitNulls_firstlast(EQLParser.Nulls_firstlastContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#asc_desc}.
* @param ctx the parse tree
*/
void enterAsc_desc(EQLParser.Asc_descContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#asc_desc}.
* @param ctx the parse tree
*/
void exitAsc_desc(EQLParser.Asc_descContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#limit_clause}.
* @param ctx the parse tree
*/
void enterLimit_clause(EQLParser.Limit_clauseContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#limit_clause}.
* @param ctx the parse tree
*/
void exitLimit_clause(EQLParser.Limit_clauseContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#offset_clause}.
* @param ctx the parse tree
*/
void enterOffset_clause(EQLParser.Offset_clauseContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#offset_clause}.
* @param ctx the parse tree
*/
void exitOffset_clause(EQLParser.Offset_clauseContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#fetch_path}.
* @param ctx the parse tree
*/
void enterFetch_path(EQLParser.Fetch_pathContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#fetch_path}.
* @param ctx the parse tree
*/
void exitFetch_path(EQLParser.Fetch_pathContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#fetch_property_set}.
* @param ctx the parse tree
*/
void enterFetch_property_set(EQLParser.Fetch_property_setContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#fetch_property_set}.
* @param ctx the parse tree
*/
void exitFetch_property_set(EQLParser.Fetch_property_setContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#fetch_property_group}.
* @param ctx the parse tree
*/
void enterFetch_property_group(EQLParser.Fetch_property_groupContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#fetch_property_group}.
* @param ctx the parse tree
*/
void exitFetch_property_group(EQLParser.Fetch_property_groupContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#fetch_path_path}.
* @param ctx the parse tree
*/
void enterFetch_path_path(EQLParser.Fetch_path_pathContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#fetch_path_path}.
* @param ctx the parse tree
*/
void exitFetch_path_path(EQLParser.Fetch_path_pathContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#fetch_property}.
* @param ctx the parse tree
*/
void enterFetch_property(EQLParser.Fetch_propertyContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#fetch_property}.
* @param ctx the parse tree
*/
void exitFetch_property(EQLParser.Fetch_propertyContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#fetch_query_hint}.
* @param ctx the parse tree
*/
void enterFetch_query_hint(EQLParser.Fetch_query_hintContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#fetch_query_hint}.
* @param ctx the parse tree
*/
void exitFetch_query_hint(EQLParser.Fetch_query_hintContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#fetch_lazy_hint}.
* @param ctx the parse tree
*/
void enterFetch_lazy_hint(EQLParser.Fetch_lazy_hintContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#fetch_lazy_hint}.
* @param ctx the parse tree
*/
void exitFetch_lazy_hint(EQLParser.Fetch_lazy_hintContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#fetch_option}.
* @param ctx the parse tree
*/
void enterFetch_option(EQLParser.Fetch_optionContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#fetch_option}.
* @param ctx the parse tree
*/
void exitFetch_option(EQLParser.Fetch_optionContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#fetch_query_option}.
* @param ctx the parse tree
*/
void enterFetch_query_option(EQLParser.Fetch_query_optionContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#fetch_query_option}.
* @param ctx the parse tree
*/
void exitFetch_query_option(EQLParser.Fetch_query_optionContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#fetch_lazy_option}.
* @param ctx the parse tree
*/
void enterFetch_lazy_option(EQLParser.Fetch_lazy_optionContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#fetch_lazy_option}.
* @param ctx the parse tree
*/
void exitFetch_lazy_option(EQLParser.Fetch_lazy_optionContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#fetch_batch_size}.
* @param ctx the parse tree
*/
void enterFetch_batch_size(EQLParser.Fetch_batch_sizeContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#fetch_batch_size}.
* @param ctx the parse tree
*/
void exitFetch_batch_size(EQLParser.Fetch_batch_sizeContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#conditional_expression}.
* @param ctx the parse tree
*/
void enterConditional_expression(EQLParser.Conditional_expressionContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#conditional_expression}.
* @param ctx the parse tree
*/
void exitConditional_expression(EQLParser.Conditional_expressionContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#conditional_term}.
* @param ctx the parse tree
*/
void enterConditional_term(EQLParser.Conditional_termContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#conditional_term}.
* @param ctx the parse tree
*/
void exitConditional_term(EQLParser.Conditional_termContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#conditional_factor}.
* @param ctx the parse tree
*/
void enterConditional_factor(EQLParser.Conditional_factorContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#conditional_factor}.
* @param ctx the parse tree
*/
void exitConditional_factor(EQLParser.Conditional_factorContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#conditional_primary}.
* @param ctx the parse tree
*/
void enterConditional_primary(EQLParser.Conditional_primaryContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#conditional_primary}.
* @param ctx the parse tree
*/
void exitConditional_primary(EQLParser.Conditional_primaryContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#any_expression}.
* @param ctx the parse tree
*/
void enterAny_expression(EQLParser.Any_expressionContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#any_expression}.
* @param ctx the parse tree
*/
void exitAny_expression(EQLParser.Any_expressionContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#inOrEmpty_expression}.
* @param ctx the parse tree
*/
void enterInOrEmpty_expression(EQLParser.InOrEmpty_expressionContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#inOrEmpty_expression}.
* @param ctx the parse tree
*/
void exitInOrEmpty_expression(EQLParser.InOrEmpty_expressionContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#in_expression}.
* @param ctx the parse tree
*/
void enterIn_expression(EQLParser.In_expressionContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#in_expression}.
* @param ctx the parse tree
*/
void exitIn_expression(EQLParser.In_expressionContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#in_value}.
* @param ctx the parse tree
*/
void enterIn_value(EQLParser.In_valueContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#in_value}.
* @param ctx the parse tree
*/
void exitIn_value(EQLParser.In_valueContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#between_expression}.
* @param ctx the parse tree
*/
void enterBetween_expression(EQLParser.Between_expressionContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#between_expression}.
* @param ctx the parse tree
*/
void exitBetween_expression(EQLParser.Between_expressionContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#inrange_expression}.
* @param ctx the parse tree
*/
void enterInrange_expression(EQLParser.Inrange_expressionContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#inrange_expression}.
* @param ctx the parse tree
*/
void exitInrange_expression(EQLParser.Inrange_expressionContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#inrange_op}.
* @param ctx the parse tree
*/
void enterInrange_op(EQLParser.Inrange_opContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#inrange_op}.
* @param ctx the parse tree
*/
void exitInrange_op(EQLParser.Inrange_opContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#propertyBetween_expression}.
* @param ctx the parse tree
*/
void enterPropertyBetween_expression(EQLParser.PropertyBetween_expressionContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#propertyBetween_expression}.
* @param ctx the parse tree
*/
void exitPropertyBetween_expression(EQLParser.PropertyBetween_expressionContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#isNull_expression}.
* @param ctx the parse tree
*/
void enterIsNull_expression(EQLParser.IsNull_expressionContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#isNull_expression}.
* @param ctx the parse tree
*/
void exitIsNull_expression(EQLParser.IsNull_expressionContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#isNotNull_expression}.
* @param ctx the parse tree
*/
void enterIsNotNull_expression(EQLParser.IsNotNull_expressionContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#isNotNull_expression}.
* @param ctx the parse tree
*/
void exitIsNotNull_expression(EQLParser.IsNotNull_expressionContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#isEmpty_expression}.
* @param ctx the parse tree
*/
void enterIsEmpty_expression(EQLParser.IsEmpty_expressionContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#isEmpty_expression}.
* @param ctx the parse tree
*/
void exitIsEmpty_expression(EQLParser.IsEmpty_expressionContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#isNotEmpty_expression}.
* @param ctx the parse tree
*/
void enterIsNotEmpty_expression(EQLParser.IsNotEmpty_expressionContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#isNotEmpty_expression}.
* @param ctx the parse tree
*/
void exitIsNotEmpty_expression(EQLParser.IsNotEmpty_expressionContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#like_expression}.
* @param ctx the parse tree
*/
void enterLike_expression(EQLParser.Like_expressionContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#like_expression}.
* @param ctx the parse tree
*/
void exitLike_expression(EQLParser.Like_expressionContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#like_op}.
* @param ctx the parse tree
*/
void enterLike_op(EQLParser.Like_opContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#like_op}.
* @param ctx the parse tree
*/
void exitLike_op(EQLParser.Like_opContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#comparison_expression}.
* @param ctx the parse tree
*/
void enterComparison_expression(EQLParser.Comparison_expressionContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#comparison_expression}.
* @param ctx the parse tree
*/
void exitComparison_expression(EQLParser.Comparison_expressionContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#comparison_operator}.
* @param ctx the parse tree
*/
void enterComparison_operator(EQLParser.Comparison_operatorContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#comparison_operator}.
* @param ctx the parse tree
*/
void exitComparison_operator(EQLParser.Comparison_operatorContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#value_expression}.
* @param ctx the parse tree
*/
void enterValue_expression(EQLParser.Value_expressionContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#value_expression}.
* @param ctx the parse tree
*/
void exitValue_expression(EQLParser.Value_expressionContext ctx);
/**
* Enter a parse tree produced by {@link EQLParser#literal}.
* @param ctx the parse tree
*/
void enterLiteral(EQLParser.LiteralContext ctx);
/**
* Exit a parse tree produced by {@link EQLParser#literal}.
* @param ctx the parse tree
*/
void exitLiteral(EQLParser.LiteralContext ctx);
}
File diff suppressed because it is too large Load Diff
@@ -1,283 +0,0 @@
// Generated from /home/rob/github/ebean-dir/ebean/src/test/resources/EQL.g4 by ANTLR 4.8
package io.ebeaninternal.server.grammer.antlr;
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
/**
* This interface defines a complete generic visitor for a parse tree produced
* by {@link EQLParser}.
*
* @param <T> The return type of the visit operation. Use {@link Void} for
* operations with no return type.
*/
public interface EQLVisitor<T> extends ParseTreeVisitor<T> {
/**
* Visit a parse tree produced by {@link EQLParser#select_statement}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitSelect_statement(EQLParser.Select_statementContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#select_properties}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitSelect_properties(EQLParser.Select_propertiesContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#select_clause}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitSelect_clause(EQLParser.Select_clauseContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#distinct}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitDistinct(EQLParser.DistinctContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#fetch_clause}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFetch_clause(EQLParser.Fetch_clauseContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#where_clause}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitWhere_clause(EQLParser.Where_clauseContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#orderby_clause}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitOrderby_clause(EQLParser.Orderby_clauseContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#orderby_property}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitOrderby_property(EQLParser.Orderby_propertyContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#nulls_firstlast}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitNulls_firstlast(EQLParser.Nulls_firstlastContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#asc_desc}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitAsc_desc(EQLParser.Asc_descContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#limit_clause}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitLimit_clause(EQLParser.Limit_clauseContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#offset_clause}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitOffset_clause(EQLParser.Offset_clauseContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#fetch_path}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFetch_path(EQLParser.Fetch_pathContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#fetch_property_set}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFetch_property_set(EQLParser.Fetch_property_setContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#fetch_property_group}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFetch_property_group(EQLParser.Fetch_property_groupContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#fetch_path_path}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFetch_path_path(EQLParser.Fetch_path_pathContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#fetch_property}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFetch_property(EQLParser.Fetch_propertyContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#fetch_query_hint}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFetch_query_hint(EQLParser.Fetch_query_hintContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#fetch_lazy_hint}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFetch_lazy_hint(EQLParser.Fetch_lazy_hintContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#fetch_option}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFetch_option(EQLParser.Fetch_optionContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#fetch_query_option}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFetch_query_option(EQLParser.Fetch_query_optionContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#fetch_lazy_option}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFetch_lazy_option(EQLParser.Fetch_lazy_optionContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#fetch_batch_size}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitFetch_batch_size(EQLParser.Fetch_batch_sizeContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#conditional_expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitConditional_expression(EQLParser.Conditional_expressionContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#conditional_term}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitConditional_term(EQLParser.Conditional_termContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#conditional_factor}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitConditional_factor(EQLParser.Conditional_factorContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#conditional_primary}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitConditional_primary(EQLParser.Conditional_primaryContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#any_expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitAny_expression(EQLParser.Any_expressionContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#inOrEmpty_expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitInOrEmpty_expression(EQLParser.InOrEmpty_expressionContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#in_expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitIn_expression(EQLParser.In_expressionContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#in_value}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitIn_value(EQLParser.In_valueContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#between_expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitBetween_expression(EQLParser.Between_expressionContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#inrange_expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitInrange_expression(EQLParser.Inrange_expressionContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#inrange_op}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitInrange_op(EQLParser.Inrange_opContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#propertyBetween_expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitPropertyBetween_expression(EQLParser.PropertyBetween_expressionContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#isNull_expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitIsNull_expression(EQLParser.IsNull_expressionContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#isNotNull_expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitIsNotNull_expression(EQLParser.IsNotNull_expressionContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#isEmpty_expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitIsEmpty_expression(EQLParser.IsEmpty_expressionContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#isNotEmpty_expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitIsNotEmpty_expression(EQLParser.IsNotEmpty_expressionContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#like_expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitLike_expression(EQLParser.Like_expressionContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#like_op}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitLike_op(EQLParser.Like_opContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#comparison_expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitComparison_expression(EQLParser.Comparison_expressionContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#comparison_operator}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitComparison_operator(EQLParser.Comparison_operatorContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#value_expression}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitValue_expression(EQLParser.Value_expressionContext ctx);
/**
* Visit a parse tree produced by {@link EQLParser#literal}.
* @param ctx the parse tree
* @return the visitor result
*/
T visitLiteral(EQLParser.LiteralContext ctx);
}
@@ -25,7 +25,6 @@ module io.ebean.core {
requires transitive io.ebean.xmapping.api;
requires transitive io.ebean.core.type;
requires transitive io.ebean.ddl.runner;
requires org.antlr.antlr4.runtime;
requires io.avaje.classpath.scanner.api;
requires io.avaje.classpath.scanner;
requires io.ebean.types;
@@ -187,42 +187,6 @@ public abstract class TQAssocBean<T, R, QB> extends TQAssoc<T, R> {
return _root;
}
/**
* Deprecated for removal - migrate to filterManyRaw()
* <p>
* Apply a filter when fetching these beans.
* <p>
* The expressions can use any valid Ebean expression and contain
* placeholders for bind values using <code>?</code> or <code>?1</code> style.
* </p>
*
* <pre>{@code
*
* new QCustomer()
* .name.startsWith("Postgres")
* .contacts.filterMany("firstName istartsWith ?", "Rob")
* .findList();
*
* }</pre>
*
* <pre>{@code
*
* new QCustomer()
* .name.startsWith("Postgres")
* .contacts.filterMany("whenCreated inRange ? to ?", startDate, endDate)
* .findList();
*
* }</pre>
*
* @param expressions The expressions including and, or, not etc with ? and ?1 bind params.
* @param params The bind parameter values
*/
@Deprecated(forRemoval = true)
public final R filterMany(String expressions, Object... params) {
expr().filterMany(_name, expressions, params);
return _root;
}
/**
* Add filter expressions for the many path. The expressions can include SQL functions if
* desired and the property names are translated to column names.
@@ -606,7 +606,7 @@ public class QCustomerTest {
new QCustomer()
.name.startsWith("Postgres")
.contacts.filterMany("firstName istartsWith ?", "Rob")
.contacts.filterManyRaw("lower(firstName) like ?", "rob%")
.findList();
final LocalDate startDate = LocalDate.now().minusDays(7);
@@ -614,7 +614,7 @@ public class QCustomerTest {
new QCustomer()
.name.startsWith("Postgres")
.contacts.filterMany("whenCreated inRange ? to ?", startDate, endDate)
.contacts.filterManyRaw("whenCreated <= ? and whenCreated > ?", startDate, endDate)
.findList();
}
@@ -22,7 +22,7 @@ public class EbeanServer_eqlTest extends BaseTestCase {
ResetBasicData.reset();
Query<Customer> query = server().createQuery(Customer.class, "order by id limit 10");
Query<Customer> query = server().createQuery(Customer.class).orderBy("id").setMaxRows(10);
query.setMaxRows(100);
query.findList();
@@ -41,7 +41,7 @@ public class EbeanServer_eqlTest extends BaseTestCase {
ResetBasicData.reset();
Query<Customer> query = DB.createQuery(Customer.class, "order by id limit 10");
Query<Customer> query = server().createQuery(Customer.class).orderBy("id").setMaxRows(10);
query.findList();
if (isSqlServer()) {
@@ -59,7 +59,7 @@ public class EbeanServer_eqlTest extends BaseTestCase {
ResetBasicData.reset();
Query<Customer> query = DB.createQuery(Customer.class, "order by id limit 10 offset 3");
Query<Customer> query = server().createQuery(Customer.class).orderBy("id").setMaxRows(10).setFirstRow(3);
query.findList();
if (isSqlServer()) {
@@ -77,7 +77,7 @@ public class EbeanServer_eqlTest extends BaseTestCase {
ResetBasicData.reset();
Query<Customer> query = DB.createQuery(Customer.class, "order by name");
Query<Customer> query = server().createQuery(Customer.class).orderBy("name");
query.setMaxRows(10);
query.setFirstRow(3);
query.findList();
@@ -102,7 +102,7 @@ public class EbeanServer_eqlTest extends BaseTestCase {
ResetBasicData.reset();
Query<Customer> query = DB.createQuery(Customer.class, "order by name");
Query<Customer> query = server().createQuery(Customer.class).orderBy("name");
query.setMaxRows(10);
query.setFirstRow(3);
query.orderById(true);
@@ -169,7 +169,7 @@ public class EbeanServer_eqlTest extends BaseTestCase {
ResetBasicData.reset();
Query<Customer> query = server().createQuery(Customer.class, "order by id");
Query<Customer> query = server().createQuery(Customer.class).orderBy("id");
// use clear() and then effectively override the orderBy clause
query.orderBy().clear().asc("name");
@@ -184,54 +184,14 @@ public class EbeanServer_eqlTest extends BaseTestCase {
ResetBasicData.reset();
Query<Customer> query = server().createQuery(Customer.class, "where name startsWith :name order by name");
query.setParameter("name", "Ro");
Query<Customer> query = server().createQuery(Customer.class)
.where().startsWith("name", "Ro")
.orderBy("name")
.query();
query.findList();
assertSql(query).contains("where t0.name like ");
}
@Test
public void unboundNamedParams_expect_PersistenceException() {
Query<Customer> query = server().createQuery(Customer.class, "where name = :name");
assertThrows(PersistenceException.class, () ->query.findOne());
}
@Test
public void namedQuery() {
ResetBasicData.reset();
Query<Customer> name = server().createNamedQuery(Customer.class, "name");
name.findList();
assertThat(sqlOf(name, 1)).contains("select t0.id, t0.name from o_customer t0 order by t0.name");
}
@Test
public void namedQuery_withStatus() {
ResetBasicData.reset();
Query<Customer> name = server().createNamedQuery(Customer.class, "withStatus");
name.order().clear().asc("status");
name.findList();
assertThat(sqlOf(name, 2)).contains("select t0.id, t0.name, t0.status from o_customer t0 order by t0.status");
}
@Test
public void namedQuery_withContacts() {
ResetBasicData.reset();
Query<Customer> query = server()
.createNamedQuery(Customer.class, "withContacts")
.setParameter("id", 1);
query.setUseCache(false);
query.findOne();
assertSql(query).contains("from o_customer t0 left join contact t1 on t1.customer_id = t0.id ");
}
}
@@ -355,17 +355,6 @@ public class TDSpiEbeanServer extends TDSpiServer implements SpiEbeanServer {
return null;
}
@Override
public <T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery) {
return null;
}
@Override
public <T> Query<T> createQuery(Class<T> beanType, String eql) {
return null;
}
@Override
public <T> SpiQuery<T> createQuery(Class<T> beanType) {
return null;
@@ -108,21 +108,11 @@ public class TDSpiServer implements SpiServer {
return null;
}
@Override
public <T> Query<T> createNamedQuery(Class<T> beanType, String namedQuery) {
return null;
}
@Override
public <T> Query<T> createQuery(Class<T> beanType) {
return null;
}
@Override
public <T> Query<T> createQuery(Class<T> beanType, String ormQuery) {
return null;
}
@Override
public <T> Query<T> find(Class<T> beanType) {
return null;
@@ -1,805 +0,0 @@
package io.ebean.xtest.internal.server.grammer;
import io.ebean.xtest.BaseTestCase;
import io.ebean.DB;
import io.ebean.Query;
import io.ebean.xtest.ForPlatform;
import io.ebean.xtest.IgnorePlatform;
import io.ebean.annotation.Platform;
import io.ebean.test.LoggedSql;
import io.ebeaninternal.api.SpiQuery;
import io.ebeaninternal.server.grammer.EqlParser;
import org.junit.jupiter.api.Test;
import org.tests.model.basic.Customer;
import org.tests.model.basic.OrderDetail;
import org.tests.model.basic.ResetBasicData;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
class EqlParserTest extends BaseTestCase {
@Test
void illegal_syntax() {
assertThrows(IllegalArgumentException.class, () -> parse("find Article where name = :p0"));
}
@Test
void where_eq() {
Query<Customer> query = parse("where name eq 'Rob'");
query.findList();
assertSql(query).contains("where t0.name = ?");
}
@Test
void where_eqOrNull_bindVal() {
Query<Customer> query = parse("where name eqOrNull 'Rob'");
query.findList();
assertSql(query).contains("where (t0.name = ? or t0.name is null)");
}
@Test
void where_eqOrNull_bindNamed() {
Query<Customer> query = parse("where name eqOrNull :name");
query.setParameter("name", "Rob");
query.findList();
assertSql(query).contains("where (t0.name = ? or t0.name is null)");
}
@Test
void where_eqOrNull_bindPositioned() {
final Query<Customer> query = where("name eqOrNull ?", "Rob");
query.findList();
if (isH2()) {
assertSql(query).contains("where (t0.name = ? or t0.name is null)");
}
}
@Test
void where_eqOrNull_bindPositioned_asNull() {
final Query<Customer> query = where("name eqOrNull ?", (String)null);
query.findList();
if (isH2()) {
assertSql(query).contains("(t0.name is null or t0.name is null)");
}
}
@Test
void where_gtOrNull_bindPositioned() {
final Query<Customer> query = where("name gtOrNull ?", "Rob");
query.findList();
if (isH2()) {
assertSql(query).contains("where (t0.name > ? or t0.name is null)");
}
}
@Test
void where_geOrNull_bindPositioned() {
final Query<Customer> query = where("name geOrNull ?", "Rob");
query.findList();
if (isH2()) {
assertSql(query).contains("where (t0.name >= ? or t0.name is null)");
}
}
@Test
void where_ltOrNull_bindPositioned() {
final Query<Customer> query = where("name ltOrNull ?", "Rob");
query.findList();
if (isH2()) {
assertSql(query).contains("where (t0.name < ? or t0.name is null)");
}
}
@Test
void where_leOrNull_bindPositioned() {
final Query<Customer> query = where("name leOrNull ?", "Rob");
query.findList();
if (isH2()) {
assertSql(query).contains("where (t0.name <= ? or t0.name is null)");
}
}
@Test
void where_eq_reverse() {
Query<Customer> query = parse("where 'Rob' eq name");
query.findList();
assertSql(query).contains("where t0.name = ?");
}
@Test
void where_gt_reverse() {
Query<Customer> query = parse("where 'Rob' > name");
query.findList();
assertSql(query).contains("where t0.name < ?");
}
@Test
void where_gte_reverse() {
Query<Customer> query = parse("where 'Rob' >= name");
query.findList();
assertSql(query).contains("where t0.name <= ?");
}
@Test
void where_lt_reverse() {
Query<Customer> query = parse("where 'Rob' < name");
query.findList();
assertSql(query).contains("where t0.name > ?");
}
@Test
void where_lte_reverse() {
Query<Customer> query = parse("where 'Rob' <= name");
query.findList();
assertSql(query).contains("where t0.name >= ?");
}
@Test
void where_ieq() {
Query<Customer> query = parse("where name ieq 'Rob'");
query.findList();
assertSql(query).contains("where lower(t0.name) = ?");
}
@Test
void where_ine() {
Query<Customer> query = parse("where name ine 'Rob'");
query.findList();
assertSql(query).contains("where lower(t0.name) != ?");
}
@Test
void where_ieq_reverse() {
Query<Customer> query = parse("where 'Rob' ieq name");
query.findList();
assertSql(query).contains("where lower(t0.name) = ?");
}
@Test
void where_ine_reverse() {
Query<Customer> query = parse("where 'Rob' ine name");
query.findList();
assertSql(query).contains("where lower(t0.name) != ?");
}
@Test
void where_eq2() {
Query<Customer> query = parse("where name = 'Rob'");
query.findList();
assertSql(query).contains("where t0.name = ?");
}
@Test
void where_namedParam() {
Query<Customer> query = parse("where name eq :name");
query.setParameter("name", "Rob");
query.findList();
assertSql(query).contains("where t0.name = ?");
}
@Test
void where_namedParam_otherOrder() {
Query<Customer> query = parse("where :nm < name");
query.setParameter("nm", "Rob");
query.findList();
assertSql(query).contains("where t0.name > ?");
}
@Test
void where_namedParam_startsWith() {
Query<Customer> query = parse("where name startsWith :name");
query.setParameter("name", "Rob");
query.findList();
assertSql(query).contains("where t0.name like ");
}
@Test
@IgnorePlatform({Platform.HANA, Platform.DB2}) // The HANA JDBC driver checks the field length on binding and rejects 'NEW'
void where_or1() {
Query<Customer> query = parse("where name = 'Rob' or (status = 'NEW' and smallnote is null)");
query.findList();
assertSql(query).contains("where (t0.name = ? or (t0.status = ? and t0.smallnote is null))");
}
@Test
@ForPlatform({Platform.HANA, Platform.DB2})
void where_or1_hana() {
Query<Customer> query = parse("where name = 'Rob' or (status = 'N' and smallnote is null)");
query.findList();
assertSql(query).contains("where (t0.name = ? or (t0.status = ? and t0.smallnote is null))");
}
@Test
@IgnorePlatform({Platform.HANA, Platform.DB2}) // The HANA & DB2 JDBC driver checks the field length on binding and rejects 'NEW'
void where_or2() {
Query<Customer> query = parse("where (name = 'Rob' or status = 'NEW') and smallnote is null");
query.findList();
assertSql(query).contains("where ((t0.name = ? or t0.status = ?) and t0.smallnote is null)");
}
@Test
@ForPlatform({Platform.HANA, Platform.DB2})
void where_or2_hana() {
Query<Customer> query = parse("where (name = 'Rob' or status = 'N') and smallnote is null");
query.findList();
assertSql(query).contains("where ((t0.name = ? or t0.status = ?) and t0.smallnote is null)");
}
@Test
@IgnorePlatform({Platform.HANA, Platform.DB2}) // The HANA & DB2 JDBC driver checks the field length on binding and rejects 'NEW'
void test_simplifyExpressions() {
Query<Customer> query = parse("where not (name = 'Rob' and status = 'NEW')");
query.findList();
assertSql(query).contains("where not (t0.name = ? and t0.status = ?)");
query = parse("where not ((name = 'Rob' and status = 'NEW'))");
query.findList();
assertSql(query).contains("where not (t0.name = ? and t0.status = ?)");
query = parse("where not (((name = 'Rob') and (status = 'NEW')))");
query.findList();
assertSql(query).contains("where not (t0.name = ? and t0.status = ?)");
}
@Test
@ForPlatform({Platform.HANA, Platform.DB2})
void test_simplifyExpressions_hana() {
Query<Customer> query = parse("where not (name = 'Rob' and status = 'N')");
query.findList();
assertSql(query).contains("where not (t0.name = ? and t0.status = ?)");
query = parse("where not ((name = 'Rob' and status = 'N'))");
query.findList();
assertSql(query).contains("where not (t0.name = ? and t0.status = ?)");
query = parse("where not (((name = 'Rob') and (status = 'N')))");
query.findList();
assertSql(query).contains("where not (t0.name = ? and t0.status = ?)");
}
@Test
void where_in() {
Query<Customer> query = parse("where name in ('Rob','Jim')");
query.findList();
platformAssertIn(query.getGeneratedSql(), "where t0.name");
}
@Test
void where_in_when_namedParams() {
Query<Customer> query = parse("where name in (:one, :two)");
query.setParameter("one", "Foo");
query.setParameter("two", "Bar");
query.findList();
platformAssertIn(query.getGeneratedSql(), "where t0.name");
}
@Test
void where_in_when_namedParams_withWhitespace() {
Query<Customer> query = parse("where name in (:one, :two)");
query.setParameter("one", "Foo");
query.setParameter("two", "Bar");
query.findList();
platformAssertIn(query.getGeneratedSql(), "where t0.name");
}
@Test
void where_in_when_namedParams_withNoWhitespace() {
Query<Customer> query = parse("where name in (:one,:two)");
query.setParameter("one", "Foo");
query.setParameter("two", "Bar");
query.findList();
platformAssertIn(query.getGeneratedSql(), "where t0.name");
}
@Test
void where_in_when_namedParamAsList() {
Query<Customer> query = parse("where name in (:names)");
query.setParameter("names", Arrays.asList("Baz", "Maz", "Jim"));
query.findList();
platformAssertIn(query.getGeneratedSql(), "where t0.name");
}
@Test
void where_inOrEmpty_withVals() {
final Query<Customer> query = where("name inOrEmpty ?", Arrays.asList("Baz", "Maz", "Jim"));
query.findList();
platformAssertIn(query.getGeneratedSql(), "where t0.name");
}
@Test
void where_inOrEmpty_withValsAsSet() {
final Query<Customer> query = where("name inOrEmpty ?", new HashSet<>(Arrays.asList("Baz", "Maz", "Jim")));
query.findList();
platformAssertIn(query.getGeneratedSql(), "where t0.name");
}
@Test
void where_inOrEmpty_withEmpty() {
final Query<Customer> query = where("name inOrEmpty ?", new ArrayList());
query.findList();
assertSql(query).doesNotContain("where");
}
@Test
void where_inOrEmpty_withNull() {
List<String> names = null;
final Query<Customer> query = where("name inOrEmpty ?", names);
query.findList();
assertSql(query).doesNotContain("where");
}
@Test
void query_inOrEmpty_withVals() {
assertThrows(IllegalArgumentException.class, () -> parse("where name inOrEmpty (:names)"));
}
/**
* This test fails in that we can't use inOrEmpty with named parameters.
*/
@Test
void query_inOrEmpty_withNamedParams_expect_IllegalArgument() {
assertThrows(IllegalArgumentException.class, () -> parse("where name inOrEmpty (:names)"));
}
@Test
void where_inrange() {
Query<Customer> query = parse("where name inrange 'As' to 'B'");
query.findList();
assertSql(query).contains("where (t0.name >= ? and t0.name < ?)");
}
@Test
void where_inrange_withNamedParams() {
Query<Customer> query = parse("where name inrange :one to :two");
query.setParameter("one", "a");
query.setParameter("two", "b");
query.findList();
assertSql(query).contains("where (t0.name >= ? and t0.name < ?)");
}
@Test
void where_between() {
Query<Customer> query = parse("where name between 'As' and 'B'");
query.findList();
assertSql(query).contains("where t0.name between ? and ?");
}
@Test
void where_between_withNamedParams() {
Query<Customer> query = parse("where name between :one and :two");
query.setParameter("one", "a");
query.setParameter("two", "b");
query.findList();
assertSql(query).contains("where t0.name between ? and ?");
}
@Test
void where_betweenProperty() {
Query<Customer> query = parse("where 'x' between name and smallnote");
query.findList();
assertSql(query).contains("where ? between t0.name and t0.smallnote");
}
@Test
void where_betweenProperty_withNamed() {
Query<Customer> query = parse("where :some between name and smallnote");
query.setParameter("some", "A");
query.findList();
assertSql(query).contains("where ? between t0.name and t0.smallnote");
}
@Test
void selectFetch_basic() {
Query<Customer> query = parse("select name fetch billingAddress");
query.findList();
assertSql(query).contains("select t0.id, t0.name, t1.id, t1.line_1, t1.line_2, t1.city, t1.cretime, t1.updtime, t1.country_code from o_customer t0 left join o_address t1 on t1.id = t0.billing_address_id");
}
@Test
void selectFetch_basic2() {
ResetBasicData.reset();
Query<Customer> query = parse("select name, status fetch billingAddress");
query.findList();
assertSql(query).contains("select t0.id, t0.name, t0.status, t1.id, t1.line_1, t1.line_2, t1.city, t1.cretime, t1.updtime, t1.country_code from o_customer t0 left join o_address t1 on t1.id = t0.billing_address_id");
}
@Test
void selectFetch_withProperties() {
Query<Customer> query = parse("select name fetch billingAddress (line1, city) ");
query.findList();
assertSql(query, 12).contains("select t0.id, t0.name, t1.id, t1.line_1, t1.city from o_customer t0 left join o_address t1 on t1.id = t0.billing_address_id");
}
@Test
@IgnorePlatform(Platform.SQLSERVER)
void selectFetchFetchLimit() {
Query<Customer> query = parse("select name fetch billingAddress (line1, city) fetch shippingAddress (line1) limit 10");
query.findList();
assertSql(query, 12).contains("select t0.id, t0.name, t1.id, t1.line_1, t1.city, t2.id, t2.line_1 from o_customer t0 left join o_address t1 on t1.id = t0.billing_address_id left join o_address t2 on t2.id = t0.shipping_address_id");
}
@Test
void selectFetchFetchMany() {
Query<Customer> query = parse("select name fetch billingAddress (line1, city) fetch contacts");
query.findList();
assertSql(query, 16).contains("select t0.id, t0.name, t1.id, t1.line_1, t1.city, t2.id, t2.first_name, t2.last_name, t2.phone, t2.mobile, t2.email, t2.is_member, t2.cretime, t2.updtime, t2.customer_id, t2.group_id from o_customer t0");
}
@Test
void selectFetchFetchManyProperties() {
Query<Customer> query = parse("select name fetch billingAddress (line1, city) fetch contacts (email)");
query.findList();
assertSql(query, 12).contains("select t0.id, t0.name, t1.id, t1.line_1, t1.city, t2.id, t2.email from o_customer t0");
}
@Test
@IgnorePlatform(Platform.SQLSERVER)
void selectFetchFetchManyPropertiesLimit() {
ResetBasicData.reset();
LoggedSql.start();
Query<Customer> query = parse("select name fetch billingAddress (line1, city) fetch contacts (email) limit 10");
query.findList();
List<String> sql = LoggedSql.stop();
assertThat(sql).hasSize(2);
assertSql(sql.get(0)).contains("select t0.id, t0.name, t1.id, t1.line_1, t1.city from o_customer t0 left join o_address");
assertSql(sql.get(1)).contains("select t0.customer_id, t0.id, t0.email from contact t0 where (t0.customer_id)");
}
@Test
void fetch_basic() {
Query<Customer> query = parse("fetch billingAddress");
query.findList();
assertSql(query).contains(", t1.id");
}
@Test
void fetch_withProperty() {
Query<Customer> query = parse("fetch billingAddress (city)");
query.findList();
assertSql(query, 10).contains(", t1.id, t1.city");
}
@Test
void fetch_withProperty_noWhitespace() {
Query<Customer> query = parse("fetch billingAddress(city)");
query.findList();
assertSql(query, 10).contains(", t1.id, t1.city");
}
@Test
void fetch_basic_multiple() {
Query<Customer> query = parse("fetch billingAddress fetch shippingAddress");
query.findList();
assertSql(query).contains(", t1.city");
assertSql(query).contains(", t2.city");
}
@Test
void fetch_basic_multiple_withProperties() {
Query<Customer> query = parse("fetch billingAddress (city) fetch shippingAddress (city)");
query.findList();
assertSql(query, 12).contains(", t1.id, t1.city, t2.id, t2.city");
}
@Test
void fetch_lazy() {
Query<Customer> query = parse("fetch lazy billingAddress");
query.findList();
assertSql(query).doesNotContain(", t1.city");
}
@Test
void fetch_lazy50() {
Query<Customer> query = parse("fetch lazy(50) billingAddress");
query.findList();
assertSql(query).doesNotContain(", t1.city");
}
@Test
void fetch_query50() {
ResetBasicData.reset();
Query<Customer> query = parse("fetch query(50) billingAddress");
query.findList();
assertSql(query).doesNotContain(", t1.city");
}
@Test
void fetch_query50_asHint() {
ResetBasicData.reset();
Query<Customer> query = parse("fetch query(50) billingAddress (city)");
query.findList();
assertSql(query).doesNotContain(", t1.city");
}
@Test
void fetch_lazy50_asHint() {
ResetBasicData.reset();
Query<Customer> query = parse("fetch lazy(50) billingAddress (city) order by id");
List<Customer> list = query.findList();
assertSql(query).doesNotContain(", t1.city");
Customer customer = list.get(0);
customer.getBillingAddress().getCity();
}
@Test
void select() {
ResetBasicData.reset();
Query<Customer> query = parse("select (name)");
query.findList();
assertSql(query).contains("select t0.id, t0.name from o_customer t0");
Query<Customer> query2 = parse("select name");
query2.findList();
assertSql(query2).contains("select t0.id, t0.name from o_customer t0");
}
@Test
void select_sum() {
ResetBasicData.reset();
Query<Customer> query = parse("select (sum(id))");
query.findSingleAttribute();
assertSql(query).contains("select sum(t0.id) from o_customer t0");
}
@Test
void select_max() {
ResetBasicData.reset();
Query<Customer> query = parse("select (max(cretime))");
query.findSingleAttribute();
assertSql(query).contains("select max(t0.cretime) from o_customer t0");
Query<Customer> query2 = parse("select max(cretime)");
query2.findSingleAttribute();
assertSql(query2).contains("select max(t0.cretime) from o_customer t0");
}
@Test
void select_agg() {
ResetBasicData.reset();
Query<Customer> query = parse("select status, max(cretime)");
List<Customer> customers = query.findList();
assertThat(customers).isNotEmpty();
assertSql(query).contains("select t0.status, max(t0.cretime) from o_customer t0 group by t0.status");
}
@Test
void select_agg_sum() {
ResetBasicData.reset();
Query<OrderDetail> query = DB.createQuery(OrderDetail.class, "select sum(orderQty) fetch `order` (id)");
List<OrderDetail> details = query.findList();
assertThat(details).isNotEmpty();
assertSql(query).contains("select sum(t0.order_qty), t1.id from o_order_detail t0 join o_order t1 on t1.id = t0.order_id group by t1.id");
}
@Test
void selectDistinct() {
ResetBasicData.reset();
Query<Customer> query = parse("select distinct (name)");
query.findList();
assertSql(query).contains("select distinct t0.name from o_customer t0");
}
@Test
void limit() {
ResetBasicData.reset();
Query<Customer> query = parse("limit 10");
query.findList();
if (isH2()) {
assertSql(query).contains(" limit 10");
}
}
@Test
void limitOffset() {
ResetBasicData.reset();
Query<Customer> query = parse("order by name limit 10 offset 5");
query.findList();
if (isH2()) {
assertSql(query).contains(" limit 10 offset 5");
}
}
@Test
void orderBy() {
ResetBasicData.reset();
Query<Customer> query = parse("order by id");
query.findList();
if (isH2()) {
assertSql(query).contains("from o_customer t0 order by t0.id");
}
}
@Test
void orderBy_desc() {
ResetBasicData.reset();
Query<Customer> query = parse("order by id desc");
query.findList();
if (isH2()) {
assertSql(query).contains("from o_customer t0 order by t0.id desc");
}
}
@Test
void orderBy_nullsLast() {
if (!isPlatformOrderNullsSupport()) {
return;
}
ResetBasicData.reset();
Query<Customer> query = parse("order by id desc nulls last");
query.findList();
if (isH2()) {
assertSql(query).contains(" from o_customer t0 order by t0.id desc nulls last");
}
}
@Test
void orderBy_nullsFirst() {
if (!isPlatformOrderNullsSupport()) {
return;
}
ResetBasicData.reset();
Query<Customer> query = parse("order by id nulls first");
query.findList();
if (isH2()) {
assertSql(query).contains(" from o_customer t0 order by t0.id nulls first");
}
}
@Test
void orderBy_multiple() {
if (!isPlatformOrderNullsSupport()) {
return;
}
ResetBasicData.reset();
Query<Customer> query = parse("order by billingAddress.city desc nulls last, name, id desc nulls last");
query.findList();
if (isH2()) {
assertSql(query).contains(" order by t1.city desc nulls last, t0.name, t0.id desc nulls last");
}
}
private Query<Customer> parse(String raw) {
Query<Customer> query = DB.find(Customer.class);
EqlParser.parse(raw, (SpiQuery<?>) query);
return query;
}
@Test
void where_simple() {
final Query<Customer> query = where("name isNotNull");
query.findList();
if (isH2()) {
assertSql(query).contains(" from o_customer t0 where t0.name is not null");
}
}
@Test
void where_withParams() {
final Query<Customer> query = where("id isNotNull and name = ? and smallnote istartsWith ?", "Rob", "Foo");
query.findList();
if (isH2()) {
assertSql(query).contains("where (t0.id is not null and t0.name = ? and lower(t0.smallnote) like ? escape'|')");
}
}
@Test
void where_withParamsQuPos() {
final Query<Customer> query = where("name = ?1 and smallnote istartsWith ?2 and name like ?1", "Rob", "Foo");
query.findList();
if (isH2()) {
assertSql(query).contains(" where (t0.name = ? and lower(t0.smallnote) like ? escape'|' and t0.name like ? escape'')");
}
}
@Test
void where_orSimple() {
final Query<Customer> query = where("id isNotNull or name = ?", "Rob", "Foo");
query.findList();
if (isH2()) {
assertSql(query).contains("where (t0.id is not null or t0.name = ?)");
}
}
@Test
void where_orWithParams() {
final Query<Customer> query = where("(id isNotNull or name = ?) and smallnote istartsWith ?", "Rob", "Foo");
query.findList();
if (isH2()) {
assertSql(query).contains("where ((t0.id is not null or t0.name = ?) and lower(t0.smallnote) like ? escape'|')");
}
}
@Test
void where_dateInRange() {
final Query<Customer> query = where("anniversary inrange ? to ?", LocalDate.now().minusDays(7), LocalDate.now());
query.findList();
if (isH2()) {
assertSql(query).contains("where (t0.anniversary >= ? and t0.anniversary < ?)");
}
}
@Test
void where_dateInRange_camelCase() {
final Query<Customer> query = where("anniversary inRange ? to ?", LocalDate.now().minusDays(7), LocalDate.now());
query.findList();
if (isH2()) {
assertSql(query).contains("where (t0.anniversary >= ? and t0.anniversary < ?)");
}
}
private Query<Customer> where(String where, Object... params) {
Query<Customer> query = DB.find(Customer.class);
EqlParser.parseWhere(where, query.where(), query.getExpressionFactory(), params);
return query;
}
}
@@ -37,9 +37,8 @@ public class CustomerFinder extends Finder<Integer, Customer> {
}
public List<Customer> byNameStatus(String nameStartsWith, Customer.Status status) {
return query("where status = :status and name istartsWith :name order by name")
.setParameter("status", status)
.setParameter("name", nameStartsWith)
return query().where().raw("status = ? and lower(name) like ?", status, nameStartsWith.toLowerCase() + "%")
.orderBy().asc("name")
.findList();
}
@@ -114,10 +114,12 @@ public class TestQueryFilterMany extends BaseTestCase {
final Query<Customer> query = DB.find(Customer.class)
.where().ieq("name", "Rob")
// use expression + fluid style adding maxRows/firstRow to filterMany
.filterMany("orders", "status = ?", Order.Status.NEW)
.setMaxRows(100).setFirstRow(3).order("orderDate desc, id")
.order().asc("id").setMaxRows(5);
.filterMany("orders")
.raw("status = ?", Order.Status.NEW)
.setMaxRows(100).setFirstRow(3)
.orderBy("orderDate desc, id")
.query()
.orderBy().asc("id").setMaxRows(5);
final List<Customer> customers = query.findList();
assertThat(customers).isNotEmpty();
@@ -363,7 +365,7 @@ public class TestQueryFilterMany extends BaseTestCase {
DB.find(Customer.class)
.where()
.filterMany("contacts", "firstName isNotNull and email istartsWith ?", "rob")
.filterManyRaw("contacts", "firstName is not null and lower(email) like ?", "rob%")
.findList();
List<String> sql = LoggedSql.stop();
@@ -372,7 +374,7 @@ public class TestQueryFilterMany extends BaseTestCase {
if (isSqlServer()) {
assertSql(sql.get(0)).contains(" from o_customer t0 left join contact t1 on t1.customer_id = t0.id where (t1.first_name is not null and lower(t1.email) like ?) order by t0.id; --bind(rob%)");
} else {
assertSql(sql.get(0)).contains(" from o_customer t0 left join contact t1 on t1.customer_id = t0.id where (t1.first_name is not null and lower(t1.email) like ? escape'|') order by t0.id; --bind(rob%)");
assertSql(sql.get(0)).contains(" from o_customer t0 left join contact t1 on t1.customer_id = t0.id where t1.first_name is not null and lower(t1.email) like ? order by t0.id; --bind(rob%)");
}
}
}