From 027641ef9efec9ed5dfc463d9c2f38c32716d9b5 Mon Sep 17 00:00:00 2001 From: Stefan Majewsky Date: Fri, 24 Apr 2026 15:41:00 +0200 Subject: remove support for SQL dialects that rely on LastInsertId() While researching for Upsert(), I noticed that both SQLite and MariaDB support INSERT with RETURNING clause, which is objectively better than LastInsertId() and cuts out a lot of useless crap from the codebase (esp. from monomorphization-relevant methods). The only tangible downside is that this drops support specifically for MySQL, but you know what? Fuck Oracle. --- plan.go | 38 +++++--------------------------------- 1 file changed, 5 insertions(+), 33 deletions(-) (limited to 'plan.go') diff --git a/plan.go b/plan.go index 9e9f44c..9dc38f6 100644 --- a/plan.go +++ b/plan.go @@ -26,10 +26,6 @@ type plan struct { // Indexes of pointer-typed fields that need to be initialized before scanning into this type. IndexesOfTransparentPointerStructs [][]int - // In dialects with UsesLastInsertID() == true, whether the ID column must be written with reflect.Value.SetInt() or reflect.Value.SetUint(). - FillIDWithSetUint bool - FillIDWithSetInt bool - // Planned queries. Select plannedQuery // only `SELECT ... FROM ... WHERE `; user supplies the rest during Select{,One}Where() Insert plannedQuery @@ -171,32 +167,6 @@ func buildPlan(t reflect.Type, dialect Dialect, opts planOpts) (plan, error) { } } - // validation: LastInsertID() only works if at most one column is auto-filled, and if that column holds an integer type - if dialect.UsesLastInsertID() { - switch len(p.AutoColumnNames) { - case 0: - // nothing to check - case 1: - columnName := p.AutoColumnNames[0] - field := t.FieldByIndex(p.IndexByColumnName[columnName]) - switch field.Type.Kind() { //nolint:exhaustive // false positive - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - p.FillIDWithSetInt = true - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - p.FillIDWithSetUint = true - default: - return plan{}, fmt.Errorf( - "column %q is marked as auto-filled, but this SQL dialect only supports auto-filling struct fields with integer types", - columnName) - } - default: - return plan{}, fmt.Errorf( - "multiple columns are marked as auto-filled (%s), but this SQL dialect only supports at most one per table", - strings.Join(p.AutoColumnNames, ", "), - ) - } - } - // prepare query strings p.Select = p.buildSelectQueryIfPossible(dialect) p.Insert = p.buildInsertQueryIfPossible(dialect, false) @@ -277,8 +247,6 @@ func (p plan) buildInsertQueryIfPossible(dialect Dialect, isUpsert bool) planned quotedPlaceholders[idx] = dialect.Placeholder(idx) } if len(p.AutoColumnNames) > 0 { - // NOTE: This is filled even if dialect.UsesLastInsertID() is false. - // We need this index to find the right value on which to run SetInt() or SetUint(). scanIndexes = make([][]int, len(p.AutoColumnNames)) for idx, columnName := range p.AutoColumnNames { scanIndexes[idx] = p.IndexByColumnName[columnName] @@ -295,7 +263,11 @@ func (p plan) buildInsertQueryIfPossible(dialect Dialect, isUpsert bool) planned query += dialect.UpsertClause(p.PrimaryKeyColumnNames, p.getNonPrimaryKeyColumnNames()) } if len(p.AutoColumnNames) > 0 { - query += dialect.InsertSuffixForAutoColumns(p.AutoColumnNames) + quotedAutoColumns := make([]string, len(p.AutoColumnNames)) + for idx, name := range p.AutoColumnNames { + quotedAutoColumns[idx] = dialect.QuoteIdentifier(name) + } + query += ` RETURNING ` + strings.Join(quotedAutoColumns, ", ") } return plannedQuery{query, argumentIndexes, scanIndexes} } -- cgit v1.2.3