diff options
Diffstat (limited to 'plan.go')
| -rw-r--r-- | plan.go | 16 |
1 files changed, 14 insertions, 2 deletions
@@ -33,6 +33,7 @@ type plan struct { // Planned queries. Select plannedQuery // only `SELECT ... FROM ... WHERE `; user supplies the rest during Select{,One}Where() Insert plannedQuery + Upsert plannedQuery Update plannedQuery Delete plannedQuery } @@ -198,7 +199,8 @@ func buildPlan(t reflect.Type, dialect Dialect, opts planOpts) (plan, error) { // prepare query strings p.Select = p.buildSelectQueryIfPossible(dialect) - p.Insert = p.buildInsertQueryIfPossible(dialect) + p.Insert = p.buildInsertQueryIfPossible(dialect, false) + p.Upsert = p.buildInsertQueryIfPossible(dialect, true) p.Update = p.buildUpdateQueryIfPossible(dialect) p.Delete = p.buildDeleteQueryIfPossible(dialect) @@ -247,7 +249,7 @@ func (p plan) buildSelectQueryIfPossible(dialect Dialect) plannedQuery { return plannedQuery{query, nil, scanIndexes} } -func (p plan) buildInsertQueryIfPossible(dialect Dialect) plannedQuery { +func (p plan) buildInsertQueryIfPossible(dialect Dialect, isUpsert bool) plannedQuery { if p.TableName == "" || len(p.AllColumnNames) == 0 { return plannedQuery{Query: ""} } @@ -256,6 +258,13 @@ func (p plan) buildInsertQueryIfPossible(dialect Dialect) plannedQuery { return plannedQuery{Query: ""} } + // UPSERT queries specifically are only generated if we have non-auto primary keys: + // - cannot hit a key conflict if there are no keys + // - cannot hit a key conflict on insert if all keys are autogenerated (and thus we never supply them during INSERT) + if isUpsert && !slices.ContainsFunc(p.PrimaryKeyColumnNames, func(n string) bool { return !slices.Contains(p.AutoColumnNames, n) }) { + return plannedQuery{Query: ""} + } + var ( argumentIndexes = make([][]int, len(nonAutoColumnNames)) scanIndexes [][]int @@ -282,6 +291,9 @@ func (p plan) buildInsertQueryIfPossible(dialect Dialect) plannedQuery { strings.Join(quotedColumnNames, ", "), strings.Join(quotedPlaceholders, ", "), ) + if isUpsert { + query += dialect.UpsertClause(p.PrimaryKeyColumnNames, p.getNonPrimaryKeyColumnNames()) + } if len(p.AutoColumnNames) > 0 { query += dialect.InsertSuffixForAutoColumns(p.AutoColumnNames) } |
