Skip to content

Add Ignore() and native conflict ignore semantics to InsertQuery#156

Closed
cungminh2710 wants to merge 1 commit into
mainfrom
feat-insert-ignore-12657405629811575658
Closed

Add Ignore() and native conflict ignore semantics to InsertQuery#156
cungminh2710 wants to merge 1 commit into
mainfrom
feat-insert-ignore-12657405629811575658

Conversation

@cungminh2710

Copy link
Copy Markdown
Contributor

Implemented dialect-native ignore semantics for InsertQuery to reach feature parity with Drizzle ORM. Added the .Ignore() method and updated SQL generation for PostgreSQL, MySQL, and SQLite. Also improved ergonomics for targetless .OnConflict().DoNothing() calls.


PR created automatically by Jules for task 12657405629811575658 started by @cungminh2710

This change adds dialect-native ignore semantics to InsertQuery, matching
Drizzle ORM's behavior and ergonomics.

- Added .Ignore() method to InsertQuery.
- MySQL: renders "INSERT IGNORE INTO".
- SQLite: renders "INSERT OR IGNORE INTO".
- PostgreSQL: renders "ON CONFLICT DO NOTHING".
- Supported targetless .OnConflict().DoNothing() for PostgreSQL and SQLite.
- SQLite targetless .OnConflict().DoNothing() automatically uses the IGNORE prefix.
- Preserved existing MySQL .OnConflict().DoNothing() behavior for compatibility.

Verified with unit tests for all three dialects.

Co-authored-by: cungminh2710 <8063319+cungminh2710@users.noreply.github.com>
@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@cursor

cursor Bot commented Jul 3, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@greptile-apps

greptile-apps Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds dialect-native ignore semantics to InsertQuery, enabling .Ignore() for MySQL (INSERT IGNORE INTO), SQLite (INSERT OR IGNORE INTO), and PostgreSQL (ON CONFLICT DO NOTHING). It also allows targetless .OnConflict().DoNothing() to succeed instead of erroring, routing it through the IGNORE prefix for MySQL/SQLite.

  • Ignore(), useIgnore(), and writeInsertInto() are added; writeConflictClause is extended with a targetless-DoNothing short-circuit path for non-MySQL dialects.
  • Tests cover all three dialects for .Ignore() and the new targetless conflict path for Postgres and SQLite, but the MySQL conflict branch doesn't call useIgnore(), so the .Ignore() + .OnConflict().DoNothing() combination on MySQL emits both the IGNORE prefix and a noop ON DUPLICATE KEY UPDATE clause.

Confidence Score: 3/5

The new .Ignore() path is correct for all three dialects when used alone; the MySQL conflict branch needs a useIgnore() guard before emitting the noop ON DUPLICATE KEY UPDATE.

The MySQL branch in writeConflictClause is the only place that doesn't mirror the useIgnore() guard used by the SQLite/Postgres path. A caller combining .Ignore() and .OnConflict().DoNothing() on MySQL would silently produce SQL with both the IGNORE modifier and a noop ON DUPLICATE KEY UPDATE clause, with ambiguous semantics and no error raised.

The MySQL conflict-handling block in pkg/rain/query_insert.go (around line 799) needs a useIgnore() guard to match the non-MySQL path. The test file would benefit from a MySQL .Ignore() + .OnConflict().DoNothing() case.

Important Files Changed

Filename Overview
pkg/rain/query_insert.go Adds ignore field, Ignore() method, useIgnore() helper, and writeInsertInto(). MySQL conflict branch does not call useIgnore(), so combining .Ignore() and .OnConflict().DoNothing() emits both the IGNORE prefix and a noop ON DUPLICATE KEY UPDATE clause.
pkg/rain/query_insert_test.go Adds tests for Ignore() across all three dialects and for targetless OnConflict().DoNothing() on Postgres and SQLite. Missing coverage for the MySQL .Ignore() + .OnConflict().DoNothing() interaction.

Comments Outside Diff (1)

  1. pkg/rain/query_insert.go, line 792-830 (link)

    P1 MySQL path skips useIgnore() guard, generating double conflict output

    When .Ignore() and .OnConflict().DoNothing() are combined on MySQL, writeInsertInto already emits INSERT IGNORE INTO (because useIgnore() returns true), but the MySQL branch in writeConflictClause has no corresponding guard — it unconditionally emits ON DUPLICATE KEY UPDATE \col` = `col`. The result is INSERT IGNORE INTO `t` (`c`) VALUES (?) ON DUPLICATE KEY UPDATE `id` = `id`, which is semantically ambiguous (IGNORE suppresses the duplicate-key error while ON DUPLICATE KEY UPDATE simultaneously acts on it) and inconsistent with the SQLite/Postgres paths that use useIgnore()to short-circuit. Add auseIgnore()check at the top of the MySQLinsertConflictActionDoNothing` branch to match the behaviour of the other paths.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: pkg/rain/query_insert.go
    Line: 792-830
    
    Comment:
    **MySQL path skips `useIgnore()` guard, generating double conflict output**
    
    When `.Ignore()` and `.OnConflict().DoNothing()` are combined on MySQL, `writeInsertInto` already emits `INSERT IGNORE INTO` (because `useIgnore()` returns true), but the MySQL branch in `writeConflictClause` has no corresponding guard — it unconditionally emits ` ON DUPLICATE KEY UPDATE \`col\` = \`col\``. The result is `INSERT IGNORE INTO \`t\` (\`c\`) VALUES (?) ON DUPLICATE KEY UPDATE \`id\` = \`id\``, which is semantically ambiguous (IGNORE suppresses the duplicate-key error while ON DUPLICATE KEY UPDATE simultaneously acts on it) and inconsistent with the SQLite/Postgres paths that use `useIgnore()` to short-circuit. Add a `useIgnore()` check at the top of the MySQL `insertConflictActionDoNothing` branch to match the behaviour of the other paths.
    
    How can I resolve this? If you propose a fix, please make it concise.

    Fix in Codex

Fix All in Codex

Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
pkg/rain/query_insert.go:792-830
**MySQL path skips `useIgnore()` guard, generating double conflict output**

When `.Ignore()` and `.OnConflict().DoNothing()` are combined on MySQL, `writeInsertInto` already emits `INSERT IGNORE INTO` (because `useIgnore()` returns true), but the MySQL branch in `writeConflictClause` has no corresponding guard — it unconditionally emits ` ON DUPLICATE KEY UPDATE \`col\` = \`col\``. The result is `INSERT IGNORE INTO \`t\` (\`c\`) VALUES (?) ON DUPLICATE KEY UPDATE \`id\` = \`id\``, which is semantically ambiguous (IGNORE suppresses the duplicate-key error while ON DUPLICATE KEY UPDATE simultaneously acts on it) and inconsistent with the SQLite/Postgres paths that use `useIgnore()` to short-circuit. Add a `useIgnore()` check at the top of the MySQL `insertConflictActionDoNothing` branch to match the behaviour of the other paths.

Reviews (1): Last reviewed commit: "feat(rain): add Ignore() and support tar..." | Re-trigger Greptile

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