diff --git a/src/main/antlr4/com/aerospike/dsl/Condition.g4 b/src/main/antlr4/com/aerospike/dsl/Condition.g4 index 745d800..7d7f123 100644 --- a/src/main/antlr4/com/aerospike/dsl/Condition.g4 +++ b/src/main/antlr4/com/aerospike/dsl/Condition.g4 @@ -79,6 +79,7 @@ operand | listConstant | orderedMapConstant | variable + | placeholder | '$.' pathOrMetadata | '(' expression ')' ; @@ -118,6 +119,10 @@ fragment STRING_VARIABLE_NAME : [a-zA-Z_][a-zA-Z0-9_]* ; +placeholder: PLACEHOLDER; + +PLACEHOLDER: '?' [0-9]+; + pathOrMetadata: path | metadata; path: basePath ('.' pathFunction)?; diff --git a/src/main/java/com/aerospike/dsl/ExpressionContext.java b/src/main/java/com/aerospike/dsl/ExpressionContext.java new file mode 100644 index 0000000..02b2cf9 --- /dev/null +++ b/src/main/java/com/aerospike/dsl/ExpressionContext.java @@ -0,0 +1,24 @@ +package com.aerospike.dsl; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * This class stores input string and optional values for placeholders (if they are used) + */ +@AllArgsConstructor(staticName = "of") +@RequiredArgsConstructor(staticName = "of") +@Getter +public class ExpressionContext { + + /** + * Input string. If placeholders are used, they should be matched with {@code values} + */ + private final String expression; + /** + * {@link PlaceholderValues} to be matched with placeholders in the {@code input} string. + * Optional (needed only if there are placeholders) + */ + private PlaceholderValues values; +} diff --git a/src/main/java/com/aerospike/dsl/IndexContext.java b/src/main/java/com/aerospike/dsl/IndexContext.java index 8229e26..17abff6 100644 --- a/src/main/java/com/aerospike/dsl/IndexContext.java +++ b/src/main/java/com/aerospike/dsl/IndexContext.java @@ -7,7 +7,7 @@ import java.util.Collection; /** - * This class stores namespace and indexes required to build secondary index {@link Filter}. + * This class stores namespace and indexes required to build secondary index {@link Filter} */ @AllArgsConstructor(staticName = "of") @Getter diff --git a/src/main/java/com/aerospike/dsl/ParseResult.java b/src/main/java/com/aerospike/dsl/ParseResult.java index 398456d..d429498 100644 --- a/src/main/java/com/aerospike/dsl/ParseResult.java +++ b/src/main/java/com/aerospike/dsl/ParseResult.java @@ -6,7 +6,7 @@ import lombok.Getter; /** - * This class stores result of parsing DSL expression using {@link DSLParserImpl#parseExpression} + * This class stores result of parsing DSL expression using {@link ParsedExpression#getResult()} * in form of Java client's secondary index {@link Filter} and filter {@link Exp}. */ @AllArgsConstructor diff --git a/src/main/java/com/aerospike/dsl/ParsedExpression.java b/src/main/java/com/aerospike/dsl/ParsedExpression.java index eb4f845..136d885 100644 --- a/src/main/java/com/aerospike/dsl/ParsedExpression.java +++ b/src/main/java/com/aerospike/dsl/ParsedExpression.java @@ -15,8 +15,9 @@ /** - * A class to build and store the results of DSL expression parsing: {@link ParseResult} that holds - * a potential secondary index {@link Filter} and a potential filter {@link Exp}, and parsed {@code expressionTree}. + * A class to build and store the results of DSL expression parsing: parsed {@code expressionTree}, {@code indexesMap} + * of given indexes, {@code placeholderValues} to match with placeholders and {@link ParseResult} that holds + * a potential secondary index {@link Filter} and a potential {@link Exp}. */ @Beta @Getter @@ -24,29 +25,40 @@ public class ParsedExpression { private final AbstractPart expressionTree; private final Map> indexesMap; + private final PlaceholderValues placeholderValues; private ParseResult result; - public ParsedExpression(AbstractPart expressionTree, Map> indexesMap) { - this.expressionTree = expressionTree; + public ParsedExpression(AbstractPart exprTree, PlaceholderValues placeholderValues, + Map> indexesMap) { + this.expressionTree = exprTree; + this.placeholderValues = placeholderValues; this.indexesMap = indexesMap; } /** - * @return Pair of secondary index {@link Filter} and filter {@link Exp}. Each can be null in case of invalid or - * unsupported DSL string + * @return {@link ParseResult} containing secondary index {@link Filter} and/or filter {@link Exp}. + * Each can be null in case of invalid or unsupported DSL string * @throws DslParseException If there was an error */ public ParseResult getResult() { if (result == null) { - result = getParseResult(); + result = getResult(placeholderValues); } return result; } - private ParseResult getParseResult() { + /** + * Traverse expression tree using the given placeholder values + * + * @param placeholderValues {@link PlaceholderValues} to match with placeholders by index + * @return {@link ParseResult} containing secondary index {@link Filter} and/or {@link Exp}. + * Each can be null in case of invalid or unsupported DSL string + * @throws DslParseException If there was an error + */ + public ParseResult getResult(PlaceholderValues placeholderValues) { if (expressionTree != null) { if (expressionTree.getPartType() == EXPRESSION_CONTAINER) { - AbstractPart resultPart = buildExpr((ExpressionContainer) expressionTree, indexesMap); + AbstractPart resultPart = buildExpr((ExpressionContainer) expressionTree, placeholderValues, indexesMap); return new ParseResult(resultPart.getFilter(), resultPart.getExp()); } else { Filter filter = expressionTree.getFilter(); diff --git a/src/main/java/com/aerospike/dsl/PlaceholderValues.java b/src/main/java/com/aerospike/dsl/PlaceholderValues.java new file mode 100644 index 0000000..9d5c259 --- /dev/null +++ b/src/main/java/com/aerospike/dsl/PlaceholderValues.java @@ -0,0 +1,41 @@ +package com.aerospike.dsl; + +/** + * This class stores values to be matched with placeholders by indexes + */ +public class PlaceholderValues { + + private final Object[] values; + + private PlaceholderValues(Object... values) { + this.values = values != null ? values : new Object[0]; + } + + /** + * Create a new {@link PlaceholderValues} object with + */ + public static PlaceholderValues of(Object... values) { + return new PlaceholderValues(values); + } + + /** + * Get value of the placeholder with the particular index + * + * @param index Index of the placeholder + * @return Value of the placeholder with the given index + * @throws IllegalArgumentException if placeholder index is out of bounds (fewer values than placeholders) + */ + public Object getValue(int index) { + if (index < 0 || index >= values.length) { + throw new IllegalArgumentException("Missing value for placeholder ?" + index); + } + return values[index]; + } + + /** + * Get overall amount of the given values + */ + public int size() { + return values.length; + } +} diff --git a/src/main/java/com/aerospike/dsl/DSLParser.java b/src/main/java/com/aerospike/dsl/api/DSLParser.java similarity index 84% rename from src/main/java/com/aerospike/dsl/DSLParser.java rename to src/main/java/com/aerospike/dsl/api/DSLParser.java index 6f48081..0a15c86 100644 --- a/src/main/java/com/aerospike/dsl/DSLParser.java +++ b/src/main/java/com/aerospike/dsl/api/DSLParser.java @@ -1,6 +1,11 @@ -package com.aerospike.dsl; +package com.aerospike.dsl.api; import com.aerospike.client.query.Filter; +import com.aerospike.dsl.DslParseException; +import com.aerospike.dsl.ExpressionContext; +import com.aerospike.dsl.Index; +import com.aerospike.dsl.IndexContext; +import com.aerospike.dsl.ParsedExpression; /** * Contains API to convert dot separated String path into an Aerospike filter - @@ -17,7 +22,7 @@ public interface DSLParser { /** - * Parse String DSL path into Aerospike filter Expression. + * Parse DSL path into Aerospike filter Expression. *

* Examples: * @@ -82,11 +87,12 @@ public interface DSLParser { * *
* - * @param dslString String consisting of dot separated elements, typically bin name and optional context + * @param input {@link ExpressionContext} containing input string of dot separated elements. If the input string has + * placeholders, matching values must be provided within {@code input} too * @return {@link ParsedExpression} object * @throws DslParseException in case of invalid syntax */ - ParsedExpression parseExpression(String dslString); + ParsedExpression parseExpression(ExpressionContext input); /** * Parse String DSL path into Aerospike filter Expression. @@ -154,11 +160,12 @@ public interface DSLParser { * * * - * @param dslString String consisting of dot separated elements, typically bin name and optional context + * @param input {@link ExpressionContext} containing input string of dot separated elements. If the input string has + * placeholders, matching values must be provided within {@code input} too * @param indexContext Class containing namespace and collection of {@link Index} objects that represent * existing secondary indexes. Required for creating {@link Filter}. Can be null * @return {@link ParsedExpression} object * @throws DslParseException in case of invalid syntax */ - ParsedExpression parseExpression(String dslString, IndexContext indexContext); + ParsedExpression parseExpression(ExpressionContext input, IndexContext indexContext); } diff --git a/src/main/java/com/aerospike/dsl/DSLParserImpl.java b/src/main/java/com/aerospike/dsl/impl/DSLParserImpl.java similarity index 62% rename from src/main/java/com/aerospike/dsl/DSLParserImpl.java rename to src/main/java/com/aerospike/dsl/impl/DSLParserImpl.java index 7253ca0..604fc3f 100644 --- a/src/main/java/com/aerospike/dsl/DSLParserImpl.java +++ b/src/main/java/com/aerospike/dsl/impl/DSLParserImpl.java @@ -1,6 +1,15 @@ -package com.aerospike.dsl; +package com.aerospike.dsl.impl; +import com.aerospike.dsl.ConditionLexer; +import com.aerospike.dsl.ConditionParser; +import com.aerospike.dsl.DslParseException; +import com.aerospike.dsl.ExpressionContext; +import com.aerospike.dsl.Index; +import com.aerospike.dsl.IndexContext; +import com.aerospike.dsl.ParsedExpression; +import com.aerospike.dsl.PlaceholderValues; import com.aerospike.dsl.annotation.Beta; +import com.aerospike.dsl.api.DSLParser; import com.aerospike.dsl.parts.AbstractPart; import com.aerospike.dsl.visitor.ExpressionConditionVisitor; import org.antlr.v4.runtime.CharStreams; @@ -17,15 +26,15 @@ public class DSLParserImpl implements DSLParser { @Beta - public ParsedExpression parseExpression(String dslString) { - ParseTree parseTree = getParseTree(dslString); - return getParsedExpression(parseTree, null); + public ParsedExpression parseExpression(ExpressionContext expressionContext) { + ParseTree parseTree = getParseTree(expressionContext.getExpression()); + return getParsedExpression(parseTree, expressionContext.getValues(), null); } @Beta - public ParsedExpression parseExpression(String input, IndexContext indexContext) { - ParseTree parseTree = getParseTree(input); - return getParsedExpression(parseTree, indexContext); + public ParsedExpression parseExpression(ExpressionContext expressionContext, IndexContext indexContext) { + ParseTree parseTree = getParseTree(expressionContext.getExpression()); + return getParsedExpression(parseTree, expressionContext.getValues(), indexContext); } private ParseTree getParseTree(String input) { @@ -34,7 +43,8 @@ private ParseTree getParseTree(String input) { return parser.parse(); } - private ParsedExpression getParsedExpression(ParseTree parseTree, IndexContext indexContext) { + private ParsedExpression getParsedExpression(ParseTree parseTree, PlaceholderValues placeholderValues, + IndexContext indexContext) { final String namespace = Optional.ofNullable(indexContext) .map(IndexContext::getNamespace) .orElse(null); @@ -54,7 +64,8 @@ private ParsedExpression getParsedExpression(ParseTree parseTree, IndexContext i if (resultingPart == null) { throw new DslParseException("Could not parse given DSL expression input"); } + // Return the parsed tree along with indexes Map - return new ParsedExpression(resultingPart, indexesMap); + return new ParsedExpression(resultingPart, placeholderValues, indexesMap); } } diff --git a/src/main/java/com/aerospike/dsl/parts/AbstractPart.java b/src/main/java/com/aerospike/dsl/parts/AbstractPart.java index d5cb098..5ed389e 100644 --- a/src/main/java/com/aerospike/dsl/parts/AbstractPart.java +++ b/src/main/java/com/aerospike/dsl/parts/AbstractPart.java @@ -13,17 +13,13 @@ public abstract class AbstractPart { protected PartType partType; protected Exp exp; protected Filter filter; + protected boolean isPlaceholder; protected AbstractPart(PartType partType) { this.partType = partType; this.exp = null; } - protected AbstractPart(PartType partType, Filter filter) { - this.partType = partType; - this.filter = filter; - } - public enum PartType { INT_OPERAND, FLOAT_OPERAND, @@ -45,6 +41,7 @@ public enum PartType { PATH_FUNCTION, METADATA_OPERAND, EXPRESSION_CONTAINER, - VARIABLE_OPERAND + VARIABLE_OPERAND, + PLACEHOLDER_OPERAND } } diff --git a/src/main/java/com/aerospike/dsl/parts/ExpressionContainer.java b/src/main/java/com/aerospike/dsl/parts/ExpressionContainer.java index 91f40bc..89fbf8f 100644 --- a/src/main/java/com/aerospike/dsl/parts/ExpressionContainer.java +++ b/src/main/java/com/aerospike/dsl/parts/ExpressionContainer.java @@ -7,8 +7,10 @@ @Getter public class ExpressionContainer extends AbstractPart { - protected final AbstractPart left; - protected final AbstractPart right; + @Setter + protected AbstractPart left; + @Setter + protected AbstractPart right; private final boolean isUnary; private final ExprPartsOperation operationType; @Setter() diff --git a/src/main/java/com/aerospike/dsl/parts/controlstructure/WhenStructure.java b/src/main/java/com/aerospike/dsl/parts/controlstructure/WhenStructure.java index 6849c9e..530cec7 100644 --- a/src/main/java/com/aerospike/dsl/parts/controlstructure/WhenStructure.java +++ b/src/main/java/com/aerospike/dsl/parts/controlstructure/WhenStructure.java @@ -2,13 +2,15 @@ import com.aerospike.dsl.parts.AbstractPart; import lombok.Getter; +import lombok.Setter; import java.util.List; @Getter +@Setter public class WhenStructure extends AbstractPart { - private final List operands; + private List operands; public WhenStructure(List operands) { super(PartType.WHEN_STRUCTURE); diff --git a/src/main/java/com/aerospike/dsl/parts/operand/BooleanOperand.java b/src/main/java/com/aerospike/dsl/parts/operand/BooleanOperand.java index 18ea4fc..be67ef0 100644 --- a/src/main/java/com/aerospike/dsl/parts/operand/BooleanOperand.java +++ b/src/main/java/com/aerospike/dsl/parts/operand/BooleanOperand.java @@ -4,13 +4,17 @@ import com.aerospike.dsl.parts.AbstractPart; import lombok.Getter; +import static com.aerospike.dsl.parts.AbstractPart.PartType.BOOL_OPERAND; + @Getter public class BooleanOperand extends AbstractPart implements ParsedValueOperand { + // Keeping the boxed type for interface compatibility private final Boolean value; public BooleanOperand(Boolean value) { - super(PartType.BOOL_OPERAND); + // Setting parent type + super(BOOL_OPERAND); this.value = value; } diff --git a/src/main/java/com/aerospike/dsl/parts/operand/FloatOperand.java b/src/main/java/com/aerospike/dsl/parts/operand/FloatOperand.java index 5c843c6..e03bc9e 100644 --- a/src/main/java/com/aerospike/dsl/parts/operand/FloatOperand.java +++ b/src/main/java/com/aerospike/dsl/parts/operand/FloatOperand.java @@ -7,6 +7,7 @@ @Getter public class FloatOperand extends AbstractPart implements ParsedValueOperand { + // Keeping the boxed type for interface compatibility private final Double value; public FloatOperand(Double value) { diff --git a/src/main/java/com/aerospike/dsl/parts/operand/IntOperand.java b/src/main/java/com/aerospike/dsl/parts/operand/IntOperand.java index e8405f6..fc21885 100644 --- a/src/main/java/com/aerospike/dsl/parts/operand/IntOperand.java +++ b/src/main/java/com/aerospike/dsl/parts/operand/IntOperand.java @@ -7,6 +7,7 @@ @Getter public class IntOperand extends AbstractPart implements ParsedValueOperand { + // Keeping the boxed type for interface compatibility private final Long value; public IntOperand(Long value) { diff --git a/src/main/java/com/aerospike/dsl/parts/operand/OperandFactory.java b/src/main/java/com/aerospike/dsl/parts/operand/OperandFactory.java new file mode 100644 index 0000000..ead32af --- /dev/null +++ b/src/main/java/com/aerospike/dsl/parts/operand/OperandFactory.java @@ -0,0 +1,55 @@ +package com.aerospike.dsl.parts.operand; + +import com.aerospike.dsl.parts.AbstractPart; + +/** + * A factory for creating different types of {@link AbstractPart} operands based on a given value. + *

+ * This factory provides a static method to dynamically create concrete operand implementations + * such as {@link StringOperand}, {@link BooleanOperand}, {@link FloatOperand}, and {@link IntOperand} + * from various Java primitive and wrapper types. It centralizes the logic for type-specific object creation. + *

+ * @see StringOperand + * @see BooleanOperand + * @see FloatOperand + * @see IntOperand + */ +public interface OperandFactory { + + /** + * Creates a concrete {@link AbstractPart} operand based on the type of the provided value. + *

+ * This method handles the creation of operands for common data types: + *

    + *
  • {@link String} to {@link StringOperand}.
  • + *
  • {@link Boolean} to {@link BooleanOperand}.
  • + *
  • {@link Float} or {@link Double} to {@link FloatOperand}.
  • + *
  • {@link Integer} or {@link Long} to {@link IntOperand}.
  • + *
+ *

+ * @param value The object to be converted into an operand. This cannot be {@code null}. + * @return A new instance of an operand that extends {@link AbstractPart}. + * @throws IllegalArgumentException If the value provided is {@code null}. + * @throws UnsupportedOperationException If the type of the value is not supported by the factory. + */ + static AbstractPart createOperand(Object value) { + if (value == null) { + throw new IllegalArgumentException("Cannot create operand from null value"); + } + + if (value instanceof String) { + return new StringOperand((String) value); + } else if (value instanceof Boolean) { + return new BooleanOperand((Boolean) value); + } else if (value instanceof Float || value instanceof Double) { + return new FloatOperand(((Number) value).doubleValue()); + } else if (value instanceof Integer || value instanceof Long) { + return new IntOperand(((Number) value).longValue()); + } else { + throw new UnsupportedOperationException(String.format("Cannot create operand from value of type %s, " + + "only String, boolean, float, double, long and integer values are currently supported", + value.getClass().getSimpleName())); + } + } +} + diff --git a/src/main/java/com/aerospike/dsl/parts/operand/ParsedValueOperand.java b/src/main/java/com/aerospike/dsl/parts/operand/ParsedValueOperand.java index d479108..c45680e 100644 --- a/src/main/java/com/aerospike/dsl/parts/operand/ParsedValueOperand.java +++ b/src/main/java/com/aerospike/dsl/parts/operand/ParsedValueOperand.java @@ -5,5 +5,6 @@ * the resulting filter (e.g., a String for StringOperand or a list of objects for ListOperand) */ public interface ParsedValueOperand { + Object getValue(); } diff --git a/src/main/java/com/aerospike/dsl/parts/operand/PlaceholderOperand.java b/src/main/java/com/aerospike/dsl/parts/operand/PlaceholderOperand.java new file mode 100644 index 0000000..1c11d0d --- /dev/null +++ b/src/main/java/com/aerospike/dsl/parts/operand/PlaceholderOperand.java @@ -0,0 +1,29 @@ +package com.aerospike.dsl.parts.operand; + +import com.aerospike.dsl.PlaceholderValues; +import com.aerospike.dsl.parts.AbstractPart; +import lombok.Getter; + +@Getter +public class PlaceholderOperand extends AbstractPart { + + private final int index; + + public PlaceholderOperand(int index) { + super(PartType.PLACEHOLDER_OPERAND); + super.isPlaceholder = true; + this.index = index; + } + + /** + * Resolve placeholder's value based on index in {@link PlaceholderValues} and create a corresponding operand using + * {@link OperandFactory#createOperand(Object)} + * + * @param values Values to be matched with placeholders by index + * @return Created {@link AbstractPart} operand + */ + public AbstractPart resolve(PlaceholderValues values) { + Object resolvedValue = values.getValue(index); + return OperandFactory.createOperand(resolvedValue); + } +} diff --git a/src/main/java/com/aerospike/dsl/parts/operand/WithOperand.java b/src/main/java/com/aerospike/dsl/parts/operand/WithOperand.java index 1611e4f..6265edf 100644 --- a/src/main/java/com/aerospike/dsl/parts/operand/WithOperand.java +++ b/src/main/java/com/aerospike/dsl/parts/operand/WithOperand.java @@ -2,12 +2,14 @@ import com.aerospike.dsl.parts.AbstractPart; import lombok.Getter; +import lombok.Setter; @Getter public class WithOperand extends AbstractPart { private final String string; - private final AbstractPart part; + @Setter + private AbstractPart part; private final boolean isLastPart; public WithOperand(AbstractPart part, String string) { diff --git a/src/main/java/com/aerospike/dsl/visitor/ExpressionConditionVisitor.java b/src/main/java/com/aerospike/dsl/visitor/ExpressionConditionVisitor.java index 7bad4cf..9f77023 100644 --- a/src/main/java/com/aerospike/dsl/visitor/ExpressionConditionVisitor.java +++ b/src/main/java/com/aerospike/dsl/visitor/ExpressionConditionVisitor.java @@ -461,6 +461,14 @@ public AbstractPart visitBooleanOperand(ConditionParser.BooleanOperandContext ct return new BooleanOperand(Boolean.parseBoolean(text)); } + @Override + public AbstractPart visitPlaceholder(ConditionParser.PlaceholderContext ctx) { + // Extract index from the placeholder + String placeholderText = ctx.getText(); + int index = Integer.parseInt(placeholderText.substring(1)); + return new PlaceholderOperand(index); + } + @Override public AbstractPart visitBasePath(ConditionParser.BasePathContext ctx) { BinPart binPart = null; diff --git a/src/main/java/com/aerospike/dsl/visitor/VisitorUtils.java b/src/main/java/com/aerospike/dsl/visitor/VisitorUtils.java index 3c53a5d..aff4b22 100644 --- a/src/main/java/com/aerospike/dsl/visitor/VisitorUtils.java +++ b/src/main/java/com/aerospike/dsl/visitor/VisitorUtils.java @@ -6,6 +6,7 @@ import com.aerospike.dsl.ConditionParser; import com.aerospike.dsl.DslParseException; import com.aerospike.dsl.Index; +import com.aerospike.dsl.PlaceholderValues; import com.aerospike.dsl.parts.AbstractPart; import com.aerospike.dsl.parts.ExpressionContainer; import com.aerospike.dsl.parts.ExpressionContainer.ExprPartsOperation; @@ -16,6 +17,7 @@ import com.aerospike.dsl.parts.controlstructure.WithStructure; import com.aerospike.dsl.parts.operand.IntOperand; import com.aerospike.dsl.parts.operand.MetadataOperand; +import com.aerospike.dsl.parts.operand.PlaceholderOperand; import com.aerospike.dsl.parts.operand.StringOperand; import com.aerospike.dsl.parts.operand.WithOperand; import com.aerospike.dsl.parts.path.BinPart; @@ -175,6 +177,9 @@ static void overrideTypeInfo(AbstractPart left, AbstractPart right) { if (right == null) { throw new DslParseException("Unable to parse right operand"); } + if (left.getPartType() == PLACEHOLDER_OPERAND || right.getPartType() == PLACEHOLDER_OPERAND) { + return; + } // Handle left part overrideTypes(left, right); @@ -302,56 +307,57 @@ static boolean shouldVisitMapElement(int i, int size, ParseTree child) { /** * Creates an expression for comparing a bin with another operand. * - * @param binPart The bin part - * @param otherPart The other operand to compare with - * @param operator The binary operator to apply - * @param binIsLeft Whether the bin is on the left side of the comparison + * @param binPart The bin part + * @param anotherPart The other operand to compare with + * @param operator The binary operator to apply + * @param binIsLeft Whether the bin is on the left side of the comparison * @return The resulting expression * @throws DslParseException if the operand type is not supported */ - private static Exp getExpBinComparison(BinPart binPart, AbstractPart otherPart, + private static Exp getExpBinComparison(BinPart binPart, AbstractPart anotherPart, BinaryOperator operator, boolean binIsLeft) { Exp binExp = Exp.bin(binPart.getBinName(), binPart.getExpType()); - Exp otherExp = switch (otherPart.getPartType()) { + Exp anotherExp = switch (anotherPart.getPartType()) { case INT_OPERAND -> { validateComparableTypes(binPart.getExpType(), Exp.Type.INT); - yield otherPart.getExp(); + yield anotherPart.getExp(); } case FLOAT_OPERAND -> { validateComparableTypes(binPart.getExpType(), Exp.Type.FLOAT); - yield otherPart.getExp(); + yield anotherPart.getExp(); } case BOOL_OPERAND -> { validateComparableTypes(binPart.getExpType(), Exp.Type.BOOL); - yield otherPart.getExp(); + yield anotherPart.getExp(); } - case STRING_OPERAND -> handleStringOperandComparison(binPart, (StringOperand) otherPart); + case STRING_OPERAND -> handleStringOperandComparison(binPart, (StringOperand) anotherPart); case METADATA_OPERAND -> { // Handle metadata comparison - type determined by metadata function - Exp.Type binType = Exp.Type.valueOf(((MetadataOperand) otherPart).getMetadataType().toString()); + Exp.Type binType = Exp.Type.valueOf(((MetadataOperand) anotherPart).getMetadataType().toString()); binExp = Exp.bin(binPart.getBinName(), binType); - yield otherPart.getExp(); + yield anotherPart.getExp(); } case EXPRESSION_CONTAINER, PATH_OPERAND, VARIABLE_OPERAND -> // Can't validate with expression container - otherPart.getExp(); + anotherPart.getExp(); case BIN_PART -> { // Both are bin parts - validateComparableTypes(binPart.getExpType(), otherPart.getExpType()); - yield otherPart.getExp(); + validateComparableTypes(binPart.getExpType(), anotherPart.getExpType()); + yield anotherPart.getExp(); } case LIST_OPERAND -> { validateComparableTypes(binPart.getExpType(), Exp.Type.LIST); - yield otherPart.getExp(); + yield anotherPart.getExp(); } case MAP_OPERAND -> { validateComparableTypes(binPart.getExpType(), Exp.Type.MAP); - yield otherPart.getExp(); + yield anotherPart.getExp(); } - default -> throw new DslParseException("Operand type not supported: %s".formatted(otherPart.getPartType())); + default -> + throw new DslParseException("Operand type not supported: %s".formatted(anotherPart.getPartType())); }; - return binIsLeft ? operator.apply(binExp, otherExp) : operator.apply(otherExp, binExp); + return binIsLeft ? operator.apply(binExp, anotherExp) : operator.apply(anotherExp, binExp); } /** @@ -658,7 +664,7 @@ private static Filter getFilter(BinPart bin, AbstractPart operand, FilterOperati validateComparableTypes(bin.getExpType(), Exp.Type.INT); yield getFilterForArithmeticOrFail(binName, ((IntOperand) operand).getValue(), type); } - case STRING_OPERAND -> handleStringOperand(bin, binName, (StringOperand) operand, type); + case STRING_OPERAND -> handleStringOperand(bin, binName, ((StringOperand) operand).getValue(), type); default -> throw new NoApplicableFilterException( "Operand type not supported: %s".formatted(operand.getPartType())); }; @@ -669,15 +675,15 @@ private static Filter getFilter(BinPart bin, AbstractPart operand, FilterOperati * and the other is a {@link StringOperand}. It currently only supports equality (`EQ`) comparisons. * It handles both regular strings and base64 encoded BLOBs. * - * @param bin The {@link BinPart} involved in the filter - * @param binName The name of the bin - * @param operand The {@link StringOperand} involved in the filter - * @param type The type of the filter operation (must be {@link FilterOperationType#EQ}) + * @param bin The {@link BinPart} involved in the filter + * @param binName The name of the bin + * @param operandValue The value of {@link StringOperand} involved in the filter + * @param type The type of the filter operation (must be {@link FilterOperationType#EQ}) * @return An Aerospike {@link Filter} for the string or blob comparison * @throws NoApplicableFilterException if the filter operation type is not equality * @throws DslParseException if type validation fails or base64 decoding fails */ - private static Filter handleStringOperand(BinPart bin, String binName, StringOperand operand, + private static Filter handleStringOperand(BinPart bin, String binName, String operandValue, FilterOperationType type) { if (type != FilterOperationType.EQ) { throw new NoApplicableFilterException("Only equality comparison is supported for string operands"); @@ -686,43 +692,44 @@ private static Filter handleStringOperand(BinPart bin, String binName, StringOpe // Handle BLOB type if (bin.getExpType() != null && bin.getExpType().equals(Exp.Type.BLOB)) { validateComparableTypes(bin.getExpType(), Exp.Type.BLOB); - byte[] value = Base64.getDecoder().decode(operand.getValue()); + byte[] value = Base64.getDecoder().decode(operandValue); return Filter.equal(binName, value); } // Handle STRING type validateComparableTypes(bin.getExpType(), Exp.Type.STRING); - return Filter.equal(binName, operand.getValue()); + return Filter.equal(binName, operandValue); } /** * Creates a Filter based on two operands and a filter operation type. * - * @param left The left operand - * @param right The right operand - * @param type The filter operation type + * @param left The left operand + * @param right The right operand + * @param type The filter operation type + * @param placeholderValues The {@link PlaceholderValues} to match with placeholders by index * @return The appropriate Filter, or null if no filter can be created * @throws DslParseException if operands are invalid */ - private static Filter getFilterOrFail(AbstractPart left, AbstractPart right, FilterOperationType type) { + private static Filter getFilterOrNull(AbstractPart left, AbstractPart right, FilterOperationType type, + PlaceholderValues placeholderValues) { validateOperands(left, right); // Handle bin operands if (left.getPartType() == BIN_PART) { return getFilter((BinPart) left, right, type); } - if (right.getPartType() == BIN_PART) { return getFilter((BinPart) right, left, invertType(type)); } // Handle expressions if (left.getPartType() == EXPRESSION_CONTAINER) { - return handleExpressionOperand((ExpressionContainer) left, right, type); + return handleExpressionOperand((ExpressionContainer) left, right, type, placeholderValues); } if (right.getPartType() == EXPRESSION_CONTAINER) { - return handleExpressionOperand((ExpressionContainer) right, left, type); + return handleExpressionOperand((ExpressionContainer) right, left, type, placeholderValues); } return null; @@ -733,22 +740,23 @@ private static Filter getFilterOrFail(AbstractPart left, AbstractPart right, Fil * It recursively processes the nested expression to determine if a filter can be generated from it in combination * with the {@code otherOperand} and the overall {@code type} of the filter operation. * - * @param expr The {@link ExpressionContainer} operand - * @param otherOperand The other operand in the filter condition - * @param type The type of the filter operation + * @param expr The {@link ExpressionContainer} operand + * @param otherOperand The other operand in the filter condition + * @param type The type of the filter operation + * @param placeholderValues The {@link PlaceholderValues} to match with placeholders by index * @return A {@link Filter} if one can be generated from the nested expression, otherwise {@code null} * @throws DslParseException if operands within the nested expression are null * @throws NoApplicableFilterException if the nested expression structure is not supported for filtering */ private static Filter handleExpressionOperand(ExpressionContainer expr, AbstractPart otherOperand, - FilterOperationType type) { + FilterOperationType type, PlaceholderValues placeholderValues) { AbstractPart exprLeft = expr.getLeft(); AbstractPart exprRight = expr.getRight(); ExprPartsOperation operation = expr.getOperationType(); validateOperands(exprLeft, exprRight); - return getFilterFromExpressionOrFail(exprLeft, exprRight, operation, otherOperand, type); + return getFilterFromExpressionOrNull(exprLeft, exprRight, operation, otherOperand, type, placeholderValues); } /** @@ -757,17 +765,19 @@ private static Filter handleExpressionOperand(ExpressionContainer expr, Abstract * by combining it with the {@code externalOperand} and the overall {@code type} of the filter operation. * It specifically looks for cases where a bin is involved in an arithmetic expression with an external operand. * - * @param exprLeft The left part of an expression - * @param exprRight The right part of an expression - * @param operationType The operation type of the expression - * @param externalOperand The operand outside the expression - * @param type The type of the overall filter operation + * @param exprLeft The left part of an expression + * @param exprRight The right part of an expression + * @param operationType The operation type of the expression + * @param externalOperand The operand outside the expression + * @param type The type of the overall filter operation + * @param placeholderValues The {@link PlaceholderValues} to match with placeholders by index * @return A {@link Filter} if one can be generated, otherwise {@code null} * @throws NoApplicableFilterException if the expression structure is not supported for filtering */ - private static Filter getFilterFromExpressionOrFail(AbstractPart exprLeft, AbstractPart exprRight, + private static Filter getFilterFromExpressionOrNull(AbstractPart exprLeft, AbstractPart exprRight, ExprPartsOperation operationType, - AbstractPart externalOperand, FilterOperationType type) { + AbstractPart externalOperand, FilterOperationType type, + PlaceholderValues placeholderValues) { // Handle bin on left side if (exprLeft.getPartType() == BIN_PART) { return handleBinArithmeticExpression((BinPart) exprLeft, exprRight, externalOperand, @@ -782,7 +792,7 @@ private static Filter getFilterFromExpressionOrFail(AbstractPart exprLeft, Abstr // Handle nested expressions if (exprLeft.getPartType() == EXPRESSION_CONTAINER) { - return getFilterOrFail(exprLeft, exprRight, type); + return getFilterOrNull(exprLeft, exprRight, type, placeholderValues); } return null; @@ -974,15 +984,19 @@ private static FilterOperationType invertType(FilterOperationType type) { * Builds a secondary index {@link Filter} and a filter {@link Exp} for a given {@link ExpressionContainer}. * This is the main entry point for enriching the parsed expression tree with query filters. * - * @param expr The {@link ExpressionContainer} representing the expression tree - * @param indexes A map of available secondary indexes, keyed by bin name + * @param expr The {@link ExpressionContainer} representing the expression tree + * @param placeholderValues The {@link PlaceholderValues} to match with placeholders by index + * @param indexes A map of available secondary indexes, keyed by bin name * @return The updated {@link ExpressionContainer} with the generated {@link Filter} and {@link Exp}. * Either of them can be null if there is no suitable filter */ - public static AbstractPart buildExpr(ExpressionContainer expr, Map> indexes) { + public static AbstractPart buildExpr(ExpressionContainer expr, PlaceholderValues placeholderValues, + Map> indexes) { + if (placeholderValues != null) resolvePlaceholders(expr, placeholderValues); + Filter secondaryIndexFilter = null; try { - secondaryIndexFilter = getSIFilter(expr, indexes); + secondaryIndexFilter = getSIFilter(expr, placeholderValues, indexes); } catch (NoApplicableFilterException ignored) { } expr.setFilter(secondaryIndexFilter); @@ -992,6 +1006,136 @@ public static AbstractPart buildExpr(ExpressionContainer expr, Map + * This method traverses the expression tree starting from the root {@link ExpressionContainer}. + * For each node, it checks for structures like {@link ExpressionContainer}, + * {@link WhenStructure}, and {@link WithStructure} and replaces any found placeholders with their + * corresponding values. + *

+ * + * @param expression The root of the expression tree to traverse + * @param placeholderValues An object storing placeholder indexes and their resolved values + */ + private static void resolvePlaceholders(ExpressionContainer expression, PlaceholderValues placeholderValues) { + Consumer exprContainersCollector = part -> { + switch (part.getPartType()) { + case EXPRESSION_CONTAINER -> replacePlaceholdersInExprContainer(part, placeholderValues); + case WHEN_STRUCTURE -> replacePlaceholdersInWhenStructure(part, placeholderValues); + case WITH_STRUCTURE -> replacePlaceholdersInWithStructure(part, placeholderValues); + case EXCLUSIVE_STRUCTURE -> replacePlaceholdersInExclusiveStructure(part, placeholderValues); + } + }; + traverseTree(expression, exprContainersCollector, null); + } + + /** + * Replaces placeholders within a {@link WithStructure} object. + *

+ * This method iterates through the operands of a given {@link WithStructure}. If an operand + * is a {@link PlaceholderOperand}, it's resolved using the provided {@link PlaceholderValues} + * and replaced with the resolved {@link AbstractPart}. + *

+ * + * @param part The {@link AbstractPart} representing the {@link WithStructure} + * @param placeholderValues An object storing placeholder indexes and their resolved values + */ + private static void replacePlaceholdersInWithStructure(AbstractPart part, PlaceholderValues placeholderValues) { + WithStructure withStructure = (WithStructure) part; + for (WithOperand subOperand : withStructure.getOperands()) { + if (subOperand.getPart().getPartType() == PLACEHOLDER_OPERAND) { + // Replace placeholder part with the resolved operand + subOperand.setPart(((PlaceholderOperand) subOperand.getPart()).resolve(placeholderValues)); + } + } + } + + /** + * Replaces placeholders within a {@link WhenStructure} object. + *

+ * This method iterates through the operands of a {@link WhenStructure}. It identifies + * and resolves {@link PlaceholderOperand}s, replacing them with their resolved values + * from the {@link PlaceholderValues}. It also recursively calls + * {@code replacePlaceholdersInExprContainer} for any nested + * {@link ExpressionContainer}s. + *

+ * + * @param part The {@link AbstractPart} representing the {@link WhenStructure} + * @param placeholderValues An object storing placeholder indexes and their resolved values + */ + private static void replacePlaceholdersInWhenStructure(AbstractPart part, PlaceholderValues placeholderValues) { + WhenStructure whenStructure = (WhenStructure) part; + List subOperands = new ArrayList<>(whenStructure.getOperands()); + boolean isResolved = false; + for (AbstractPart subOperand : whenStructure.getOperands()) { + if (subOperand.getPartType() == PLACEHOLDER_OPERAND) { + PlaceholderOperand placeholder = (PlaceholderOperand) subOperand; + // Replace placeholder with the resolved operand + subOperands.set(subOperands.indexOf(subOperand), placeholder.resolve(placeholderValues)); + isResolved = true; + } else if (subOperand.getPartType() == EXPRESSION_CONTAINER) { + replacePlaceholdersInExprContainer(subOperand, placeholderValues); + } + } + + if (isResolved) whenStructure.setOperands(subOperands); + } + + /** + * Replaces placeholders within a {@link ExclusiveStructure} object. + *

+ * This method iterates through the operands of a given {@link ExclusiveStructure}. If an operand + * has a {@link PlaceholderOperand}, it's resolved using the provided {@link PlaceholderValues} + * and replaced with the resolved {@link AbstractPart}. + *

+ * + * @param part The {@link AbstractPart} representing the {@link ExclusiveStructure} + * @param placeholderValues An object storing placeholder indexes and their resolved values + */ + private static void replacePlaceholdersInExclusiveStructure(AbstractPart part, PlaceholderValues placeholderValues) { + ExclusiveStructure exclStructure = (ExclusiveStructure) part; + for (ExpressionContainer exprContainer : exclStructure.getOperands()) { + replacePlaceholdersInExprContainer(exprContainer, placeholderValues); + } + } + + /** + * Replaces placeholders within an {@link ExpressionContainer}. + *

+ * This method checks the left and right operands of the {@link ExpressionContainer}. If either + * operand is a {@link PlaceholderOperand}, it resolves the placeholder using the provided + * {@link PlaceholderValues} and updates the operand. For specific comparison operations + * (LT, LTEQ, GT, GTEQ, NOTEQ, EQ), it also calls {@code overrideTypeInfo} after + * resolution. + *

+ * + * @param part The {@link AbstractPart} representing the {@link ExpressionContainer} + * @param placeholderValues An object storing placeholder indexes and their resolved values + */ + private static void replacePlaceholdersInExprContainer(AbstractPart part, PlaceholderValues placeholderValues) { + ExpressionContainer expr = (ExpressionContainer) part; + boolean leftIsPlaceholder = expr.getLeft().getPartType() == PLACEHOLDER_OPERAND; + boolean rightIsPlaceholder = !expr.isUnary() && expr.getRight().getPartType() == PLACEHOLDER_OPERAND; + boolean isResolved = false; + + // Resolve left placeholder and replace it with the resolved operand + if (leftIsPlaceholder) { + PlaceholderOperand placeholder = (PlaceholderOperand) expr.getLeft(); + expr.setLeft(placeholder.resolve(placeholderValues)); + isResolved = true; + } else if (rightIsPlaceholder) { + // Resolve right placeholder and replace it with the resolved operand + PlaceholderOperand placeholder = (PlaceholderOperand) expr.getRight(); + expr.setRight(placeholder.resolve(placeholderValues)); + isResolved = true; + } + + if (isResolved && List.of(LT, LTEQ, GT, GTEQ, NOTEQ, EQ).contains(expr.getOperationType())) { + overrideTypeInfo(expr.getLeft(), expr.getRight()); + } + } + /** * Returns the {@link Exp} generated for a given {@link ExpressionContainer}. * @@ -1104,9 +1248,11 @@ private static Exp andStructureToExp(ExpressionContainer expr) { * @throws DslParseException if left or right operands are null in a binary expression */ private static Exp processExpression(ExpressionContainer expr) { + AbstractPart left = getExistingPart(expr.getLeft(), "Unable to parse left operand"); + // For unary expressions if (expr.isUnary()) { - Exp operandExp = processOperand(expr.getLeft()); + Exp operandExp = processOperand(left); if (operandExp == null) return null; UnaryOperator operator = getUnaryExpOperator(expr.getOperationType()); @@ -1114,14 +1260,7 @@ private static Exp processExpression(ExpressionContainer expr) { } // For binary expressions - AbstractPart left = expr.getLeft(); - AbstractPart right = expr.getRight(); - if (left == null) { - throw new DslParseException("Unable to parse left operand"); - } - if (right == null) { - throw new DslParseException("Unable to parse right operand"); - } + AbstractPart right = getExistingPart(expr.getRight(), "Unable to parse right operand"); // Process operands Exp leftExp = processOperand(left); @@ -1145,6 +1284,27 @@ private static Exp processExpression(ExpressionContainer expr) { return operator.apply(leftExp, rightExp); } + /** + * Ensures that an {@link AbstractPart} object is not null. + *

+ * This is a utility method used to validate that the given {@link AbstractPart} exists. If the provided + * {@code part} is {@code null}, it indicates a parsing error, and a {@link DslParseException} + * is thrown with a custom error message. Otherwise, the method simply returns the non-null part. + *

+ * + * @param part The part of the expression to be validated + * @param errMsg The error message to be included in the exception if the part is null + * @return The provided {@link AbstractPart}, if it is not null + * @throws DslParseException if the provided {@code part} is {@code null} + */ + private static AbstractPart getExistingPart(AbstractPart part, String errMsg) { + if (part == null) { + throw new DslParseException(errMsg); + } + return part; + } + + /** * Processes an expression operand to generate its corresponding Aerospike {@link Exp}. * If the operand is an {@link ExpressionContainer}, it recursively calls {@link #getFilterExp(ExpressionContainer)} @@ -1195,17 +1355,19 @@ private static Exp getExp(AbstractPart part) { * @return A secondary index {@link Filter}, or {@code null} if no applicable filter can be generated * @throws NoApplicableFilterException if the expression operation type is not supported */ - private static Filter getSIFilter(ExpressionContainer expr, Map> indexes) { + private static Filter getSIFilter(ExpressionContainer expr, PlaceholderValues placeholderValues, + Map> indexes) { // If it is an OR query if (expr.getOperationType() == OR) return null; ExpressionContainer chosenExpr = chooseExprForFilter(expr, indexes); if (chosenExpr == null) return null; - return getFilterOrFail( + return getFilterOrNull( chosenExpr.getLeft(), chosenExpr.getRight(), - getFilterOperation(chosenExpr.getOperationType()) + getFilterOperation(chosenExpr.getOperationType()), + placeholderValues ); } diff --git a/src/test/java/com/aerospike/dsl/expression/ArithmeticExpressionsTests.java b/src/test/java/com/aerospike/dsl/expression/ArithmeticExpressionsTests.java index b132b80..4199abf 100644 --- a/src/test/java/com/aerospike/dsl/expression/ArithmeticExpressionsTests.java +++ b/src/test/java/com/aerospike/dsl/expression/ArithmeticExpressionsTests.java @@ -2,6 +2,7 @@ import com.aerospike.client.exp.Exp; import com.aerospike.dsl.DslParseException; +import com.aerospike.dsl.ExpressionContext; import com.aerospike.dsl.util.TestUtils; import org.junit.jupiter.api.Test; @@ -12,112 +13,112 @@ public class ArithmeticExpressionsTests { @Test void add() { - TestUtils.parseFilterExpressionAndCompare("($.apples + $.bananas) > 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples + $.bananas) > 10"), Exp.gt(Exp.add(Exp.intBin("apples"), Exp.intBin("bananas")), Exp.val(10))); - TestUtils.parseFilterExpressionAndCompare("($.apples + 5) > 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples + 5) > 10"), Exp.gt(Exp.add(Exp.intBin("apples"), Exp.val(5)), Exp.val(10))); - TestUtils.parseFilterExpressionAndCompare("(5 + $.bananas) > 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("(5 + $.bananas) > 10"), Exp.gt(Exp.add(Exp.val(5), Exp.intBin("bananas")), Exp.val(10))); - TestUtils.parseFilterExpressionAndCompare("(5.2 + $.bananas) > 10.2", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("(5.2 + $.bananas) > 10.2"), Exp.gt(Exp.add(Exp.val(5.2), Exp.floatBin("bananas")), Exp.val(10.2))); } @Test void sub() { - TestUtils.parseFilterExpressionAndCompare("($.apples - $.bananas) == 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples - $.bananas) == 10"), Exp.eq(Exp.sub(Exp.intBin("apples"), Exp.intBin("bananas")), Exp.val(10))); - TestUtils.parseFilterExpressionAndCompare("($.apples - 5) == 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples - 5) == 10"), Exp.eq(Exp.sub(Exp.intBin("apples"), Exp.val(5)), Exp.val(10))); - TestUtils.parseFilterExpressionAndCompare("(15 - $.bananas) == 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("(15 - $.bananas) == 10"), Exp.eq(Exp.sub(Exp.val(15), Exp.intBin("bananas")), Exp.val(10))); } @Test void mul() { - TestUtils.parseFilterExpressionAndCompare("($.apples * $.bananas) != 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples * $.bananas) != 10"), Exp.ne(Exp.mul(Exp.intBin("apples"), Exp.intBin("bananas")), Exp.val(10))); - TestUtils.parseFilterExpressionAndCompare("($.apples * 7) != 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples * 7) != 10"), Exp.ne(Exp.mul(Exp.intBin("apples"), Exp.val(7)), Exp.val(10))); - TestUtils.parseFilterExpressionAndCompare("(3 * $.bananas) != 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("(3 * $.bananas) != 10"), Exp.ne(Exp.mul(Exp.val(3), Exp.intBin("bananas")), Exp.val(10))); } @Test void div() { - TestUtils.parseFilterExpressionAndCompare("($.apples / $.bananas) <= 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples / $.bananas) <= 10"), Exp.le(Exp.div(Exp.intBin("apples"), Exp.intBin("bananas")), Exp.val(10))); - TestUtils.parseFilterExpressionAndCompare("($.apples / 5) <= 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples / 5) <= 10"), Exp.le(Exp.div(Exp.intBin("apples"), Exp.val(5)), Exp.val(10))); - TestUtils.parseFilterExpressionAndCompare("(33 / $.bananas) <= 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("(33 / $.bananas) <= 10"), Exp.le(Exp.div(Exp.val(33), Exp.intBin("bananas")), Exp.val(10))); // Exp should be constructed and equal and therefore the test is passing // but when actually triggered server will throw divide by zero exception - TestUtils.parseFilterExpressionAndCompare("($.apples / 0) <= 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples / 0) <= 10"), Exp.le(Exp.div(Exp.intBin("apples"), Exp.val(0)), Exp.val(10))); } @Test void mod() { - TestUtils.parseFilterExpressionAndCompare("($.apples % $.bananas) != 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples % $.bananas) != 10"), Exp.ne(Exp.mod(Exp.intBin("apples"), Exp.intBin("bananas")), Exp.val(10))); - TestUtils.parseFilterExpressionAndCompare("($.apples % 7) != 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples % 7) != 10"), Exp.ne(Exp.mod(Exp.intBin("apples"), Exp.val(7)), Exp.val(10))); - TestUtils.parseFilterExpressionAndCompare("(3 % $.bananas) != 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("(3 % $.bananas) != 10"), Exp.ne(Exp.mod(Exp.val(3), Exp.intBin("bananas")), Exp.val(10))); } @Test void intAnd() { - TestUtils.parseFilterExpressionAndCompare("($.apples & $.bananas) != 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples & $.bananas) != 10"), Exp.ne(Exp.intAnd(Exp.intBin("apples"), Exp.intBin("bananas")), Exp.val(10))); - TestUtils.parseFilterExpressionAndCompare("($.apples & 7) != 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples & 7) != 10"), Exp.ne(Exp.intAnd(Exp.intBin("apples"), Exp.val(7)), Exp.val(10))); - TestUtils.parseFilterExpressionAndCompare("(3 & $.bananas) != 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("(3 & $.bananas) != 10"), Exp.ne(Exp.intAnd(Exp.val(3), Exp.intBin("bananas")), Exp.val(10))); } @Test void intOr() { - TestUtils.parseFilterExpressionAndCompare("($.apples | $.bananas) != 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples | $.bananas) != 10"), Exp.ne(Exp.intOr(Exp.intBin("apples"), Exp.intBin("bananas")), Exp.val(10))); - TestUtils.parseFilterExpressionAndCompare("($.apples | 7) != 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples | 7) != 10"), Exp.ne(Exp.intOr(Exp.intBin("apples"), Exp.val(7)), Exp.val(10))); - TestUtils.parseFilterExpressionAndCompare("(3 | $.bananas) != 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("(3 | $.bananas) != 10"), Exp.ne(Exp.intOr(Exp.val(3), Exp.intBin("bananas")), Exp.val(10))); } @Test void intXor() { - TestUtils.parseFilterExpressionAndCompare("($.apples ^ $.bananas) != 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples ^ $.bananas) != 10"), Exp.ne(Exp.intXor(Exp.intBin("apples"), Exp.intBin("bananas")), Exp.val(10))); - TestUtils.parseFilterExpressionAndCompare("($.apples ^ 7) != 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples ^ 7) != 10"), Exp.ne(Exp.intXor(Exp.intBin("apples"), Exp.val(7)), Exp.val(10))); - TestUtils.parseFilterExpressionAndCompare("(3 ^ $.bananas) != 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("(3 ^ $.bananas) != 10"), Exp.ne(Exp.intXor(Exp.val(3), Exp.intBin("bananas")), Exp.val(10))); } @Test void intNot() { - TestUtils.parseFilterExpressionAndCompare("(~$.apples) != 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("(~$.apples) != 10"), Exp.ne(Exp.intNot(Exp.intBin("apples")), Exp.val(10))); } @Test void intLShift() { - TestUtils.parseFilterExpressionAndCompare("$.visits << 1", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.visits << 1"), Exp.lshift(Exp.intBin("visits"), Exp.val(1))); } @Test void intRShift() { - TestUtils.parseFilterExpressionAndCompare("(($.flags >> 6) & 1) == 1", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("(($.flags >> 6) & 1) == 1"), Exp.eq(Exp.intAnd(Exp.rshift(Exp.intBin("flags"), Exp.val(6)), Exp.val(1)), Exp.val(1))); } @Test void negativeArithmetic() { - assertThatThrownBy(() -> parseFilterExp("($.apples.get(type: STRING) + 5) > 10")) + assertThatThrownBy(() -> parseFilterExp(ExpressionContext.of("($.apples.get(type: STRING) + 5) > 10"))) .isInstanceOf(DslParseException.class) .hasMessageContaining("Cannot compare STRING to INT"); diff --git a/src/test/java/com/aerospike/dsl/expression/BinExpressionsTests.java b/src/test/java/com/aerospike/dsl/expression/BinExpressionsTests.java index 821226d..7e60521 100644 --- a/src/test/java/com/aerospike/dsl/expression/BinExpressionsTests.java +++ b/src/test/java/com/aerospike/dsl/expression/BinExpressionsTests.java @@ -2,66 +2,69 @@ import com.aerospike.client.exp.Exp; import com.aerospike.dsl.DslParseException; +import com.aerospike.dsl.ExpressionContext; import org.junit.jupiter.api.Test; -import static com.aerospike.dsl.util.TestUtils.*; +import static com.aerospike.dsl.util.TestUtils.parseFilterExp; +import static com.aerospike.dsl.util.TestUtils.parseFilterExpressionAndCompare; import static org.assertj.core.api.Assertions.assertThatThrownBy; class BinExpressionsTests { @Test void binGT() { - parseFilterExpressionAndCompare("$.intBin1 > 100", Exp.gt(Exp.intBin("intBin1"), Exp.val(100))); - parseFilterExpressionAndCompare("$.stringBin1 > 'text'", Exp.gt(Exp.stringBin("stringBin1"), Exp.val("text"))); - parseFilterExpressionAndCompare("$.stringBin1 > \"text\"", Exp.gt(Exp.stringBin("stringBin1"), Exp.val("text"))); + parseFilterExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100"), Exp.gt(Exp.intBin("intBin1"), Exp.val(100))); + parseFilterExpressionAndCompare(ExpressionContext.of("$.stringBin1 > 'text'"), Exp.gt(Exp.stringBin("stringBin1"), Exp.val("text"))); + parseFilterExpressionAndCompare(ExpressionContext.of("$.stringBin1 > \"text\""), Exp.gt(Exp.stringBin("stringBin1"), Exp.val("text"))); + parseFilterExpressionAndCompare(ExpressionContext.of("$.stringBin1 > '?0'"), Exp.gt(Exp.stringBin("stringBin1"), Exp.val("?0"))); - parseFilterExpressionAndCompare("100 < $.intBin1", Exp.lt(Exp.val(100), Exp.intBin("intBin1"))); - parseFilterExpressionAndCompare("'text' < $.stringBin1", Exp.lt(Exp.val("text"), Exp.stringBin("stringBin1"))); - parseFilterExpressionAndCompare("\"text\" < $.stringBin1", Exp.lt(Exp.val("text"), Exp.stringBin("stringBin1"))); + parseFilterExpressionAndCompare(ExpressionContext.of("100 < $.intBin1"), Exp.lt(Exp.val(100), Exp.intBin("intBin1"))); + parseFilterExpressionAndCompare(ExpressionContext.of("'text' < $.stringBin1"), Exp.lt(Exp.val("text"), Exp.stringBin("stringBin1"))); + parseFilterExpressionAndCompare(ExpressionContext.of("\"text\" < $.stringBin1"), Exp.lt(Exp.val("text"), Exp.stringBin("stringBin1"))); } @Test void binGE() { - parseFilterExpressionAndCompare("$.intBin1 >= 100", Exp.ge(Exp.intBin("intBin1"), Exp.val(100))); - parseFilterExpressionAndCompare("$.stringBin1 >= 'text'", Exp.ge(Exp.stringBin("stringBin1"), Exp.val("text"))); - parseFilterExpressionAndCompare("$.stringBin1 >= \"text\"", Exp.ge(Exp.stringBin("stringBin1"), Exp.val("text"))); + parseFilterExpressionAndCompare(ExpressionContext.of("$.intBin1 >= 100"), Exp.ge(Exp.intBin("intBin1"), Exp.val(100))); + parseFilterExpressionAndCompare(ExpressionContext.of("$.stringBin1 >= 'text'"), Exp.ge(Exp.stringBin("stringBin1"), Exp.val("text"))); + parseFilterExpressionAndCompare(ExpressionContext.of("$.stringBin1 >= \"text\""), Exp.ge(Exp.stringBin("stringBin1"), Exp.val("text"))); } @Test void binLT() { - parseFilterExpressionAndCompare("$.intBin1 < 100", Exp.lt(Exp.intBin("intBin1"), Exp.val(100))); - parseFilterExpressionAndCompare("$.stringBin1 < 'text'", Exp.lt(Exp.stringBin("stringBin1"), Exp.val("text"))); - parseFilterExpressionAndCompare("$.stringBin1 < \"text\"", Exp.lt(Exp.stringBin("stringBin1"), Exp.val("text"))); + parseFilterExpressionAndCompare(ExpressionContext.of("$.intBin1 < 100"), Exp.lt(Exp.intBin("intBin1"), Exp.val(100))); + parseFilterExpressionAndCompare(ExpressionContext.of("$.stringBin1 < 'text'"), Exp.lt(Exp.stringBin("stringBin1"), Exp.val("text"))); + parseFilterExpressionAndCompare(ExpressionContext.of("$.stringBin1 < \"text\""), Exp.lt(Exp.stringBin("stringBin1"), Exp.val("text"))); } @Test void binLE() { - parseFilterExpressionAndCompare("$.intBin1 <= 100", Exp.le(Exp.intBin("intBin1"), Exp.val(100))); - parseFilterExpressionAndCompare("$.stringBin1 <= 'text'", Exp.le(Exp.stringBin("stringBin1"), Exp.val("text"))); - parseFilterExpressionAndCompare("$.stringBin1 <= \"text\"", Exp.le(Exp.stringBin("stringBin1"), Exp.val("text"))); + parseFilterExpressionAndCompare(ExpressionContext.of("$.intBin1 <= 100"), Exp.le(Exp.intBin("intBin1"), Exp.val(100))); + parseFilterExpressionAndCompare(ExpressionContext.of("$.stringBin1 <= 'text'"), Exp.le(Exp.stringBin("stringBin1"), Exp.val("text"))); + parseFilterExpressionAndCompare(ExpressionContext.of("$.stringBin1 <= \"text\""), Exp.le(Exp.stringBin("stringBin1"), Exp.val("text"))); } @Test void binEquals() { - parseFilterExpressionAndCompare("$.intBin1 == 100", Exp.eq(Exp.intBin("intBin1"), Exp.val(100))); - parseFilterExpressionAndCompare("$.strBin == \"yes\"", Exp.eq(Exp.stringBin("strBin"), Exp.val("yes"))); - parseFilterExpressionAndCompare("$.strBin == 'yes'", Exp.eq(Exp.stringBin("strBin"), Exp.val("yes"))); + parseFilterExpressionAndCompare(ExpressionContext.of("$.intBin1 == 100"), Exp.eq(Exp.intBin("intBin1"), Exp.val(100))); + parseFilterExpressionAndCompare(ExpressionContext.of("$.strBin == \"yes\""), Exp.eq(Exp.stringBin("strBin"), Exp.val("yes"))); + parseFilterExpressionAndCompare(ExpressionContext.of("$.strBin == 'yes'"), Exp.eq(Exp.stringBin("strBin"), Exp.val("yes"))); - parseFilterExpressionAndCompare("100 == $.intBin1", Exp.eq(Exp.val(100), Exp.intBin("intBin1"))); - parseFilterExpressionAndCompare("\"yes\" == $.strBin", Exp.eq(Exp.val("yes"), Exp.stringBin("strBin"))); - parseFilterExpressionAndCompare("'yes' == $.strBin", Exp.eq(Exp.val("yes"), Exp.stringBin("strBin"))); + parseFilterExpressionAndCompare(ExpressionContext.of("100 == $.intBin1"), Exp.eq(Exp.val(100), Exp.intBin("intBin1"))); + parseFilterExpressionAndCompare(ExpressionContext.of("\"yes\" == $.strBin"), Exp.eq(Exp.val("yes"), Exp.stringBin("strBin"))); + parseFilterExpressionAndCompare(ExpressionContext.of("'yes' == $.strBin"), Exp.eq(Exp.val("yes"), Exp.stringBin("strBin"))); } @Test void binNotEquals() { - parseFilterExpressionAndCompare("$.intBin1 != 100", Exp.ne(Exp.intBin("intBin1"), Exp.val(100))); - parseFilterExpressionAndCompare("$.strBin != \"yes\"", Exp.ne(Exp.stringBin("strBin"), Exp.val("yes"))); - parseFilterExpressionAndCompare("$.strBin != 'yes'", Exp.ne(Exp.stringBin("strBin"), Exp.val("yes"))); + parseFilterExpressionAndCompare(ExpressionContext.of("$.intBin1 != 100"), Exp.ne(Exp.intBin("intBin1"), Exp.val(100))); + parseFilterExpressionAndCompare(ExpressionContext.of("$.strBin != \"yes\""), Exp.ne(Exp.stringBin("strBin"), Exp.val("yes"))); + parseFilterExpressionAndCompare(ExpressionContext.of("$.strBin != 'yes'"), Exp.ne(Exp.stringBin("strBin"), Exp.val("yes"))); } @Test void negativeStringBinEquals() { - assertThatThrownBy(() -> parseFilterExp("$.strBin == yes")) + assertThatThrownBy(() -> parseFilterExp(ExpressionContext.of("$.strBin == yes"))) .isInstanceOf(DslParseException.class) .hasMessage("Unable to parse right operand"); } diff --git a/src/test/java/com/aerospike/dsl/expression/CastingTests.java b/src/test/java/com/aerospike/dsl/expression/CastingTests.java index f41a000..61aba61 100644 --- a/src/test/java/com/aerospike/dsl/expression/CastingTests.java +++ b/src/test/java/com/aerospike/dsl/expression/CastingTests.java @@ -2,11 +2,11 @@ import com.aerospike.client.exp.Exp; import com.aerospike.dsl.DslParseException; +import com.aerospike.dsl.ExpressionContext; import com.aerospike.dsl.util.TestUtils; import org.junit.jupiter.api.Test; import static com.aerospike.dsl.util.TestUtils.parseFilterExp; -import static com.aerospike.dsl.util.TestUtils.parseDslExpressionAndCompare; import static org.assertj.core.api.Assertions.assertThatThrownBy; public class CastingTests { @@ -15,19 +15,19 @@ public class CastingTests { void floatToIntComparison() { Exp expectedExp = Exp.gt(Exp.intBin("intBin1"), Exp.intBin("floatBin1")); // Int is default - TestUtils.parseFilterExpressionAndCompare("$.intBin1 > $.floatBin1.asInt()", expectedExp); - TestUtils.parseFilterExpressionAndCompare("$.intBin1.get(type: INT) > $.floatBin1.asInt()", expectedExp); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.intBin1 > $.floatBin1.asInt()"), expectedExp); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.intBin1.get(type: INT) > $.floatBin1.asInt()"), expectedExp); } @Test void intToFloatComparison() { - TestUtils.parseFilterExpressionAndCompare("$.intBin1.get(type: INT) > $.intBin2.asFloat()", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.intBin1.get(type: INT) > $.intBin2.asFloat()"), Exp.gt(Exp.intBin("intBin1"), Exp.floatBin("intBin2"))); } @Test void negativeInvalidTypesComparison() { - assertThatThrownBy(() -> parseFilterExp("$.stringBin1.get(type: STRING) > $.intBin2.asFloat()")) + assertThatThrownBy(() -> parseFilterExp(ExpressionContext.of("$.stringBin1.get(type: STRING) > $.intBin2.asFloat()"))) .isInstanceOf(DslParseException.class) .hasMessageContaining("Cannot compare STRING to FLOAT"); } diff --git a/src/test/java/com/aerospike/dsl/expression/ControlStructuresTests.java b/src/test/java/com/aerospike/dsl/expression/ControlStructuresTests.java index f8c1660..e65b314 100644 --- a/src/test/java/com/aerospike/dsl/expression/ControlStructuresTests.java +++ b/src/test/java/com/aerospike/dsl/expression/ControlStructuresTests.java @@ -1,11 +1,10 @@ package com.aerospike.dsl.expression; import com.aerospike.client.exp.Exp; +import com.aerospike.dsl.ExpressionContext; import com.aerospike.dsl.util.TestUtils; import org.junit.jupiter.api.Test; -import static com.aerospike.dsl.util.TestUtils.parseDslExpressionAndCompare; - public class ControlStructuresTests { @Test @@ -18,10 +17,10 @@ void whenWithASingleDeclaration() { Exp.val("other") ); - TestUtils.parseFilterExpressionAndCompare("when ($.who == 1 => \"bob\", default => \"other\")", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("when ($.who == 1 => \"bob\", default => \"other\")"), expected); // different spacing style - TestUtils.parseFilterExpressionAndCompare("when($.who == 1 => \"bob\", default => \"other\")", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("when($.who == 1 => \"bob\", default => \"other\")"), expected); } @@ -41,7 +40,8 @@ void whenUsingTheResult() { // Implicit detect as String //translateAndCompare("$.stringBin1 == (when ($.who == 1 => \"bob\", default => \"other\"))", // expected); - TestUtils.parseFilterExpressionAndCompare("$.stringBin1.get(type: STRING) == (when ($.who == 1 => \"bob\", default => \"other\"))", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.stringBin1.get(type: STRING) == " + + "(when ($.who == 1 => \"bob\", default => \"other\"))"), expected); } @@ -59,7 +59,8 @@ void whenWithMultipleDeclarations() { Exp.val("other") ); - TestUtils.parseFilterExpressionAndCompare("when ($.who == 1 => \"bob\", $.who == 2 => \"fred\", default => \"other\")", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("when ($.who == 1 => \"bob\", " + + "$.who == 2 => \"fred\", default => \"other\")"), expected); } @@ -75,10 +76,10 @@ void withMultipleVariablesDefinitionAndUsage() { Exp.add(Exp.var("x"), Exp.var("y")) ); - TestUtils.parseFilterExpressionAndCompare("with (x = 1, y = ${x} + 1) do (${x} + ${y})", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("with (x = 1, y = ${x} + 1) do (${x} + ${y})"), expected); // different spacing style - TestUtils.parseFilterExpressionAndCompare("with(x = 1, y = ${x}+1) do(${x}+${y})", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("with(x = 1, y = ${x}+1) do(${x}+${y})"), expected); } } diff --git a/src/test/java/com/aerospike/dsl/expression/ExplicitTypesTests.java b/src/test/java/com/aerospike/dsl/expression/ExplicitTypesTests.java index 2e04bb4..d1dff38 100644 --- a/src/test/java/com/aerospike/dsl/expression/ExplicitTypesTests.java +++ b/src/test/java/com/aerospike/dsl/expression/ExplicitTypesTests.java @@ -2,6 +2,7 @@ import com.aerospike.client.exp.Exp; import com.aerospike.dsl.DslParseException; +import com.aerospike.dsl.ExpressionContext; import com.aerospike.dsl.util.TestUtils; import org.junit.jupiter.api.Test; @@ -10,7 +11,6 @@ import java.util.TreeMap; import static com.aerospike.dsl.util.TestUtils.parseFilterExp; -import static com.aerospike.dsl.util.TestUtils.parseDslExpressionAndCompare; import static org.assertj.core.api.Assertions.assertThatThrownBy; // Explicit types tests, list and map explicit types are tested in their own test classes @@ -18,33 +18,34 @@ public class ExplicitTypesTests { @Test void integerComparison() { - TestUtils.parseFilterExpressionAndCompare("$.intBin1.get(type: INT) > 5", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.intBin1.get(type: INT) > 5"), Exp.gt(Exp.intBin("intBin1"), Exp.val(5))); - TestUtils.parseFilterExpressionAndCompare("5 < $.intBin1.get(type: INT)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("5 < $.intBin1.get(type: INT)"), Exp.lt(Exp.val(5), Exp.intBin("intBin1"))); } @Test void stringComparison() { // A String constant must contain quoted Strings - TestUtils.parseFilterExpressionAndCompare("$.stringBin1.get(type: STRING) == \"yes\"", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.stringBin1.get(type: STRING) == \"yes\""), Exp.eq(Exp.stringBin("stringBin1"), Exp.val("yes"))); - TestUtils.parseFilterExpressionAndCompare("$.stringBin1.get(type: STRING) == 'yes'", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.stringBin1.get(type: STRING) == 'yes'"), Exp.eq(Exp.stringBin("stringBin1"), Exp.val("yes"))); - TestUtils.parseFilterExpressionAndCompare("\"yes\" == $.stringBin1.get(type: STRING)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("\"yes\" == $.stringBin1.get(type: STRING)"), Exp.eq(Exp.val("yes"), Exp.stringBin("stringBin1"))); - TestUtils.parseFilterExpressionAndCompare("'yes' == $.stringBin1.get(type: STRING)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("'yes' == $.stringBin1.get(type: STRING)"), Exp.eq(Exp.val("yes"), Exp.stringBin("stringBin1"))); } @Test void stringComparisonNegativeTest() { // A String constant must be quoted - assertThatThrownBy(() -> TestUtils.parseFilterExpressionAndCompare("$.stringBin1.get(type: STRING) == yes", + assertThatThrownBy(() -> + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.stringBin1.get(type: STRING) == yes"), Exp.eq(Exp.stringBin("stringBin1"), Exp.val("yes")))) .isInstanceOf(DslParseException.class) .hasMessage("Unable to parse right operand"); @@ -54,65 +55,67 @@ void stringComparisonNegativeTest() { void blobComparison() { byte[] data = new byte[]{1, 2, 3}; String encodedString = Base64.getEncoder().encodeToString(data); - TestUtils.parseFilterExpressionAndCompare("$.blobBin1.get(type: BLOB) == \"" + encodedString + "\"", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.blobBin1.get(type: BLOB) == \"" + + encodedString + "\""), Exp.eq(Exp.blobBin("blobBin1"), Exp.val(data))); // Reverse - TestUtils.parseFilterExpressionAndCompare("\"" + encodedString + "\"" + " == $.blobBin1.get(type: BLOB)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("\"" + encodedString + "\"" + + " == $.blobBin1.get(type: BLOB)"), Exp.eq(Exp.val(data), Exp.blobBin("blobBin1"))); } @Test void floatComparison() { - TestUtils.parseFilterExpressionAndCompare("$.floatBin1.get(type: FLOAT) == 1.5", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.floatBin1.get(type: FLOAT) == 1.5"), Exp.eq(Exp.floatBin("floatBin1"), Exp.val(1.5))); - TestUtils.parseFilterExpressionAndCompare("1.5 == $.floatBin1.get(type: FLOAT)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("1.5 == $.floatBin1.get(type: FLOAT)"), Exp.eq(Exp.val(1.5), Exp.floatBin("floatBin1"))); } @Test void booleanComparison() { - TestUtils.parseFilterExpressionAndCompare("$.boolBin1.get(type: BOOL) == true", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.boolBin1.get(type: BOOL) == true"), Exp.eq(Exp.boolBin("boolBin1"), Exp.val(true))); - TestUtils.parseFilterExpressionAndCompare("true == $.boolBin1.get(type: BOOL)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("true == $.boolBin1.get(type: BOOL)"), Exp.eq(Exp.val(true), Exp.boolBin("boolBin1"))); } @Test void negativeBooleanComparison() { - assertThatThrownBy(() -> parseFilterExp("$.boolBin1.get(type: BOOL) == 5")) + assertThatThrownBy(() -> parseFilterExp(ExpressionContext.of("$.boolBin1.get(type: BOOL) == 5"))) .isInstanceOf(DslParseException.class) .hasMessageContaining("Cannot compare BOOL to INT"); } @Test void listComparison_constantOnRightSide() { - TestUtils.parseFilterExpressionAndCompare("$.listBin1.get(type: LIST) == [100]", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.get(type: LIST) == [100]"), Exp.eq(Exp.listBin("listBin1"), Exp.val(List.of(100)))); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[] == [100]", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[] == [100]"), Exp.eq(Exp.listBin("listBin1"), Exp.val(List.of(100)))); // integer values are read as long - TestUtils.parseFilterExpressionAndCompare("$.listBin1.get(type: LIST) == [100, 200, 300, 400]", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.get(type: LIST) == [100, 200, 300, 400]"), Exp.eq(Exp.listBin("listBin1"), Exp.val(List.of(100, 200, 300, 400)))); // integer values are read as long - TestUtils.parseFilterExpressionAndCompare("$.listBin1.get(type: LIST) == [100, 200, 300, 400]", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.get(type: LIST) == [100, 200, 300, 400]"), Exp.eq(Exp.listBin("listBin1"), Exp.val(List.of(100L, 200L, 300L, 400L)))); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.get(type: LIST) == ['yes']", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.get(type: LIST) == ['yes']"), Exp.eq(Exp.listBin("listBin1"), Exp.val(List.of("yes")))); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.get(type: LIST) == ['yes', 'of course']", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.get(type: LIST) == ['yes', 'of course']"), Exp.eq(Exp.listBin("listBin1"), Exp.val(List.of("yes", "of course")))); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.get(type: LIST) == [\"yes\"]", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.get(type: LIST) == [\"yes\"]"), Exp.eq(Exp.listBin("listBin1"), Exp.val(List.of("yes")))); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.get(type: LIST) == [\"yes\", \"of course\"]", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.get(type: LIST) == [\"yes\", \"of course\"]"), Exp.eq(Exp.listBin("listBin1"), Exp.val(List.of("yes", "of course")))); } @@ -120,7 +123,7 @@ void listComparison_constantOnRightSide() { void listComparison_constantOnRightSide_NegativeTest() { // A String constant must be quoted assertThatThrownBy(() -> - TestUtils.parseFilterExpressionAndCompare("$.listBin1.get(type: LIST) == [yes, of course]", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.get(type: LIST) == [yes, of course]"), Exp.eq(Exp.listBin("listBin1"), Exp.val(List.of("yes", "of course")))) ) .isInstanceOf(DslParseException.class) @@ -129,30 +132,30 @@ void listComparison_constantOnRightSide_NegativeTest() { @Test void listComparison_constantOnLeftSide() { - TestUtils.parseFilterExpressionAndCompare("[100] == $.listBin1.get(type: LIST)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("[100] == $.listBin1.get(type: LIST)"), Exp.eq(Exp.val(List.of(100)), Exp.listBin("listBin1"))); - TestUtils.parseFilterExpressionAndCompare("[100] == $.listBin1.[]", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("[100] == $.listBin1.[]"), Exp.eq(Exp.val(List.of(100)), Exp.listBin("listBin1"))); // integer values are read as long - TestUtils.parseFilterExpressionAndCompare("[100, 200, 300, 400] == $.listBin1.get(type: LIST)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("[100, 200, 300, 400] == $.listBin1.get(type: LIST)"), Exp.eq(Exp.val(List.of(100, 200, 300, 400)), Exp.listBin("listBin1"))); // integer values are read as long - TestUtils.parseFilterExpressionAndCompare("[100, 200, 300, 400] == $.listBin1.get(type: LIST)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("[100, 200, 300, 400] == $.listBin1.get(type: LIST)"), Exp.eq(Exp.val(List.of(100L, 200L, 300L, 400L)), Exp.listBin("listBin1"))); - TestUtils.parseFilterExpressionAndCompare("['yes'] == $.listBin1.get(type: LIST)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("['yes'] == $.listBin1.get(type: LIST)"), Exp.eq(Exp.val(List.of("yes")), Exp.listBin("listBin1"))); - TestUtils.parseFilterExpressionAndCompare("['yes', 'of course'] == $.listBin1.get(type: LIST)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("['yes', 'of course'] == $.listBin1.get(type: LIST)"), Exp.eq(Exp.val(List.of("yes", "of course")), Exp.listBin("listBin1"))); - TestUtils.parseFilterExpressionAndCompare("[\"yes\"] == $.listBin1.get(type: LIST)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("[\"yes\"] == $.listBin1.get(type: LIST)"), Exp.eq(Exp.val(List.of("yes")), Exp.listBin("listBin1"))); - TestUtils.parseFilterExpressionAndCompare("[\"yes\", \"of course\"] == $.listBin1.get(type: LIST)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("[\"yes\", \"of course\"] == $.listBin1.get(type: LIST)"), Exp.eq(Exp.val(List.of("yes", "of course")), Exp.listBin("listBin1"))); } @@ -160,7 +163,7 @@ void listComparison_constantOnLeftSide() { void listComparison_constantOnLeftSide_NegativeTest() { // A String constant must be quoted assertThatThrownBy(() -> - TestUtils.parseFilterExpressionAndCompare("[yes, of course] == $.listBin1.get(type: LIST)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("[yes, of course] == $.listBin1.get(type: LIST)"), Exp.eq(Exp.val(List.of("yes", "of course")), Exp.listBin("listBin1"))) ) .isInstanceOf(DslParseException.class) @@ -168,7 +171,7 @@ void listComparison_constantOnLeftSide_NegativeTest() { } @SuppressWarnings("unchecked") - public static TreeMap treeMapOf(Object... entries) { + public static , V> TreeMap treeMapOf(Object... entries) { TreeMap map = new TreeMap<>(); if (entries.length % 2 != 0) { @@ -186,39 +189,40 @@ public static TreeMap treeMapOf(Object... entries) { @Test void mapComparison_constantOnRightSide() { // Prerequisite for comparing maps: both sides must be ordered maps - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.get(type: MAP) == {100:100}", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.get(type: MAP) == {100:100}"), Exp.eq(Exp.mapBin("mapBin1"), Exp.val(treeMapOf(100, 100)))); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.get(type: MAP) == {100 : 100}", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.get(type: MAP) == {100 : 100}"), Exp.eq(Exp.mapBin("mapBin1"), Exp.val(treeMapOf(100, 100)))); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{} == {100:100}", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{} == {100:100}"), Exp.eq(Exp.mapBin("mapBin1"), Exp.val(treeMapOf(100, 100)))); byte[] blobKey = new byte[]{1, 2, 3}; String encodedBlobKey = Base64.getEncoder().encodeToString(blobKey); // encoded blob key must be quoted as it is a String - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{} == {'" + encodedBlobKey + "':100}", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{} == {'" + encodedBlobKey + "':100}"), Exp.eq(Exp.mapBin("mapBin1"), Exp.val(treeMapOf(encodedBlobKey, 100)))); // integer values are read as long - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.get(type: MAP) == {100:200, 300:400}", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.get(type: MAP) == {100:200, 300:400}"), Exp.eq(Exp.mapBin("mapBin1"), Exp.val(treeMapOf(100L, 200L, 300L, 400L)))); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.get(type: MAP) == {100:200, 300:400}", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.get(type: MAP) == {100:200, 300:400}"), Exp.eq(Exp.mapBin("mapBin1"), Exp.val(treeMapOf(100, 200, 300, 400)))); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.get(type: MAP) == {'yes?':'yes!'}", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.get(type: MAP) == {'yes?':'yes!'}"), Exp.eq(Exp.mapBin("mapBin1"), Exp.val(treeMapOf("yes?", "yes!")))); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.get(type: MAP) == {\"yes\" : \"yes\"}", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.get(type: MAP) == {\"yes\" : \"yes\"}"), Exp.eq(Exp.mapBin("mapBin1"), Exp.val(treeMapOf("yes", "yes")))); TestUtils.parseFilterExpressionAndCompare( - "$.mapBin1.get(type: MAP) == {\"yes of course\" : \"yes of course\"}", + ExpressionContext.of("$.mapBin1.get(type: MAP) == {\"yes of course\" : \"yes of course\"}"), Exp.eq(Exp.mapBin("mapBin1"), Exp.val(treeMapOf("yes of course", "yes of course")))); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.get(type: MAP) == {\"yes\" : [\"yes\", \"of course\"]}", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.get(type: MAP) == " + + "{\"yes\" : [\"yes\", \"of course\"]}"), Exp.eq(Exp.mapBin("mapBin1"), Exp.val(treeMapOf("yes", List.of("yes", "of course"))))); } @@ -226,14 +230,14 @@ void mapComparison_constantOnRightSide() { void mapComparison_constantOnRightSide_NegativeTest() { // A String constant must be quoted assertThatThrownBy(() -> - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.get(type: MAP) == {yes, of course}", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.get(type: MAP) == {yes, of course}"), Exp.eq(Exp.mapBin("mapBin1"), Exp.val(treeMapOf("yes", "of course")))) ) .isInstanceOf(DslParseException.class) .hasMessage("Unable to parse map operand"); assertThatThrownBy(() -> - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.get(type: MAP) == ['yes', 'of course']", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.get(type: MAP) == ['yes', 'of course']"), Exp.eq(Exp.mapBin("mapBin1"), Exp.val(List.of("yes", "of course")))) ) .isInstanceOf(DslParseException.class) @@ -241,7 +245,7 @@ void mapComparison_constantOnRightSide_NegativeTest() { // Map key can only be Integer or String assertThatThrownBy(() -> - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.get(type: MAP) == {[100]:[100]}", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.get(type: MAP) == {[100]:[100]}"), Exp.eq(Exp.mapBin("mapBin1"), Exp.val(List.of("yes", "of course")))) ) .isInstanceOf(DslParseException.class) @@ -251,39 +255,40 @@ void mapComparison_constantOnRightSide_NegativeTest() { @Test void mapComparison_constantOnLeftSide() { // Prerequisite for comparing maps: both sides must be ordered maps - TestUtils.parseFilterExpressionAndCompare("{100:100} == $.mapBin1.get(type: MAP)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("{100:100} == $.mapBin1.get(type: MAP)"), Exp.eq(Exp.val(treeMapOf(100, 100)), Exp.mapBin("mapBin1"))); - TestUtils.parseFilterExpressionAndCompare("{100 : 100} == $.mapBin1.get(type: MAP)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("{100 : 100} == $.mapBin1.get(type: MAP)"), Exp.eq(Exp.val(treeMapOf(100, 100)), Exp.mapBin("mapBin1"))); - TestUtils.parseFilterExpressionAndCompare("{100:100} == $.mapBin1.{}", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("{100:100} == $.mapBin1.{}"), Exp.eq(Exp.val(treeMapOf(100, 100)), Exp.mapBin("mapBin1"))); byte[] blobKey = new byte[]{1, 2, 3}; String encodedBlobKey = Base64.getEncoder().encodeToString(blobKey); // encoded blob key must be quoted as it is a String - TestUtils.parseFilterExpressionAndCompare("{'" + encodedBlobKey + "':100} == $.mapBin1.{}", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("{'" + encodedBlobKey + "':100} == $.mapBin1.{}"), Exp.eq(Exp.val(treeMapOf(encodedBlobKey, 100)), Exp.mapBin("mapBin1"))); // integer values are read as long - TestUtils.parseFilterExpressionAndCompare("{100:200, 300:400} == $.mapBin1.get(type: MAP)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("{100:200, 300:400} == $.mapBin1.get(type: MAP)"), Exp.eq(Exp.val(treeMapOf(100L, 200L, 300L, 400L)), Exp.mapBin("mapBin1"))); - TestUtils.parseFilterExpressionAndCompare("{100:200, 300:400} == $.mapBin1.get(type: MAP)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("{100:200, 300:400} == $.mapBin1.get(type: MAP)"), Exp.eq(Exp.val(treeMapOf(100, 200, 300, 400)), Exp.mapBin("mapBin1"))); - TestUtils.parseFilterExpressionAndCompare("{'yes?':'yes!'} == $.mapBin1.get(type: MAP)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("{'yes?':'yes!'} == $.mapBin1.get(type: MAP)"), Exp.eq(Exp.val(treeMapOf("yes?", "yes!")), Exp.mapBin("mapBin1"))); - TestUtils.parseFilterExpressionAndCompare("{\"yes\" : \"yes\"} == $.mapBin1.get(type: MAP)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("{\"yes\" : \"yes\"} == $.mapBin1.get(type: MAP)"), Exp.eq(Exp.val(treeMapOf("yes", "yes")), Exp.mapBin("mapBin1"))); TestUtils.parseFilterExpressionAndCompare( - "{\"yes of course\" : \"yes of course\"} == $.mapBin1.get(type: MAP)", + ExpressionContext.of("{\"yes of course\" : \"yes of course\"} == $.mapBin1.get(type: MAP)"), Exp.eq(Exp.val(treeMapOf("yes of course", "yes of course")), Exp.mapBin("mapBin1"))); - TestUtils.parseFilterExpressionAndCompare("{\"yes\" : [\"yes\", \"of course\"]} == $.mapBin1.get(type: MAP)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("{\"yes\" : [\"yes\", \"of course\"]} " + + "== $.mapBin1.get(type: MAP)"), Exp.eq(Exp.val(treeMapOf("yes", List.of("yes", "of course"))), Exp.mapBin("mapBin1"))); } @@ -291,14 +296,14 @@ void mapComparison_constantOnLeftSide() { void mapComparison_constantOnLeftSide_NegativeTest() { // A String constant must be quoted assertThatThrownBy(() -> - TestUtils.parseFilterExpressionAndCompare("{yes, of course} == $.mapBin1.get(type: MAP)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("{yes, of course} == $.mapBin1.get(type: MAP)"), Exp.eq(Exp.mapBin("mapBin1"), Exp.val(treeMapOf("of course", "yes")))) ) .isInstanceOf(DslParseException.class) .hasMessage("Could not parse given DSL expression input"); assertThatThrownBy(() -> - TestUtils.parseFilterExpressionAndCompare("['yes', 'of course'] == $.mapBin1.get(type: MAP)", // incorrect: must be {} + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("['yes', 'of course'] == $.mapBin1.get(type: MAP)"), // incorrect: must be {} Exp.eq(Exp.val(List.of("yes", "of course")), Exp.mapBin("mapBin1"))) ) .isInstanceOf(DslParseException.class) @@ -306,7 +311,7 @@ void mapComparison_constantOnLeftSide_NegativeTest() { // Map key can only be Integer or String assertThatThrownBy(() -> - TestUtils.parseFilterExpressionAndCompare("{[100]:[100]} == $.mapBin1.get(type: MAP)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("{[100]:[100]} == $.mapBin1.get(type: MAP)"), Exp.eq(Exp.val(List.of("yes", "of course")), Exp.mapBin("mapBin1"))) ) .isInstanceOf(DslParseException.class) @@ -315,45 +320,45 @@ void mapComparison_constantOnLeftSide_NegativeTest() { @Test void twoStringBinsComparison() { - TestUtils.parseFilterExpressionAndCompare("$.stringBin1.get(type: STRING) == $.stringBin2.get(type: STRING)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.stringBin1.get(type: STRING) == $.stringBin2.get(type: STRING)"), Exp.eq(Exp.stringBin("stringBin1"), Exp.stringBin("stringBin2"))); } @Test void twoIntegerBinsComparison() { - TestUtils.parseFilterExpressionAndCompare("$.intBin1.get(type: INT) == $.intBin2.get(type: INT)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.intBin1.get(type: INT) == $.intBin2.get(type: INT)"), Exp.eq(Exp.intBin("intBin1"), Exp.intBin("intBin2"))); } @Test void twoFloatBinsComparison() { - TestUtils.parseFilterExpressionAndCompare("$.floatBin1.get(type: FLOAT) == $.floatBin2.get(type: FLOAT)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.floatBin1.get(type: FLOAT) == $.floatBin2.get(type: FLOAT)"), Exp.eq(Exp.floatBin("floatBin1"), Exp.floatBin("floatBin2"))); } @Test void twoBlobBinsComparison() { - TestUtils.parseFilterExpressionAndCompare("$.blobBin1.get(type: BLOB) == $.blobBin2.get(type: BLOB)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.blobBin1.get(type: BLOB) == $.blobBin2.get(type: BLOB)"), Exp.eq(Exp.blobBin("blobBin1"), Exp.blobBin("blobBin2"))); } @Test void negativeTwoDifferentBinTypesComparison() { - assertThatThrownBy(() -> parseFilterExp("$.stringBin1.get(type: STRING) == $.floatBin2.get(type: FLOAT)")) + assertThatThrownBy(() -> parseFilterExp(ExpressionContext.of("$.stringBin1.get(type: STRING) == $.floatBin2.get(type: FLOAT)"))) .isInstanceOf(DslParseException.class) .hasMessageContaining("Cannot compare STRING to FLOAT"); } @Test void secondDegreeExplicitFloat() { - TestUtils.parseFilterExpressionAndCompare("($.apples.get(type: FLOAT) + $.bananas.get(type: FLOAT)) > 10.5", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples.get(type: FLOAT) + $.bananas.get(type: FLOAT)) > 10.5"), Exp.gt(Exp.add(Exp.floatBin("apples"), Exp.floatBin("bananas")), Exp.val(10.5))); } @Test void forthDegreeComplicatedExplicitFloat() { - TestUtils.parseFilterExpressionAndCompare("(($.apples.get(type: FLOAT) + $.bananas.get(type: FLOAT))" + - " + ($.oranges.get(type: FLOAT) + $.acai.get(type: FLOAT))) > 10.5", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("(($.apples.get(type: FLOAT) + $.bananas.get(type: FLOAT))" + + " + ($.oranges.get(type: FLOAT) + $.acai.get(type: FLOAT))) > 10.5"), Exp.gt( Exp.add( Exp.add(Exp.floatBin("apples"), Exp.floatBin("bananas")), @@ -383,11 +388,11 @@ void complicatedWhenExplicitTypeIntDefault() { ) ); - TestUtils.parseFilterExpressionAndCompare("$.a.get(type: INT) == " + + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.a.get(type: INT) == " + "(when($.b.get(type: INT) == 1 => $.a1.get(type: INT)," + " $.b.get(type: INT) == 2 => $.a2.get(type: INT)," + " $.b.get(type: INT) == 3 => $.a3.get(type: INT)," + - " default => $.a4.get(type: INT) + 1))", + " default => $.a4.get(type: INT) + 1))"), expected); } @@ -412,11 +417,11 @@ void complicatedWhenExplicitTypeString() { ) ); - TestUtils.parseFilterExpressionAndCompare("$.a.get(type: STRING) == " + + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.a.get(type: STRING) == " + "(when($.b == 1 => $.a1.get(type: STRING)," + " $.b == 2 => $.a2.get(type: STRING)," + " $.b == 3 => $.a3.get(type: STRING)," + - " default => \"hello\")", + " default => \"hello\"))"), expected); } } diff --git a/src/test/java/com/aerospike/dsl/expression/ImplicitTypesTests.java b/src/test/java/com/aerospike/dsl/expression/ImplicitTypesTests.java index 059b30f..714276e 100644 --- a/src/test/java/com/aerospike/dsl/expression/ImplicitTypesTests.java +++ b/src/test/java/com/aerospike/dsl/expression/ImplicitTypesTests.java @@ -1,6 +1,7 @@ package com.aerospike.dsl.expression; import com.aerospike.client.exp.Exp; +import com.aerospike.dsl.ExpressionContext; import com.aerospike.dsl.util.TestUtils; import org.junit.jupiter.api.Test; @@ -8,17 +9,17 @@ public class ImplicitTypesTests { @Test void floatComparison() { - TestUtils.parseFilterExpressionAndCompare("$.floatBin1 >= 100.25", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.floatBin1 >= 100.25"), Exp.ge(Exp.floatBin("floatBin1"), Exp.val(100.25))); } @Test void booleanComparison() { - TestUtils.parseFilterExpressionAndCompare("$.boolBin1 == true", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.boolBin1 == true"), Exp.eq(Exp.boolBin("boolBin1"), Exp.val(true))); - TestUtils.parseFilterExpressionAndCompare("false == $.boolBin1", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("false == $.boolBin1"), Exp.eq(Exp.val(false), Exp.boolBin("boolBin1"))); - TestUtils.parseFilterExpressionAndCompare("$.boolBin1 != false", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.boolBin1 != false"), Exp.ne(Exp.boolBin("boolBin1"), Exp.val(false))); } @@ -26,31 +27,32 @@ void booleanComparison() { // this can also be an expression that evaluates to a boolean result @Test void binBooleanImplicitLogicalComparison() { - TestUtils.parseFilterExpressionAndCompare("$.boolBin1 and $.boolBin2", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.boolBin1 and $.boolBin2"), Exp.and(Exp.boolBin("boolBin1"), Exp.boolBin("boolBin2"))); - TestUtils.parseFilterExpressionAndCompare("$.boolBin1 or $.boolBin2", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.boolBin1 or $.boolBin2"), Exp.or(Exp.boolBin("boolBin1"), Exp.boolBin("boolBin2"))); - TestUtils.parseFilterExpressionAndCompare("not($.boolBin1)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("not($.boolBin1)"), Exp.not(Exp.boolBin("boolBin1"))); - TestUtils.parseFilterExpressionAndCompare("exclusive($.boolBin1, $.boolBin2)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("exclusive($.boolBin1, $.boolBin2)"), Exp.exclusive(Exp.boolBin("boolBin1"), Exp.boolBin("boolBin2"))); } @Test void implicitDefaultIntComparison() { - TestUtils.parseFilterExpressionAndCompare("$.intBin1 < $.intBin2", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.intBin1 < $.intBin2"), Exp.lt(Exp.intBin("intBin1"), Exp.intBin("intBin2"))); } @Test void secondDegreeImplicitCastingFloat() { - TestUtils.parseFilterExpressionAndCompare("($.apples + $.bananas) > 10.5", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples + $.bananas) > 10.5"), Exp.gt(Exp.add(Exp.floatBin("apples"), Exp.floatBin("bananas")), Exp.val(10.5))); } @Test void secondDegreeComplicatedFloatFirstImplicitCastingFloat() { - TestUtils.parseFilterExpressionAndCompare("($.apples + $.bananas) > 10.5 and ($.oranges + $.grapes) <= 5", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples + $.bananas) > 10.5 " + + "and ($.oranges + $.grapes) <= 5"), Exp.and( Exp.gt(Exp.add(Exp.floatBin("apples"), Exp.floatBin("bananas")), Exp.val(10.5)), Exp.le(Exp.add(Exp.intBin("oranges"), Exp.intBin("grapes")), Exp.val(5))) @@ -59,7 +61,8 @@ void secondDegreeComplicatedFloatFirstImplicitCastingFloat() { @Test void secondDegreeComplicatedIntFirstImplicitCastingFloat() { - TestUtils.parseFilterExpressionAndCompare("($.apples + $.bananas) > 5 and ($.oranges + $.grapes) <= 10.5", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.apples + $.bananas) > 5 " + + "and ($.oranges + $.grapes) <= 10.5"), Exp.and( Exp.gt(Exp.add(Exp.intBin("apples"), Exp.intBin("bananas")), Exp.val(5)), Exp.le(Exp.add(Exp.floatBin("oranges"), Exp.floatBin("grapes")), Exp.val(10.5))) @@ -68,7 +71,7 @@ void secondDegreeComplicatedIntFirstImplicitCastingFloat() { @Test void thirdDegreeComplicatedDefaultInt() { - TestUtils.parseFilterExpressionAndCompare("(($.apples + $.bananas) + $.oranges) > 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("(($.apples + $.bananas) + $.oranges) > 10"), Exp.gt( Exp.add(Exp.add(Exp.intBin("apples"), Exp.intBin("bananas")), Exp.intBin("oranges")), Exp.val(10)) @@ -77,7 +80,7 @@ void thirdDegreeComplicatedDefaultInt() { @Test void thirdDegreeComplicatedImplicitCastingFloat() { - TestUtils.parseFilterExpressionAndCompare("(($.apples + $.bananas) + $.oranges) > 10.5", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("(($.apples + $.bananas) + $.oranges) > 10.5"), Exp.gt( Exp.add( Exp.add(Exp.floatBin("apples"), Exp.floatBin("bananas")), @@ -89,7 +92,7 @@ void thirdDegreeComplicatedImplicitCastingFloat() { @Test void forthDegreeComplicatedDefaultInt() { - TestUtils.parseFilterExpressionAndCompare("(($.apples + $.bananas) + ($.oranges + $.acai)) > 10", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("(($.apples + $.bananas) + ($.oranges + $.acai)) > 10"), Exp.gt( Exp.add( Exp.add(Exp.intBin("apples"), Exp.intBin("bananas")), @@ -100,7 +103,7 @@ void forthDegreeComplicatedDefaultInt() { @Test void forthDegreeComplicatedImplicitCastingFloat() { - TestUtils.parseFilterExpressionAndCompare("(($.apples + $.bananas) + ($.oranges + $.acai)) > 10.5", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("(($.apples + $.bananas) + ($.oranges + $.acai)) > 10.5"), Exp.gt( Exp.add( Exp.add(Exp.floatBin("apples"), Exp.floatBin("bananas")), @@ -130,9 +133,8 @@ void complicatedWhenImplicitTypeInt() { ) ); - TestUtils.parseFilterExpressionAndCompare("$.a == (when($.b == 1 => $.a1, $.b == 2 => $.a2, $.b == 3 => $.a3, " + - "default => $.a4+1))", - expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.a == (when($.b == 1 => $.a1, $.b == 2 => $.a2, " + + "$.b == 3 => $.a3, default => $.a4+1))"), expected); } // TODO: FMWK-533 Implicit Type Detection for Control Structures @@ -157,8 +159,7 @@ void complicatedWhenImplicitTypeString() { ) ); - TestUtils.parseFilterExpressionAndCompare("$.a == (when($.b == 1 => $.a1, $.b == 2 => $.a2, $.b == 3 => $.a3, " + - "default => \"hello\"))", - expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.a == (when($.b == 1 => $.a1, $.b == 2 => $.a2, " + + "$.b == 3 => $.a3, default => \"hello\"))"), expected); } } diff --git a/src/test/java/com/aerospike/dsl/expression/ListExpressionsTests.java b/src/test/java/com/aerospike/dsl/expression/ListExpressionsTests.java index f3ed559..0208226 100644 --- a/src/test/java/com/aerospike/dsl/expression/ListExpressionsTests.java +++ b/src/test/java/com/aerospike/dsl/expression/ListExpressionsTests.java @@ -5,6 +5,7 @@ import com.aerospike.client.exp.Exp; import com.aerospike.client.exp.ListExp; import com.aerospike.dsl.DslParseException; +import com.aerospike.dsl.ExpressionContext; import com.aerospike.dsl.util.TestUtils; import org.junit.jupiter.api.Test; @@ -26,10 +27,11 @@ void listByIndexInteger() { ), Exp.val(100)); // Implicit detect as Int - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[0] == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[0].get(type: INT) == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[0].get(type: INT, return: VALUE) == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[0].asInt() == 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[0] == 100"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[0].get(type: INT) == 100"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[0].get(type: INT, return: VALUE) == 100"), + expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[0].asInt() == 100"), expected); } @Test @@ -43,9 +45,11 @@ void listByIndexOtherTypes() { ), Exp.val("stringVal")); // Implicit detect as string - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[0] == \"stringVal\"", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[0].get(type: STRING) == \"stringVal\"", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[0].get(type: STRING, return: VALUE) == \"stringVal\"", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[0] == \"stringVal\""), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[0].get(type: STRING) == \"stringVal\""), + expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[0].get(type: STRING, return: VALUE)" + + " == \"stringVal\""), expected); expected = Exp.eq( ListExp.getByIndex( @@ -56,9 +60,10 @@ void listByIndexOtherTypes() { ), Exp.val(true)); // Implicit detect as boolean - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[0] == true", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[0].get(type: BOOL) == true", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[0].get(type: BOOL, return: VALUE) == true", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[0] == true"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[0].get(type: BOOL) == true"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[0].get(type: BOOL, return: VALUE) == true"), + expected); } @Test @@ -70,10 +75,11 @@ void listByValue() { Exp.listBin("listBin1") ), Exp.val(100)); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[=100] == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[=100].get(type: INT) == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[=100].get(type: INT, return: VALUE) == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[=100].asInt() == 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[=100] == 100"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[=100].get(type: INT) == 100"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[=100].get(type: INT, return: VALUE) == 100"), + expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[=100].asInt() == 100"), expected); } @Test @@ -84,8 +90,8 @@ void listByValueCount() { Exp.listBin("listBin1")), Exp.val(0) ); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[=100].count() > 0", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[=100].[].count() > 0", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[=100].count() > 0"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[=100].[].count() > 0"), expected); } @Test @@ -98,10 +104,11 @@ void listByRank() { Exp.listBin("listBin1") ), Exp.val(100)); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[#-1] == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[#-1].get(type: INT) == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[#-1].get(type: INT, return: VALUE) == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[#-1].asInt() == 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[#-1] == 100"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[#-1].get(type: INT) == 100"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[#-1].get(type: INT, return: VALUE) == 100"), + expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[#-1].asInt() == 100"), expected); } @Test @@ -116,9 +123,11 @@ void listBinElementEquals_Nested() { CTX.listIndex(0) ), Exp.val(100)); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[0].[0].[0] == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[0].[0].[0].get(type: INT) == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[0].[0].[0].get(type: INT, return: VALUE) == 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[0].[0].[0] == 100"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[0].[0].[0].get(type: INT) == 100"), + expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[0].[0].[0].get(type: INT, return: VALUE) == 100"), + expected); } @Test @@ -126,10 +135,10 @@ void listSize() { Exp expected = Exp.eq( ListExp.size(Exp.listBin("listBin1")), Exp.val(1)); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[].count() == 1", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[].count() == 1"), expected); // the default behaviour for count() without List '[]' or Map '{}' designators is List - TestUtils.parseFilterExpressionAndCompare("$.listBin1.count() == 1", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.count() == 1"), expected); } @Test @@ -143,10 +152,10 @@ void nestedListSize() { Exp.listBin("listBin1")) ), Exp.val(100)); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[1].[].count() == 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[1].[].count() == 100"), expected); // the default behaviour for count() without List '[]' or Map '{}' designators is List - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[1].count() == 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[1].count() == 100"), expected); } @@ -162,10 +171,10 @@ void nestedListSizeWithContext() { CTX.listIndex(1)) ), Exp.val(100)); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[1].[2].[].count() == 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[1].[2].[].count() == 100"), expected); // the default behaviour for count() without List '[]' or Map '{}' designators is List - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[1].[2].count() == 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[1].[2].count() == 100"), expected); } @Test @@ -179,7 +188,8 @@ void nestedLists() { CTX.listIndex(5) ), Exp.val("stringVal")); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[5].[1].get(type: STRING) == \"stringVal\"", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[5].[1].get(type: STRING) == \"stringVal\""), + expected); } @Test @@ -195,8 +205,9 @@ void nestedListsWithDifferentContextTypes() { ), Exp.val("stringVal")); // Implicit detect as String - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[5].[#-1] == \"stringVal\"", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[5].[#-1].get(type: STRING) == \"stringVal\"", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[5].[#-1] == \"stringVal\""), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[5].[#-1].get(type: STRING) == \"stringVal\""), + expected); // Nested List Rank Value expected = Exp.eq( @@ -209,7 +220,7 @@ void nestedListsWithDifferentContextTypes() { ), Exp.val(200)); // Implicit detect as Int - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[5].[#-1].[=100] == 200", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[5].[#-1].[=100] == 200"), expected); } @Test @@ -223,21 +234,21 @@ void listBinElementCount() { ), Exp.val(100) ); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[0].count() == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[0].[].count() == 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[0].count() == 100"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[0].[].count() == 100"), expected); } @Test void negativeSyntaxList() { // TODO: throw meaningful exception (by ANTLR?) - assertThatThrownBy(() -> parseFilterExp("$.listBin1.[stringValue] == 100")) + assertThatThrownBy(() -> parseFilterExp(ExpressionContext.of("$.listBin1.[stringValue] == 100"))) .isInstanceOf(DslParseException.class); } //@Test void negativeTypeComparisonList() { // TODO: should fail? Exp is successfully created but comparing int to a string value (validations on List) - assertThatThrownBy(() -> parseFilterExp("$.listBin1.[#-1].get(type: INT) == \"stringValue\"")) + assertThatThrownBy(() -> parseFilterExp(ExpressionContext.of("$.listBin1.[#-1].get(type: INT) == \"stringValue\""))) .isInstanceOf(NullPointerException.class); } @@ -248,7 +259,7 @@ void listIndexRange() { Exp.val(1), Exp.val(2), Exp.listBin("listBin1")); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[1:3]", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[1:3]"), expected); // Negative expected = ListExp.getByIndexRange( @@ -256,7 +267,7 @@ void listIndexRange() { Exp.val(-3), Exp.val(4), Exp.listBin("listBin1")); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[-3:1]", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[-3:1]"), expected); // Inverted expected = ListExp.getByIndexRange( @@ -264,14 +275,14 @@ void listIndexRange() { Exp.val(2), Exp.val(2), Exp.listBin("listBin1")); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[!2:4]", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[!2:4]"), expected); // From start till the end expected = ListExp.getByIndexRange( ListReturnType.VALUE, Exp.val(1), Exp.listBin("listBin1")); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[1:]", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[1:]"), expected); } @Test @@ -280,23 +291,23 @@ void listValueList() { ListReturnType.VALUE, Exp.val(List.of("a", "b", "c")), Exp.listBin("listBin1")); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[=a,b,c]", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[=\"a\",\"b\",\"c\"]", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[=a,b,c]"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[=\"a\",\"b\",\"c\"]"), expected); // Integer expected = ListExp.getByValueList( ListReturnType.VALUE, Exp.val(List.of(1, 2, 3)), Exp.listBin("listBin1")); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[=1,2,3]", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[=1,2,3]"), expected); // Inverted expected = ListExp.getByValueList( ListReturnType.VALUE | ListReturnType.INVERTED, Exp.val(List.of("a", "b", "c")), Exp.listBin("listBin1")); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[!=a,b,c]", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[!=\"a\",\"b\",\"c\"]", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[!=a,b,c]"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[!=\"a\",\"b\",\"c\"]"), expected); } @Test @@ -307,7 +318,7 @@ void listValueRange() { Exp.val(111), Exp.val(334), Exp.listBin("listBin1")); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[=111:334]", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[=111:334]"), expected); // Inverted expected = ListExp.getByValueRange( @@ -315,7 +326,7 @@ void listValueRange() { Exp.val(10), Exp.val(20), Exp.listBin("listBin1")); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[!=10:20]", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[!=10:20]"), expected); // From start till the end expected = ListExp.getByValueRange( @@ -323,7 +334,7 @@ void listValueRange() { Exp.val(111), null, Exp.listBin("listBin1")); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[=111:]", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[=111:]"), expected); } @Test @@ -333,7 +344,7 @@ void listRankRange() { Exp.val(0), Exp.val(3), Exp.listBin("listBin1")); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[#0:3]", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[#0:3]"), expected); // Inverted expected = ListExp.getByRankRange( @@ -341,14 +352,14 @@ void listRankRange() { Exp.val(0), Exp.val(3), Exp.listBin("listBin1")); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[!#0:3]", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[!#0:3]"), expected); // From start till the end expected = ListExp.getByRankRange( ListReturnType.VALUE, Exp.val(-3), Exp.listBin("listBin1")); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[#-3:]", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[#-3:]"), expected); // From start till the end with context expected = ListExp.getByRankRange( @@ -356,7 +367,7 @@ void listRankRange() { Exp.val(-3), Exp.listBin("listBin1"), CTX.listIndex(5)); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[5].[#-3:]", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[5].[#-3:]"), expected); } @Test @@ -367,7 +378,7 @@ void listRankRangeRelative() { Exp.val("b"), Exp.val(2), Exp.listBin("listBin1")); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[#-3:-1~b]", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[#-3:-1~b]"), expected); // Inverted expected = ListExp.getByValueRelativeRankRange( @@ -376,7 +387,7 @@ void listRankRangeRelative() { Exp.val("b"), Exp.val(2), Exp.listBin("listBin1")); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[!#-3:-1~b]", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[!#-3:-1~b]"), expected); // From start till the end expected = ListExp.getByValueRelativeRankRange( @@ -384,7 +395,7 @@ void listRankRangeRelative() { Exp.val(-3), Exp.val("b"), Exp.listBin("listBin1")); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[#-3:~b]", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[#-3:~b]"), expected); } @Test @@ -397,7 +408,7 @@ void listReturnTypes() { Exp.listBin("listBin1") ), Exp.val(5)); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[0].get(return: COUNT) == 5", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[0].get(return: COUNT) == 5"), expected); expected = Exp.eq( ListExp.getByIndex( @@ -408,7 +419,7 @@ void listReturnTypes() { ), Exp.val(true)); // Implicit detect as BOOL - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[0].get(return: EXISTS) == true", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[0].get(return: EXISTS) == true"), expected); expected = Exp.eq( ListExp.getByIndex( @@ -419,6 +430,6 @@ void listReturnTypes() { ), Exp.val(1)); // Implicit detect as INT - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[0].get(return: INDEX) == 1", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[0].get(return: INDEX) == 1"), expected); } } diff --git a/src/test/java/com/aerospike/dsl/expression/LogicalExpressionsTests.java b/src/test/java/com/aerospike/dsl/expression/LogicalExpressionsTests.java index 1c1cbf8..9d32f72 100644 --- a/src/test/java/com/aerospike/dsl/expression/LogicalExpressionsTests.java +++ b/src/test/java/com/aerospike/dsl/expression/LogicalExpressionsTests.java @@ -2,6 +2,7 @@ import com.aerospike.client.exp.Exp; import com.aerospike.dsl.DslParseException; +import com.aerospike.dsl.ExpressionContext; import com.aerospike.dsl.util.TestUtils; import org.junit.jupiter.api.Test; import org.opentest4j.AssertionFailedError; @@ -15,7 +16,7 @@ public class LogicalExpressionsTests { void binLogicalAndOrCombinations() { Exp expected1 = Exp.and(Exp.gt(Exp.intBin("intBin1"), Exp.val(100)), Exp.gt(Exp.intBin("intBin2"), Exp.val(100))); - TestUtils.parseFilterExpressionAndCompare("$.intBin1 > 100 and $.intBin2 > 100", expected1); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 and $.intBin2 > 100"), expected1); Exp expected2 = Exp.or( Exp.and( @@ -24,9 +25,12 @@ void binLogicalAndOrCombinations() { ), Exp.lt(Exp.intBin("intBin3"), Exp.val(100)) ); - TestUtils.parseFilterExpressionAndCompare("$.intBin1 > 100 and $.intBin2 > 100 or $.intBin3 < 100", expected2); - TestUtils.parseFilterExpressionAndCompare("($.intBin1 > 100 and $.intBin2 > 100) or $.intBin3 < 100", expected2); - TestUtils.parseFilterExpressionAndCompare("(($.intBin1 > 100 and $.intBin2 > 100) or $.intBin3 < 100)", expected2); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 and $.intBin2 > 100 or $.intBin3 < 100"), + expected2); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.intBin1 > 100 and $.intBin2 > 100) or $.intBin3 < 100"), + expected2); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("(($.intBin1 > 100 and $.intBin2 > 100) or $.intBin3 < 100)"), + expected2); Exp expected3 = Exp.and( Exp.gt(Exp.intBin("intBin1"), Exp.val(100)), @@ -35,28 +39,32 @@ void binLogicalAndOrCombinations() { Exp.lt(Exp.intBin("intBin3"), Exp.val(100)) ) ); - TestUtils.parseFilterExpressionAndCompare("($.intBin1 > 100 and ($.intBin2 > 100 or $.intBin3 < 100))", expected3); - TestUtils.parseFilterExpressionAndCompare("$.intBin1 > 100 and ($.intBin2 > 100 or $.intBin3 < 100)", expected3); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.intBin1 > 100 and ($.intBin2 > 100 or $.intBin3 < 100))"), + expected3); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 and ($.intBin2 > 100 or $.intBin3 < 100)"), + expected3); // Check that parentheses make difference assertThatThrownBy( - () -> TestUtils.parseFilterExpressionAndCompare("($.intBin1 > 100 and ($.intBin2 > 100 or $.intBin3 < 100))", expected2) + () -> TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("($.intBin1 > 100 and" + + " ($.intBin2 > 100 or $.intBin3 < 100))"), expected2) ).isInstanceOf(AssertionFailedError.class); } @Test void logicalNot() { - TestUtils.parseFilterExpressionAndCompare("not($.keyExists())", Exp.not(Exp.keyExists())); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("not($.keyExists())"), Exp.not(Exp.keyExists())); } @Test void binLogicalExclusive() { - TestUtils.parseFilterExpressionAndCompare("exclusive($.hand == \"hook\", $.leg == \"peg\")", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("exclusive($.hand == \"hook\", $.leg == \"peg\")"), Exp.exclusive( Exp.eq(Exp.stringBin("hand"), Exp.val("hook")), Exp.eq(Exp.stringBin("leg"), Exp.val("peg")))); // More than 2 expressions exclusive - TestUtils.parseFilterExpressionAndCompare("exclusive($.a == \"aVal\", $.b == \"bVal\", $.c == \"cVal\", $.d == 4)", + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("exclusive($.a == \"aVal\", $.b == \"bVal\", " + + "$.c == \"cVal\", $.d == 4)"), Exp.exclusive( Exp.eq(Exp.stringBin("a"), Exp.val("aVal")), Exp.eq(Exp.stringBin("b"), Exp.val("bVal")), @@ -67,7 +75,7 @@ void binLogicalExclusive() { @Test void flatHierarchyAnd() { TestUtils.parseFilterExpressionAndCompare( - "$.intBin1 > 100 and $.intBin2 > 100 and $.intBin3 < 100 and $.intBin4 < 100", + ExpressionContext.of("$.intBin1 > 100 and $.intBin2 > 100 and $.intBin3 < 100 and $.intBin4 < 100"), Exp.and( Exp.gt(Exp.intBin("intBin1"), Exp.val(100)), Exp.gt(Exp.intBin("intBin2"), Exp.val(100)), @@ -79,26 +87,26 @@ void flatHierarchyAnd() { @Test void negativeSyntaxLogicalOperators() { - assertThatThrownBy(() -> parseFilterExp("($.intBin1 > 100 and ($.intBin2 > 100) or")) + assertThatThrownBy(() -> parseFilterExp(ExpressionContext.of("($.intBin1 > 100 and ($.intBin2 > 100) or"))) .isInstanceOf(DslParseException.class) .hasMessageContaining("Could not parse given DSL expression input"); - assertThatThrownBy(() -> parseFilterExp("and ($.intBin1 > 100 and ($.intBin2 > 100)")) + assertThatThrownBy(() -> parseFilterExp(ExpressionContext.of("and ($.intBin1 > 100 and ($.intBin2 > 100)"))) .isInstanceOf(DslParseException.class) .hasMessageContaining("Could not parse given DSL expression input"); - assertThatThrownBy(() -> parseFilterExp("($.intBin1 > 100 and ($.intBin2 > 100) not")) + assertThatThrownBy(() -> parseFilterExp(ExpressionContext.of("($.intBin1 > 100 and ($.intBin2 > 100) not"))) .isInstanceOf(DslParseException.class) .hasMessageContaining("Could not parse given DSL expression input"); - assertThatThrownBy(() -> parseFilterExp("($.intBin1 > 100 and ($.intBin2 > 100) exclusive")) + assertThatThrownBy(() -> parseFilterExp(ExpressionContext.of("($.intBin1 > 100 and ($.intBin2 > 100) exclusive"))) .isInstanceOf(DslParseException.class) .hasMessageContaining("Could not parse given DSL expression input"); } @Test void negativeBinLogicalExclusiveWithOneParam() { - assertThatThrownBy(() -> TestUtils.parseFilterExpressionAndCompare("exclusive($.hand == \"hook\")", + assertThatThrownBy(() -> TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("exclusive($.hand == \"hook\")"), Exp.exclusive( Exp.eq(Exp.stringBin("hand"), Exp.val("hook"))))) .isInstanceOf(DslParseException.class) diff --git a/src/test/java/com/aerospike/dsl/expression/MapAndListExpressionsTests.java b/src/test/java/com/aerospike/dsl/expression/MapAndListExpressionsTests.java index 68158b3..16926e7 100644 --- a/src/test/java/com/aerospike/dsl/expression/MapAndListExpressionsTests.java +++ b/src/test/java/com/aerospike/dsl/expression/MapAndListExpressionsTests.java @@ -7,6 +7,7 @@ import com.aerospike.client.exp.Exp; import com.aerospike.client.exp.ListExp; import com.aerospike.client.exp.MapExp; +import com.aerospike.dsl.ExpressionContext; import com.aerospike.dsl.util.TestUtils; import org.junit.jupiter.api.Test; @@ -23,7 +24,7 @@ void listInsideAMap() { CTX.mapKey(Value.get("a")) ), Exp.val(100)); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.[0] == 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.[0] == 100"), expected); expected = Exp.gt( ListExp.getByIndex( @@ -34,7 +35,7 @@ void listInsideAMap() { CTX.mapKey(Value.get("a")), CTX.mapKey(Value.get("cc")) ), Exp.val(100)); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.cc.[2].get(type: INT) > 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.cc.[2].get(type: INT) > 100"), expected); } @Test @@ -49,7 +50,7 @@ void mapListList() { CTX.listIndex(0) ), Exp.val(100)); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.[0].[0] == 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.[0].[0] == 100"), expected); } @Test @@ -62,7 +63,7 @@ void mapInsideAList() { Exp.listBin("listBin1"), CTX.listIndex(2) ), Exp.val(100)); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[2].cc.get(type: INT) > 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[2].cc.get(type: INT) > 100"), expected); } @Test @@ -76,8 +77,8 @@ void listMapMap() { CTX.listIndex(2), CTX.mapKey(Value.get("aa")) ), Exp.val(100)); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[2].aa.cc > 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[2].aa.cc.get(type: INT) > 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[2].aa.cc > 100"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[2].aa.cc.get(type: INT) > 100"), expected); } @Test @@ -92,7 +93,7 @@ void listMapList() { CTX.mapKey(Value.get("a")) ), Exp.val(100)); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[1].a.[0] == 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[1].a.[0] == 100"), expected); } @Test @@ -109,8 +110,8 @@ void listMapListSize() { ) ), Exp.val(100)); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[1].a.[0].count() == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.listBin1.[1].a.[0].[].count() == 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[1].a.[0].count() == 100"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[1].a.[0].[].count() == 100"), expected); } @Test @@ -124,8 +125,8 @@ void mapListMap() { CTX.mapKey(Value.get("a")), CTX.listIndex(0) ), Exp.val(100)); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.[0].cc > 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.[0].cc.get(type: INT) > 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.[0].cc > 100"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.[0].cc.get(type: INT) > 100"), expected); } // @Test diff --git a/src/test/java/com/aerospike/dsl/expression/MapExpressionsTests.java b/src/test/java/com/aerospike/dsl/expression/MapExpressionsTests.java index 61ead01..4399d7c 100644 --- a/src/test/java/com/aerospike/dsl/expression/MapExpressionsTests.java +++ b/src/test/java/com/aerospike/dsl/expression/MapExpressionsTests.java @@ -7,13 +7,12 @@ import com.aerospike.client.exp.Exp; import com.aerospike.client.exp.ListExp; import com.aerospike.client.exp.MapExp; +import com.aerospike.dsl.ExpressionContext; import com.aerospike.dsl.util.TestUtils; import org.junit.jupiter.api.Test; import java.util.List; -import static com.aerospike.dsl.util.TestUtils.parseDslExpressionAndCompare; - public class MapExpressionsTests { @Test @@ -28,10 +27,11 @@ void mapOneLevelExpressions() { ), Exp.val(200)); // Implicit detect as Int - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a == 200", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.get(type: INT) == 200", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.get(type: INT, return: VALUE) == 200", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.asInt() == 200", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a == 200"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.get(type: INT) == 200"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.get(type: INT, return: VALUE) == 200"), + expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.asInt() == 200"), expected); // String expected = Exp.eq( @@ -43,9 +43,11 @@ void mapOneLevelExpressions() { ), Exp.val("stringVal")); // Implicit detect as String - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a == \"stringVal\"", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.get(type: STRING) == \"stringVal\"", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.get(type: STRING, return: VALUE) == \"stringVal\"", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a == \"stringVal\""), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.get(type: STRING) == \"stringVal\""), + expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.get(type: STRING, return: VALUE) ==" + + " \"stringVal\""), expected); } @Test @@ -59,9 +61,10 @@ void mapNestedLevelExpressions() { CTX.mapKey(Value.get("a")), CTX.mapKey(Value.get("bb")) ), Exp.val(200)); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.bb.bcc > 200", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.bb.bcc.get(type: INT) > 200", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.bb.bcc.get(type: INT, return: VALUE) > 200", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.bb.bcc > 200"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.bb.bcc.get(type: INT) > 200"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.bb.bcc.get(type: INT, return: VALUE) > 200"), + expected); // String expected = Exp.eq( @@ -74,9 +77,11 @@ void mapNestedLevelExpressions() { ), Exp.val("stringVal")); // Implicit detect as String - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.bb.bcc == \"stringVal\"", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.bb.bcc.get(type: STRING) == \"stringVal\"", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.bb.bcc.get(type: STRING, return: VALUE) == \"stringVal\"", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.bb.bcc == \"stringVal\""), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.bb.bcc.get(type: STRING) == \"stringVal\""), + expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.bb.bcc.get(type: STRING, return: VALUE)" + + " == \"stringVal\""), expected); } @Test @@ -90,9 +95,9 @@ void quotedStringInExpressionPath() { CTX.mapKey(Value.get("a")), CTX.mapKey(Value.get("bb")) ), Exp.val(200)); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.bb.bcc.get(type: INT) > 200", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.\"bb\".bcc.get(type: INT) > 200", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.'bb'.bcc.get(type: INT) > 200", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.bb.bcc.get(type: INT) > 200"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.\"bb\".bcc.get(type: INT) > 200"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.'bb'.bcc.get(type: INT) > 200"), expected); expected = Exp.gt( MapExp.getByKey( @@ -103,8 +108,10 @@ void quotedStringInExpressionPath() { CTX.mapKey(Value.get("127.0.0.1")) ), Exp.val(200)); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.\"127.0.0.1\".bcc.get(type: INT) > 200", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.'127.0.0.1'.bcc.get(type: INT) > 200", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.\"127.0.0.1\".bcc.get(type: INT) > 200"), + expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.'127.0.0.1'.bcc.get(type: INT) > 200"), + expected); } @Test @@ -114,7 +121,7 @@ void mapSize() { Exp.mapBin("mapBin1") ), Exp.val(200)); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{}.count() > 200", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{}.count() > 200"), expected); // the default behaviour for count() without List '[]' or Map '{}' designators is List Exp expected2 = Exp.gt( @@ -122,7 +129,7 @@ void mapSize() { Exp.listBin("mapBin1") ), Exp.val(200)); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.count() > 200", expected2); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.count() > 200"), expected2); } @Test @@ -136,7 +143,7 @@ void nestedMapSize() { Exp.mapBin("mapBin1")) ), Exp.val(200)); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.{}.count() == 200", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.{}.count() == 200"), expected); // the default behaviour for count() without Map '{}' or List '[]' designators is List Exp expected2 = Exp.eq( @@ -147,7 +154,7 @@ void nestedMapSize() { Exp.mapBin("mapBin1")) ), Exp.val(200)); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.count() == 200", expected2); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.count() == 200"), expected2); } @Test @@ -162,7 +169,7 @@ void nestedMapSizeWithContext() { CTX.mapKey(Value.get("a"))) ), Exp.val(200)); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.b.{}.count() == 200", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.b.{}.count() == 200"), expected); // the default behaviour for count() without Map '{}' or List '[]' designators is List Exp expected2 = Exp.eq( @@ -174,7 +181,7 @@ void nestedMapSizeWithContext() { CTX.mapKey(Value.get("a"))) ), Exp.val(200)); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.b.count() == 200", expected2); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.b.count() == 200"), expected2); } @Test @@ -187,10 +194,11 @@ void mapByIndex() { Exp.mapBin("mapBin1") ), Exp.val(100)); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{0} == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{0}.get(type: INT) == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{0}.get(type: INT, return: VALUE) == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{0}.asInt() == 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{0} == 100"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{0}.get(type: INT) == 100"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{0}.get(type: INT, return: VALUE) == 100"), + expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{0}.asInt() == 100"), expected); } @Test @@ -202,10 +210,11 @@ void mapByValue() { Exp.mapBin("mapBin1") ), Exp.val(100)); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{=100} == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{=100}.get(type: INT) == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{=100}.get(type: INT, return: VALUE) == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{=100}.asInt() == 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{=100} == 100"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{=100}.get(type: INT) == 100"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{=100}.get(type: INT, return: VALUE) == 100"), + expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{=100}.asInt() == 100"), expected); } @Test @@ -216,8 +225,8 @@ void mapByValueCount() { Exp.mapBin("mapBin1")), Exp.val(0) ); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{=100}.count() > 0", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{=100}.{}.count() > 0", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{=100}.count() > 0"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{=100}.{}.count() > 0"), expected); } @Test @@ -230,10 +239,11 @@ void mapByRank() { Exp.mapBin("mapBin1") ), Exp.val(100)); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{#-1} == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{#-1}.get(type: INT) == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{#-1}.get(type: INT, return: VALUE) == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{#-1}.asInt() == 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{#-1} == 100"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{#-1}.get(type: INT) == 100"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{#-1}.get(type: INT, return: VALUE) == 100"), + expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{#-1}.asInt() == 100"), expected); } @Test @@ -247,10 +257,11 @@ void mapByRankWithNesting() { CTX.mapKey(Value.get("a")) ), Exp.val(100)); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.{#-1} == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.{#-1}.get(type: INT) == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.{#-1}.get(type: INT, return: VALUE) == 100", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.{#-1}.asInt() == 100", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.{#-1} == 100"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.{#-1}.get(type: INT) == 100"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.{#-1}.get(type: INT, return: VALUE) == 100"), + expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.{#-1}.asInt() == 100"), expected); } @Test @@ -266,8 +277,9 @@ void nestedListsWithDifferentContextTypes() { ), Exp.val("stringVal")); // Implicit detect as String - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{5}.{#-1} == \"stringVal\"", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{5}.{#-1}.get(type: STRING) == \"stringVal\"", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{5}.{#-1} == \"stringVal\""), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{5}.{#-1}.get(type: STRING) == \"stringVal\""), + expected); // Nested List Rank Value expected = Exp.eq( @@ -279,7 +291,7 @@ void nestedListsWithDifferentContextTypes() { CTX.mapRank(-1) ), Exp.val(200)); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{5}.{#-1}.{=100} == 200", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{5}.{#-1}.{=100} == 200"), expected); } @Test @@ -289,8 +301,8 @@ void mapKeyRange() { Exp.val("a"), Exp.val("c"), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{a-c}", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{\"a\"-\"c\"}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{a-c}"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{\"a\"-\"c\"}"), expected); // Inverted expected = MapExp.getByKeyRange( @@ -298,8 +310,8 @@ void mapKeyRange() { Exp.val("a"), Exp.val("c"), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{!a-c}", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{!\"a\"-\"c\"}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{!a-c}"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{!\"a\"-\"c\"}"), expected); // From start till the end expected = MapExp.getByKeyRange( @@ -307,8 +319,8 @@ void mapKeyRange() { Exp.val("a"), null, Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{a-}", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{\"a\"-}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{a-}"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{\"a\"-}"), expected); } @Test @@ -317,16 +329,16 @@ void mapKeyList() { MapReturnType.VALUE, Exp.val(List.of("a", "b", "c")), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{a,b,c}", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{\"a\",\"b\",\"c\"}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{a,b,c}"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{\"a\",\"b\",\"c\"}"), expected); // Inverted expected = MapExp.getByKeyList( MapReturnType.VALUE | MapReturnType.INVERTED, Exp.val(List.of("a", "b", "c")), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{!a,b,c}", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{!\"a\",\"b\",\"c\"}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{!a,b,c}"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{!\"a\",\"b\",\"c\"}"), expected); } @Test @@ -336,7 +348,7 @@ void mapIndexRange() { Exp.val(1), Exp.val(2), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{1:3}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{1:3}"), expected); // Negative expected = MapExp.getByIndexRange( @@ -344,7 +356,7 @@ void mapIndexRange() { Exp.val(-3), Exp.val(4), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{-3:1}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{-3:1}"), expected); // Inverted expected = MapExp.getByIndexRange( @@ -352,14 +364,14 @@ void mapIndexRange() { Exp.val(2), Exp.val(2), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{!2:4}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{!2:4}"), expected); // From start till the end expected = MapExp.getByIndexRange( MapReturnType.VALUE, Exp.val(1), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{1:}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{1:}"), expected); } @Test @@ -368,23 +380,23 @@ void mapValueList() { MapReturnType.VALUE, Exp.val(List.of("a", "b", "c")), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{=a,b,c}", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{=\"a\",\"b\",\"c\"}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{=a,b,c}"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{=\"a\",\"b\",\"c\"}"), expected); // Integer expected = MapExp.getByValueList( MapReturnType.VALUE, Exp.val(List.of(1, 2, 3)), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{=1,2,3}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{=1,2,3}"), expected); // Inverted expected = MapExp.getByValueList( MapReturnType.VALUE | MapReturnType.INVERTED, Exp.val(List.of("a", "b", "c")), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{!=a,b,c}", expected); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{!=\"a\",\"b\",\"c\"}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{!=a,b,c}"), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{!=\"a\",\"b\",\"c\"}"), expected); } @Test @@ -394,7 +406,7 @@ void mapValueRange() { Exp.val(111), Exp.val(334), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{=111:334}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{=111:334}"), expected); // Inverted expected = MapExp.getByValueRange( @@ -402,7 +414,7 @@ void mapValueRange() { Exp.val(10), Exp.val(20), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{!=10:20}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{!=10:20}"), expected); // From start till the end expected = MapExp.getByValueRange( @@ -410,7 +422,7 @@ void mapValueRange() { Exp.val(111), null, Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{=111:}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{=111:}"), expected); } @Test @@ -420,7 +432,7 @@ void mapRankRange() { Exp.val(0), Exp.val(3), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{#0:3}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{#0:3}"), expected); // Inverted expected = MapExp.getByRankRange( @@ -428,14 +440,14 @@ void mapRankRange() { Exp.val(0), Exp.val(3), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{!#0:3}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{!#0:3}"), expected); // From start till the end expected = MapExp.getByRankRange( MapReturnType.VALUE, Exp.val(-3), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{#-3:}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{#-3:}"), expected); // From start till the end with context expected = MapExp.getByRankRange( @@ -443,7 +455,7 @@ void mapRankRange() { Exp.val(-3), Exp.mapBin("mapBin1"), CTX.mapIndex(5)); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{5}.{#-3:}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{5}.{#-3:}"), expected); } @Test @@ -454,7 +466,7 @@ void mapRankRangeRelative() { Exp.val(10), Exp.val(2), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{#-1:1~10}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{#-1:1~10}"), expected); // Inverted expected = MapExp.getByValueRelativeRankRange( @@ -463,7 +475,7 @@ void mapRankRangeRelative() { Exp.val(10), Exp.val(2), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{!#-1:1~10}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{!#-1:1~10}"), expected); // From start till the end expected = MapExp.getByValueRelativeRankRange( @@ -471,7 +483,7 @@ void mapRankRangeRelative() { Exp.val(-2), Exp.val(10), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{#-2:~10}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{#-2:~10}"), expected); } @Test @@ -482,7 +494,7 @@ void mapIndexRangeRelative() { Exp.val(0), Exp.val(1), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{0:1~a}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{0:1~a}"), expected); // Inverted expected = MapExp.getByKeyRelativeIndexRange( @@ -491,7 +503,7 @@ void mapIndexRangeRelative() { Exp.val(0), Exp.val(1), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{!0:1~a}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{!0:1~a}"), expected); // From start till the end expected = MapExp.getByKeyRelativeIndexRange( @@ -499,7 +511,7 @@ void mapIndexRangeRelative() { Exp.val("a"), Exp.val(0), Exp.mapBin("mapBin1")); - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.{0:~a}", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.{0:~a}"), expected); } @Test @@ -513,7 +525,8 @@ void mapReturnTypes() { ), Exp.val(5)); // Implicit detect as Int - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.get(type: INT, return: COUNT) == 5", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.get(type: INT, return: COUNT) == 5"), + expected); expected = MapExp.getByKey( MapReturnType.ORDERED_MAP, @@ -522,7 +535,7 @@ void mapReturnTypes() { Exp.mapBin("mapBin1") ); // Implicit detect as Int - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.get(return: ORDERED_MAP)", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.get(return: ORDERED_MAP)"), expected); expected = Exp.eq( MapExp.getByKey( @@ -533,6 +546,7 @@ void mapReturnTypes() { ), Exp.val(5)); // Implicit detect as Int - TestUtils.parseFilterExpressionAndCompare("$.mapBin1.a.get(type: INT, return: RANK) == 5", expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.get(type: INT, return: RANK) == 5"), + expected); } } diff --git a/src/test/java/com/aerospike/dsl/expression/RecordMetadataTests.java b/src/test/java/com/aerospike/dsl/expression/RecordMetadataTests.java index fc9569d..0c25243 100644 --- a/src/test/java/com/aerospike/dsl/expression/RecordMetadataTests.java +++ b/src/test/java/com/aerospike/dsl/expression/RecordMetadataTests.java @@ -2,11 +2,11 @@ import com.aerospike.client.exp.Exp; import com.aerospike.dsl.DslParseException; +import com.aerospike.dsl.ExpressionContext; import com.aerospike.dsl.util.TestUtils; import org.junit.jupiter.api.Test; import static com.aerospike.dsl.util.TestUtils.parseFilterExp; -import static com.aerospike.dsl.util.TestUtils.parseDslExpressionAndCompare; import static org.assertj.core.api.Assertions.assertThatThrownBy; class RecordMetadataTests { @@ -14,7 +14,7 @@ class RecordMetadataTests { @Test void deviceSize() { // Expression to find records that occupy more than 1 MiB of storage space - String input = "$.deviceSize() > 1048576"; + ExpressionContext input = ExpressionContext.of("$.deviceSize() > 1048576"); Exp expected = Exp.gt(Exp.deviceSize(), Exp.val(1024 * 1024)); TestUtils.parseFilterExpressionAndCompare(input, expected); } @@ -22,7 +22,7 @@ void deviceSize() { @Test void memorySize() { // Expression to find records that occupy more than 1 MiB of memory - String input = "$.memorySize() > 1048576"; + ExpressionContext input = ExpressionContext.of("$.memorySize() > 1048576"); Exp expected = Exp.gt(Exp.memorySize(), Exp.val(1024 * 1024)); TestUtils.parseFilterExpressionAndCompare(input, expected); } @@ -30,7 +30,7 @@ void memorySize() { @Test void recordSize() { // Expression to find records that occupy more than 1 MiB of memory - String input = "$.recordSize() > 1048576"; + ExpressionContext input = ExpressionContext.of("$.recordSize() > 1048576"); Exp expected = Exp.gt(Exp.recordSize(), Exp.val(1024 * 1024)); TestUtils.parseFilterExpressionAndCompare(input, expected); } @@ -38,12 +38,12 @@ void recordSize() { @Test void digestModulo() { // Expression to find records where digest mod 3 equals 0 - String input = "$.digestModulo(3) == 0"; + ExpressionContext input = ExpressionContext.of("$.digestModulo(3) == 0"); Exp expected = Exp.eq(Exp.digestModulo(3), Exp.val(0)); TestUtils.parseFilterExpressionAndCompare(input, expected); // Expression to find records where digest mod 3 equals the value stored in the bin called "digestModulo" - String input2 = "$.digestModulo(3) == $.digestModulo"; + ExpressionContext input2 = ExpressionContext.of("$.digestModulo(3) == $.digestModulo"); Exp expected2 = Exp.eq(Exp.digestModulo(3), Exp.intBin("digestModulo")); TestUtils.parseFilterExpressionAndCompare(input2, expected2); } @@ -51,7 +51,7 @@ void digestModulo() { @Test void isTombstone() { // Expression to find records that are tombstones - String input = "$.isTombstone()"; + ExpressionContext input = ExpressionContext.of("$.isTombstone()"); Exp expected = Exp.isTombstone(); TestUtils.parseFilterExpressionAndCompare(input, expected); } @@ -59,7 +59,7 @@ void isTombstone() { @Test void keyExists() { // Expression to find records that has a stored key - String input = "$.keyExists()"; + ExpressionContext input = ExpressionContext.of("$.keyExists()"); Exp expected = Exp.keyExists(); TestUtils.parseFilterExpressionAndCompare(input, expected); } @@ -68,12 +68,12 @@ void keyExists() { @Test void lastUpdate() { // Expression to find records where the last-update-time is less than bin 'updateBy' - String inputMetadataLeft = "$.lastUpdate() < $.updateBy"; + ExpressionContext inputMetadataLeft = ExpressionContext.of("$.lastUpdate() < $.updateBy"); Exp expectedLeft = Exp.lt(Exp.lastUpdate(), Exp.intBin("updateBy")); TestUtils.parseFilterExpressionAndCompare(inputMetadataLeft, expectedLeft); // Expression to find records where the last-update-time is less than bin 'updateBy' - String inputMetadataRight = "$.updateBy > $.lastUpdate()"; + ExpressionContext inputMetadataRight = ExpressionContext.of("$.updateBy > $.lastUpdate()"); Exp expectedRight = Exp.gt(Exp.intBin("updateBy"), Exp.lastUpdate()); TestUtils.parseFilterExpressionAndCompare(inputMetadataRight, expectedRight); } @@ -81,22 +81,22 @@ void lastUpdate() { @Test void sinceUpdate() { // Expression to find records that were updated within the last 2 hours - String input = "$.sinceUpdate() < 7200000"; + ExpressionContext input = ExpressionContext.of("$.sinceUpdate() < 7200000"); Exp expected = Exp.lt(Exp.sinceUpdate(), Exp.val(2 * 60 * 60 * 1000)); TestUtils.parseFilterExpressionAndCompare(input, expected); // Expression to find records that were update within the value stored in the bin called "intBin" - String input2 = "$.sinceUpdate() < $.intBin"; + ExpressionContext input2 = ExpressionContext.of("$.sinceUpdate() < $.intBin"); Exp expected2 = Exp.lt(Exp.sinceUpdate(), Exp.intBin("intBin")); TestUtils.parseFilterExpressionAndCompare(input2, expected2); // Expression to find records that were updated within the value stored in the bin called "sinceUpdate" - String input3 = "$.sinceUpdate() < $.sinceUpdate"; + ExpressionContext input3 = ExpressionContext.of("$.sinceUpdate() < $.sinceUpdate"); Exp expected3 = Exp.lt(Exp.sinceUpdate(), Exp.intBin("sinceUpdate")); TestUtils.parseFilterExpressionAndCompare(input3, expected3); // Expression to find records that were updated within the value stored in the bin called "sinceUpdate" - String input4 = "$.sinceUpdate > $.sinceUpdate()"; + ExpressionContext input4 = ExpressionContext.of("$.sinceUpdate > $.sinceUpdate()"); Exp expected4 = Exp.gt(Exp.intBin("sinceUpdate"), Exp.sinceUpdate()); TestUtils.parseFilterExpressionAndCompare(input4, expected4); } @@ -104,7 +104,7 @@ void sinceUpdate() { @Test void setName() { // Expression to find records where the set_name is either 'groupA' or 'groupB' - String input = "$.setName() == \"groupA\" or $.setName() == \"groupB\""; + ExpressionContext input = ExpressionContext.of("$.setName() == \"groupA\" or $.setName() == \"groupB\""); Exp expected = Exp.or( Exp.eq(Exp.setName(), Exp.val("groupA")), Exp.eq(Exp.setName(), Exp.val("groupB")) @@ -112,15 +112,15 @@ void setName() { TestUtils.parseFilterExpressionAndCompare(input, expected); // set name compared with String Bin - input = "$.mySetBin == $.setName()"; + ExpressionContext input2 = ExpressionContext.of("$.mySetBin == $.setName()"); expected = Exp.eq(Exp.stringBin("mySetBin"), Exp.setName()); - TestUtils.parseFilterExpressionAndCompare(input, expected); + TestUtils.parseFilterExpressionAndCompare(input2, expected); } @Test void ttl() { // Expression to find records that will expire within 24 hours - String input = "$.ttl() <= 86400"; + ExpressionContext input = ExpressionContext.of("$.ttl() <= 86400"); Exp expected = Exp.le(Exp.ttl(), Exp.val(24 * 60 * 60)); TestUtils.parseFilterExpressionAndCompare(input, expected); } @@ -128,7 +128,7 @@ void ttl() { //@Test void negativeTtlAsDifferentType() { // TODO: should be supported when adding operator + metadata validations (requires a refactor) - assertThatThrownBy(() -> parseFilterExp("$.ttl() == true")) + assertThatThrownBy(() -> parseFilterExp(ExpressionContext.of("$.ttl() == true"))) .isInstanceOf(DslParseException.class) .hasMessageContaining("Expecting non-bin operand, got BOOL_OPERAND"); } @@ -136,7 +136,7 @@ void negativeTtlAsDifferentType() { @Test void voidTime() { // Expression to find records where the void-time is set to 'never expire' - String input = "$.voidTime() == -1"; + ExpressionContext input = ExpressionContext.of("$.voidTime() == -1"); Exp expected = Exp.eq(Exp.voidTime(), Exp.val(-1)); TestUtils.parseFilterExpressionAndCompare(input, expected); } @@ -144,7 +144,7 @@ void voidTime() { @Test void metadataWithLogicalOperatorsExpressions() { // test AND - String input = "$.deviceSize() > 1024 and $.ttl() < 300"; + ExpressionContext input = ExpressionContext.of("$.deviceSize() > 1024 and $.ttl() < 300"); Exp expected = Exp.and( Exp.gt(Exp.deviceSize(), Exp.val(1024)), Exp.lt(Exp.ttl(), Exp.val(300)) @@ -152,7 +152,7 @@ void metadataWithLogicalOperatorsExpressions() { TestUtils.parseFilterExpressionAndCompare(input, expected); // test OR - String input2 = "$.deviceSize() > 1024 or $.ttl() < 300"; + ExpressionContext input2 = ExpressionContext.of("$.deviceSize() > 1024 or $.ttl() < 300"); Exp expected2 = Exp.or( Exp.gt(Exp.deviceSize(), Exp.val(1024)), Exp.lt(Exp.ttl(), Exp.val(300)) @@ -162,18 +162,18 @@ void metadataWithLogicalOperatorsExpressions() { @Test void metadataAsExpressionWithLogicalOperator() { - String input = "$.isTombstone() and $.ttl() < 300"; + ExpressionContext input = ExpressionContext.of("$.isTombstone() and $.ttl() < 300"); Exp expected = Exp.and( Exp.isTombstone(), Exp.lt(Exp.ttl(), Exp.val(300)) ); TestUtils.parseFilterExpressionAndCompare(input, expected); - input = "$.ttl() < 300 or $.keyExists()"; + ExpressionContext input2 = ExpressionContext.of("$.ttl() < 300 or $.keyExists()"); expected = Exp.or( Exp.lt(Exp.ttl(), Exp.val(300)), Exp.keyExists() ); - TestUtils.parseFilterExpressionAndCompare(input, expected); + TestUtils.parseFilterExpressionAndCompare(input2, expected); } } diff --git a/src/test/java/com/aerospike/dsl/filter/ArithmeticFiltersTests.java b/src/test/java/com/aerospike/dsl/filter/ArithmeticFiltersTests.java index b0a21a9..128b7be 100644 --- a/src/test/java/com/aerospike/dsl/filter/ArithmeticFiltersTests.java +++ b/src/test/java/com/aerospike/dsl/filter/ArithmeticFiltersTests.java @@ -2,9 +2,9 @@ import com.aerospike.client.query.Filter; import com.aerospike.client.query.IndexType; +import com.aerospike.dsl.ExpressionContext; import com.aerospike.dsl.Index; import com.aerospike.dsl.IndexContext; -import com.aerospike.dsl.DslParseException; import org.junit.jupiter.api.Test; import java.util.Collection; @@ -13,7 +13,6 @@ import static com.aerospike.dsl.util.TestUtils.parseFilter; import static com.aerospike.dsl.util.TestUtils.parseFilterAndCompare; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; public class ArithmeticFiltersTests { @@ -27,287 +26,287 @@ public class ArithmeticFiltersTests { @Test void add() { // not supported by secondary index filter - assertThat(parseFilter("($.apples + $.bananas) > 10", INDEX_FILTER_INPUT)).isNull(); + assertThat(parseFilter(ExpressionContext.of("($.apples + $.bananas) > 10"), INDEX_FILTER_INPUT)).isNull(); - parseFilterAndCompare("($.apples + 5) > 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples + 5) > 10"), INDEX_FILTER_INPUT, Filter.range("apples", 10 - 5 + 1, Long.MAX_VALUE)); - parseFilterAndCompare("($.apples + 5) >= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples + 5) >= 10"), INDEX_FILTER_INPUT, Filter.range("apples", 10 - 5, Long.MAX_VALUE)); - parseFilterAndCompare("($.apples + 5) < 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples + 5) < 10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, 10 - 5 - 1)); - parseFilterAndCompare("($.apples + 5) <= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples + 5) <= 10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, 10 - 5)); - parseFilterAndCompare("(9 + $.bananas) > 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("(9 + $.bananas) > 10"), INDEX_FILTER_INPUT, Filter.range("bananas", 10 - 9 + 1, Long.MAX_VALUE)); - parseFilterAndCompare("(9 + $.bananas) >= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("(9 + $.bananas) >= 10"), INDEX_FILTER_INPUT, Filter.range("bananas", 10 - 9, Long.MAX_VALUE)); - parseFilterAndCompare("(9 + $.bananas) < 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("(9 + $.bananas) < 10"), INDEX_FILTER_INPUT, Filter.range("bananas", Long.MIN_VALUE, 10 - 9 - 1)); - parseFilterAndCompare("(9 + $.bananas) <= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("(9 + $.bananas) <= 10"), INDEX_FILTER_INPUT, Filter.range("bananas", Long.MIN_VALUE, 10 - 9)); - assertThat(parseFilter("(5.2 + $.bananas) > 10.2")).isNull(); // not supported by secondary index filter - assertThat(parseFilter("($.apples + $.bananas + 5) > 10")).isNull(); // not supported by the current grammar + assertThat(parseFilter(ExpressionContext.of("(5.2 + $.bananas) > 10.2"))).isNull(); // not supported by secondary index filter + assertThat(parseFilter(ExpressionContext.of("($.apples + $.bananas + 5) > 10"))).isNull(); // not supported by the current grammar } @Test void sub() { - assertThat(parseFilter("($.apples - $.bananas) > 10", INDEX_FILTER_INPUT)).isNull(); // not supported by secondary index filter + assertThat(parseFilter(ExpressionContext.of("($.apples - $.bananas) > 10"), INDEX_FILTER_INPUT)).isNull(); // not supported by secondary index filter - parseFilterAndCompare("($.apples - 5) > 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples - 5) > 10"), INDEX_FILTER_INPUT, Filter.range("apples", 10 + 5 + 1, Long.MAX_VALUE)); - parseFilterAndCompare("($.apples - 5) >= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples - 5) >= 10"), INDEX_FILTER_INPUT, Filter.range("apples", 10 + 5, Long.MAX_VALUE)); - parseFilterAndCompare("($.apples - 5) < 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples - 5) < 10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, 10 + 5 - 1)); - parseFilterAndCompare("($.apples - 5) <= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples - 5) <= 10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, 10 + 5)); - parseFilterAndCompare("($.apples - 5) > -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples - 5) > -10"), INDEX_FILTER_INPUT, Filter.range("apples", -10 + 5 + 1, Long.MAX_VALUE)); - parseFilterAndCompare("($.apples - 5) >= -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples - 5) >= -10"), INDEX_FILTER_INPUT, Filter.range("apples", -10 + 5, Long.MAX_VALUE)); - parseFilterAndCompare("($.apples - 5) < -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples - 5) < -10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, -10 + 5 - 1)); - parseFilterAndCompare("($.apples - 5) <= -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples - 5) <= -10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, -10 + 5)); - parseFilterAndCompare("(9 - $.bananas) > 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("(9 - $.bananas) > 10"), INDEX_FILTER_INPUT, Filter.range("bananas", Long.MIN_VALUE, 9 - 10 - 1)); - parseFilterAndCompare("(9 - $.bananas) >= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("(9 - $.bananas) >= 10"), INDEX_FILTER_INPUT, Filter.range("bananas", Long.MIN_VALUE, 9 - 10)); - parseFilterAndCompare("(9 - $.bananas) < 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("(9 - $.bananas) < 10"), INDEX_FILTER_INPUT, Filter.range("bananas", 9 - 10 + 1, Long.MAX_VALUE)); - parseFilterAndCompare("(9 - $.bananas) <= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("(9 - $.bananas) <= 10"), INDEX_FILTER_INPUT, Filter.range("bananas", 9 - 10, Long.MAX_VALUE)); - assertThat(parseFilter("($.apples - $.bananas) > 10")).isNull(); // not supported by secondary index filter - assertThat(parseFilter("($.apples - $.bananas - 5) > 10")).isNull(); // not supported by the current grammar + assertThat(parseFilter(ExpressionContext.of("($.apples - $.bananas) > 10"))).isNull(); // not supported by secondary index filter + assertThat(parseFilter(ExpressionContext.of("($.apples - $.bananas - 5) > 10"))).isNull(); // not supported by the current grammar } @Test void mul() { - assertThat(parseFilter("($.apples * $.bananas) > 10", INDEX_FILTER_INPUT)).isNull(); // not supported by secondary index filter + assertThat(parseFilter(ExpressionContext.of("($.apples * $.bananas) > 10"), INDEX_FILTER_INPUT)).isNull(); // not supported by secondary index filter - parseFilterAndCompare("($.apples * 5) > 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples * 5) > 10"), INDEX_FILTER_INPUT, Filter.range("apples", 10 / 5 + 1, Long.MAX_VALUE)); - parseFilterAndCompare("($.apples * 5) >= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples * 5) >= 10"), INDEX_FILTER_INPUT, Filter.range("apples", 10 / 5, Long.MAX_VALUE)); - parseFilterAndCompare("($.apples * 5) < 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples * 5) < 10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, 10 / 5 - 1)); - parseFilterAndCompare("($.apples * 5) <= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples * 5) <= 10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, 10 / 5)); - parseFilterAndCompare("(9 * $.bananas) > 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("(9 * $.bananas) > 10"), INDEX_FILTER_INPUT, Filter.range("bananas", 10 / 9 + 1, Long.MAX_VALUE)); - parseFilterAndCompare("(9 * $.bananas) >= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("(9 * $.bananas) >= 10"), INDEX_FILTER_INPUT, Filter.range("bananas", 10 / 9, Long.MAX_VALUE)); - parseFilterAndCompare("(9 * $.bananas) < 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("(9 * $.bananas) < 10"), INDEX_FILTER_INPUT, Filter.range("bananas", Long.MIN_VALUE, 10 / 9)); - parseFilterAndCompare("(9 * $.bananas) <= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("(9 * $.bananas) <= 10"), INDEX_FILTER_INPUT, Filter.range("bananas", Long.MIN_VALUE, 10 / 9)); - parseFilterAndCompare("($.apples * -5) > 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples * -5) > 10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, 10 / -5 - 1)); - parseFilterAndCompare("($.apples * -5) >= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples * -5) >= 10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, 10 / -5)); - parseFilterAndCompare("($.apples * -5) < 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples * -5) < 10"), INDEX_FILTER_INPUT, Filter.range("apples", 10 / -5 + 1, Long.MAX_VALUE)); - parseFilterAndCompare("($.apples * -5) <= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples * -5) <= 10"), INDEX_FILTER_INPUT, Filter.range("apples", 10 / -5, Long.MAX_VALUE)); - assertThat(parseFilter("(0 * $.bananas) > 10", INDEX_FILTER_INPUT)).isNull(); // Cannot divide by zero + assertThat(parseFilter(ExpressionContext.of("(0 * $.bananas) > 10"), INDEX_FILTER_INPUT)).isNull(); // Cannot divide by zero - parseFilterAndCompare("(9 * $.bananas) > 0", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("(9 * $.bananas) > 0"), INDEX_FILTER_INPUT, Filter.range("bananas", 0 / 9 + 1, Long.MAX_VALUE)); - assertThat(parseFilter("($.apples * $.bananas - 5) > 10")).isNull(); // not supported by the current grammar + assertThat(parseFilter(ExpressionContext.of("($.apples * $.bananas - 5) > 10"))).isNull(); // not supported by the current grammar } @Test void div_twoBins() { - assertThat(parseFilter("($.apples / $.bananas) <= 10", INDEX_FILTER_INPUT)).isNull(); // not supported by secondary index filter + assertThat(parseFilter(ExpressionContext.of("($.apples / $.bananas) <= 10"), INDEX_FILTER_INPUT)).isNull(); // not supported by secondary index filter } @Test void div_binIsDivided_leftNumberIsLarger() { - parseFilterAndCompare("($.apples / 50) > 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 50) > 10"), INDEX_FILTER_INPUT, Filter.range("apples", 50 * 10 + 1, Long.MAX_VALUE)); // [501, 2^63 - 1] - parseFilterAndCompare("($.apples / 50) >= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 50) >= 10"), INDEX_FILTER_INPUT, Filter.range("apples", 50 * 10, Long.MAX_VALUE)); // [500, 2^63 - 1] - parseFilterAndCompare("($.apples / 50) < 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 50) < 10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, 50 * 10 - 1)); // [-2^63, 499] - parseFilterAndCompare("($.apples / 50) <= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 50) <= 10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, 50 * 10)); // [-2^63, 500] - parseFilterAndCompare("($.apples / -50) > 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -50) > 10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, -50 * 10 - 1)); // [-2^63, -501] - parseFilterAndCompare("($.apples / -50) >= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -50) >= 10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, -50 * 10)); // [-2^63, -500] - parseFilterAndCompare("($.apples / -50) < 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -50) < 10"), INDEX_FILTER_INPUT, Filter.range("apples", -50 * 10 + 1, Long.MAX_VALUE)); // [-499, 2^63 - 1] - parseFilterAndCompare("($.apples / -50) <= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -50) <= 10"), INDEX_FILTER_INPUT, Filter.range("apples", -50 * 10, Long.MAX_VALUE)); // [-500, 2^63 - 1] - parseFilterAndCompare("($.apples / 50) > -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 50) > -10"), INDEX_FILTER_INPUT, Filter.range("apples", 50 * -10 + 1, Long.MAX_VALUE)); // [-499, 2^63 - 1] - parseFilterAndCompare("($.apples / 50) >= -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 50) >= -10"), INDEX_FILTER_INPUT, Filter.range("apples", 50 * -10, Long.MAX_VALUE)); // [-500, 2^63 - 1] - parseFilterAndCompare("($.apples / 50) < -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 50) < -10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, 50 * -10 - 1)); // [-2^63, -501] - parseFilterAndCompare("($.apples / 50) <= -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 50) <= -10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, 50 * -10)); // [-2^63, -500] - parseFilterAndCompare("($.apples / -50) > -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -50) > -10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, -50 * -10 - 1)); // [-2^63, 499] - parseFilterAndCompare("($.apples / -50) >= -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -50) >= -10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, -10 * -50)); // [-2^63, 500] - parseFilterAndCompare("($.apples / -50) < -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -50) < -10"), INDEX_FILTER_INPUT, Filter.range("apples", -10 * -50 + 1, Long.MAX_VALUE)); // [501, 2^63 - 1] - parseFilterAndCompare("($.apples / -50) <= -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -50) <= -10"), INDEX_FILTER_INPUT, Filter.range("apples", -10 * -50, Long.MAX_VALUE)); // [500, 2^63 - 1] } @Test void div_binIsDivided_leftNumberIsSmaller() { - parseFilterAndCompare("($.apples / 5) > 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 5) > 10"), INDEX_FILTER_INPUT, Filter.range("apples", 5 * 10 + 1, Long.MAX_VALUE)); // [51, 2^63 - 1] - parseFilterAndCompare("($.apples / 5) >= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 5) >= 10"), INDEX_FILTER_INPUT, Filter.range("apples", 5 * 10, Long.MAX_VALUE)); // [50, 2^63 - 1] - parseFilterAndCompare("($.apples / 5) < 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 5) < 10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, 5 * 10 - 1)); // [-2^63, 49] - parseFilterAndCompare("($.apples / 5) <= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 5) <= 10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, 5 * 10)); // [-2^63, 50] - parseFilterAndCompare("($.apples / -5) > 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -5) > 10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, -5 * 10 - 1)); // [-2^63, -51] - parseFilterAndCompare("($.apples / -5) >= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -5) >= 10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, -5 * 10)); // [-2^63, -50] - parseFilterAndCompare("($.apples / -5) < 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -5) < 10"), INDEX_FILTER_INPUT, Filter.range("apples", -5 * 10 + 1, Long.MAX_VALUE)); // [-49, 2^63 - 1] - parseFilterAndCompare("($.apples / -5) <= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -5) <= 10"), INDEX_FILTER_INPUT, Filter.range("apples", -5 * 10, Long.MAX_VALUE)); // [-50, 2^63 - 1] - parseFilterAndCompare("($.apples / 5) > -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 5) > -10"), INDEX_FILTER_INPUT, Filter.range("apples", 5 * -10 + 1, Long.MAX_VALUE)); // [-49, 2^63 - 1] - parseFilterAndCompare("($.apples / 5) >= -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 5) >= -10"), INDEX_FILTER_INPUT, Filter.range("apples", 5 * -10, Long.MAX_VALUE)); // [-50, 2^63 - 1] - parseFilterAndCompare("($.apples / 5) < -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 5) < -10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, 5 * -10 - 1)); // [-2^63, -51] - parseFilterAndCompare("($.apples / 5) <= -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 5) <= -10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, 5 * -10)); // [-2^63, -50] - parseFilterAndCompare("($.apples / -5) > -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -5) > -10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, -5 * -10 - 1)); // [-2^63, 49] - parseFilterAndCompare("($.apples / -5) >= -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -5) >= -10"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, -10 * -5)); // [-2^63, 50] - parseFilterAndCompare("($.apples / -5) < -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -5) < -10"), INDEX_FILTER_INPUT, Filter.range("apples", -10 * -5 + 1, Long.MAX_VALUE)); // [51, 2^63 - 1] - parseFilterAndCompare("($.apples / -5) <= -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -5) <= -10"), INDEX_FILTER_INPUT, Filter.range("apples", -10 * -5, Long.MAX_VALUE)); // [50, 2^63 - 1] } @Test void div_binIsDivided_leftNumberEqualsRight() { - parseFilterAndCompare("($.apples / 5) > 5", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 5) > 5"), INDEX_FILTER_INPUT, Filter.range("apples", 5 * 5 + 1, Long.MAX_VALUE)); // [26, 2^63 - 1] - parseFilterAndCompare("($.apples / 5) >= 5", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 5) >= 5"), INDEX_FILTER_INPUT, Filter.range("apples", 5 * 5, Long.MAX_VALUE)); // [25, 2^63 - 1] - parseFilterAndCompare("($.apples / 5) < 5", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 5) < 5"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, 5 * 5 - 1)); // [-2^63, 24] - parseFilterAndCompare("($.apples / 5) <= 5", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / 5) <= 5"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, 5 * 5)); // [-2^63, 25] - parseFilterAndCompare("($.apples / -5) > -5", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -5) > -5"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, -5 * -5 - 1)); // [-2^63, 24] - parseFilterAndCompare("($.apples / -5) >= -5", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -5) >= -5"), INDEX_FILTER_INPUT, Filter.range("apples", Long.MIN_VALUE, -5 * -5)); // [-2^63, 25] - parseFilterAndCompare("($.apples / -5) < -5", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -5) < -5"), INDEX_FILTER_INPUT, Filter.range("apples", -5 * -5 + 1, Long.MAX_VALUE)); // [26, 2^63 - 1] - parseFilterAndCompare("($.apples / -5) <= -5", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("($.apples / -5) <= -5"), INDEX_FILTER_INPUT, Filter.range("apples", -5 * -5, Long.MAX_VALUE)); // [25, 2^63 - 1] } @Test void div_binIsDivisor_leftNumberIsLarger() { - parseFilterAndCompare("(90 / $.bananas) > 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("(90 / $.bananas) > 10"), INDEX_FILTER_INPUT, Filter.range("bananas", 1, 90 / 10 - 1)); // [1,8] - parseFilterAndCompare("(90 / $.bananas) >= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("(90 / $.bananas) >= 10"), INDEX_FILTER_INPUT, Filter.range("bananas", 1, 90 / 10)); // [1,9] // Not supported by secondary index filter - assertThat(parseFilter("(90 / $.bananas) < 10", INDEX_FILTER_INPUT)).isNull(); - assertThat(parseFilter("(90 / $.bananas) <= 10", INDEX_FILTER_INPUT)).isNull(); + assertThat(parseFilter(ExpressionContext.of("(90 / $.bananas) < 10"), INDEX_FILTER_INPUT)).isNull(); + assertThat(parseFilter(ExpressionContext.of("(90 / $.bananas) <= 10"), INDEX_FILTER_INPUT)).isNull(); // Not supported by secondary index filter - assertThat(parseFilter("(90 / $.bananas) > -10", INDEX_FILTER_INPUT)).isNull(); - assertThat(parseFilter("(90 / $.bananas) >= -10", INDEX_FILTER_INPUT)).isNull(); - parseFilterAndCompare("(90 / $.bananas) < -10", INDEX_FILTER_INPUT, + assertThat(parseFilter(ExpressionContext.of("(90 / $.bananas) > -10"), INDEX_FILTER_INPUT)).isNull(); + assertThat(parseFilter(ExpressionContext.of("(90 / $.bananas) >= -10"), INDEX_FILTER_INPUT)).isNull(); + parseFilterAndCompare(ExpressionContext.of("(90 / $.bananas) < -10"), INDEX_FILTER_INPUT, Filter.range("bananas", 90 / -10 + 1, -1)); // [-8, -1] - parseFilterAndCompare("(90 / $.bananas) <= -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("(90 / $.bananas) <= -10"), INDEX_FILTER_INPUT, Filter.range("bananas", 90 / -10, -1)); // [-8, -1] - parseFilterAndCompare("(-90 / $.bananas) > 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("(-90 / $.bananas) > 10"), INDEX_FILTER_INPUT, Filter.range("bananas", -90 / 10 + 1, -1)); // [-8, -1] - parseFilterAndCompare("(90 / $.bananas) >= 10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("(90 / $.bananas) >= 10"), INDEX_FILTER_INPUT, Filter.range("bananas", 1, 90 / 10)); // [1,9] // Not supported by secondary index filter - assertThat(parseFilter("(-90 / $.bananas) < 10", INDEX_FILTER_INPUT)).isNull(); - assertThat(parseFilter("(-90 / $.bananas) <= 10", INDEX_FILTER_INPUT)).isNull(); + assertThat(parseFilter(ExpressionContext.of("(-90 / $.bananas) < 10"), INDEX_FILTER_INPUT)).isNull(); + assertThat(parseFilter(ExpressionContext.of("(-90 / $.bananas) <= 10"), INDEX_FILTER_INPUT)).isNull(); // Not supported by secondary index filter - assertThat(parseFilter("(-90 / $.bananas) > -10", INDEX_FILTER_INPUT)).isNull(); - assertThat(parseFilter("(-90 / $.bananas) >= -10", INDEX_FILTER_INPUT)).isNull(); - parseFilterAndCompare("(-90 / $.bananas) < -10", INDEX_FILTER_INPUT, + assertThat(parseFilter(ExpressionContext.of("(-90 / $.bananas) > -10"), INDEX_FILTER_INPUT)).isNull(); + assertThat(parseFilter(ExpressionContext.of("(-90 / $.bananas) >= -10"), INDEX_FILTER_INPUT)).isNull(); + parseFilterAndCompare(ExpressionContext.of("(-90 / $.bananas) < -10"), INDEX_FILTER_INPUT, Filter.range("bananas", 1L, -90 / -10 - 1)); // [1, 8] - parseFilterAndCompare("(-90 / $.bananas) <= -10", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("(-90 / $.bananas) <= -10"), INDEX_FILTER_INPUT, Filter.range("bananas", 1L, -90 / -10)); // [1, 9] } @Test void div_binIsDivisor_leftNumberIsSmaller() { // Not supported by secondary index filter - assertThat(parseFilter("(9 / $.bananas) > 10", INDEX_FILTER_INPUT)).isNull(); // no integer numbers - assertThat(parseFilter("(9 / $.bananas) >= 10", INDEX_FILTER_INPUT)).isNull(); // no integer numbers - assertThat(parseFilter("(9 / $.bananas) < 10", INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers - assertThat(parseFilter("(9 / $.bananas) <= 10", INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers - - assertThat(parseFilter("(9 / $.bananas) > -10", INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers - assertThat(parseFilter("(9 / $.bananas) >= -10", INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers - assertThat(parseFilter("(9 / $.bananas) < -10", INDEX_FILTER_INPUT)).isNull(); // no integer numbers - assertThat(parseFilter("(9 / $.bananas) <= -10", INDEX_FILTER_INPUT)).isNull(); // no integer numbers - - assertThat(parseFilter("(-9 / $.bananas) > 10", INDEX_FILTER_INPUT)).isNull(); // no integer numbers - assertThat(parseFilter("(-9 / $.bananas) >= 10", INDEX_FILTER_INPUT)).isNull(); // no integer numbers - assertThat(parseFilter("(-9 / $.bananas) < 10", INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers - assertThat(parseFilter("(-9 / $.bananas) <= 10", INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers - - assertThat(parseFilter("(-9 / $.bananas) > -10", INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers - assertThat(parseFilter("(-9 / $.bananas) >= -10", INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers - assertThat(parseFilter("(-9 / $.bananas) < -10", INDEX_FILTER_INPUT)).isNull(); // no integer numbers - assertThat(parseFilter("(-9 / $.bananas) <= -10", INDEX_FILTER_INPUT)).isNull(); // no integer numbers + assertThat(parseFilter(ExpressionContext.of("(9 / $.bananas) > 10"), INDEX_FILTER_INPUT)).isNull(); // no integer numbers + assertThat(parseFilter(ExpressionContext.of("(9 / $.bananas) >= 10"), INDEX_FILTER_INPUT)).isNull(); // no integer numbers + assertThat(parseFilter(ExpressionContext.of("(9 / $.bananas) < 10"), INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers + assertThat(parseFilter(ExpressionContext.of("(9 / $.bananas) <= 10"), INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers + + assertThat(parseFilter(ExpressionContext.of("(9 / $.bananas) > -10"), INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers + assertThat(parseFilter(ExpressionContext.of("(9 / $.bananas) >= -10"), INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers + assertThat(parseFilter(ExpressionContext.of("(9 / $.bananas) < -10"), INDEX_FILTER_INPUT)).isNull(); // no integer numbers + assertThat(parseFilter(ExpressionContext.of("(9 / $.bananas) <= -10"), INDEX_FILTER_INPUT)).isNull(); // no integer numbers + + assertThat(parseFilter(ExpressionContext.of("(-9 / $.bananas) > 10"), INDEX_FILTER_INPUT)).isNull(); // no integer numbers + assertThat(parseFilter(ExpressionContext.of("(-9 / $.bananas) >= 10"), INDEX_FILTER_INPUT)).isNull(); // no integer numbers + assertThat(parseFilter(ExpressionContext.of("(-9 / $.bananas) < 10"), INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers + assertThat(parseFilter(ExpressionContext.of("(-9 / $.bananas) <= 10"), INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers + + assertThat(parseFilter(ExpressionContext.of("(-9 / $.bananas) > -10"), INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers + assertThat(parseFilter(ExpressionContext.of("(-9 / $.bananas) >= -10"), INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers + assertThat(parseFilter(ExpressionContext.of("(-9 / $.bananas) < -10"), INDEX_FILTER_INPUT)).isNull(); // no integer numbers + assertThat(parseFilter(ExpressionContext.of("(-9 / $.bananas) <= -10"), INDEX_FILTER_INPUT)).isNull(); // no integer numbers // Not supported by secondary index Filter - assertThat(parseFilter("(0 / $.bananas) > 10", INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers + assertThat(parseFilter(ExpressionContext.of("(0 / $.bananas) > 10"), INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers // Not supported by secondary index Filter, cannot divide by zero - assertThat(parseFilter("(9 / $.bananas) > 0", INDEX_FILTER_INPUT)).isNull(); // no integer numbers + assertThat(parseFilter(ExpressionContext.of("(9 / $.bananas) > 0"), INDEX_FILTER_INPUT)).isNull(); // no integer numbers } @Test void div_binIsDivisor_leftNumberEqualsRight() { // Not supported by secondary index filter - assertThat(parseFilter("(90 / $.bananas) > 90", INDEX_FILTER_INPUT)).isNull(); // no integer numbers - parseFilterAndCompare("(90 / $.bananas) >= 90", INDEX_FILTER_INPUT, + assertThat(parseFilter(ExpressionContext.of("(90 / $.bananas) > 90"), INDEX_FILTER_INPUT)).isNull(); // no integer numbers + parseFilterAndCompare(ExpressionContext.of("(90 / $.bananas) >= 90"), INDEX_FILTER_INPUT, Filter.range("bananas", 90 / 90, 90 / 90)); // [1, 1] - assertThat(parseFilter("(90 / $.bananas) < 90", INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers - assertThat(parseFilter("(90 / $.bananas) <= 90", INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers + assertThat(parseFilter(ExpressionContext.of("(90 / $.bananas) < 90"), INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers + assertThat(parseFilter(ExpressionContext.of("(90 / $.bananas) <= 90"), INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers - assertThat(parseFilter("(-90 / $.bananas) > -90", INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers - assertThat(parseFilter("(-90 / $.bananas) >= -90", INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers - assertThat(parseFilter("(-90 / $.bananas) < -90", INDEX_FILTER_INPUT)).isNull(); // no integer numbers - parseFilterAndCompare("(-90 / $.bananas) <= -90", INDEX_FILTER_INPUT, + assertThat(parseFilter(ExpressionContext.of("(-90 / $.bananas) > -90"), INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers + assertThat(parseFilter(ExpressionContext.of("(-90 / $.bananas) >= -90"), INDEX_FILTER_INPUT)).isNull(); // maximal range is all numbers + assertThat(parseFilter(ExpressionContext.of("(-90 / $.bananas) < -90"), INDEX_FILTER_INPUT)).isNull(); // no integer numbers + parseFilterAndCompare(ExpressionContext.of("(-90 / $.bananas) <= -90"), INDEX_FILTER_INPUT, Filter.range("bananas", 1L, 90 / 90)); // [1, 1] } } diff --git a/src/test/java/com/aerospike/dsl/filter/BinFiltersTests.java b/src/test/java/com/aerospike/dsl/filter/BinFiltersTests.java index aec4b3a..98745de 100644 --- a/src/test/java/com/aerospike/dsl/filter/BinFiltersTests.java +++ b/src/test/java/com/aerospike/dsl/filter/BinFiltersTests.java @@ -2,6 +2,7 @@ import com.aerospike.client.query.Filter; import com.aerospike.client.query.IndexType; +import com.aerospike.dsl.ExpressionContext; import com.aerospike.dsl.Index; import com.aerospike.dsl.IndexContext; import org.junit.jupiter.api.Test; @@ -23,22 +24,22 @@ class BinFiltersTests { @Test void binGT() { - parseFilterAndCompare("$.intBin1 > 100", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("$.intBin1 > 100", null), INDEX_FILTER_INPUT, Filter.range("intBin1", 101, Long.MAX_VALUE)); - parseFilterAndCompare("$.intBin1 > -100", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("$.intBin1 > -100"), INDEX_FILTER_INPUT, Filter.range("intBin1", -99, Long.MAX_VALUE)); // Comparing Strings is not supported by secondary index Filters - assertThat(parseFilter("$.stringBin1 > 'text'", INDEX_FILTER_INPUT)).isNull(); - assertThat(parseFilter("$.stringBin1 > \"text\"", INDEX_FILTER_INPUT)).isNull(); + assertThat(parseFilter(ExpressionContext.of("$.stringBin1 > 'text'"), INDEX_FILTER_INPUT)).isNull(); + assertThat(parseFilter(ExpressionContext.of("$.stringBin1 > \"text\""), INDEX_FILTER_INPUT)).isNull(); // "$.intBin1 > 100" and "100 < $.intBin1" represent identical Filters - parseFilterAndCompare("100 < $.intBin1", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("100 < $.intBin1"), INDEX_FILTER_INPUT, Filter.range("intBin1", 101, Long.MAX_VALUE)); // Comparing Strings is not supported by secondary index Filters - assertThat(parseFilter("'text' > $.stringBin1", INDEX_FILTER_INPUT)).isNull(); - assertThat(parseFilter("\"text\" > $.stringBin1", INDEX_FILTER_INPUT)).isNull(); + assertThat(parseFilter(ExpressionContext.of("'text' > $.stringBin1"), INDEX_FILTER_INPUT)).isNull(); + assertThat(parseFilter(ExpressionContext.of("\"text\" > $.stringBin1"), INDEX_FILTER_INPUT)).isNull(); } @Test @@ -47,62 +48,62 @@ void binGT_logical_combinations() { Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build() ); - parseFilterAndCompare("$.intBin1 > 100 and $.intBin2 < 1000", IndexContext.of(NAMESPACE, indexes), + parseFilterAndCompare(ExpressionContext.of("$.intBin1 > 100 and $.intBin2 < 1000"), IndexContext.of(NAMESPACE, indexes), Filter.range("intBin2", Long.MIN_VALUE, 999)); - parseFilterAndCompare("$.intBin1 > 100 and $.intBin2 < 1000", null); // No indexes given + parseFilterAndCompare(ExpressionContext.of("$.intBin1 > 100 and $.intBin2 < 1000"), null); // No indexes given } @Test void binGE() { - parseFilterAndCompare("$.intBin1 >= 100", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("$.intBin1 >= 100"), INDEX_FILTER_INPUT, Filter.range("intBin1", 100, Long.MAX_VALUE)); // "$.intBin1 >= 100" and "100 <= $.intBin1" represent identical Filters - parseFilterAndCompare("100 <= $.intBin1", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("100 <= $.intBin1"), INDEX_FILTER_INPUT, Filter.range("intBin1", 100, Long.MAX_VALUE)); } @Test void binLT() { - parseFilterAndCompare("$.intBin1 < 100", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("$.intBin1 < 100"), INDEX_FILTER_INPUT, Filter.range("intBin1", Long.MIN_VALUE, 99)); - parseFilterAndCompare("100 > $.intBin1", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("100 > $.intBin1"), INDEX_FILTER_INPUT, Filter.range("intBin1", Long.MIN_VALUE, 99)); } @Test void binLE() { - parseFilterAndCompare("$.intBin1 <= 100", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("$.intBin1 <= 100"), INDEX_FILTER_INPUT, Filter.range("intBin1", Long.MIN_VALUE, 100)); - parseFilterAndCompare("100 >= $.intBin1", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("100 >= $.intBin1"), INDEX_FILTER_INPUT, Filter.range("intBin1", Long.MIN_VALUE, 100)); } @Test void binEQ() { - parseFilterAndCompare("$.intBin1 == 100", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("$.intBin1 == 100"), INDEX_FILTER_INPUT, Filter.equal("intBin1", 100)); - parseFilterAndCompare("100 == $.intBin1", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("100 == $.intBin1"), INDEX_FILTER_INPUT, Filter.equal("intBin1", 100)); - parseFilterAndCompare("$.stringBin1 == 'text'", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("$.stringBin1 == 'text'"), INDEX_FILTER_INPUT, Filter.equal("stringBin1", "text")); - parseFilterAndCompare("$.stringBin1 == \"text\"", INDEX_FILTER_INPUT, + parseFilterAndCompare(ExpressionContext.of("$.stringBin1 == \"text\""), INDEX_FILTER_INPUT, Filter.equal("stringBin1", "text")); } @Test void binNOTEQ() { // NOT EQUAL is not supported by secondary index filter - assertThat(parseFilter("$.intBin1 != 100", INDEX_FILTER_INPUT)).isNull(); - assertThat(parseFilter("$.stringBin1 != 'text'", INDEX_FILTER_INPUT)).isNull(); - assertThat(parseFilter("$.stringBin1 != \"text\"", INDEX_FILTER_INPUT)).isNull(); + assertThat(parseFilter(ExpressionContext.of("$.intBin1 != 100"), INDEX_FILTER_INPUT)).isNull(); + assertThat(parseFilter(ExpressionContext.of("$.stringBin1 != 'text'"), INDEX_FILTER_INPUT)).isNull(); + assertThat(parseFilter(ExpressionContext.of("$.stringBin1 != \"text\""), INDEX_FILTER_INPUT)).isNull(); - assertThat(parseFilter("100 != $.intBin1", INDEX_FILTER_INPUT)).isNull(); - assertThat(parseFilter("100 != 'text'", INDEX_FILTER_INPUT)).isNull(); - assertThat(parseFilter("100 != \"text\"", INDEX_FILTER_INPUT)).isNull(); + assertThat(parseFilter(ExpressionContext.of("100 != $.intBin1"), INDEX_FILTER_INPUT)).isNull(); + assertThat(parseFilter(ExpressionContext.of("100 != 'text'"), INDEX_FILTER_INPUT)).isNull(); + assertThat(parseFilter(ExpressionContext.of("100 != \"text\""), INDEX_FILTER_INPUT)).isNull(); } } diff --git a/src/test/java/com/aerospike/dsl/filter/ExplicitTypesFiltersTests.java b/src/test/java/com/aerospike/dsl/filter/ExplicitTypesFiltersTests.java index f46d98e..224cce7 100644 --- a/src/test/java/com/aerospike/dsl/filter/ExplicitTypesFiltersTests.java +++ b/src/test/java/com/aerospike/dsl/filter/ExplicitTypesFiltersTests.java @@ -2,9 +2,10 @@ import com.aerospike.client.query.Filter; import com.aerospike.client.query.IndexType; +import com.aerospike.dsl.DslParseException; +import com.aerospike.dsl.ExpressionContext; import com.aerospike.dsl.Index; import com.aerospike.dsl.IndexContext; -import com.aerospike.dsl.DslParseException; import com.aerospike.dsl.util.TestUtils; import org.junit.jupiter.api.Test; @@ -28,34 +29,34 @@ public class ExplicitTypesFiltersTests { @Test void integerComparison() { // Namespace and indexes must be given to create a Filter - TestUtils.parseFilterAndCompare("$.intBin1.get(type: INT) > 5", null); + TestUtils.parseFilterAndCompare(ExpressionContext.of("$.intBin1.get(type: INT) > 5"), null); - TestUtils.parseFilterAndCompare("$.intBin1.get(type: INT) > 5", INDEX_FILTER_INPUT, + TestUtils.parseFilterAndCompare(ExpressionContext.of("$.intBin1.get(type: INT) > 5"), INDEX_FILTER_INPUT, Filter.range("intBin1", 6, Long.MAX_VALUE)); - TestUtils.parseFilterAndCompare("5 < $.intBin1.get(type: INT)", INDEX_FILTER_INPUT, + TestUtils.parseFilterAndCompare(ExpressionContext.of("5 < $.intBin1.get(type: INT)"), INDEX_FILTER_INPUT, Filter.range("intBin1", 6, Long.MAX_VALUE)); } @Test void stringComparison() { - TestUtils.parseFilterAndCompare("$.stringBin1.get(type: STRING) == \"yes\"", INDEX_FILTER_INPUT, + TestUtils.parseFilterAndCompare(ExpressionContext.of("$.stringBin1.get(type: STRING) == \"yes\""), INDEX_FILTER_INPUT, Filter.equal("stringBin1", "yes")); - TestUtils.parseFilterAndCompare("$.stringBin1.get(type: STRING) == 'yes'", INDEX_FILTER_INPUT, + TestUtils.parseFilterAndCompare(ExpressionContext.of("$.stringBin1.get(type: STRING) == 'yes'"), INDEX_FILTER_INPUT, Filter.equal("stringBin1", "yes")); - TestUtils.parseFilterAndCompare("\"yes\" == $.stringBin1.get(type: STRING)", INDEX_FILTER_INPUT, + TestUtils.parseFilterAndCompare(ExpressionContext.of("\"yes\" == $.stringBin1.get(type: STRING)"), INDEX_FILTER_INPUT, Filter.equal("stringBin1", "yes")); - TestUtils.parseFilterAndCompare("'yes' == $.stringBin1.get(type: STRING)", INDEX_FILTER_INPUT, + TestUtils.parseFilterAndCompare(ExpressionContext.of("'yes' == $.stringBin1.get(type: STRING)"), INDEX_FILTER_INPUT, Filter.equal("stringBin1", "yes")); } @Test void stringComparisonNegativeTest() { // A String constant must be quoted - assertThatThrownBy(() -> parseFilter("$.stringBin1.get(type: STRING) == yes")) + assertThatThrownBy(() -> parseFilter(ExpressionContext.of("$.stringBin1.get(type: STRING) == yes"))) .isInstanceOf(DslParseException.class) .hasMessage("Unable to parse right operand"); } @@ -64,31 +65,31 @@ void stringComparisonNegativeTest() { void blobComparison() { byte[] data = new byte[]{1, 2, 3}; String encodedString = Base64.getEncoder().encodeToString(data); - TestUtils.parseFilterAndCompare("$.blobBin1.get(type: BLOB) == \"" + encodedString + "\"", INDEX_FILTER_INPUT, - Filter.equal("blobBin1", data)); + TestUtils.parseFilterAndCompare(ExpressionContext.of("$.blobBin1.get(type: BLOB) == \"" + encodedString + "\""), + INDEX_FILTER_INPUT, Filter.equal("blobBin1", data)); // Reverse - TestUtils.parseFilterAndCompare("\"" + encodedString + "\" == $.blobBin1.get(type: BLOB)", INDEX_FILTER_INPUT, - Filter.equal("blobBin1", data)); + TestUtils.parseFilterAndCompare(ExpressionContext.of("\"" + encodedString + "\" == $.blobBin1.get(type: BLOB)"), + INDEX_FILTER_INPUT, Filter.equal("blobBin1", data)); } @Test void floatComparison() { // No float support in secondary index filter - assertThat(parseFilter("$.floatBin1.get(type: FLOAT) == 1.5")).isNull(); - assertThat(parseFilter("1.5 == $.floatBin1.get(type: FLOAT)")).isNull(); + assertThat(parseFilter(ExpressionContext.of("$.floatBin1.get(type: FLOAT) == 1.5"))).isNull(); + assertThat(parseFilter(ExpressionContext.of("1.5 == $.floatBin1.get(type: FLOAT)"))).isNull(); } @Test void booleanComparison() { // No boolean support in secondary index filter - assertThat(parseFilter("$.boolBin1.get(type: BOOL) == true")).isNull(); - assertThat(parseFilter("true == $.boolBin1.get(type: BOOL)")).isNull(); + assertThat(parseFilter(ExpressionContext.of("$.boolBin1.get(type: BOOL) == true"))).isNull(); + assertThat(parseFilter(ExpressionContext.of("true == $.boolBin1.get(type: BOOL)"))).isNull(); } @Test void negativeBooleanComparison() { - assertThatThrownBy(() -> parseFilter("$.boolBin1.get(type: BOOL) == 5")) + assertThatThrownBy(() -> parseFilter(ExpressionContext.of("$.boolBin1.get(type: BOOL) == 5"))) .isInstanceOf(DslParseException.class) .hasMessage("Cannot compare BOOL to INT"); } @@ -96,75 +97,76 @@ void negativeBooleanComparison() { @Test void listComparison_constantOnRightSide() { // Not supported by secondary index filter - assertThat(parseFilter("$.listBin1.get(type: LIST) == [100]")).isNull(); + assertThat(parseFilter(ExpressionContext.of("$.listBin1.get(type: LIST) == [100]"))).isNull(); } @Test void listComparison_constantOnRightSide_NegativeTest() { - assertThatThrownBy(() -> parseFilter("$.listBin1.get(type: LIST) == [yes, of course]")) + assertThatThrownBy(() -> parseFilter(ExpressionContext.of("$.listBin1.get(type: LIST) == [yes, of course]"))) .isInstanceOf(DslParseException.class) .hasMessage("Unable to parse list operand"); } @Test void listComparison_constantOnLeftSide() { - assertThat(parseFilter("[100] == $.listBin1.get(type: LIST)")).isNull(); + assertThat(parseFilter(ExpressionContext.of("[100] == $.listBin1.get(type: LIST)"))).isNull(); } @Test void listComparison_constantOnLeftSide_NegativeTest() { - assertThatThrownBy(() -> parseFilter("[yes, of course] == $.listBin1.get(type: LIST)")) + assertThatThrownBy(() -> parseFilter(ExpressionContext.of("[yes, of course] == $.listBin1.get(type: LIST)"))) .isInstanceOf(DslParseException.class) .hasMessage("Could not parse given DSL expression input"); } @Test void mapComparison_constantOnRightSide() { - assertThat(parseFilter("$.mapBin1.get(type: MAP) == {100:100}")).isNull(); + assertThat(parseFilter(ExpressionContext.of("$.mapBin1.get(type: MAP) == {100:100}"))).isNull(); } @Test void mapComparison_constantOnRightSide_NegativeTest() { - assertThatThrownBy(() -> parseFilter("$.mapBin1.get(type: MAP) == {yes, of course}")) + assertThatThrownBy(() -> parseFilter(ExpressionContext.of("$.mapBin1.get(type: MAP) == {yes, of course}"))) .isInstanceOf(DslParseException.class) .hasMessage("Unable to parse map operand"); } @Test void mapComparison_constantOnLeftSide() { - assertThat(parseFilter("{100:100} == $.mapBin1.get(type: MAP)")).isNull(); + assertThat(parseFilter(ExpressionContext.of("{100:100} == $.mapBin1.get(type: MAP)"))).isNull(); } @Test void mapComparison_constantOnLeftSide_NegativeTest() { - assertThatThrownBy(() -> parseFilter("{yes, of course} == $.mapBin1.get(type: MAP)")) + assertThatThrownBy(() -> parseFilter(ExpressionContext.of("{yes, of course} == $.mapBin1.get(type: MAP)"))) .isInstanceOf(DslParseException.class) .hasMessage("Could not parse given DSL expression input"); } @Test void twoStringBinsComparison() { - assertThat(parseFilter("$.stringBin1.get(type: STRING) == $.stringBin2.get(type: STRING)")).isNull(); + assertThat(parseFilter(ExpressionContext.of("$.stringBin1.get(type: STRING) == $.stringBin2.get(type: STRING)"))) + .isNull(); } @Test void twoIntegerBinsComparison() { - assertThat(parseFilter("$.intBin1.get(type: INT) == $.intBin2.get(type: INT)")).isNull(); + assertThat(parseFilter(ExpressionContext.of("$.intBin1.get(type: INT) == $.intBin2.get(type: INT)"))).isNull(); } @Test void twoFloatBinsComparison() { - assertThat(parseFilter("$.floatBin1.get(type: FLOAT) == $.floatBin2.get(type: FLOAT)")).isNull(); + assertThat(parseFilter(ExpressionContext.of("$.floatBin1.get(type: FLOAT) == $.floatBin2.get(type: FLOAT)"))).isNull(); } @Test void twoBlobBinsComparison() { - assertThat(parseFilter("$.blobBin1.get(type: BLOB) == $.blobBin2.get(type: BLOB)")).isNull(); + assertThat(parseFilter(ExpressionContext.of("$.blobBin1.get(type: BLOB) == $.blobBin2.get(type: BLOB)"))).isNull(); } @Test void negativeTwoDifferentBinTypesComparison() { - assertThatThrownBy(() -> parseFilter("$.stringBin1.get(type: STRING) == $.floatBin2.get(type: FLOAT)")) + assertThatThrownBy(() -> parseFilter(ExpressionContext.of("$.stringBin1.get(type: STRING) == $.floatBin2.get(type: FLOAT)"))) .isInstanceOf(DslParseException.class) .hasMessage("Cannot compare STRING to FLOAT"); } diff --git a/src/test/java/com/aerospike/dsl/filter/ImplicitTypesFiltersTests.java b/src/test/java/com/aerospike/dsl/filter/ImplicitTypesFiltersTests.java index 79690f8..42d7d1a 100644 --- a/src/test/java/com/aerospike/dsl/filter/ImplicitTypesFiltersTests.java +++ b/src/test/java/com/aerospike/dsl/filter/ImplicitTypesFiltersTests.java @@ -1,5 +1,6 @@ package com.aerospike.dsl.filter; +import com.aerospike.dsl.ExpressionContext; import org.junit.jupiter.api.Test; import static com.aerospike.dsl.util.TestUtils.parseFilter; @@ -9,16 +10,16 @@ public class ImplicitTypesFiltersTests { @Test void implicitDefaultIntComparison() { - assertThat(parseFilter("$.intBin1 < $.intBin2")).isNull(); + assertThat(parseFilter(ExpressionContext.of("$.intBin1 < $.intBin2"))).isNull(); } @Test void floatComparison() { - assertThat(parseFilter("$.floatBin1 >= 100.25")).isNull(); + assertThat(parseFilter(ExpressionContext.of("$.floatBin1 >= 100.25"))).isNull(); } @Test void booleanComparison() { - assertThat(parseFilter("$.boolBin1 == true")).isNull(); + assertThat(parseFilter(ExpressionContext.of("$.boolBin1 == true"))).isNull(); } } diff --git a/src/test/java/com/aerospike/dsl/parsedExpression/LogicalParsedExpressionTests.java b/src/test/java/com/aerospike/dsl/parsedExpression/LogicalParsedExpressionTests.java index c220ae2..3982d8d 100644 --- a/src/test/java/com/aerospike/dsl/parsedExpression/LogicalParsedExpressionTests.java +++ b/src/test/java/com/aerospike/dsl/parsedExpression/LogicalParsedExpressionTests.java @@ -3,6 +3,7 @@ import com.aerospike.client.exp.Exp; import com.aerospike.client.query.Filter; import com.aerospike.client.query.IndexType; +import com.aerospike.dsl.ExpressionContext; import com.aerospike.dsl.Index; import com.aerospike.dsl.IndexContext; import com.aerospike.dsl.util.TestUtils; @@ -14,50 +15,50 @@ public class LogicalParsedExpressionTests { - String NAMESPACE = "test1"; - @Test void binLogical_AND_no_indexes() { Filter filter = null; Exp exp = Exp.and(Exp.gt(Exp.intBin("intBin1"), Exp.val(100)), Exp.gt(Exp.intBin("intBin2"), Exp.val(100))); - TestUtils.parseDslExpressionAndCompare("$.intBin1 > 100 and $.intBin2 > 100", filter, exp); + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 and $.intBin2 > 100"), filter, exp); } @Test void binLogical_AND_all_indexes() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC) + .binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC) + .binValuesRatio(1).build() ); Filter filter = Filter.range("intBin2", 101, Long.MAX_VALUE); Exp exp = Exp.gt(Exp.intBin("intBin1"), Exp.val(100)); - parseDslExpressionAndCompare("$.intBin1 > 100 and $.intBin2 > 100", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 and $.intBin2 > 100"), filter, exp, + IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_AND_all_indexes_no_cardinality() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).build() ); // Filter is chosen alphabetically because no cardinality is given Filter filter = Filter.range("intBin1", 101, Long.MAX_VALUE); // Complementary Exp is provided for the remaining part of the expression Exp exp = Exp.gt(Exp.intBin("intBin2"), Exp.val(100)); - parseDslExpressionAndCompare("$.intBin1 > 100 and $.intBin2 > 100", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 and $.intBin2 > 100"), filter, exp, + IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_AND_one_index() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build()); + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build()); Filter filter = Filter.range("intBin1", 101, Long.MAX_VALUE); Exp exp = Exp.gt(Exp.intBin("intBin2"), Exp.val(100)); - parseDslExpressionAndCompare("$.intBin1 > 100 and $.intBin2 > 100", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 and $.intBin2 > 100"), filter, exp, + IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test @@ -68,7 +69,8 @@ void binLogical_AND_AND_no_indexes() { Exp.gt(Exp.intBin("intBin2"), Exp.val(100)), Exp.gt(Exp.intBin("intBin3"), Exp.val(100)) ); - TestUtils.parseDslExpressionAndCompare("$.intBin1 > 100 and $.intBin2 > 100 and $.intBin3 > 100", filter, exp); + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 and $.intBin2 > 100 and $.intBin3 > 100"), + filter, exp); } @Test @@ -83,7 +85,7 @@ void binLogical_AND_OR_OR_no_indexes() { Exp.gt(Exp.intBin("intBin4"), Exp.val(100)) ); TestUtils.parseDslExpressionAndCompare( - "$.intBin1 > 100 and $.intBin2 > 100 or $.intBin3 > 100 or $.intBin4 > 100", filter, exp); + ExpressionContext.of("$.intBin1 > 100 and $.intBin2 > 100 or $.intBin3 > 100 or $.intBin4 > 100"), filter, exp); } @Test @@ -98,31 +100,31 @@ void binLogical_OR_AND_AND_no_indexes() { ) ); TestUtils.parseDslExpressionAndCompare( - "$.intBin1 > 100 or $.intBin2 > 100 and $.intBin3 > 100 and $.intBin4 > 100", filter, exp); + ExpressionContext.of("$.intBin1 > 100 or $.intBin2 > 100 and $.intBin3 > 100 and $.intBin4 > 100"), filter, exp); } @Test void binLogical_AND_AND_all_indexes() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(0).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(0).build() ); Filter filter = Filter.range("intBin2", 101, Long.MAX_VALUE); Exp exp = Exp.and( Exp.gt(Exp.intBin("intBin1"), Exp.val(100)), Exp.gt(Exp.intBin("intBin3"), Exp.val(100)) ); - parseDslExpressionAndCompare("$.intBin1 > 100 and $.intBin2 > 100 and $.intBin3 > 100", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 and $.intBin2 > 100 and $.intBin3 > 100"), filter, exp, + IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_AND_AND_all_indexes_same_cardinality() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(100).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(100).build(), - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(100).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(100).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(100).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(100).build() ); // Filter is chosen alphabetically because the same cardinality is given Filter filter = Filter.range("intBin1", 101, Long.MAX_VALUE); @@ -130,16 +132,16 @@ void binLogical_AND_AND_all_indexes_same_cardinality() { Exp.gt(Exp.intBin("intBin2"), Exp.val(100)), Exp.gt(Exp.intBin("intBin3"), Exp.val(100)) ); - parseDslExpressionAndCompare("$.intBin1 > 100 and $.intBin2 > 100 and $.intBin3 > 100", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 and $.intBin2 > 100 and $.intBin3 > 100"), filter, exp, + IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_AND_AND_all_indexes_no_cardinality() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).build(), - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).build() ); // Filter is chosen alphabetically because no cardinality is given Filter filter = Filter.range("intBin1", 101, Long.MAX_VALUE); @@ -147,18 +149,18 @@ void binLogical_AND_AND_all_indexes_no_cardinality() { Exp.gt(Exp.intBin("intBin2"), Exp.val(100)), Exp.gt(Exp.intBin("intBin3"), Exp.val(100)) ); - parseDslExpressionAndCompare("$.intBin1 > 100 and $.intBin2 > 100 and $.intBin3 > 100", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 and $.intBin2 > 100 and $.intBin3 > 100"), filter, exp, + IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_AND_AND_all_indexes_partial_data() { List indexes = List.of( Index.builder().bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.STRING).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.STRING).binValuesRatio(0).build(), // The only matching index with full data - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(0).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(0).build() ); // The only matching index with full data is for intBin3 Filter filter = Filter.range("intBin3", 101, Long.MAX_VALUE); @@ -166,23 +168,23 @@ void binLogical_AND_AND_all_indexes_partial_data() { Exp.gt(Exp.intBin("intBin1"), Exp.val(100)), Exp.gt(Exp.intBin("intBin2"), Exp.val(100)) ); - parseDslExpressionAndCompare("$.intBin1 > 100 and $.intBin2 > 100 and $.intBin3 > 100", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 and $.intBin2 > 100 and $.intBin3 > 100"), + filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_AND_AND_two_indexes() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(0).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(0).build() ); Filter filter = Filter.range("intBin2", 101, Long.MAX_VALUE); Exp exp = Exp.and( Exp.gt(Exp.intBin("intBin1"), Exp.val(100)), Exp.gt(Exp.intBin("intBin3"), Exp.val(100)) ); - parseDslExpressionAndCompare("$.intBin1 > 100 and $.intBin2 > 100 and $.intBin3 > 100", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 and $.intBin2 > 100 and $.intBin3 > 100"), + filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test @@ -190,44 +192,44 @@ void binLogical_OR_no_indexes() { Filter filter = null; Exp exp = Exp.or(Exp.gt(Exp.intBin("intBin1"), Exp.val(100)), Exp.gt(Exp.intBin("intBin2"), Exp.val(100))); - TestUtils.parseDslExpressionAndCompare("$.intBin1 > 100 or $.intBin2 > 100", filter, exp); + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 or $.intBin2 > 100"), filter, exp); } @Test void binLogical_OR_all_indexes() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build() ); Filter filter = null; Exp exp = Exp.or( Exp.gt(Exp.intBin("intBin1"), Exp.val(100)), Exp.gt(Exp.intBin("intBin2"), Exp.val(100)) ); - parseDslExpressionAndCompare("$.intBin1 > 100 or $.intBin2 > 100", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 or $.intBin2 > 100"), filter, exp, + IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_OR_one_index() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build() ); Filter filter = null; Exp exp = Exp.or( Exp.gt(Exp.intBin("intBin1"), Exp.val(100)), Exp.gt(Exp.intBin("intBin2"), Exp.val(100)) ); - parseDslExpressionAndCompare("$.intBin1 > 100 or $.intBin2 > 100", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 or $.intBin2 > 100"), filter, exp, + IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_OR_OR_all_indexes() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(0).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(0).build() ); Filter filter = null; Exp exp = Exp.or( @@ -235,16 +237,16 @@ void binLogical_OR_OR_all_indexes() { Exp.gt(Exp.intBin("intBin2"), Exp.val(100)), Exp.gt(Exp.intBin("intBin3"), Exp.val(100)) ); - parseDslExpressionAndCompare("$.intBin1 > 100 or $.intBin2 > 100 or $.intBin3 > 100", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 or $.intBin2 > 100 or $.intBin3 > 100"), filter, + exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_OR_OR_all_indexes_same_cardinality() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build() ); Filter filter = null; Exp exp = Exp.or( @@ -252,16 +254,16 @@ void binLogical_OR_OR_all_indexes_same_cardinality() { Exp.gt(Exp.intBin("intBin2"), Exp.val(100)), Exp.gt(Exp.intBin("intBin3"), Exp.val(100)) ); - parseDslExpressionAndCompare("$.intBin1 > 100 or $.intBin2 > 100 or $.intBin3 > 100", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 or $.intBin2 > 100 or $.intBin3 > 100"), filter, exp, + IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_prioritizedAND_OR_indexed() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build() ); Filter filter = null; Exp exp = Exp.or( @@ -271,36 +273,36 @@ void binLogical_prioritizedAND_OR_indexed() { ), Exp.gt(Exp.intBin("intBin3"), Exp.val(100)) ); - parseDslExpressionAndCompare("$.intBin1 > 100 and $.intBin2 > 100 or $.intBin3 > 100", filter, exp, - IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("($.intBin1 > 100 and $.intBin2 > 100) or $.intBin3 > 100", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > 100 and $.intBin2 > 100 or $.intBin3 > 100"), filter, + exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("($.intBin1 > 100 and $.intBin2 > 100) or $.intBin3 > 100"), filter, + exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_AND_prioritizedOR_indexed() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build() ); Filter filter = Filter.range("intBin3", 101, Long.MAX_VALUE); Exp exp = Exp.or( Exp.gt(Exp.intBin("intBin2"), Exp.val(100)), Exp.gt(Exp.intBin("intBin1"), Exp.val(100)) ); - parseDslExpressionAndCompare("$.intBin3 > 100 and ($.intBin2 > 100 or $.intBin1 > 100)", filter, exp, - IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("($.intBin3 > 100 and ($.intBin2 > 100 or $.intBin1 > 100))", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin3 > 100 and ($.intBin2 > 100 or $.intBin1 > 100)"), filter, + exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("($.intBin3 > 100 and ($.intBin2 > 100 or $.intBin1 > 100))"), filter, + exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_AND_prioritizedOR_indexed_same_cardinality() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build() ); // Cardinality is the same, is it correct that intBin3 is chosen because it is the only one filtered? Filter filter = Filter.range("intBin3", 101, Long.MAX_VALUE); @@ -308,18 +310,18 @@ void binLogical_AND_prioritizedOR_indexed_same_cardinality() { Exp.gt(Exp.intBin("intBin2"), Exp.val(100)), Exp.gt(Exp.intBin("intBin1"), Exp.val(100)) ); - parseDslExpressionAndCompare("$.intBin3 > 100 and ($.intBin2 > 100 or $.intBin1 > 100)", filter, exp, - IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("($.intBin3 > 100 and ($.intBin2 > 100 or $.intBin1 > 100))", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin3 > 100 and ($.intBin2 > 100 or $.intBin1 > 100)"), filter, + exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("($.intBin3 > 100 and ($.intBin2 > 100 or $.intBin1 > 100))"), filter, + exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_AND_prioritizedOR_indexed_no_cardinality() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).build() ); // Cardinality is the same, is it correct that intBin3 is chosen because it is the only one filtered? Filter filter = Filter.range("intBin3", 101, Long.MAX_VALUE); @@ -327,18 +329,18 @@ void binLogical_AND_prioritizedOR_indexed_no_cardinality() { Exp.gt(Exp.intBin("intBin2"), Exp.val(100)), Exp.gt(Exp.intBin("intBin1"), Exp.val(100)) ); - parseDslExpressionAndCompare("$.intBin3 > 100 and ($.intBin2 > 100 or $.intBin1 > 100)", filter, exp, - IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("($.intBin3 > 100 and ($.intBin2 > 100 or $.intBin1 > 100))", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin3 > 100 and ($.intBin2 > 100 or $.intBin1 > 100)"), filter, + exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("($.intBin3 > 100 and ($.intBin2 > 100 or $.intBin1 > 100))"), filter, + exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_OR_prioritizedOR_indexed() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build() ); Filter filter = null; Exp exp = Exp.or( @@ -348,18 +350,18 @@ void binLogical_OR_prioritizedOR_indexed() { Exp.gt(Exp.intBin("intBin1"), Exp.val(100)) ) ); - parseDslExpressionAndCompare("$.intBin3 > 100 or ($.intBin2 > 100 or $.intBin1 > 100)", filter, exp, - IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("($.intBin3 > 100 or ($.intBin2 > 100 or $.intBin1 > 100))", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin3 > 100 or ($.intBin2 > 100 or $.intBin1 > 100)"), filter, + exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("($.intBin3 > 100 or ($.intBin2 > 100 or $.intBin1 > 100))"), filter, + exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_OR_prioritizedOR_indexed_same_cardinality() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build() ); Filter filter = null; Exp exp = Exp.or( @@ -369,18 +371,18 @@ void binLogical_OR_prioritizedOR_indexed_same_cardinality() { Exp.gt(Exp.intBin("intBin1"), Exp.val(100)) ) ); - parseDslExpressionAndCompare("$.intBin3 > 100 or ($.intBin2 > 100 or $.intBin1 > 100)", filter, exp, - IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("($.intBin3 > 100 or ($.intBin2 > 100 or $.intBin1 > 100))", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin3 > 100 or ($.intBin2 > 100 or $.intBin1 > 100)"), filter, + exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("($.intBin3 > 100 or ($.intBin2 > 100 or $.intBin1 > 100))"), filter, + exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_OR_prioritizedAND_indexed() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build() ); Filter filter = null; Exp exp = Exp.or( @@ -390,18 +392,18 @@ void binLogical_OR_prioritizedAND_indexed() { Exp.gt(Exp.intBin("intBin1"), Exp.val(100)) ) ); - parseDslExpressionAndCompare("$.intBin3 > 100 or ($.intBin2 > 100 and $.intBin1 > 100)", filter, exp, - IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("($.intBin3 > 100 or ($.intBin2 > 100 and $.intBin1 > 100))", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin3 > 100 or ($.intBin2 > 100 and $.intBin1 > 100)"), filter, exp, + IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("($.intBin3 > 100 or ($.intBin2 > 100 and $.intBin1 > 100))"), filter, exp, + IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_OR_prioritizedAND_indexed_same_cardinality() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build() ); Filter filter = null; Exp exp = Exp.or( @@ -411,19 +413,19 @@ void binLogical_OR_prioritizedAND_indexed_same_cardinality() { Exp.gt(Exp.intBin("intBin1"), Exp.val(100)) ) ); - parseDslExpressionAndCompare("$.intBin3 > 100 or ($.intBin2 > 100 and $.intBin1 > 100)", filter, exp, - IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("($.intBin3 > 100 or ($.intBin2 > 100 and $.intBin1 > 100))", filter, exp, - IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("$.intBin3 > 100 or ($.intBin2 > 100 and $.intBin1 > 100)"), filter, exp, + IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("($.intBin3 > 100 or ($.intBin2 > 100 and $.intBin1 > 100))"), filter, exp, + IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_prioritizedAND_OR_prioritizedAND_indexed() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(0).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(0).build() ); Filter filter = null; Exp exp = Exp.or( @@ -436,19 +438,21 @@ void binLogical_prioritizedAND_OR_prioritizedAND_indexed() { Exp.gt(Exp.intBin("intBin1"), Exp.val(100)) ) ); - parseDslExpressionAndCompare("($.intBin3 > 100 and $.intBin4 > 100) or ($.intBin2 > 100 and $.intBin1 > 100)", - filter, exp, IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("(($.intBin3 > 100 and $.intBin4 > 100) or ($.intBin2 > 100 and $.intBin1 > 100))", - filter, exp, IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("($.intBin3 > 100 and $.intBin4 > 100) or" + + " ($.intBin2 > 100 and $.intBin1 > 100)"), + filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("(($.intBin3 > 100 and $.intBin4 > 100) or" + + " ($.intBin2 > 100 and $.intBin1 > 100))"), + filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_prioritizedAND_OR_prioritizedAND_indexed_same_cardinality() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(1).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(1).build() ); Filter filter = null; Exp exp = Exp.or( @@ -461,19 +465,19 @@ void binLogical_prioritizedAND_OR_prioritizedAND_indexed_same_cardinality() { Exp.gt(Exp.intBin("intBin1"), Exp.val(100)) ) ); - parseDslExpressionAndCompare("($.intBin3 > 100 and $.intBin4 > 100) or ($.intBin2 > 100 and $.intBin1 > 100)", - filter, exp, IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("(($.intBin3 > 100 and $.intBin4 > 100) or ($.intBin2 > 100 and $.intBin1 > 100))", - filter, exp, IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("($.intBin3 > 100 and $.intBin4 > 100) or" + + " ($.intBin2 > 100 and $.intBin1 > 100)"), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("(($.intBin3 > 100 and $.intBin4 > 100) or" + + " ($.intBin2 > 100 and $.intBin1 > 100))"), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_prioritizedOR_AND_prioritizedOR_indexed() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(0).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(0).build() ); Filter filter = null; Exp exp = Exp.and( @@ -486,19 +490,19 @@ void binLogical_prioritizedOR_AND_prioritizedOR_indexed() { Exp.gt(Exp.intBin("intBin1"), Exp.val(100)) ) ); - parseDslExpressionAndCompare("($.intBin3 > 100 or $.intBin4 > 100) and ($.intBin2 > 100 or $.intBin1 > 100)", - filter, exp, IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("(($.intBin3 > 100 or $.intBin4 > 100) and ($.intBin2 > 100 or $.intBin1 > 100))", - filter, exp, IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("($.intBin3 > 100 or $.intBin4 > 100) and" + + " ($.intBin2 > 100 or $.intBin1 > 100)"), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("(($.intBin3 > 100 or $.intBin4 > 100) and" + + " ($.intBin2 > 100 or $.intBin1 > 100))"), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_prioritizedOR_AND_prioritizedOR_indexed_same_cardinality() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(1).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(1).build() ); Filter filter = null; Exp exp = Exp.and( @@ -511,19 +515,19 @@ void binLogical_prioritizedOR_AND_prioritizedOR_indexed_same_cardinality() { Exp.gt(Exp.intBin("intBin1"), Exp.val(100)) ) ); - parseDslExpressionAndCompare("($.intBin3 > 100 or $.intBin4 > 100) and ($.intBin2 > 100 or $.intBin1 > 100)", - filter, exp, IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("(($.intBin3 > 100 or $.intBin4 > 100) and ($.intBin2 > 100 or $.intBin1 > 100))", - filter, exp, IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("($.intBin3 > 100 or $.intBin4 > 100) and" + + " ($.intBin2 > 100 or $.intBin1 > 100)"), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("(($.intBin3 > 100 or $.intBin4 > 100) and" + + " ($.intBin2 > 100 or $.intBin1 > 100))"), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_prioritizedOR_AND_prioritizedAND_indexed() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(0).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(0).build() ); Filter filter = Filter.range("intBin2", 101, Long.MAX_VALUE); Exp exp = Exp.and( @@ -533,19 +537,19 @@ void binLogical_prioritizedOR_AND_prioritizedAND_indexed() { ), Exp.gt(Exp.intBin("intBin1"), Exp.val(100)) ); - parseDslExpressionAndCompare("($.intBin3 > 100 or $.intBin4 > 100) and ($.intBin2 > 100 and $.intBin1 > 100)", - filter, exp, IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("(($.intBin3 > 100 or $.intBin4 > 100) and ($.intBin2 > 100 and $.intBin1 > 100))", - filter, exp, IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("($.intBin3 > 100 or $.intBin4 > 100) and" + + " ($.intBin2 > 100 and $.intBin1 > 100)"), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("(($.intBin3 > 100 or $.intBin4 > 100) and" + + " ($.intBin2 > 100 and $.intBin1 > 100))"), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_prioritizedOR_AND_prioritizedAND_indexed_same_cardinality() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(1).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(1).build() ); Filter filter = Filter.range("intBin1", 101, Long.MAX_VALUE); Exp exp = Exp.and( @@ -555,19 +559,19 @@ void binLogical_prioritizedOR_AND_prioritizedAND_indexed_same_cardinality() { ), Exp.gt(Exp.intBin("intBin2"), Exp.val(100)) ); - parseDslExpressionAndCompare("($.intBin3 > 100 or $.intBin4 > 100) and ($.intBin2 > 100 and $.intBin1 > 100)", - filter, exp, IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("(($.intBin3 > 100 or $.intBin4 > 100) and ($.intBin2 > 100 and $.intBin1 > 100))", - filter, exp, IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("($.intBin3 > 100 or $.intBin4 > 100) and" + + " ($.intBin2 > 100 and $.intBin1 > 100)"), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("(($.intBin3 > 100 or $.intBin4 > 100) and" + + " ($.intBin2 > 100 and $.intBin1 > 100))"), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_prioritizedOR_prioritizedAND_AND_indexed_withFilter() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(0).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(0).build() ); Filter filter = Filter.range("intBin1", 101, Long.MAX_VALUE); Exp exp = Exp.or( @@ -577,19 +581,19 @@ void binLogical_prioritizedOR_prioritizedAND_AND_indexed_withFilter() { Exp.gt(Exp.intBin("intBin2"), Exp.val(100)) ) ); - parseDslExpressionAndCompare("($.intBin3 > 100 or $.intBin4 > 100 and $.intBin2 > 100) and $.intBin1 > 100", - filter, exp, IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("(($.intBin3 > 100 or $.intBin4 > 100 and $.intBin2 > 100) and $.intBin1 > 100)", - filter, exp, IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("($.intBin3 > 100 or $.intBin4 > 100 and $.intBin2 > 100) and" + + " $.intBin1 > 100"), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("(($.intBin3 > 100 or $.intBin4 > 100 and $.intBin2 > 100) and" + + " $.intBin1 > 100)"), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_prioritizedOR_prioritizedAND_AND_indexed_withTheOnlyFilter() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(0).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(0).build() ); // This expression part does not have the index with the largest cardinality, but it is the only applicable // because all other parts participate in an OR-combined query @@ -601,19 +605,19 @@ void binLogical_prioritizedOR_prioritizedAND_AND_indexed_withTheOnlyFilter() { Exp.gt(Exp.intBin("intBin2"), Exp.val(100)) ) ); - parseDslExpressionAndCompare("($.intBin3 > 100 or $.intBin4 > 100 and $.intBin2 > 100) and $.intBin1 > 100", - filter, exp, IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("(($.intBin3 > 100 or $.intBin4 > 100 and $.intBin2 > 100) and $.intBin1 > 100)", - filter, exp, IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("($.intBin3 > 100 or $.intBin4 > 100 and $.intBin2 > 100) and" + + " $.intBin1 > 100"), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("(($.intBin3 > 100 or $.intBin4 > 100 and $.intBin2 > 100) and" + + " $.intBin1 > 100)"), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_prioritizedOR_prioritizedAND_AND_indexed_same_cardinality() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(1).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(1).build() ); Filter filter = Filter.range("intBin1", 101, Long.MAX_VALUE); Exp exp = Exp.or( @@ -623,19 +627,19 @@ void binLogical_prioritizedOR_prioritizedAND_AND_indexed_same_cardinality() { Exp.gt(Exp.intBin("intBin2"), Exp.val(100)) ) ); - parseDslExpressionAndCompare("($.intBin3 > 100 or $.intBin4 > 100 and $.intBin2 > 100) and $.intBin1 > 100", - filter, exp, IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("(($.intBin3 > 100 or $.intBin4 > 100 and $.intBin2 > 100) and $.intBin1 > 100)", - filter, exp, IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("($.intBin3 > 100 or $.intBin4 > 100 and $.intBin2 > 100) and" + + " $.intBin1 > 100"), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("(($.intBin3 > 100 or $.intBin4 > 100 and $.intBin2 > 100) and" + + " $.intBin1 > 100)"), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_prioritizedOR_prioritizedAND_AND_indexed_withFilterPerCardinality() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), - Index.builder().namespace(NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(0).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).binValuesRatio(0).build() ); // This expression part has the index with the largest cardinality and is applicable for Filter building, // another applicable expression part is "$.intBin1 > 100", but intBin1 has index with lower cardinality @@ -647,21 +651,21 @@ void binLogical_prioritizedOR_prioritizedAND_AND_indexed_withFilterPerCardinalit ), Exp.gt(Exp.intBin("intBin1"), Exp.val(100)) ); - parseDslExpressionAndCompare("(($.intBin3 > 100 or $.intBin4 > 100) and $.intBin2 > 100) and $.intBin1 > 100", - filter, exp, IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("((($.intBin3 > 100 or $.intBin4 > 100) and $.intBin2 > 100) and $.intBin1 > 100)", - filter, exp, IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("(($.intBin3 > 100 or $.intBin4 > 100) and $.intBin2 > 100) and" + + " $.intBin1 > 100"), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("((($.intBin3 > 100 or $.intBin4 > 100) and $.intBin2 > 100) and" + + " $.intBin1 > 100)"), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_OR2_OR1_AND2_AND_AND1_indexed_no_cardinality() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).build(), - Index.builder().namespace(NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).build(), - Index.builder().namespace(NAMESPACE).bin("intBin5").indexType(IndexType.NUMERIC).build(), - Index.builder().namespace(NAMESPACE).bin("intBin6").indexType(IndexType.NUMERIC).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin5").indexType(IndexType.NUMERIC).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin6").indexType(IndexType.NUMERIC).build() ); Filter filter = Filter.range("intBin1", 101, Long.MAX_VALUE); Exp exp = Exp.and( @@ -679,21 +683,22 @@ void binLogical_OR2_OR1_AND2_AND_AND1_indexed_no_cardinality() { ); String dslString = "(($.intBin3 > 100 or $.intBin4 > 100) or ($.intBin5 > 100 and $.intBin6 > 100)) " + "and ($.intBin2 > 100 and $.intBin1 > 100)"; - parseDslExpressionAndCompare(dslString, filter, exp, IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("(" + dslString + ")", filter, exp, IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of(dslString), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("(" + dslString + ")"), filter, exp, + IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test void binLogical_OR2_OR1_AND2_AND_AND2_OR1_AND2_indexed_no_cardinality() { List indexes = List.of( - Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).build(), - Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).build(), - Index.builder().namespace(NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).build(), - Index.builder().namespace(NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).build(), - Index.builder().namespace(NAMESPACE).bin("intBin5").indexType(IndexType.NUMERIC).build(), - Index.builder().namespace(NAMESPACE).bin("intBin6").indexType(IndexType.NUMERIC).build(), - Index.builder().namespace(NAMESPACE).bin("intBin7").indexType(IndexType.NUMERIC).build(), - Index.builder().namespace(NAMESPACE).bin("intBin8").indexType(IndexType.NUMERIC).build() + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin3").indexType(IndexType.NUMERIC).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin4").indexType(IndexType.NUMERIC).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin5").indexType(IndexType.NUMERIC).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin6").indexType(IndexType.NUMERIC).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin7").indexType(IndexType.NUMERIC).build(), + Index.builder().namespace(TestUtils.NAMESPACE).bin("intBin8").indexType(IndexType.NUMERIC).build() ); // No Filter can be built as all expression parts participate in OR-combined queries Filter filter = null; @@ -721,18 +726,19 @@ void binLogical_OR2_OR1_AND2_AND_AND2_OR1_AND2_indexed_no_cardinality() { ); String dslString = "(($.intBin3 > 100 or $.intBin4 > 100) or ($.intBin5 > 100 and $.intBin6 > 100)) " + "and (($.intBin2 > 100 and $.intBin1 > 100) or ($.intBin7 > 100 and $.intBin8 > 100))"; - parseDslExpressionAndCompare(dslString, filter, exp, IndexContext.of(NAMESPACE, indexes)); - parseDslExpressionAndCompare("(" + dslString + ")", filter, exp, IndexContext.of(NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of(dslString), filter, exp, IndexContext.of(TestUtils.NAMESPACE, indexes)); + parseDslExpressionAndCompare(ExpressionContext.of("(" + dslString + ")"), filter, exp, + IndexContext.of(TestUtils.NAMESPACE, indexes)); } @Test - void binLogical_EXCL_EXCL_no_indexes() { + void binLogical_EXCL_no_indexes() { Filter filter = null; Exp exp = Exp.exclusive( Exp.eq(Exp.stringBin("hand"), Exp.val("stand")), Exp.eq(Exp.stringBin("pun"), Exp.val("done")) ); - TestUtils.parseDslExpressionAndCompare("exclusive($.hand == \"stand\", $.pun == \"done\")", filter, exp); + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("exclusive($.hand == \"stand\", $.pun == \"done\")"), + filter, exp); } - } diff --git a/src/test/java/com/aerospike/dsl/parsedExpression/PlaceholdersTests.java b/src/test/java/com/aerospike/dsl/parsedExpression/PlaceholdersTests.java new file mode 100644 index 0000000..9a555c4 --- /dev/null +++ b/src/test/java/com/aerospike/dsl/parsedExpression/PlaceholdersTests.java @@ -0,0 +1,317 @@ +package com.aerospike.dsl.parsedExpression; + +import com.aerospike.client.Value; +import com.aerospike.client.cdt.CTX; +import com.aerospike.client.cdt.ListReturnType; +import com.aerospike.client.cdt.MapReturnType; +import com.aerospike.client.exp.Exp; +import com.aerospike.client.exp.Expression; +import com.aerospike.client.exp.ListExp; +import com.aerospike.client.exp.MapExp; +import com.aerospike.client.query.Filter; +import com.aerospike.client.query.IndexType; +import com.aerospike.dsl.DslParseException; +import com.aerospike.dsl.ExpressionContext; +import com.aerospike.dsl.Index; +import com.aerospike.dsl.IndexContext; +import com.aerospike.dsl.ParseResult; +import com.aerospike.dsl.ParsedExpression; +import com.aerospike.dsl.PlaceholderValues; +import com.aerospike.dsl.util.TestUtils; +import org.junit.jupiter.api.Test; + +import java.util.Base64; +import java.util.Collection; +import java.util.List; + +import static com.aerospike.dsl.util.TestUtils.NAMESPACE; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class PlaceholdersTests { + + @Test + void intBin_GT_no_indexes() { + Filter filter = null; + Exp exp = Exp.gt(Exp.intBin("intBin1"), Exp.val(100)); + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > ?0", PlaceholderValues.of(100)), + filter, exp); + + Exp expString = Exp.gt(Exp.stringBin("strBin1"), Exp.val("str")); + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("$.strBin1 > ?0", PlaceholderValues.of("str")), + filter, expString); + Exp expString2 = Exp.gt(Exp.stringBin("strBin1"), Exp.val("'str'")); + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("$.strBin1 > ?0", PlaceholderValues.of("'str'")), + filter, expString2); + Exp expString3 = Exp.gt(Exp.stringBin("strBin1"), Exp.val("\"str\"")); + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("$.strBin1 > ?0", PlaceholderValues.of("\"str\"")), + filter, expString3); + + byte[] data = new byte[]{1, 2, 3}; + String encodedString = Base64.getEncoder().encodeToString(data); + Exp expStringBase64 = Exp.gt(Exp.blobBin("blobBin1"), Exp.val(data)); + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("$.blobBin1.get(type: BLOB) > ?0", + PlaceholderValues.of(encodedString)), filter, expStringBase64); + } + + @Test + void intBin_GT_no_indexes_reuseExprTree() { + ParsedExpression parsedExpr = + TestUtils.getParsedExpression(ExpressionContext.of("$.intBin1 > ?0", PlaceholderValues.of(100)), null); + ParseResult result = parsedExpr.getResult(PlaceholderValues.of(200)); + + assertThat(result.getFilter()).isNull(); + Expression expToCompare = Exp.build(Exp.gt(Exp.intBin("intBin1"), Exp.val(200))); + assertThat(Exp.build(result.getExp())).isEqualTo(expToCompare); + } + + @Test + void intBin_GT_no_indexes_size_mismatch() { + assertThatThrownBy(() -> + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > ?0", PlaceholderValues.of()), + null, null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("Missing value for placeholder ?0"); + + assertThatThrownBy(() -> + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > ?0", null), + null, null)) + .isInstanceOf(DslParseException.class) + .hasMessageContaining("Operand type not supported: PLACEHOLDER_OPERAND"); + + assertThatThrownBy(() -> + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > ?0"), + null, null)) + .isInstanceOf(DslParseException.class) + .hasMessageContaining("Operand type not supported: PLACEHOLDER_OPERAND"); + + assertThatThrownBy(() -> + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > ?0 and $.intBin2 > ?1", + PlaceholderValues.of(100)), null, null)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("Missing value for placeholder ?1"); + + Filter filter = null; + Exp exp = Exp.gt(Exp.intBin("intBin1"), Exp.val(100)); + // If there are more values than placeholders we only match the required indexes + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > ?0", PlaceholderValues.of(100, 200)), + filter, exp); + } + + @Test + void intBin_GT_has_index() { + List indexes = List.of( + Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build() + ); + Filter filter = Filter.range("intBin1", 101, Long.MAX_VALUE); + Exp exp = null; + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > ?0", PlaceholderValues.of(100)), + filter, exp, IndexContext.of(NAMESPACE, indexes)); + } + + @Test + void intBin_GT_has_index_reuseExprTree() { + List indexes = List.of( + Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build() + ); + ParsedExpression parsedExpr = + TestUtils.getParsedExpression(ExpressionContext.of("$.intBin1 > ?0", PlaceholderValues.of(100)), + IndexContext.of(NAMESPACE, indexes)); + ParseResult result = parsedExpr.getResult(PlaceholderValues.of(200)); + + Filter filter = Filter.range("intBin1", 201, Long.MAX_VALUE); + assertThat(result.getFilter()).isEqualTo(filter); + assertThat(result.getExp()).isNull(); + } + + @Test + void intBin_GT_AND_no_indexes() { + Filter filter = null; + Exp exp = Exp.and(Exp.gt(Exp.intBin("intBin1"), Exp.val(100)), Exp.gt(Exp.intBin("intBin2"), Exp.val(100))); + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > ?0 and $.intBin2 > ?1", + PlaceholderValues.of(100, 100)), filter, exp); + } + + @Test + void intBin_GT_AND_all_indexes() { + List indexes = List.of( + Index.builder().namespace(NAMESPACE).bin("intBin1").indexType(IndexType.NUMERIC).binValuesRatio(0).build(), + Index.builder().namespace(NAMESPACE).bin("intBin2").indexType(IndexType.NUMERIC).binValuesRatio(1).build() + ); + Filter filter = Filter.range("intBin2", 101, Long.MAX_VALUE); + Exp exp = Exp.gt(Exp.intBin("intBin1"), Exp.val(100)); + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("$.intBin1 > ?0 and $.intBin2 > ?1", + PlaceholderValues.of(100, 100)), filter, exp, IndexContext.of(NAMESPACE, indexes)); + } + + @Test + void metadataExpression_TTL() { + // Expression to find records that will expire within 24 hours + Filter filter = null; + + Exp exp = Exp.le(Exp.ttl(), Exp.val(24 * 60 * 60)); + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("$.ttl() <= ?0", PlaceholderValues.of(86400)), + filter, exp); + } + + @Test + void arithmeticExpression() { + Filter filter = null; + Exp exp = Exp.gt(Exp.add(Exp.intBin("apples"), Exp.val(5)), Exp.val(10)); + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("($.apples + ?0) > ?1", PlaceholderValues.of(5, 10)), + filter, exp); + + Collection INDEXES = List.of( + Index.builder().namespace("test1").bin("apples").indexType(IndexType.NUMERIC).binValuesRatio(1).build(), + Index.builder().namespace("test1").bin("bananas").indexType(IndexType.NUMERIC).binValuesRatio(1).build() + ); + IndexContext INDEX_FILTER_INPUT = IndexContext.of(NAMESPACE, INDEXES); + Filter filter2 = Filter.range("apples", 10 - 5 + 1, Long.MAX_VALUE); + Exp exp2 = null; + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("($.apples + ?0) > ?1", PlaceholderValues.of(5, 10)), + filter2, exp2, INDEX_FILTER_INPUT); + } + + @Test + void mapNestedExp() { + Exp expected = Exp.gt( + MapExp.getByKey( + MapReturnType.VALUE, + Exp.Type.INT, + Exp.val("bcc"), + Exp.mapBin("mapBin1"), + CTX.mapKey(Value.get("a")), CTX.mapKey(Value.get("bb")) + ), + Exp.val(200)); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.bb.bcc > ?0", PlaceholderValues.of(200)), + expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.bb.bcc.get(type: INT) > ?0", + PlaceholderValues.of(200)), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.bb.bcc.get(type: INT, return: VALUE) > ?0", + PlaceholderValues.of(200)), expected); + + // String + expected = Exp.eq( + MapExp.getByKey( + MapReturnType.VALUE, + Exp.Type.STRING, + Exp.val("bcc"), + Exp.mapBin("mapBin1"), + CTX.mapKey(Value.get("a")), CTX.mapKey(Value.get("bb")) + ), + Exp.val("stringVal")); + // Implicit detect as String + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.bb.bcc == ?0", + PlaceholderValues.of("stringVal")), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.bb.bcc.get(type: STRING) == ?0", + PlaceholderValues.of("stringVal")), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.mapBin1.a.bb.bcc.get(type: STRING, return: VALUE) == ?0", + PlaceholderValues.of("stringVal")), expected); + } + + @Test + void nestedListsExpWithDifferentContextTypes() { + // Nested List Rank + Exp expected = Exp.eq( + ListExp.getByRank( + ListReturnType.VALUE, + Exp.Type.STRING, + Exp.val(-1), + Exp.listBin("listBin1"), + CTX.listIndex(5) + ), + Exp.val("stringVal")); + // Implicit detect as String + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[5].[#-1] == ?0", + PlaceholderValues.of("stringVal")), expected); + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[5].[#-1].get(type: STRING) == ?0", + PlaceholderValues.of("stringVal")), expected); + + // Nested List Rank Value + expected = Exp.eq( + ListExp.getByValue( + ListReturnType.VALUE, + Exp.val(100), + Exp.listBin("listBin1"), + CTX.listIndex(5), + CTX.listRank(-1) + ), + Exp.val(200)); + // Implicit detect as Int + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.listBin1.[5].[#-1].[=100] == ?0", + PlaceholderValues.of(200)), expected); + } + + @Test + void forthDegreeComplicatedExplicitFloat() { + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of( + "(($.apples.get(type: FLOAT) + $.bananas.get(type: FLOAT))" + + " + ($.oranges.get(type: FLOAT) + $.acai.get(type: FLOAT))) > ?0", PlaceholderValues.of(10.5)), + Exp.gt( + Exp.add( + Exp.add(Exp.floatBin("apples"), Exp.floatBin("bananas")), + Exp.add(Exp.floatBin("oranges"), Exp.floatBin("acai"))), + Exp.val(10.5)) + ); + } + + @Test + void complicatedWhenExplicitTypeString() { + Exp expected = Exp.eq( + Exp.stringBin("a"), + Exp.cond( + Exp.eq( + Exp.intBin("b"), + Exp.val(1) + ), Exp.stringBin("a1"), + Exp.eq( + Exp.intBin("b"), + Exp.val(2) + ), Exp.stringBin("a2"), + Exp.eq( + Exp.intBin("b"), + Exp.val(3) + ), Exp.stringBin("a3"), + Exp.val("hello") + ) + ); + + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("$.a.get(type: STRING) == " + + "(when($.b == ?0 => $.a1.get(type: STRING)," + + " $.b == ?1 => $.a2.get(type: STRING)," + + " $.b == ?2 => $.a3.get(type: STRING)," + + " default => ?3))", PlaceholderValues.of(1, 2, 3, "hello")), expected); + } + + @Test + void whenWithMultipleDeclarations() { + Exp expected = Exp.cond( + Exp.eq( + Exp.intBin("who"), + Exp.val(1) + ), Exp.val("bob"), + Exp.eq( + Exp.intBin("who"), + Exp.val(2) + ), Exp.val("fred"), + Exp.val("other") + ); + + TestUtils.parseFilterExpressionAndCompare(ExpressionContext.of("when ($.who == ?0 => ?1, " + + "$.who == ?2 => ?3, default => ?4)", PlaceholderValues.of(1, "bob", 2, "fred", "other")), + expected); + } + + @Test + void binLogical_EXCL_no_indexes() { + Filter filter = null; + Exp exp = Exp.exclusive( + Exp.eq(Exp.stringBin("hand"), Exp.val("stand")), + Exp.eq(Exp.stringBin("pun"), Exp.val("done")) + ); + TestUtils.parseDslExpressionAndCompare(ExpressionContext.of("exclusive($.hand == ?0, $.pun == ?1)", + PlaceholderValues.of("stand", "done")), filter, exp); + } +} diff --git a/src/test/java/com/aerospike/dsl/util/TestUtils.java b/src/test/java/com/aerospike/dsl/util/TestUtils.java index ff77e7f..f6beec1 100644 --- a/src/test/java/com/aerospike/dsl/util/TestUtils.java +++ b/src/test/java/com/aerospike/dsl/util/TestUtils.java @@ -3,9 +3,10 @@ import com.aerospike.client.exp.Exp; import com.aerospike.client.exp.Expression; import com.aerospike.client.query.Filter; -import com.aerospike.dsl.DSLParserImpl; +import com.aerospike.dsl.ExpressionContext; import com.aerospike.dsl.IndexContext; import com.aerospike.dsl.ParsedExpression; +import com.aerospike.dsl.impl.DSLParserImpl; import lombok.experimental.UtilityClass; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -13,94 +14,87 @@ @UtilityClass public class TestUtils { - private final DSLParserImpl parser = new DSLParserImpl(); - - /** - * Parses the given DSL expression and returns a {@link ParsedExpression} object. - * - * @param input The string input representing DSL expression - * @param indexContext The {@link IndexContext} to be used during parsing - * @return A {@link ParsedExpression} object containing the result of the parsing - */ - public static ParsedExpression parseExpression(String input, IndexContext indexContext) { - return parser.parseExpression(input, indexContext); - } + public static final String NAMESPACE = "test1"; + private static final DSLParserImpl parser = new DSLParserImpl(); /** * Parses the given DSL expression and extracts the resulting {@link Exp} object. * - * @param input The string input representing DSL expression + * @param expressionContext The input representing DSL expression * @return The {@link Exp} object derived from the parsed filter expression */ - public static Exp parseFilterExp(String input) { - return parser.parseExpression(input).getResult().getExp(); + public static Exp parseFilterExp(ExpressionContext expressionContext) { + return parser.parseExpression(expressionContext).getResult().getExp(); } /** - * Parses the given DSL expression and builds an {@link Expression} object from the resulting - * {@link Exp}. + * Parses the given DSL expression and returns the resulting {@link ParsedExpression} object. * - * @param input The string input representing DSL expression - * @return An {@link Expression} object built from the parsed filter expression + * @param expressionContext The {@link ExpressionContext} representing DSL expression + * @param indexContext The {@link IndexContext} to be used for building secondary index filter + * @return The {@link Exp} object derived from the parsed filter expression */ - public static Expression parseFilterExpression(String input) { - return Exp.build(parser.parseExpression(input).getResult().getExp()); + public static ParsedExpression getParsedExpression(ExpressionContext expressionContext, IndexContext indexContext) { + return parser.parseExpression(expressionContext, indexContext); } /** - * Parses the given DSL expression, extracts the resulting {@link Exp} object, converts it to an {@link Expression} object, - * and then asserts that it is equal to the {@code expected} {@link Exp} also built into an {@link Expression}. + * Parses the given DSL expression, extracts the resulting {@link Exp} object, converts it to an {@link Expression} + * object, and then asserts that it is equal to the {@code expected} {@link Exp} also built into an + * {@link Expression}. * - * @param input The string input representing DSL expression - * @param expected The expected {@link Exp} object to compare against the parsed result + * @param expressionContext The input representing DSL expression + * @param expected The expected {@link Exp} object to compare against the parsed result */ - public static void parseFilterExpressionAndCompare(String input, Exp expected) { - Expression actualExpression = Exp.build(parser.parseExpression(input).getResult().getExp()); + public static void parseFilterExpressionAndCompare(ExpressionContext expressionContext, Exp expected) { + Expression actualExpression = Exp.build(parser.parseExpression(expressionContext).getResult().getExp()); Expression expectedExpression = Exp.build(expected); assertEquals(expectedExpression, actualExpression); } /** - * Parses the given DSL expression and returns the resulting {@link Filter} object. - * This method uses the parser without an {@link IndexContext}. + * Parses the given DL expression using the provided {@link ExpressionContext} to match placeholders + * and returns the resulting {@link Filter} object. * - * @param input The string input representing DSL expression + * @param expressionContext The {@link ExpressionContext} to be used to match placeholders * @return A {@link Filter} object derived from the parsed result */ - public static Filter parseFilter(String input) { - return parser.parseExpression(input).getResult().getFilter(); + public static Filter parseFilter(ExpressionContext expressionContext) { + return parser.parseExpression(expressionContext).getResult().getFilter(); } /** * Parses the given DL expression using the provided {@link IndexContext} and returns the resulting {@link Filter} object. * - * @param input The string input representing DSL expression - * @param indexContext The {@link IndexContext} to be used during parsing + * @param expressionContext The input representing DSL expression + * @param indexContext The {@link IndexContext} to be used for building secondary index filter * @return A {@link Filter} object derived from the parsed result */ - public static Filter parseFilter(String input, IndexContext indexContext) { - return parser.parseExpression(input, indexContext).getResult().getFilter(); + public static Filter parseFilter(ExpressionContext expressionContext, IndexContext indexContext) { + return parser.parseExpression(expressionContext, indexContext).getResult().getFilter(); } /** - * Parses the given DSL expression and asserts that the result is equal to the {@code expected} {@link Filter} object. + * Parses the given DSL expression and asserts that the result is equal to the {@code expected} {@link Filter} + * object. * - * @param input The string input representing DSL expression + * @param input The input representing DSL expression * @param expected The expected {@link Filter} object to compare against the parsed result */ - public static void parseFilterAndCompare(String input, Filter expected) { + public static void parseFilterAndCompare(ExpressionContext input, Filter expected) { Filter actualFilter = parseFilter(input); assertEquals(expected, actualFilter); } /** - * Parses the given DSL expression using the provided {@link IndexContext} and asserts that the result is equal to the {@code expected} {@link Filter} object. + * Parses the given DSL expression using the provided {@link IndexContext} and asserts that the result is equal to + * the {@code expected} {@link Filter} object. * - * @param input The string input representing DSL expression - * @param indexContext The {@link IndexContext} to be used during parsing - * @param expected The expected {@link Filter} object to compare against the parsed result + * @param input The string input representing DSL expression + * @param indexContext The {@link IndexContext} to be used for building secondary index filter + * @param expected The expected {@link Filter} object to compare against the parsed result */ - public static void parseFilterAndCompare(String input, IndexContext indexContext, Filter expected) { + public static void parseFilterAndCompare(ExpressionContext input, IndexContext indexContext, Filter expected) { Filter actualFilter = parseFilter(input, indexContext); assertEquals(expected, actualFilter); } @@ -109,12 +103,12 @@ public static void parseFilterAndCompare(String input, IndexContext indexContext * Parses the given DSL expression and compares the resulting * {@link Filter} and {@link Exp} components with the expected {@code filter} and {@code exp}. * - * @param input The string input representing DSL expression - * @param filter The expected {@link Filter} component of the parsed result - * @param exp The expected {@link Exp} component of the parsed result. Can be {@code null} + * @param expressionContext The input representing DSL expression + * @param filter The expected {@link Filter} component of the parsed result + * @param exp The expected {@link Exp} component of the parsed result. Can be {@code null} */ - public static void parseDslExpressionAndCompare(String input, Filter filter, Exp exp) { - ParsedExpression actualExpression = parser.parseExpression(input); + public static void parseDslExpressionAndCompare(ExpressionContext expressionContext, Filter filter, Exp exp) { + ParsedExpression actualExpression = parser.parseExpression(expressionContext); assertEquals(filter, actualExpression.getResult().getFilter()); Exp actualExp = actualExpression.getResult().getExp(); assertEquals(exp == null ? null : Exp.build(exp), actualExp == null ? null : Exp.build(actualExp)); @@ -124,13 +118,13 @@ public static void parseDslExpressionAndCompare(String input, Filter filter, Exp * Parses the given DSL expression using the provided {@link IndexContext} * and compares the resulting {@link Filter} and {@link Exp} components with the expected {@code filter} and {@code exp}. * - * @param input The string input representing DSL expression - * @param filter The expected {@link Filter} component of the parsed result - * @param exp The expected {@link Exp} component of the parsed result. Can be {@code null} - * @param indexContext The {@link IndexContext} to be used during parsing + * @param expressionContext The input representing DSL expression + * @param filter The expected {@link Filter} component of the parsed result + * @param exp The expected {@link Exp} component of the parsed result. Can be {@code null} + * @param indexContext The {@link IndexContext} to be used for building secondary index filter */ - public static void parseDslExpressionAndCompare(String input, Filter filter, Exp exp, IndexContext indexContext) { - ParsedExpression actualExpression = parser.parseExpression(input, indexContext); + public static void parseDslExpressionAndCompare(ExpressionContext expressionContext, Filter filter, Exp exp, IndexContext indexContext) { + ParsedExpression actualExpression = parser.parseExpression(expressionContext, indexContext); assertEquals(filter, actualExpression.getResult().getFilter()); Exp actualExp = actualExpression.getResult().getExp(); assertEquals(exp == null ? null : Exp.build(exp), actualExp == null ? null : Exp.build(actualExp));