aboutsummaryrefslogtreecommitdiff
path: root/plan.go
diff options
context:
space:
mode:
Diffstat (limited to 'plan.go')
-rw-r--r--plan.go16
1 files changed, 14 insertions, 2 deletions
diff --git a/plan.go b/plan.go
index 9c4da54..9e9f44c 100644
--- a/plan.go
+++ b/plan.go
@@ -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)
}