Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

CLIENT-4216 Support IN operation for Lists#65

Open
agrgr wants to merge 11 commits intomainaerospike/expression-dsl-java:mainfrom
CLIENT-4216-support-in-list-operationaerospike/expression-dsl-java:CLIENT-4216-support-in-list-operationCopy head branch name to clipboard
Open

CLIENT-4216 Support IN operation for Lists#65
agrgr wants to merge 11 commits intomainaerospike/expression-dsl-java:mainfrom
CLIENT-4216-support-in-list-operationaerospike/expression-dsl-java:CLIENT-4216-support-in-list-operationCopy head branch name to clipboard

Conversation

@agrgr
Copy link
Collaborator

@agrgr agrgr commented Feb 27, 2026

No description provided.

@agrgr agrgr requested a review from Copilot February 27, 2026 17:38
@agrgr agrgr added the enhancement New feature or request label Feb 27, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds support for an IN operator in the Aerospike DSL so expressions like $.bin in [1,2,3] and "x" in $.listBin compile into Aerospike list existence expressions, while ensuring IN clauses are excluded from secondary-index filter selection.

Changes:

  • Extend the ANTLR grammar and expression AST to recognize the IN operator.
  • Generate Aerospike expressions for IN via ListExp.getByValue(ListReturnType.EXISTS, left, right) and exclude IN from SI filter selection.
  • Add comprehensive expression and parsed-expression/index-selection tests for IN.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/main/antlr4/com/aerospike/dsl/Condition.g4 Adds IN token/rule and updates list constant parsing to support [] tokenization.
src/main/java/com/aerospike/dsl/parts/ExpressionContainer.java Adds IN to the operation enum.
src/main/java/com/aerospike/dsl/visitor/ExpressionConditionVisitor.java Builds IN expression containers and infers operand types for IN.
src/main/java/com/aerospike/dsl/visitor/VisitorUtils.java Emits Aerospike IN expression, validates IN placeholder RHS, and excludes IN from index-cardinality filter selection.
src/test/java/com/aerospike/dsl/expression/InExpressionsTests.java Adds parsing/Exp-building tests (including negatives) for IN.
src/test/java/com/aerospike/dsl/parsedExpression/InFilterTests.java Adds parsed-expression tests to ensure IN is excluded from secondary-index Filter selection.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1141 to +1143
if (expr.getOperationType() == IN && rightIsPlaceholder) {
validateInPlaceholderValue((PlaceholderOperand) expr.getRight(), placeholderValues);
}
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IN with a right-hand placeholder that resolves to a Java List will still fail later: this validation passes, but the placeholder is then resolved via OperandFactory.createOperand(...), which currently doesn't support List values (it throws UnsupportedOperationException). Consider either extending placeholder resolution to wrap list values into a ListOperand (and map values into MapOperand if needed), or special-casing IN placeholder resolution to build Exp.val(resolvedList) directly so $.bin in ?0 works when ?0 is a list.

Copilot uses AI. Check for mistakes.

private static void inferInTypes(AbstractPart left, AbstractPart right) {
if (right.getPartType() == AbstractPart.PartType.BIN_PART) {
((BinPart) right).updateExp(Exp.Type.LIST);
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inferInTypes currently forces the right operand BIN_PART to Exp.Type.LIST unconditionally. This overwrites an explicitly provided type (e.g. $.x.get(type: INT)) and can mask user errors. Suggest only auto-setting LIST when the right bin type is not explicitly set; if it is explicitly set and not LIST, fail fast with the same parse exception used elsewhere for invalid IN right operands.

Suggested change
((BinPart) right).updateExp(Exp.Type.LIST);
BinPart rightBin = (BinPart) right;
if (!rightBin.isTypeExplicitlySet()) {
rightBin.updateExp(Exp.Type.LIST);
}

Copilot uses AI. Check for mistakes.

@Test
void placeholderAsRightOperand() {
parseFilterExp(ExpressionContext.of("$.name in ?0"));
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

placeholderAsRightOperand currently calls parseFilterExp(ExpressionContext.of("$.name in ?0")) without providing PlaceholderValues. In the existing placeholder tests, missing values causes a parse failure (PLACEHOLDER_OPERAND is unsupported when values are null), so this test will fail. Either provide placeholder values here (ideally a List value once placeholder list support is implemented) or change the test to assert the expected exception for missing placeholder values.

Suggested change
parseFilterExp(ExpressionContext.of("$.name in ?0"));
assertThatThrownBy(() -> parseFilterExp(ExpressionContext.of("$.name in ?0")))
.isInstanceOf(DslParseException.class);

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

QUOTED_STRING: ('\'' (~'\'')* '\'') | ('"' (~'"')* '"');

listConstant: '[' unaryExpression? (',' unaryExpression)* ']';
listConstant: '[' unaryExpression? (',' unaryExpression)* ']' | LIST_TYPE_DESIGNATOR;
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The addition of LIST_TYPE_DESIGNATOR as an alternative in the listConstant rule appears unrelated to the IN operation support. The LIST_TYPE_DESIGNATOR token (defined as '[]' on line 417) is already used in the listPart rule for path operations. Adding it here would allow '[]' to be parsed as a list literal, but there are no tests demonstrating this functionality or explaining its purpose in relation to the IN operation. Consider removing this addition if it's not needed for the IN operation, or add tests and documentation if it's intentional.

Suggested change
listConstant: '[' unaryExpression? (',' unaryExpression)* ']' | LIST_TYPE_DESIGNATOR;
listConstant: '[' unaryExpression? (',' unaryExpression)* ']';

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is done to handle empty list, added a comment

Comment on lines +314 to +323
static Exp.Type inferTypeFromListElements(ListOperand listOperand) {
List<Object> values = listOperand.getValue();
if (values.isEmpty()) return null;
Object first = values.get(0);
if (first instanceof String) return Exp.Type.STRING;
if (first instanceof Boolean) return Exp.Type.BOOL;
if (first instanceof Float || first instanceof Double) return Exp.Type.FLOAT;
if (first instanceof Integer || first instanceof Long) return Exp.Type.INT;
if (first instanceof java.util.List) return Exp.Type.LIST;
if (first instanceof java.util.Map) return Exp.Type.MAP;
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inferTypeFromListElements method only checks the first element of the list to infer the type. This could lead to incorrect type inference if the list contains mixed types (e.g., [1, "string", 2]). While Aerospike may not support heterogeneous lists, consider adding a comment explaining this assumption or validating that all elements are of the same type to prevent silent type mismatches.

Suggested change
static Exp.Type inferTypeFromListElements(ListOperand listOperand) {
List<Object> values = listOperand.getValue();
if (values.isEmpty()) return null;
Object first = values.get(0);
if (first instanceof String) return Exp.Type.STRING;
if (first instanceof Boolean) return Exp.Type.BOOL;
if (first instanceof Float || first instanceof Double) return Exp.Type.FLOAT;
if (first instanceof Integer || first instanceof Long) return Exp.Type.INT;
if (first instanceof java.util.List) return Exp.Type.LIST;
if (first instanceof java.util.Map) return Exp.Type.MAP;
/**
* Infer the Aerospike Exp.Type for a list operand by examining its elements.
* <p>
* This method assumes/enforces that all non-null elements in the list are of the same
* logical type (e.g. all strings, all integers, etc.). If heterogeneous element types
* are detected, a DslParseException is thrown to avoid silent type mismatches.
*/
static Exp.Type inferTypeFromListElements(ListOperand listOperand) {
List<Object> values = listOperand.getValue();
if (values.isEmpty()) {
return null;
}
Exp.Type inferredType = null;
for (Object value : values) {
if (value == null) {
// Skip nulls for the purpose of type inference.
continue;
}
Exp.Type currentType = inferElementType(value);
if (currentType == null) {
throw new DslParseException(
"Unsupported element type in IN list: " + value.getClass().getName());
}
if (inferredType == null) {
inferredType = currentType;
} else if (inferredType != currentType) {
throw new DslParseException(
"IN list elements must all be of the same type; found " +
inferredType + " and " + currentType);
}
}
return inferredType;
}
/**
* Map a single Java object to the corresponding Aerospike Exp.Type.
*/
private static Exp.Type inferElementType(Object element) {
if (element instanceof String) return Exp.Type.STRING;
if (element instanceof Boolean) return Exp.Type.BOOL;
if (element instanceof Float || element instanceof Double) return Exp.Type.FLOAT;
if (element instanceof Integer || element instanceof Long) return Exp.Type.INT;
if (element instanceof java.util.List) return Exp.Type.LIST;
if (element instanceof java.util.Map) return Exp.Type.MAP;

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +305 to +310
&& !((BinPart) left).isTypeExplicitlySet()
&& right.getPartType() == AbstractPart.PartType.LIST_OPERAND) {
Exp.Type inferredType = inferTypeFromListElements((ListOperand) right);
if (inferredType != null) {
((BinPart) left).updateExp(inferredType);
}
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For IN, type compatibility between the left operand and the list element type is not validated when the left side has an explicit type (e.g. $.name.get(type: STRING) in [1,2] will currently parse/build an expression). Consider inferring the element type for LIST_OPERAND right-hand sides and calling validateComparableTypes() against the left operand type (at least when left is a BIN_PART with an explicitly set type), so mismatches fail fast like other comparison operators.

Suggested change
&& !((BinPart) left).isTypeExplicitlySet()
&& right.getPartType() == AbstractPart.PartType.LIST_OPERAND) {
Exp.Type inferredType = inferTypeFromListElements((ListOperand) right);
if (inferredType != null) {
((BinPart) left).updateExp(inferredType);
}
&& right.getPartType() == AbstractPart.PartType.LIST_OPERAND) {
BinPart leftBin = (BinPart) left;
Exp.Type inferredType = inferTypeFromListElements((ListOperand) right);
// If the list is empty (or only nulls), we cannot infer a type – nothing to do.
if (inferredType == null) {
return;
}
if (!leftBin.isTypeExplicitlySet()) {
// Existing behavior: infer the left bin type from homogeneous list elements.
leftBin.updateExp(inferredType);
} else {
// New behavior: when the left type is explicit, validate compatibility with
// the inferred list element type so mismatches fail fast.
Exp.Type leftType = leftBin.getExpType();
if (leftType != inferredType) {
throw new DslParseException(
"Type mismatch in IN operation: left operand is of type "
+ leftType + " but list elements are of type " + inferredType);
}
}

Copilot uses AI. Check for mistakes.
Comment on lines 57 to 66
} else if (value instanceof List) {
return new ListOperand((List<Object>) value);
} else if (value instanceof SortedMap) {
return new MapOperand((SortedMap<Object, Object>) value);
} else if (value instanceof Map) {
return new MapOperand(new TreeMap<>((Map<Object, Object>) value));
} 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",
throw new UnsupportedOperationException(String.format("Cannot create operand from value of type %s",
value.getClass().getSimpleName()));
}
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

createOperand() wraps any Map in a TreeMap, which will throw a ClassCastException at runtime if the map keys are not mutually comparable (or if mixed key types are present). Since this method is used for resolving placeholders, it would be better to fail deterministically with a DslParseException/UnsupportedOperationException that explains the requirement (or only accept SortedMap and reject other Map inputs).

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +244 to 246
| IN
;

Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding IN as an alternative in the mapKey rule (and using ctx.IN() in MapKey.from()) is correct. However, MapKeyRange and MapKeyList (which also use mapKey) have not been updated to handle the IN token. When the IN keyword is used as a key in a range expression (like $.mapBin.{in-z}) or a key list ($.mapBin.{in,z}), the existing code in MapKeyRange.from() and MapKeyList.from() will throw a NullPointerException because it only checks for NAME_IDENTIFIER() and QUOTED_STRING(), not IN(). These classes should be updated with the same fix applied to MapKey.from() in this PR.

Suggested change
| IN
;
;

Copilot uses AI. Check for mistakes.
@agrgr agrgr requested a review from tim-aero February 27, 2026 22:45
@agrgr agrgr marked this pull request as ready for review February 27, 2026 22:45
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 28 out of 28 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1197 to +1205
if (left.getPartType() != BIN_PART
|| right.getPartType() != LIST_OPERAND) {
return;
}
BinPart leftBin = (BinPart) left;
Exp.Type inferredType = inferTypeFromListElements((ListOperand) right);
if (inferredType == null) {
return;
}
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inferTypeFromListElements() enforces homogeneous element types, but it’s only invoked via inferLeftBinTypeFromList(), which returns early unless the left operand is BIN_PART. As a result, expressions like "x" in [1, "y"] or ?0 in [1, "y"] won’t throw, while $.bin in [1, "y"] will—this is inconsistent with the stated rule and the negative tests. Consider validating LIST_OPERAND element types for all IN expressions (even when the left isn’t a bin) and add a test that covers a non-bin left operand with a mixed-type list.

Suggested change
if (left.getPartType() != BIN_PART
|| right.getPartType() != LIST_OPERAND) {
return;
}
BinPart leftBin = (BinPart) left;
Exp.Type inferredType = inferTypeFromListElements((ListOperand) right);
if (inferredType == null) {
return;
}
// Only proceed when the right operand is a list; otherwise nothing to infer/validate.
if (right.getPartType() != LIST_OPERAND) {
return;
}
// Always validate list element types for IN expressions, regardless of the left operand.
Exp.Type inferredType = inferTypeFromListElements((ListOperand) right);
if (inferredType == null) {
// Empty list: nothing to infer or validate further.
return;
}
// If the left operand is not a bin, there is no bin type to infer or validate against.
if (left.getPartType() != BIN_PART) {
return;
}
// For bin operands, infer or validate the bin's Exp type against the list element type.
BinPart leftBin = (BinPart) left;

Copilot uses AI. Check for mistakes.
Comment on lines +1179 to +1181
Object value = placeholderValues.getValue(placeholder.getIndex());
if (!(value instanceof List)) {
throw new DslParseException("IN operation requires a List as the right operand");
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Javadoc says this validation happens "so that the error message references the placeholder index", but the thrown message doesn’t include the index (it’s the same for any placeholder). Either include the placeholder index in the exception message (e.g., ?0) or adjust the Javadoc to match the current behavior.

Suggested change
Object value = placeholderValues.getValue(placeholder.getIndex());
if (!(value instanceof List)) {
throw new DslParseException("IN operation requires a List as the right operand");
int index = placeholder.getIndex();
Object value = placeholderValues.getValue(index);
if (!(value instanceof List)) {
throw new DslParseException("IN operation requires a List as the right operand for placeholder ?" + index);

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 29 out of 30 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1173 to +1186
* Validates that a placeholder used as the right operand of an IN expression
* resolves to a {@link java.util.List}. Called before placeholder resolution
* so that the error message references the placeholder index.
*
* @throws DslParseException if the placeholder value is not a List
*/
private static void validateInPlaceholderValue(PlaceholderOperand placeholder,
PlaceholderValues placeholderValues) {
int index = placeholder.getIndex();
Object value = placeholderValues.getValue(index);
if (!(value instanceof List)) {
throw new DslParseException(
"IN operation requires a List as the right operand for placeholder ?" + index);
}
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Javadoc for validateInPlaceholderValue says it throws DslParseException when the placeholder value is not a list, but placeholderValues.getValue(index) can also throw IllegalArgumentException when the placeholder index is missing. Consider documenting that behavior here (or wrapping it into a DslParseException) so callers/tests don’t see an unexpected exception type.

Copilot uses AI. Check for mistakes.
Comment on lines +311 to +332
private static void inferInTypes(AbstractPart left, AbstractPart right) {
if (right.getPartType() == AbstractPart.PartType.BIN_PART) {
BinPart rightBin = (BinPart) right;
if (!rightBin.isTypeExplicitlySet()) {
rightBin.updateExp(Exp.Type.LIST);
} else if (rightBin.getExpType() != Exp.Type.LIST) {
throw new DslParseException(
"IN operation requires a List as the right operand");
}
} else if (right.getPartType() == AbstractPart.PartType.PATH_OPERAND) {
Path rightPath = (Path) right;
if (rightPath.getPathFunction() != null) {
Exp.Type pathType = rightPath.getPathFunction().getBinType();
if (pathType != null && pathType != Exp.Type.LIST) {
throw new DslParseException(
"IN operation requires a List as the right operand");
}
}
}
Exp.Type inferredType = VisitorUtils.validateListHomogeneity(right);
VisitorUtils.inferBinTypeFromList(left, inferredType);
}
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For IN, the right operand is required to evaluate to a LIST, but inferInTypes() only enforces this for BIN_PART (and PATH_OPERAND when a path function has an explicit non-LIST type). Plain PATH/VARIABLE operands with no explicit type info are always accepted, which means ListExp.getByValue(...) can be built over operands whose inferred/default type is not LIST (e.g., nested map paths default to STRING). Consider either requiring an explicit LIST type on PATH/VARIABLE right operands (e.g., .get(type: LIST) / designator) or coercing the right operand’s type metadata to LIST when used with IN, so validation and generated Exp types align with the operation contract.

Copilot uses AI. Check for mistakes.
Comment on lines +75 to 76
throw new UnsupportedOperationException(String.format("Cannot create operand from value of type %s",
value.getClass().getSimpleName()));
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fallback UnsupportedOperationException message became less actionable (it no longer tells callers which operand value types are supported). Consider restoring the previous detail or switching to a DslParseException with a clearer guidance message, since this error can surface for placeholder values at runtime.

Suggested change
throw new UnsupportedOperationException(String.format("Cannot create operand from value of type %s",
value.getClass().getSimpleName()));
throw new DslParseException(String.format(
"Unsupported operand value type '%s'. Supported types are: String, Boolean, Float/Double, Integer/Long, List, and Map/SortedMap. "
+ "If this value comes from a placeholder, ensure it is resolved to one of the supported types before operand creation.",
value.getClass().getName()));

Copilot uses AI. Check for mistakes.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Irrelevant for now

@agrgr
Copy link
Collaborator Author

agrgr commented Mar 2, 2026

Implicit type setting only applies to BIN_PART. Once the path becomes a PATH_OPERAND (by having CDT parts like $.rooms.room1.tags), the same implicit setting currently does nnot work.
If we go with the same implicit approach here instead of requiring explicit types, then we still want recognizing the type once, but it looks like any external type override (set type from outside Path, read it inside processPath) bears similar fundamental drawbacks: the override is applied unconditionally after processing actual type, unable to distinguish wrong defaults from correct structural inferences (designators, COUNT/SIZE etc.), risking silent corruption of otherwise correct types, and it will likely introduce a mutable state where unneccessary.

There is a way to go with an operation-aware hint approach (effectively "default of a default") which seems to be the least bad of implicit approaches so far. We could store a defaultTypeHint on Path (or pass it through processValueType -> findValueType). The hint replaces getDefaultType() only at the final fallback of findValueType, preserving all earlier resolution steps.
It will be likely able to preserve explicit types, designators, and COUNT (the three cases where the parser has real information in the current implementation). It only overrides the heuristic default (when the parser is guessing anyway). Its blind spot will be the same user errors that already exist with right operand being a path, e.g., $.name IN $.rooms.room1.name.

When the right operand is a PATH_OPERAND, there's no list literal to inspect, so no cross-inference happens. With the mentioned hint an expression $.rooms.room1.name IN $.rooms.room1.tags will work, with the left operand having the default type String (for a Map key) - again, if in reality user really has these types stored.
However, with $.data[0] IN $.rooms.room1.tags, the left operand gets default INT (list index heuristic), the right gets LIST. If the actual list at tags contains strings, not ints, the left operand type is wrong. But this is the same level blind spot -- the parser can't know the element type of a list it only has a path reference to. This gap already exists for BIN_PART IN PATH_OPERAND and isn't introduced or worsened by the hint.

So overall, currently there seem to be two approaches:

  • Operation-aware hint -> extend implicit type setting to PATH_OPERAND, full validation unavailable.
  • Require explicit types -> reject PATH_OPERAND without .get(type: LIST) on simple bin, .get(type: LIST) on CDT path or [] list designator (the most explicit, can be validated, a bit changes UX but has its reasons).

What do you think, @tim-aero?

@tim-aero
Copy link

tim-aero commented Mar 3, 2026

I think it's valid to require types when they are abiguous, eg $.name in $.rooms.room1.name. There is no type information on anything in the expression where you can work out $.name is a string or integer, and therefore if $.rooms.room1.name should be a list of Strings or integers. So in this case we would require a type on the left type. Note that the right type shouldn't need a type -- we know it's meant to be a LIST due to its position relative to the IN operator, and we're returning a COUNT so the element type doesn't matter.

However, if we have already determined the type of the left operand, the type should not be necessary: $.name =='Room1' and $.name IN $.rooms.room1.name should be able to derive the type of $.name
`
I was confused about your comments re:

  • $.rooms.room1.name IN $.rooms.room1.tags will work, with the left operand having the default type String (for a Map key)
  • $.data[0] IN $.rooms.room1.tags, the left operand gets default INT (list index heuristic),

My confusion arises because $.rooms.room1.name returns the element (value) of the appropriate sub-map with the map key of name. This could be of any supported type, not just Strings. Similarly, $.data[0] gets the first item in the list bin data, which could be any type and is not necessarily an INT. Am I missing something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.