Skip to content

Add InTuples expression for multi-column IN expression#3124

Merged
rbygrave merged 3 commits intomasterfrom
feature/InTuples
Jul 3, 2023
Merged

Add InTuples expression for multi-column IN expression#3124
rbygrave merged 3 commits intomasterfrom
feature/InTuples

Conversation

@rbygrave
Copy link
Copy Markdown
Member

@rbygrave rbygrave commented Jul 2, 2023

Example

    var c = QContact.alias();

    InTuples inTuples = InTuples.of(c.firstName, c.lastName)
      .add("Rob", "B")
      .add("Bob", "C")
      .add("Mob", "D");

    var query = new QContact()
      .firstName.isNotNull()
      .email.isNotNull()
      .inTuples(inTuples)
      .query();

    query.findList();
    assertThat(query.getGeneratedSql()).contains("(t0.first_name,t0.last_name) in ((?,?),(?,?),(?,?))");

Note this is currently not supported by SQLServer or DB2.

@rbygrave rbygrave marked this pull request as draft July 2, 2023 23:50
@rbygrave rbygrave self-assigned this Jul 2, 2023
@rob-bygrave rob-bygrave marked this pull request as ready for review July 3, 2023 00:42
@rob-bygrave rob-bygrave added this to the 13.20.1 milestone Jul 3, 2023
@rbygrave rbygrave merged commit 7702169 into master Jul 3, 2023
@rbygrave rbygrave deleted the feature/InTuples branch July 3, 2023 00:48
@rPraml
Copy link
Copy Markdown
Contributor

rPraml commented Jul 3, 2023

Hi @rbygrave

I like that feature, unfortunately it will not work on all databases.

On DB2 you have to use where (prop1, prop2) in ( VALUES (?,?),(?,?) ...) (Same syntax works on MariaDB)

On SqlServer, you have to do other tricks, like subqueries or just a simple conjunction of ANDs / ORs.
See: https://stackoverflow.com/questions/8006901/using-tuples-in-sql-in-clause

BTW: What do you think about this syntax?

 var query = new QContact()
      .firstName.isNotNull()
      .email.isNotNull()
      .inTuples(c.firstName, c.lastName)
         .add("Rob", "B")
         .add("Bob", "C")
         .add("Mob", "D")
      .endTuple()
      .query();

Roland.

@rbygrave
Copy link
Copy Markdown
Member Author

rbygrave commented Jul 3, 2023

DB2

Oh, I didn't know DB2 supported it via that syntax with VALUES - interesting and maybe we can support that. I was ok with putting this into the next version knowing it does not work with SQLServer and DB2.

SQLServer

Yes. It's almost easier to use concat functions and use a plain IN which is what we have with inPairs() (noting that only supports 2 columns).

BTW: What do you think about this syntax?

Well I expect the normal case is that we have a collection of things ... and iterate the collection calling add(...). That is, I don't think we will do this in-line in the query much at all.

Hmmm, let me think about it. endTuple() is consistent with endOr().

@rPraml
Copy link
Copy Markdown
Contributor

rPraml commented Jul 3, 2023

SQLServer

Yes. It's almost easier to use concat functions and use a plain IN which is what we have with inPairs() (noting that only supports 2 columns).

Do you plan to make a fallback implementation for platforms that do not support tuples? I really like that, as we are often using this here (we use and/or queries), so it would be great, if we can get some benefits, if the platfrom supports it

Some thoughts:

  • concat: easy to implement, will make problems on special data types where java.toString differs from server.toString (e.g. dates + times)
  • combination of AND/OR: Should be also easy to implement, but makes complex queries
  • some complex subquery: would make query less complex (=shorter) but difficult to implement

@rbygrave
Copy link
Copy Markdown
Member Author

rbygrave commented Jul 3, 2023

Do you plan to make a fallback implementation for platforms that do not support tuples?

Yes, that is the plan. I'll look to release as it is in 13.20.1 and add an implementation for DB2 & SQLServer later. [Rant, why is it that 2 of the largest tech companies on the planet can't implement this like everyone else ??? ]

combination of AND/OR:

This is what I thought InTuples will have to do for SQLServer. In theory people can do the concat + IN today but perhaps need guidance / example to show them.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants