Skip to content

fix(parser)!: keep quoted custom operation values as strings - #118

Open
pdevito3 wants to merge 1 commit into
mainfrom
fm/qk-breaking-quoted-custom-values
Open

pdevito3 wants to merge 1 commit into
mainfrom
fm/qk-breaking-quoted-custom-values

Conversation

@pdevito3

Copy link
Copy Markdown
Owner

Summary

This PR keeps a quoted value for a custom operation as a string. 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, or the opt-in setting below.

Old behavior (v1.14.2 and main)

The value for a custom operation goes through ConvertStringToBasicType without the quote information.

  • A quoted number becomes an int or a decimal.
  • A quoted "true" becomes a bool.
  • A quoted "null" becomes null.

New behavior

A quoted value skips the null, boolean, and number conversions, so it stays a string. A quoted value in the date format of the grammar and a quoted guid still convert, as the docs show. An unquoted value converts as before.

Example

sku_is == "001"

The custom operation is x.Sku == (string)value. Proof from the verify-querykit harness. Pancakes has Sku 001.

Target main This PR
memory InvalidCastException (the operation gets the int value 1) Pancakes
Postgres 0 rows (r."Sku" = 1::text) Pancakes (r."Sku" = '001'::text)

An unquoted number still converts. total_stock_above == 20 returns Beef Stew on both targets, with > 20::int.

After this change, a custom operation that casts a quoted value, for example (int)value for "10", throws InvalidCastException.

Justification

Quotes are the only way that a client can say "this value is text". Everywhere else in the grammar, a quoted value is a string. The custom operation path ignores the quotes, so a client cannot send a code, a SKU, or a postal code with leading zeros. The client also cannot send the literal text "true" or "null".

The fix makes custom operations obey the same rule as the rest of the grammar. A consumer that wants a number can send it without quotes.

Migration and opt-in alternative

  • Send the value without quotes to get a number, a boolean, or null.
  • Alternative: add an opt-in setting on the custom operation, for example KeepQuotedValuesAsStrings(). The setting can keep the v1.14.2 default until the next major version. This PR does not add the setting.

Tests

  • New unit tests: custom_operation_keeps_quoted_value_as_string and custom_operation_converts_unquoted_number_and_quoted_date.
  • New integration test: custom_operation_keeps_quoted_value_as_string.
  • dotnet test: 352 unit tests and 269 integration tests pass.

A custom operation converted its value without the quote information, so 'sku_is == "001"' gave the operation the int 1. A quoted value now skips the null, boolean, and number conversions.

A quoted value in the date format of the grammar or a quoted guid still converts, as the docs show. Other quoted values, for example "4.5", stay strings.

BREAKING CHANGE: a custom operation gets a quoted number, boolean, or "null" value as a string. A custom operation that casts a quoted value, for example (int)value for "10", throws InvalidCastException. Send the value without quotes to get a number, a boolean, or null.
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