Skip to content

Commit

Permalink
[Blazebit#857] Fix some regressions in JPQLNext parser
Browse files Browse the repository at this point in the history
  • Loading branch information
Mobe91 committed Oct 2, 2019
1 parent fffcf3f commit 974b303
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.blazebit.persistence.parser.JPQLNextParser;
import com.blazebit.persistence.parser.predicate.Predicate;
import org.antlr.v4.runtime.ANTLRErrorListener;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.Parser;
Expand Down Expand Up @@ -157,7 +158,8 @@ private Expression createExpression(RuleInvoker ruleInvoker, String expression,
if (expression.isEmpty()) {
throw new IllegalArgumentException("expression");
}
JPQLNextLexer l = new JPQLNextLexer(CharStreams.fromString(expression));
CharStream inputCharStream = CharStreams.fromString(expression);
JPQLNextLexer l = new JPQLNextLexer(inputCharStream);
configureLexer(l);
CommonTokenStream tokens = new CommonTokenStream(l);
JPQLNextParser p = new JPQLNextParser(tokens);
Expand All @@ -182,7 +184,7 @@ private Expression createExpression(RuleInvoker ruleInvoker, String expression,
LOG.finest(ctx.toStringTree());
}

JPQLNextExpressionVisitorImpl visitor = new JPQLNextExpressionVisitorImpl(functions, enumTypes, entityTypes, minEnumSegmentCount, minEntitySegmentCount, macroConfiguration == null ? Collections.EMPTY_MAP : macroConfiguration.macros, usedMacros, allowOuter, allowQuantifiedPredicates, allowObjectExpression);
JPQLNextExpressionVisitorImpl visitor = new JPQLNextExpressionVisitorImpl(functions, enumTypes, entityTypes, minEnumSegmentCount, minEntitySegmentCount, macroConfiguration == null ? Collections.EMPTY_MAP : macroConfiguration.macros, usedMacros, allowOuter, allowQuantifiedPredicates, allowObjectExpression, inputCharStream);
Expression parsedExpression = visitor.visit(ctx);
if (optimize) {
parsedExpression = parsedExpression.accept(optimizer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@
import com.blazebit.persistence.parser.predicate.Predicate;
import com.blazebit.persistence.parser.predicate.PredicateQuantifier;
import com.blazebit.persistence.parser.util.TypeUtils;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.tree.ErrorNode;
import org.antlr.v4.runtime.tree.TerminalNode;

Expand Down Expand Up @@ -65,8 +67,9 @@ public class JPQLNextExpressionVisitorImpl extends JPQLNextParserBaseVisitor<Exp
private final boolean allowOuter;
private final boolean allowQuantifiedPredicates;
private final boolean allowObjectExpression;
private final CharStream input;

public JPQLNextExpressionVisitorImpl(Map<String, Boolean> functions, Map<String, Class<Enum<?>>> enums, Map<String, Class<?>> entities, int minEnumSegmentCount, int minEntitySegmentCount, Map<String, MacroFunction> macros, Set<String> usedMacros, boolean allowOuter, boolean allowQuantifiedPredicates, boolean allowObjectExpression) {
public JPQLNextExpressionVisitorImpl(Map<String, Boolean> functions, Map<String, Class<Enum<?>>> enums, Map<String, Class<?>> entities, int minEnumSegmentCount, int minEntitySegmentCount, Map<String, MacroFunction> macros, Set<String> usedMacros, boolean allowOuter, boolean allowQuantifiedPredicates, boolean allowObjectExpression, CharStream input) {
this.functions = functions;
this.enums = enums;
this.entities = entities;
Expand All @@ -77,6 +80,7 @@ public JPQLNextExpressionVisitorImpl(Map<String, Boolean> functions, Map<String,
this.allowOuter = allowOuter;
this.allowQuantifiedPredicates = allowQuantifiedPredicates;
this.allowObjectExpression = allowObjectExpression;
this.input = input;
}

@Override
Expand Down Expand Up @@ -352,7 +356,7 @@ private Expression handleFunction(String name, boolean distinct, List<Expression
return new FunctionExpression(name, Collections.<Expression>emptyList());
case "outer":
if (!allowOuter) {
throw new SyntaxErrorException("Invalid disallowed use of OUTER in: " + ctx.getText());
throw new SyntaxErrorException("Invalid disallowed use of OUTER in: " + getInputText(ctx));
}
case "concat":
case "substring":
Expand Down Expand Up @@ -443,13 +447,13 @@ private Expression handleMacro(String name, List<Expression> arguments, ParserRu
try {
return macro.apply(arguments);
} catch (RuntimeException ex) {
throw new IllegalArgumentException("Could not apply the macro for the expression: " + ctx.getText(), ex);
throw new IllegalArgumentException("Could not apply the macro for the expression: " + getInputText(ctx), ex);
}
}

private void failDistinct(boolean distinct, ParserRuleContext ctx) {
if (distinct) {
throw new SyntaxErrorException("Invalid use of DISTINCT for function: " + ctx.getText());
throw new SyntaxErrorException("Invalid use of DISTINCT for function: " + getInputText(ctx));
}
}

Expand Down Expand Up @@ -575,7 +579,7 @@ private OrderByItem createOrderByItem(JPQLNextParser.OrderByItemContext ctx) {
boolean asc = true;
boolean nullsFirst = true;
if (ctx.STRING_LITERAL() != null) {
throw new SyntaxErrorException("Collations are not yet supported: " + ctx.getText());
throw new SyntaxErrorException("Collations are not yet supported: " + getInputText(ctx));
}
if (ctx.DESC() != null) {
asc = false;
Expand All @@ -593,10 +597,10 @@ public Expression visitPathExpression(JPQLNextParser.PathExpressionContext ctx)
if (expression instanceof PathExpression) {
List<PathElementExpression> expressions = ((PathExpression) expression).getExpressions();
if (expressions.size() == 1 && expressions.get(0) instanceof TreatExpression) {
throw new SyntaxErrorException("A top level treat expression is not allowed. Consider to further dereference the expression: " + ctx.getText());
throw new SyntaxErrorException("A top level treat expression is not allowed. Consider to further dereference the expression: " + getInputText(ctx));
}
} else if (expression instanceof TreatExpression) {
throw new SyntaxErrorException("A top level treat expression is not allowed. Consider to further dereference the expression: " + ctx.getText());
throw new SyntaxErrorException("A top level treat expression is not allowed. Consider to further dereference the expression: " + getInputText(ctx));
}
}
return expression;
Expand Down Expand Up @@ -870,7 +874,7 @@ public Expression visitQuantifiedSimpleGreaterThanOrEqualPredicate(JPQLNextParse

private void failQuantified(ParserRuleContext ctx, Token qualifier) {
if (qualifier != null && !allowQuantifiedPredicates) {
throw new SyntaxErrorException("The use of quantifiers is not allowed in the context of the expression: " + ctx.getText());
throw new SyntaxErrorException("The use of quantifiers is not allowed in the context of the expression: " + getInputText(ctx));
}
}

Expand Down Expand Up @@ -948,7 +952,7 @@ public Expression visitLikePredicate(JPQLNextParser.LikePredicateContext ctx) {
if (expression instanceof LiteralExpression<?>) {
escapeCharacter = ((LiteralExpression) expression).getValue().toString().charAt(0);
} else {
throw new SyntaxErrorException("Only a character literal is allowed as escape character in like predicate: " + ctx.getText());
throw new SyntaxErrorException("Only a character literal is allowed as escape character in like predicate: " + getInputText(ctx));
}
}
return new LikePredicate(
Expand Down Expand Up @@ -1026,4 +1030,11 @@ private Expression createEntityTypeLiteral(String entityLiteralStr) {
}
return new EntityLiteral(entityType, entityLiteralStr);
}

private String getInputText(ParserRuleContext ctx) {
int from = ctx.start.getStartIndex();
int to = ctx.stop.getStopIndex();
Interval interval = new Interval(from,to);
return input.getText(interval);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ public Map<String, Boolean> getCollectionJoinMappings(ManagedType<?> managedType
return Collections.emptyMap();
}

context.getTypeValidationExpressionFactory().createSimpleExpression(expression, false).accept(visitor);
context.getTypeValidationExpressionFactory().createSimpleExpression(expression, false, false, true).accept(visitor);
Map<String, Boolean> mappings = new HashMap<>();
boolean aggregate = getAttributeType() == AttributeType.SINGULAR;

Expand Down Expand Up @@ -589,7 +589,7 @@ private static void validateTypesCompatible(ManagedType<?> managedType, String e
ScalarTargetResolvingExpressionVisitor visitor = new ScalarTargetResolvingExpressionVisitor(managedType, context.getEntityMetamodel(), context.getJpqlFunctions());

try {
context.getTypeValidationExpressionFactory().createSimpleExpression(expression, false).accept(visitor);
context.getTypeValidationExpressionFactory().createSimpleExpression(expression, false, false, true).accept(visitor);
} catch (SyntaxErrorException ex) {
context.addError("Syntax error in " + expressionLocation + " '" + expression + "' of the " + location + ": " + ex.getMessage());
} catch (IllegalArgumentException ex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ private void applyMapping(StringBuilder sb, String prefixParts, String mapping,
return;
}
if (prefixParts != null && !prefixParts.isEmpty()) {
Expression expr = ef.createSimpleExpression(mapping, false);
Expression expr = ef.createSimpleExpression(mapping, false, false, true);
EmbeddingViewJpqlMacro embeddingViewJpqlMacro = (EmbeddingViewJpqlMacro) ef.getDefaultMacroConfiguration().get("EMBEDDING_VIEW").getState()[0];
SimpleQueryGenerator generator = new PrefixingQueryGenerator(Collections.singletonList(prefixParts), embeddingViewJpqlMacro.getEmbeddingViewPath(), CorrelatedSubqueryEmbeddingViewJpqlMacro.CORRELATION_EMBEDDING_VIEW_ALIAS, skippedAlias);
generator.setQueryBuffer(sb);
Expand Down

0 comments on commit 974b303

Please sign in to comment.