Skip to content

fix(filter)!: accept a property path on the right side of a comparison - #150

Merged
pdevito3 merged 1 commit into
v2from
fm/qk-breaking-right-side-path
Oct 3, 2026
Merged

pdevito3 merged 1 commit into
v2from
fm/qk-breaking-right-side-path

Conversation

@pdevito3

@pdevito3 pdevito3 commented Oct 1, 2026 •

Copy link
Copy Markdown
Owner

Summary

-            .XOr(Identifier.Select(v => new RightSideValue(v, false)));
+            .XOr(Identifier.DelimitedBy(Parse.Char('.')).Select(v => v.ToList()).Select(v => new RightSideValue(string.Join(".", v), false, IsPropertyPath: v.Count > 1)));
  • The right side of a comparison reads a dotted property path, not only one word.
  • An unquoted dotted name on the right side must resolve to a property. If it does not resolve, the filter throws UnknownFilterPropertyException.
  • The right-side path uses PropertyResolver.ResolveWithoutQueryName, so it obeys MaxPropertyDepth and PreventFilter.
  • A property list ((Title, Directions) == ...) does not accept a path on the right side. The parse fails with ParsingException, like before.

v1.14.2 behavior (and main)

The right side reads one identifier. An unquoted dotted word on the right side throws ParsingException. The README shows right-side paths (Email.Value == CollectionEmail.Value, Rating > Author.Score), but these examples throw.

New behavior

Filter on Recipe Result
Title == Author.Name x => (x.Title == x.Author.Name)
Title == Author.Nmae UnknownFilterPropertyException: "The filter property 'Nmae' was not recognized."
Title == foo.bar UnknownFilterPropertyException for foo
Title == Ingredients.Name UnknownFilterPropertyException for Ingredients.Name (a path through a collection is not one value)
Title == Author.Name with MaxPropertyDepth = 0 QueryKitPropertyDepthExceededException
Title == Author.Name || Rating > 3 with Author.Name prevented x => (x.Rating > 3)
Title == "foo.bar", Rating == 3.5 values, no change

Only identifier-shaped dotted text is a path. Numbers, dates, Guids, and quoted text keep their parsers, which run first. A single unquoted identifier that is not a property stays a value, as before. An unresolved path throws also when AllowUnknownProperties is on, like an unknown property on the right side of arithmetic.

Justification

The README documents property paths on the right side, and a path works on the left side. The right side must accept the same paths with the same checks. A typo in a path must not turn into a silent string comparison.

Migration

A filter that compared with an unquoted dotted word as text must quote it: Title == "foo.bar".

README

"Child Property Comparisons" now tells that an unquoted dotted name on the right side must resolve to a property, and how to quote a literal.

Tests

  • Unit PropertyResolverTests.property_path_on_the_right_side_is_compared
  • Unit unresolved_property_path_on_the_right_side_throws (Author.Nmae, foo.bar, Ingredients.Name) and ..._when_unknown_properties_are_allowed
  • Unit property_path_on_the_right_side_obeys_max_property_depth
  • Unit prevented_property_path_on_the_right_side_removes_the_clause
  • Unit property_path_on_the_right_side_of_a_property_list_throws
  • Unit number_with_a_dot_on_the_right_side_is_a_value, quoted_value_with_a_dot_on_the_right_side_is_a_value
  • Postgres property_path_on_the_right_side_is_compared, prevented_property_path_on_the_right_side_is_not_compared

dotnet test: 574 unit tests and 359 Postgres integration tests (Testcontainers) pass, 0 failures.

Rebase on v2

The branch is rebased on v2, after #136, #154, and #141. The v2 tests that expected a throw for Title == Author.Name and Title == foo.bar are replaced by the tests above.

The right side of a comparison read one identifier. Title == Author.Name threw ParsingException, and the README examples with a path on the right side (Rating > Author.Score) did not work. Read a dotted property path on the right side, and resolve it like a path on the left side.

An unquoted dotted name on the right side must resolve to a property. If it does not, the filter throws UnknownFilterPropertyException. A path through a collection also throws. The path obeys MaxPropertyDepth and PreventFilter. A property list does not accept a path on the right side.

BREAKING CHANGE: Title == Author.Name compares the two properties. Title == foo.bar throws UnknownFilterPropertyException instead of ParsingException. Quote the text to compare with a literal value.
@pdevito3
pdevito3 force-pushed the fm/qk-breaking-right-side-path branch from 4d42f5a to 53350f1 Compare October 3, 2026 12:08
@pdevito3
pdevito3 merged commit 2943e23 into v2 Oct 3, 2026
2 checks passed
@pdevito3
pdevito3 deleted the fm/qk-breaking-right-side-path branch October 3, 2026 12:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant