Skip to content

Add INSERT IGNORE and INSERT OR IGNORE support#150

Closed
cungminh2710 wants to merge 1 commit into
mainfrom
feat/insert-ignore-support-16120343557627706943
Closed

Add INSERT IGNORE and INSERT OR IGNORE support#150
cungminh2710 wants to merge 1 commit into
mainfrom
feat/insert-ignore-support-16120343557627706943

Conversation

@cungminh2710

Copy link
Copy Markdown
Contributor

Implement INSERT IGNORE (MySQL) and INSERT OR IGNORE (SQLite) support in Rain ORM.

Feature parity target

Matches Drizzle ORM's behavior for ignoring conflicts during insertion.

What was implemented

  • Added .Ignore() method to InsertQuery builder.
  • Added ignore field to InsertQuery struct.
  • Implemented writeInsertInto helper in pkg/rain/query_insert.go to render dialect-native ignore syntax (INSERT IGNORE for MySQL, INSERT OR IGNORE for SQLite).
  • Implemented useIgnore helper to determine when to use the ignore syntax, including automatic mapping from .OnConflict().DoNothing() when no targets are specified for MySQL/SQLite.
  • Updated writeValuesSQL and writeSelectSQL to use writeInsertInto.
  • Modified writeConflictClause to suppress redundant ON DUPLICATE KEY UPDATE (MySQL) or ON CONFLICT (SQLite) when ignore is active.
  • Refactored writeInsertInto to be more robust based on code review.

How it maps to Drizzle ORM behavior

  • Drizzle uses .ignore() on MySQL and SQLite to render these keywords.
  • Drizzle also treats .onConflictDoNothing() without targets as INSERT IGNORE / INSERT OR IGNORE on these dialects.

Tests added or updated

  • Added TestInsertIgnoreToSQL in pkg/rain/query_insert_test.go covering various ignore scenarios.
  • Updated TestInsertOnConflictMySQL to reflect the new, more idiomatic ignore behavior.

Commands run

  • make test
  • go test -race ./pkg/rain
  • make fmt
  • make lint

Remaining gaps or follow-up work

  • None identified for this specific feature.

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

Implement support for ignoring insertion conflicts using dialect-native
syntax: INSERT IGNORE for MySQL and INSERT OR IGNORE for SQLite.

Added a new .Ignore() method to the InsertQuery builder. mapped
.OnConflict().DoNothing() to these native keywords for MySQL and SQLite
when no conflict targets are provided, matching Drizzle ORM's behavior.
This also removes a previous no-op update hack for MySQL DoNothing.

Tests added for explicit .Ignore() and implicit conflict-to-ignore
translations across targeted 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.

@greptile-apps

greptile-apps Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds ignore support for insert queries. The main changes are:

  • A new .Ignore() method on InsertQuery.
  • Dialect-specific INSERT IGNORE and INSERT OR IGNORE rendering.
  • Mapping bare conflict-do-nothing inserts to ignore syntax for MySQL and SQLite.
  • Tests for the new SQL output paths.

Confidence Score: 4/5

The insert ignore path needs fixes before merging.

  • Postgres .Ignore() compiles to a plain insert.
  • MySQL conflict-do-nothing now suppresses non-duplicate insert errors.
  • SQLite can drop a conflict target predicate and ignore every constraint failure.

pkg/rain/query_insert.go

Important Files Changed

Filename Overview
pkg/rain/query_insert.go Adds ignore rendering and conflict suppression, with edge cases that can silently change conflict behavior.
pkg/rain/query_insert_test.go Adds coverage for MySQL and SQLite ignore output, but misses unsupported dialect and mixed conflict-target cases.

Fix All in Codex

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

---

### Issue 1 of 3
pkg/rain/query_insert.go:546-548
**Postgres Ignore Becomes Plain Insert**

When a Postgres caller uses `.Ignore()` without also adding `.OnConflict()`, this branch marks ignore as active but `writeInsertInto()` has no Postgres rendering case and `writeConflictClause()` returns because no conflict clause exists. The query compiles as a plain `INSERT`, so duplicate-key conflicts still fail instead of being ignored or rejected as unsupported.

### Issue 2 of 3
pkg/rain/query_insert.go:552-553
**MySQL Ignore Broadens Errors**

Existing MySQL callers of `.OnConflict().DoNothing()` now get `INSERT IGNORE` instead of the old no-op `ON DUPLICATE KEY UPDATE` clause. That ignores more than duplicate keys: invalid values, truncation, or NOT NULL problems can be downgraded into warnings and coerced/default data, where the old query would still return an error.

### Issue 3 of 3
pkg/rain/query_insert.go:786-789
**Target Predicate Gets Dropped**

For SQLite, `.OnConflict().Where(predicate).DoNothing()` has no columns or constraint but does have a target predicate. This shortcut treats it as untargeted ignore and emits `INSERT OR IGNORE`, silently discarding the predicate and ignoring all constraint failures instead of reporting the incomplete conflict target.

Reviews (1): Last reviewed commit: "feat(rain): add INSERT IGNORE and INSERT..." | Re-trigger Greptile

Comment thread pkg/rain/query_insert.go
Comment on lines +546 to +548
if q.ignore {
return true
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Postgres Ignore Becomes Plain Insert

When a Postgres caller uses .Ignore() without also adding .OnConflict(), this branch marks ignore as active but writeInsertInto() has no Postgres rendering case and writeConflictClause() returns because no conflict clause exists. The query compiles as a plain INSERT, so duplicate-key conflicts still fail instead of being ignored or rejected as unsupported.

Context Used: AGENTS.md (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: pkg/rain/query_insert.go
Line: 546-548

Comment:
**Postgres Ignore Becomes Plain Insert**

When a Postgres caller uses `.Ignore()` without also adding `.OnConflict()`, this branch marks ignore as active but `writeInsertInto()` has no Postgres rendering case and `writeConflictClause()` returns because no conflict clause exists. The query compiles as a plain `INSERT`, so duplicate-key conflicts still fail instead of being ignored or rejected as unsupported.

**Context Used:** AGENTS.md ([source](https://app.greptile.com/hyperlocalise/github/hyperlocalise/rain-orm/-/custom-context?memory=3b24bd19-4fb7-4328-8fc3-52795c121ec6))

How can I resolve this? If you propose a fix, please make it concise.

Fix in Codex

Comment thread pkg/rain/query_insert.go
Comment on lines +552 to +553
if ctx.dialect.Name() == "mysql" {
return true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 MySQL Ignore Broadens Errors

Existing MySQL callers of .OnConflict().DoNothing() now get INSERT IGNORE instead of the old no-op ON DUPLICATE KEY UPDATE clause. That ignores more than duplicate keys: invalid values, truncation, or NOT NULL problems can be downgraded into warnings and coerced/default data, where the old query would still return an error.

Context Used: AGENTS.md (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: pkg/rain/query_insert.go
Line: 552-553

Comment:
**MySQL Ignore Broadens Errors**

Existing MySQL callers of `.OnConflict().DoNothing()` now get `INSERT IGNORE` instead of the old no-op `ON DUPLICATE KEY UPDATE` clause. That ignores more than duplicate keys: invalid values, truncation, or NOT NULL problems can be downgraded into warnings and coerced/default data, where the old query would still return an error.

**Context Used:** AGENTS.md ([source](https://app.greptile.com/hyperlocalise/github/hyperlocalise/rain-orm/-/custom-context?memory=3b24bd19-4fb7-4328-8fc3-52795c121ec6))

How can I resolve this? If you propose a fix, please make it concise.

Fix in Codex

Comment thread pkg/rain/query_insert.go
Comment on lines 786 to +789
if len(q.conflict.columns) == 0 && q.conflict.constraint == "" {
if q.useIgnore(ctx) {
return nil
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Target Predicate Gets Dropped

For SQLite, .OnConflict().Where(predicate).DoNothing() has no columns or constraint but does have a target predicate. This shortcut treats it as untargeted ignore and emits INSERT OR IGNORE, silently discarding the predicate and ignoring all constraint failures instead of reporting the incomplete conflict target.

Context Used: AGENTS.md (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: pkg/rain/query_insert.go
Line: 786-789

Comment:
**Target Predicate Gets Dropped**

For SQLite, `.OnConflict().Where(predicate).DoNothing()` has no columns or constraint but does have a target predicate. This shortcut treats it as untargeted ignore and emits `INSERT OR IGNORE`, silently discarding the predicate and ignoring all constraint failures instead of reporting the incomplete conflict target.

**Context Used:** AGENTS.md ([source](https://app.greptile.com/hyperlocalise/github/hyperlocalise/rain-orm/-/custom-context?memory=3b24bd19-4fb7-4328-8fc3-52795c121ec6))

How can I resolve this? If you propose a fix, please make it concise.

Fix in Codex

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