Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add case-insensitive support in advanced Json filtering #4977

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

lubosmato
Copy link

@lubosmato lubosmato commented Aug 9, 2024

The PR adds case field into Json filtering to allow case-insensitive text filtering with Json fields.

E.g.:

prisma.article.findMany({
  where: {
    title: {
      path: ["en"],
      string_contains: searchText,
      mode: "insensitive",
    },
  }
})

Fixes prisma/prisma#7390

@CLAassistant
Copy link

CLAassistant commented Aug 9, 2024

CLA assistant check
All committers have signed the CLA.

@lubosmato lubosmato marked this pull request as ready for review August 9, 2024 14:57
@lubosmato lubosmato requested a review from a team as a code owner August 9, 2024 14:57
@lubosmato lubosmato requested review from jkomyno and removed request for a team August 9, 2024 14:57
@lubosmato lubosmato changed the title fix: add case-insensitive support in advanced Json filtering feat: add case-insensitive support in advanced Json filtering Aug 9, 2024
@macrozone
Copy link

that would be some awesome to have

Copy link
Contributor

@jkomyno jkomyno left a comment

Choose a reason for hiding this comment

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

Thanks for this PR! I've left a couple of comments for further iterations and better compatibility with the other database providers.

let contains = expr_string.like(format!("%{value}%"));
let contains = match query_mode {
QueryMode::Default => expr_string.like(format!("%{value}%")),
QueryMode::Insensitive => expr_string.compare_raw("ILIKE", format!("%{value}%")),
Copy link
Contributor

Choose a reason for hiding this comment

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

The ILIKE comparison operator is only available on PostgreSQL and CockroachDB.
Since Prisma supports several other database providers (like SQLite, MySQL, MongoDB), we should steer away from using raw operators directly.

Usually, we rely on connector-specific primitives wrapped in a common abstraction (quaint::connector::queryable::Queryable).

But in this case, the way forward is probably to change the implementations of the quaint::visitor::Visitor trait to align visit_json_extract and similar methods to prisma/prisma#7390 (comment), lowering the case of both compared values when mode: 'insensitive' is applied.

Copy link
Author

Choose a reason for hiding this comment

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

Nice catch, thank you!

let starts_with = expr_string.like(format!("{value}%"));
let starts_with = match query_mode {
QueryMode::Default => expr_string.like(format!("{value}%")),
QueryMode::Insensitive => expr_string.compare_raw("ILIKE", format!("{value}%")),
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we choose another name for the currently called "query mode"? How about case: 'sensitive' | 'insensitive', where case: 'sensitive' is the default option?

Copy link
Author

Choose a reason for hiding this comment

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

After adding case enum, it feels a bit incosistent with the rest of where api. Especially when looking into cases like:

prisma.recipe.findMany({
  where: {
    allergens: {
      not: { contains: "peanuts" },
      mode: "insensitive", // <-- mode
    },
    title: {
      path: [locale],
      string_contains: filter.search,
      case: "insensitive", // <-- case
    },
  },
})

Copy link
Contributor

Choose a reason for hiding this comment

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

Hi @lubosmato, after talking with a colleague, and observing this output, I stand corrected. I didn't realise QueryMode was an already existing enum in out codebase (

). So, let's stick with mode: 'default' | 'insensitive':)

Copy link
Author

Choose a reason for hiding this comment

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

Hi @jkomyno, thank you for reply. I reverted the commit with case enum.

@jkomyno jkomyno self-assigned this Aug 12, 2024
@lubosmato lubosmato marked this pull request as draft August 12, 2024 13:26
@lubosmato lubosmato force-pushed the main branch 2 times, most recently from 76913f0 to db9cf81 Compare August 14, 2024 16:38
@lubosmato lubosmato marked this pull request as ready for review August 14, 2024 16:41
@lubosmato
Copy link
Author

lubosmato commented Aug 14, 2024

@jkomyno thank you for review, would you find time for another round?

Also I would like to ask you if you could point me to the right direction. I tried to hook up prisma client with locally built bins/libs to test this feature with prisma generate on an existing project but generated files have no mention of newly added changes (e.g. case field is missing). In dmmf output I can see newly added field case.

I tried to set env vars PRISMA_QUERY_ENGINE_* and PRISMA_SCHEMA_ENGINE_BINARY and run prisma generate. prisma version is showing that correct libs/bins are used but resulting generated types for prisma-client-js generator are not affected.

What needs to be done in order to make prisma-client-js generator generate types with locally built prisma-engines?

@lubosmato
Copy link
Author

Hi @jkomyno, what are the next steps/is there anything else that needs to be done from my end?

Copy link

codspeed-hq bot commented Aug 30, 2024

CodSpeed Performance Report

Merging #4977 will not alter performance

Comparing lubosmato:main (860c583) with main (f2561ec)

Summary

✅ 11 untouched benchmarks

@aqrln
Copy link
Member

aqrln commented Aug 30, 2024

Also I would like to ask you if you could point me to the right direction. I tried to hook up prisma client with locally built bins/libs to test this feature with prisma generate on an existing project but generated files have no mention of newly added changes (e.g. case field is missing). In dmmf output I can see newly added field case.

I tried to set env vars PRISMA_QUERY_ENGINE_* and PRISMA_SCHEMA_ENGINE_BINARY and run prisma generate. prisma version is showing that correct libs/bins are used but resulting generated types for prisma-client-js generator are not affected.

What needs to be done in order to make prisma-client-js generator generate types with locally built prisma-engines?

This is slightly annoying to do, sorry for that. Prisma CLI (and generator) doesn't use the query engine to get the DMMF, it uses the WASM module (published as @prisma/prisma-schema-wasm on npm). You can build it locally by running make build-schema-wasm in the engines directory, the built package will be in target/prisma-schema-wasm. Unfortunately there's no convenient way to make CLI use it; what I do is just manually edit https://github.com/prisma/prisma/blob/7955bca6c4e343e452f9138547d42d952ad0c54d/packages/internals/src/wasm.ts#L1 to import this package from the engines directory in the local filesystem and rebuild Prisma.

@lubosmato
Copy link
Author

Hi @jkomyno, what needs to be done to finish this?

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.

Support case insensitive advanced Json filtering
5 participants