dialect/sql/schema: properly handle indexes of tables with uncountable name (#828)

This commit is contained in:
Ariel Mashraki
2020-10-08 23:24:54 +03:00
committed by GitHub
parent 064c25609b
commit 13b379d07c
24 changed files with 2715 additions and 25 deletions

View File

@@ -189,8 +189,10 @@ func (d *Postgres) indexes(ctx context.Context, tx dialect.Tx, table string) (In
if err := rows.Scan(&name, &column, &primary, &unique, &seqindex); err != nil {
return nil, fmt.Errorf("scanning index description: %v", err)
}
// If the index is prefixed with the table, it's probably was
// added by `addIndex` (and not entc) and it should be trimmed.
// If the index is prefixed with the table, it may was added by
// `addIndex` and it should be trimmed. But, since entc prefixes
// all indexes with schema-type, for uncountable types (like, media
// or equipment) this isn't correct, and we fallback for the real-name.
short := strings.TrimPrefix(name, table+"_")
idx, ok := names[short]
if !ok {

View File

@@ -483,20 +483,32 @@ func TestPostgres_Create(t *testing.T) {
{
name: "add and remove indexes",
tables: func() []*Table {
c := []*Column{
c1 := []*Column{
{Name: "id", Type: field.TypeInt, Increment: true},
// Add implicit index.
{Name: "age", Type: field.TypeInt, Unique: true},
{Name: "score", Type: field.TypeInt},
}
c2 := []*Column{
{Name: "id", Type: field.TypeInt, Increment: true},
{Name: "score", Type: field.TypeInt},
}
return []*Table{
{
Name: "users",
Columns: c,
PrimaryKey: c[0:1],
Columns: c1,
PrimaryKey: c1[0:1],
Indexes: Indexes{
// Change non-unique index to unique.
{Name: "user_score", Columns: c[2:3], Unique: true},
{Name: "user_score", Columns: c1[2:3], Unique: true},
},
},
{
Name: "equipment",
Columns: c2,
PrimaryKey: c2[0:1],
Indexes: Indexes{
{Name: "equipment_score", Columns: c2[1:]},
},
},
}
@@ -525,6 +537,16 @@ func TestPostgres_Create(t *testing.T) {
WillReturnResult(sqlmock.NewResult(0, 1))
mock.ExpectExec(escape(`CREATE UNIQUE INDEX "user_score" ON "users"("score")`)).
WillReturnResult(sqlmock.NewResult(0, 1))
mock.tableExists("equipment", true)
mock.ExpectQuery(escape(`SELECT "column_name", "data_type", "is_nullable", "column_default" FROM INFORMATION_SCHEMA.COLUMNS WHERE "table_schema" = CURRENT_SCHEMA() AND "table_name" = $1`)).
WithArgs("equipment").
WillReturnRows(sqlmock.NewRows([]string{"column_name", "data_type", "is_nullable", "column_default"}).
AddRow("id", "bigint", "NO", "NULL").
AddRow("score", "bigint", "NO", "NULL"))
mock.ExpectQuery(escape(fmt.Sprintf(indexesQuery, "equipment"))).
WillReturnRows(sqlmock.NewRows([]string{"index_name", "column_name", "primary", "unique", "seq_in_index"}).
AddRow("users_pkey", "id", "t", "t", 0).
AddRow("equipment_score", "score", "f", "f", 0))
mock.ExpectCommit()
},
},

View File

@@ -100,7 +100,7 @@ func (t *Table) column(name string) (*Column, bool) {
// index returns a table index by its name.
func (t *Table) index(name string) (*Index, bool) {
for _, idx := range t.Indexes {
if idx.Name == name {
if name == idx.Name || name == idx.realname {
return idx, true
}
// Same as below, there are cases where the index name