mirror of
https://github.com/ent/ent.git
synced 2026-05-24 09:31:56 +03:00
dialect/sql/schema: add support for pg arrays in migration
This commit is contained in:
committed by
Ariel Mashraki
parent
eff6552989
commit
fd1f2df150
@@ -354,7 +354,7 @@ func (m *Migrate) changeSet(curr, new *Table) (*changes, error) {
|
||||
}
|
||||
change.index.drop.append(idx)
|
||||
// Extending column types.
|
||||
case m.cType(c1) != m.cType(c2):
|
||||
case m.needsConversion(c2, c1):
|
||||
if !c2.ConvertibleTo(c1) {
|
||||
return nil, fmt.Errorf("changing column type for %q is invalid (%s != %s)", c1.Name, m.cType(c1), m.cType(c2))
|
||||
}
|
||||
@@ -645,6 +645,7 @@ type sqlDialect interface {
|
||||
tBuilder(*Table) *sql.TableBuilder
|
||||
addIndex(*Index, string) *sql.IndexBuilder
|
||||
alterColumns(table string, add, modify, drop []*Column) sql.Queries
|
||||
needsConversion(*Column, *Column) bool
|
||||
}
|
||||
|
||||
type preparer interface {
|
||||
|
||||
@@ -677,3 +677,9 @@ func (d *MySQL) defaultSize(c *Column) int64 {
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
// needsConversion reports if column "old" needs to be converted
|
||||
// (by table altering) to column "new".
|
||||
func (d *MySQL) needsConversion(old, new *Column) bool {
|
||||
return d.cType(old) != d.cType(new)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"entgo.io/ent/dialect"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
@@ -262,6 +263,17 @@ func (d *Postgres) scanColumn(c *Column, rows *sql.Rows) error {
|
||||
c.Type = field.TypeUUID
|
||||
case "cidr", "inet", "macaddr", "macaddr8":
|
||||
c.Type = field.TypeOther
|
||||
case "ARRAY":
|
||||
c.Type = field.TypeOther
|
||||
if !udt.Valid {
|
||||
return fmt.Errorf("missing array type for column %q", c.Name)
|
||||
}
|
||||
// Note that for ARRAY types, the 'udt_name' column holds the array type
|
||||
// prefixed with '_'. For example, for 'integer[]' the result is '_int',
|
||||
// and for 'text[N][M]' the result is also '_text'. That's because, the
|
||||
// database ignores any size or multi-dimensions constraints.
|
||||
c.SchemaType = map[string]string{dialect.Postgres: "ARRAY"}
|
||||
c.typ = udt.String
|
||||
case "USER-DEFINED":
|
||||
c.Type = field.TypeOther
|
||||
if !udt.Valid {
|
||||
@@ -484,6 +496,13 @@ func (d *Postgres) alterColumns(table string, add, modify, drop []*Column) sql.Q
|
||||
return sql.Queries{b}
|
||||
}
|
||||
|
||||
// needsConversion reports if column "old" needs to be converted
|
||||
// (by table altering) to column "new".
|
||||
func (d *Postgres) needsConversion(old, new *Column) bool {
|
||||
oldT, newT := d.cType(old), d.cType(new)
|
||||
return oldT != newT && (oldT != "ARRAY" || !arrayType(newT))
|
||||
}
|
||||
|
||||
// seqfunc reports if the given string is a sequence function.
|
||||
func seqfunc(defaults string) bool {
|
||||
for _, fn := range [...]string{"currval", "lastval", "setval", "nextval"} {
|
||||
@@ -493,3 +512,17 @@ func seqfunc(defaults string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// arrayType reports if the given string is an array type (e.g. int[], text[2]).
|
||||
func arrayType(t string) bool {
|
||||
i, j := strings.LastIndexByte(t, '['), strings.LastIndexByte(t, ']')
|
||||
if i == -1 || j == -1 {
|
||||
return false
|
||||
}
|
||||
for _, r := range t[i+1 : j] {
|
||||
if !unicode.IsDigit(r) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -328,3 +328,9 @@ func (d *SQLite) tables() sql.Querier {
|
||||
From(sql.Table("sqlite_schema")).
|
||||
Where(sql.EQ("type", "table"))
|
||||
}
|
||||
|
||||
// needsConversion reports if column "old" needs to be converted
|
||||
// (by table altering) to column "new".
|
||||
func (d *SQLite) needsConversion(old, new *Column) bool {
|
||||
return d.cType(old) != d.cType(new)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user