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

add MERGE query support. #700

Merged
merged 66 commits into from
Jan 8, 2024
Merged

Conversation

igalklebanov
Copy link
Member

@igalklebanov igalklebanov commented Sep 16, 2023

closes #203.

This PR adds MERGE query support. A special, complex query supported by engines such as PostgreSQL, MS SQL Server and OracleDB. It combines boolean logic (ExpressionBuilder shines here) between 2 tables (target table and source table) as a decision whether to insert, update or delete rows in a target table. There's a combination of various things that already exist in Kysely: filter expressions, ExpressionBuilder, InsertQueryBuilder and UpdateQueryBuilder.

Breaking changes:

  • into is now optional in InsertQueryNode as insert queries in then do not reference the table being inserted into. (then insert [(...columns...)] values ...)
  • table is now optional in UpdateQueryNode as update queries in then do not reference the table being updated. (then update set ...)

Things to add later:

  • if we add top clause support, we need it here too (for mssql).
  • if we add output clause support, we need it here too (for mssql).
  • if we add insert default values support, we need it here too (for postgres).
  • if we add only and * support, we need it here too (for postgres).

progress:

  • implement.
  • js docs.
  • unit tests.
  • typings tests.

@igalklebanov igalklebanov added api Related to library's API enhancement New feature or request mssql Related to MS SQL Server (MSSQL) postgres Related to PostgreSQL labels Sep 16, 2023
@vercel
Copy link

vercel bot commented Sep 16, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
kysely ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jan 8, 2024 11:08pm

@michael-land
Copy link

Thank you, been waiting for this for a long time.

@koskimas
Copy link
Member

koskimas commented Jan 6, 2024

Let's try to get this merged next 😅 @igalklebanov Could you rebase this when you have time?

@igalklebanov
Copy link
Member Author

Let's try to get this merged next 😅 @igalklebanov Could you rebase this when you have time?

and...... it is rebased.

Copy link
Member

@koskimas koskimas left a comment

Choose a reason for hiding this comment

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

Dude, you are so good! This is perfect! Only one nitpick about maybe improving typescript perf. Feel free to ignore if it causes some typescript issues and doesn't improve perf. (you can just run time npm run test:typings and see if anything changes).

Feel free to merge as soon as you like ❤️ ❤️

src/dialect/mssql/mssql-query-compiler.ts Show resolved Hide resolved
* delete
* ```
*/
whenMatchedAnd<RE extends ReferenceExpression<DB, TT | ST>>(
Copy link
Member

Choose a reason for hiding this comment

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

I found it did great things to typescript performance to hoist all complex argument types (that would create a lot of new type instantiations) to generics. My theory (pulled straight from my butt) is that typescript doesn't instantiate and compare the argument types when they are generics when comparing the parent interface.

So here you'd use:

whenMatchedAnd<
  RE extends ReferenceExpression<DB, TT | ST>,
  VE extends OperandValueExpressionOrList<DB, TT | ST, RE>
>(
  lhs: RE,
  op: ComparisonOperatorExpression,
  rhs: VE
): MatchedThenableMergeQueryBuilder<DB, TT, ST, TT | ST, O>

All where and other methods of this family now use this style, so maybe you could switch to that here even if there's no performance benefit.

Copy link
Member Author

Choose a reason for hiding this comment

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

user time went down by 1 sec. 👌

rhs: OperandValueExpressionOrList<DB, TT | ST, RE>
): MatchedThenableMergeQueryBuilder<DB, TT, ST, TT | ST, O>

whenMatchedAnd(
Copy link
Member

Choose a reason for hiding this comment

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

Same here

whenMatchedAnd<E extends ExpressionOrFactory<DB, TT | ST, SqlBool>>(...)

Copy link
Member Author

Choose a reason for hiding this comment

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

this one had barely any effect.

* This method is similar to {@link SelectQueryBuilder.whereRef}, so see the documentation
* for that method for more examples.
*/
whenMatchedAndRef(
Copy link
Member

Choose a reason for hiding this comment

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

Aaaand here.. Well you get the gist.

  whenMatchedAndRef<
    LRE extends ReferenceExpression<DB, TB>,
    RRE extends ReferenceExpression<DB, TB>
  >(

Copy link
Member Author

Choose a reason for hiding this comment

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

not sure this had any effect.

@igalklebanov igalklebanov merged commit 9deb62a into kysely-org:master Jan 8, 2024
5 checks passed
@igalklebanov igalklebanov deleted the merge branch January 8, 2024 23:14
thecodrr pushed a commit to thecodrr/kysely that referenced this pull request Sep 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api Related to library's API breaking change Includes breaking changes enhancement New feature or request mssql Related to MS SQL Server (MSSQL) oracle Related to Oracle postgres Related to PostgreSQL
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support MERGE SQL command
3 participants