Skip to content

fix(migrator): support functional prefix indexes for PostgreSQL#7753

Open
hamid17amu wants to merge 2 commits intogo-gorm:masterfrom
hamid17amu:fix-migrator
Open

fix(migrator): support functional prefix indexes for PostgreSQL#7753
hamid17amu wants to merge 2 commits intogo-gorm:masterfrom
hamid17amu:fix-migrator

Conversation

@hamid17amu
Copy link
Copy Markdown

  • Do only one thing
  • Non breaking API changes
  • Tested

What did this pull request do?

1. The Problem

GORM currently uses MySQL-specific syntax column(length) when generating indexes with a length tag. While this works for MySQL, it is invalid in PostgreSQL. Currently, when a user defines gorm:"index:idx_name,length:10" in a Postgres environment, GORM generates:
CREATE INDEX "idx_name" ON "table" ("column"(10))
This results in either a syntax error or a standard B-tree index that ignores the length, depending on the driver version.

2. The Solution

This PR introduces two changes:

Schema Parser: Updates parseFieldIndexes to be case-insensitive when looking for the length tag, ensuring length:10 and LENGTH:10 both populate theIndexOption.Lengthfield.

Migrator: Updates BuildIndexOptions to check the database dialect. If the dialect is PostgreSQL, it uses the functional LEFT(column, length) syntax wrapped in parentheses.

3. Impact

  • MySQL/SQLite: No change (standard syntax preserved).
  • PostgreSQL: Now correctly creates prefix indexes as functional indexes.

User Case Description

  1. Define a model with a prefix index:
type User struct {
    Name string `gorm:"index:idx_name,length:10"`
}
  1. Run AutoMigrate on a PostgreSQL database.
  2. Verify the index using \d users.
  3. Expected result: idx_name btree (left(name, 10))

Resolves #7752

@propel-code-bot
Copy link
Copy Markdown
Contributor

propel-code-bot Bot commented Apr 11, 2026

Fix BuildIndexOptions to generate PostgreSQL-compatible prefix index expressions

This PR updates index SQL generation in migrator/migrator.go so prefix index handling is dialect-aware. In Migrator.BuildIndexOptions, when opt.Length > 0, PostgreSQL now uses LEFT(column, length) expression syntax, while non-PostgreSQL dialects retain the previous column(length) format.

The change appears to be a targeted bug fix for invalid PostgreSQL index SQL generation from length index tags, while preserving existing behavior for MySQL/SQLite. The final patch also addresses earlier review feedback that warned against applying PostgreSQL functional syntax globally.

Key Changes

• Modified Migrator.BuildIndexOptions in migrator/migrator.go to branch behavior by detected dialect.
• Added dialect detection via m.DB.Dialector type string check and strings.Contains(..., "postgres").
• For PostgreSQL, length-based index options now emit LEFT(%s,%d) instead of appending (%d) directly to a quoted column.
• For other dialects, preserved existing str += fmt.Sprintf("(%d)", opt.Length) behavior.

Affected Areas

migrator/migrator.go
Migrator.BuildIndexOptions index option SQL construction path
• Auto-migration index creation paths that rely on BuildIndexOptions

This summary was automatically generated by @propel-code-bot

propel-code-bot[bot]

This comment was marked as outdated.

Co-authored-by: propel-code-bot[bot] <203372662+propel-code-bot[bot]@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@propel-code-bot propel-code-bot Bot left a comment

Choose a reason for hiding this comment

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

Review found no issues; the PostgreSQL prefix-index support change appears safe and well-scoped.

Status: No Issues Found | Risk: Low

Review Details

📁 1 files reviewed | 💬 0 comments

@hamid17amu
Copy link
Copy Markdown
Author

@jinzhu Please review

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.

postgresql index:idx_name,length:5 can't work when AutoMigrate

1 participant