Skip to content

fix(parser)!: parse numbers with the invariant culture only - #121

Open
pdevito3 wants to merge 1 commit into
mainfrom
fm/qk-breaking-invariant-numbers
Open

pdevito3 wants to merge 1 commit into
mainfrom
fm/qk-breaking-invariant-numbers

Conversation

@pdevito3

Copy link
Copy Markdown
Owner

Summary

This PR makes the number grammar use the invariant culture only, so a decimal comma is not accepted. This is a breaking change. It is one of the six breaking changes that were removed from #114 so that main stays compatible with v1.14.2.

Status: for later consideration. Do not merge this PR now. The captain decides on each breaking change separately. If this change is accepted, it needs a major version.

Main already parses 4.5 in every culture, and list numbers always use .. This PR adds only the strict invariant grammar that rejects 4,5.

Old behavior (v1.14.2 and main)

  • v1.14.2: the number grammar uses CurrentCulture. Under de-DE, Rating > 4.5 fails to parse. Rating > 4,5 parses, and the value conversion reads it with the invariant culture as 45.
  • main: Rating > 4.5 parses in every culture. Under de-DE, Rating > 4,5 still gives 45.

New behavior

The number grammar uses the invariant culture only. Rating > 4.5 means 4.5 in every culture. Rating > 4,5 throws a QueryKitException in every culture.

The change removes UnsignedNumberParser and ListNumberParser. The number grammar, the list grammar, the count operator value, and the literal checks in IsPropertyPath use the invariant culture only.

Example

Proof from the verify-querykit harness, with the culture set to de-DE. Each row gives the same result in memory and on Postgres.

Filter main This PR
Price > 4,5 0 rows, no error (the parameter value is 45) ParsingException: "unexpected ','; expected end of input (Line 1, Column 10)"
Price > 4.5 Beef Stew Beef Stew

Justification

The v1.14.2 result for 4,5 is 45, which is not the value that any user means. This result is silent, so the API returns wrong rows with no error. A filter string is a machine format, and the same filter must give the same result on every server.

The strict invariant grammar gives one meaning for 4.5 everywhere and rejects 4,5 with a clear error. The break affects only a consumer on a comma culture that sends 4,5 and depends on the value 45.

Migration

Send the number with a . decimal point, for example Rating > 4.5.

Tests

  • The two unit tests for the comma culture are now one theory, decimal_value_with_decimal_comma_is_not_accepted, for de-DE, fr-FR, and en-US. It expects QueryKitException.
  • dotnet test: 346 unit tests and 268 integration tests pass.

The number grammar also accepted the decimal separator of the current culture. Under de-DE, Rating > 4,5 parsed, and the value conversion read it with the invariant culture as 45. The API returned wrong rows with no error.

The number grammar, the count operator value, and the literal checks in IsPropertyPath now use the invariant culture only. A number always uses the '.' decimal point.

BREAKING CHANGE: a number with a decimal comma, for example Rating > 4,5, throws a QueryKitException in every culture. Before, a server with a comma culture read this value as 45. Send the number with a '.' decimal point, for example Rating > 4.5.
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