@@ -26,7 +26,10 @@ type MigrationFile struct {
2626 Statements []string
2727}
2828
29- var migrateFilePattern = regexp .MustCompile (`^([0-9]+)_(.*)\.sql$` )
29+ var (
30+ migrateFilePattern = regexp .MustCompile (`^([0-9]+)_(.*)\.sql$` )
31+ typeNamePattern = regexp .MustCompile (`type "([^"]+)" does not exist` )
32+ )
3033
3134func NewMigrationFromFile (path string , fsys fs.FS ) (* MigrationFile , error ) {
3235 lines , err := parseFile (path , fsys )
@@ -97,17 +100,11 @@ func (m *MigrationFile) ExecBatch(ctx context.Context, conn *pgx.Conn) error {
97100 msg = append (msg , pgErr .Detail )
98101 }
99102 // Provide helpful hint for extension type errors (SQLSTATE 42704: undefined_object)
100- if pgErr .Code == "42704" && strings .Contains (pgErr .Message , "type" ) && strings .Contains (pgErr .Message , "does not exist" ) {
101- // Extract type name from error message (e.g., 'type "ltree" does not exist')
102- typeName := extractTypeName (pgErr .Message )
103+ if typeName := extractTypeName (pgErr .Message ); len (typeName ) > 0 && pgErr .Code == "42704" && ! IsSchemaQualified (typeName ) {
103104 msg = append (msg , "" )
104105 msg = append (msg , "Hint: This type may be defined in a schema that's not in your search_path." )
105106 msg = append (msg , " Use schema-qualified type references to avoid this error:" )
106- if typeName != "" {
107- msg = append (msg , fmt .Sprintf (" CREATE TABLE example (col extensions.%s);" , typeName ))
108- } else {
109- msg = append (msg , " CREATE TABLE example (col extensions.<type_name>);" )
110- }
107+ msg = append (msg , fmt .Sprintf (" CREATE TABLE example (col extensions.%s);" , typeName ))
111108 msg = append (msg , " Learn more: supabase migration new --help" )
112109 }
113110 }
@@ -137,15 +134,18 @@ func markError(stat string, pos int) string {
137134// extractTypeName extracts the type name from PostgreSQL error messages like:
138135// 'type "ltree" does not exist' -> "ltree"
139136func extractTypeName (errMsg string ) string {
140- // Match pattern: type "typename" does not exist
141- re := regexp .MustCompile (`type "([^"]+)" does not exist` )
142- matches := re .FindStringSubmatch (errMsg )
137+ matches := typeNamePattern .FindStringSubmatch (errMsg )
143138 if len (matches ) > 1 {
144139 return matches [1 ]
145140 }
146141 return ""
147142}
148143
144+ // IsSchemaQualified checks if a type name already contains a schema qualifier (e.g., "extensions.ltree")
145+ func IsSchemaQualified (typeName string ) bool {
146+ return strings .Contains (typeName , "." )
147+ }
148+
149149func (m * MigrationFile ) insertVersionSQL (conn * pgx.Conn , batch * pgconn.Batch ) error {
150150 value := pgtype.TextArray {}
151151 if err := value .Set (m .Statements ); err != nil {
0 commit comments