@@ -53,6 +53,31 @@ func (r *RenameTable) String() string {
5353 return fmt .Sprintf ("Rename table %s to %s" , r .OldNames , r .NewNames )
5454}
5555
56+ func (r * RenameTable ) RowIter (ctx * sql.Context , row sql.Row ) (sql.RowIter , error ) {
57+ // TODO: 'ALTER TABLE newViewName RENAME view1' should fail on renaming views - should be fixed in vitess
58+ renamer , _ := r .Db .(sql.TableRenamer )
59+ viewDb , _ := r .Db .(sql.ViewDatabase )
60+ viewRegistry := ctx .GetViewRegistry ()
61+
62+ for i , oldName := range r .OldNames {
63+ if tbl , exists := r .tableExists (ctx , oldName ); exists {
64+ err := r .renameTable (ctx , renamer , tbl , oldName , r .NewNames [i ])
65+ if err != nil {
66+ return nil , err
67+ }
68+ } else {
69+ success , err := r .renameView (ctx , viewDb , viewRegistry , oldName , r .NewNames [i ])
70+ if err != nil {
71+ return nil , err
72+ } else if ! success {
73+ return nil , sql .ErrTableNotFound .New (oldName )
74+ }
75+ }
76+ }
77+
78+ return sql .RowsToRowIter (sql .NewRow (types .NewOkResult (0 ))), nil
79+ }
80+
5681func (r * RenameTable ) WithChildren (children ... sql.Node ) (sql.Node , error ) {
5782 return NillaryWithChildren (r , children ... )
5883}
@@ -74,6 +99,106 @@ func (*RenameTable) CollationCoercibility(ctx *sql.Context) (collation sql.Colla
7499 return sql .Collation_binary , 7
75100}
76101
102+ func (r * RenameTable ) tableExists (ctx * sql.Context , name string ) (sql.Table , bool ) {
103+ tbl , ok , err := r .Db .GetTableInsensitive (ctx , name )
104+ if err != nil || ! ok {
105+ return nil , false
106+ }
107+ return tbl , true
108+ }
109+
110+ func (r * RenameTable ) renameTable (ctx * sql.Context , renamer sql.TableRenamer , tbl sql.Table , oldName , newName string ) error {
111+ if renamer == nil {
112+ return sql .ErrRenameTableNotSupported .New (r .Db .Name ())
113+ }
114+
115+ if fkTable , ok := tbl .(sql.ForeignKeyTable ); ok {
116+ parentFks , err := fkTable .GetReferencedForeignKeys (ctx )
117+ if err != nil {
118+ return err
119+ }
120+ for _ , parentFk := range parentFks {
121+ //TODO: support renaming tables across databases for foreign keys
122+ if strings .ToLower (parentFk .Database ) != strings .ToLower (parentFk .ParentDatabase ) {
123+ return fmt .Errorf ("updating foreign key table names across databases is not yet supported" )
124+ }
125+ parentFk .ParentTable = newName
126+ childTbl , ok , err := r .Db .GetTableInsensitive (ctx , parentFk .Table )
127+ if err != nil {
128+ return err
129+ }
130+ if ! ok {
131+ return sql .ErrTableNotFound .New (parentFk .Table )
132+ }
133+ childFkTbl , ok := childTbl .(sql.ForeignKeyTable )
134+ if ! ok {
135+ return fmt .Errorf ("referenced table `%s` supports foreign keys but declaring table `%s` does not" , parentFk .ParentTable , parentFk .Table )
136+ }
137+ err = childFkTbl .UpdateForeignKey (ctx , parentFk .Name , parentFk )
138+ if err != nil {
139+ return err
140+ }
141+ }
142+
143+ fks , err := fkTable .GetDeclaredForeignKeys (ctx )
144+ if err != nil {
145+ return err
146+ }
147+ for _ , fk := range fks {
148+ fk .Table = newName
149+ err = fkTable .UpdateForeignKey (ctx , fk .Name , fk )
150+ if err != nil {
151+ return err
152+ }
153+ }
154+ }
155+
156+ err := renamer .RenameTable (ctx , oldName , newName )
157+ if err != nil {
158+ return err
159+ }
160+
161+ return nil
162+ }
163+
164+ func (r * RenameTable ) renameView (ctx * sql.Context , viewDb sql.ViewDatabase , vr * sql.ViewRegistry , oldName , newName string ) (bool , error ) {
165+ if viewDb != nil {
166+ oldView , exists , err := viewDb .GetViewDefinition (ctx , oldName )
167+ if err != nil {
168+ return false , err
169+ } else if ! exists {
170+ return false , nil
171+ }
172+
173+ err = viewDb .DropView (ctx , oldName )
174+ if err != nil {
175+ return false , err
176+ }
177+
178+ err = viewDb .CreateView (ctx , newName , oldView .TextDefinition , oldView .CreateViewStatement )
179+ if err != nil {
180+ return false , err
181+ }
182+
183+ return true , nil
184+ } else {
185+ view , exists := vr .View (r .Db .Name (), oldName )
186+ if ! exists {
187+ return false , nil
188+ }
189+
190+ err := vr .Delete (r .Db .Name (), oldName )
191+ if err != nil {
192+ return false , nil
193+ }
194+ err = vr .Register (r .Db .Name (), sql .NewView (newName , view .Definition (), view .TextDefinition (), view .CreateStatement ()))
195+ if err != nil {
196+ return false , nil
197+ }
198+ return true , nil
199+ }
200+ }
201+
77202type AddColumn struct {
78203 ddlNode
79204 Table sql.Node
0 commit comments