-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ddl, parser: support 'ALTER TABLE RENAME KEY TO' syntax #6475
Conversation
@spongedu Thanks! |
ddl/ddl_api.go
Outdated
return errors.Trace(infoschema.ErrKeyNotExists.GenByArgs(spec.FromKey.O, tb.Meta().Name)) | ||
} | ||
if spec.FromKey.O == spec.ToKey.O { | ||
return nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's MySQL's behavior ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the MySQL's behavior. You can see the test case in line 2660.
ddl/ddl_api.go
Outdated
if spec.FromKey.O == spec.ToKey.O { | ||
return nil | ||
} | ||
if toIdx := findIndexByName(spec.ToKey.L, tb.Meta().Indices); toIdx != nil && spec.FromKey.L != spec.ToKey.L { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spec.FromKey.L != spec.ToKey.L
?
I'm confused with .L
and .O
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TiDB is case-insensitive.
So I think we should use spec.FromKey.L == spec.ToKey.L
in line 1580, and we can remove this check here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tiancaiamao @zimulala although index check is case-insensitive (index a
and index A
are considered the same index when check), but indexes' names, or say indexes' representations, are still case-sensitive, we can rename a index a
to A
.
The logic from line 1580 to line 1586 are as follows:
- in line 1580, we just do nothing but return if the
FromKey
andToKey
are exactly the same. (rename key a to a
ends here) - in line 1583, we check if an index is renamed as an already-exists index (
rename key a to exist-key
ends here,rename key a to non-exists-key
andrename key a to A
pass the check)
Take an example in MySQL, pay attention to KEY a:
mysql> create table t1 (pk int primary key, i int, j int, key a(i));
Query OK, 0 rows affected (0.03 sec)
mysql> show create table t1;
+-------+------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------+
| Table | Create Table
|
+-------+------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------+
| t1 | CREATE TABLE `t1` (
`pk` int(11) NOT NULL,
`i` int(11) DEFAULT NULL,
`j` int(11) DEFAULT NULL,
PRIMARY KEY (`pk`),
KEY `a` (`i`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------+
1 row in set (0.00 sec)
mysql> alter table t1 rename key a to A;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table t1;
+-------+------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------+
| Table | Create Table
|
+-------+------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------+
| t1 | CREATE TABLE `t1` (
`pk` int(11) NOT NULL,
`i` int(11) DEFAULT NULL,
`j` int(11) DEFAULT NULL,
PRIMARY KEY (`pk`),
KEY `A` (`i`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------+
1 row in set (0.00 sec)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, add comment to the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
ddl/table.go
Outdated
return ver, errors.Trace(err) | ||
} | ||
|
||
idx := findIndexByName(from.L, tblInfo.Indices) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm afraid we have to double check here if we don't take @coocood 's suggestion.
Take this scenario for example:
TiDB client1, rename idx1 to idx3, check success, put into queue
TiDB client2, rename idx2 to idx3, check success, put into queue
When the code runs to here, those two request would both success!
We lost a index, no error!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, double check is needed here.
infoschema/infoschema.go
Outdated
// ErrKeyNameDuplicate returns for index duplicate when rename index. | ||
ErrKeyNameDuplicate = terror.ClassSchema.New(codeKeyNameDuplicate, "Duplicate key name '%s'") | ||
// ErrKeyNotExists returns for index not exists. | ||
ErrKeyNotExists = terror.ClassSchema.New(codeKeyNotExists, " Key '%s' doesn't exist in table '%s'") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need replace " Key" with "Key"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes.
parser/parser.y
Outdated
| "RENAME" KeyOrIndex Identifier "TO" Identifier | ||
{ | ||
$$ = &ast.AlterTableSpec{ | ||
Tp: ast.AlterTableRenameIndex, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keep alignment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
ddl/ddl_api.go
Outdated
return errors.Trace(infoschema.ErrKeyNotExists.GenByArgs(spec.FromKey.O, tb.Meta().Name)) | ||
} | ||
if spec.FromKey.O == spec.ToKey.O { | ||
return nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the MySQL's behavior. You can see the test case in line 2660.
ddl/ddl_api.go
Outdated
if spec.FromKey.O == spec.ToKey.O { | ||
return nil | ||
} | ||
if toIdx := findIndexByName(spec.ToKey.L, tb.Meta().Indices); toIdx != nil && spec.FromKey.L != spec.ToKey.L { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TiDB is case-insensitive.
So I think we should use spec.FromKey.L == spec.ToKey.L
in line 1580, and we can remove this check here.
ddl/ddl_api.go
Outdated
@@ -1559,6 +1561,42 @@ func (d *ddl) AlterTableComment(ctx sessionctx.Context, ident ast.Ident, spec *a | |||
return errors.Trace(err) | |||
} | |||
|
|||
// RenameIndex updates the table comment information. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the comment not correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lamxTyler ennnnn..... Forget to change this.. Will fix.
LGTM |
ddl/table.go
Outdated
return ver, errors.Trace(err) | ||
} | ||
job.FinishTableJob(model.JobStateDone, model.StatePublic, ver, tblInfo) | ||
return ver, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/nil/ errors.Trace(err)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think return nil is ok.
ddl/table.go
Outdated
} | ||
tblInfo, err := getTableInfo(t, job, job.SchemaID) | ||
if err != nil { | ||
return ver, errors.Trace(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add job.State = model.JobStateCancelled
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK
ddl/table.go
Outdated
// Double check. See function `RenameIndex` in ddl_api.go | ||
idx := findIndexByName(from.L, tblInfo.Indices) | ||
if idx == nil { | ||
return ver, errors.Trace(infoschema.ErrKeyNotExists.GenByArgs(from, tblInfo.Name)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK
@zimulala PTAL |
/run-all-tests |
@ciscoxll PTAL |
/run-all-tests |
ddl/table.go
Outdated
} | ||
if err != nil { | ||
job.State = model.JobStateCancelled | ||
return ver, err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/err/error.Trace(err)
ddl/ddl_api.go
Outdated
return nil | ||
} | ||
if err != nil { | ||
return err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/err/error.Trace(err)
ddl/ddl_api.go
Outdated
return errors.Trace(err) | ||
} | ||
|
||
func (d *ddl) validateRenameIndex(from, to model.CIStr, tbl *model.TableInfo) (duplicate bool, err error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you put this function to the file of index.go?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
Done @zimulala PTAL :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rest LGTM
ddl/index.go
Outdated
@@ -175,6 +176,23 @@ func dropIndexColumnFlag(tblInfo *model.TableInfo, indexInfo *model.IndexInfo) { | |||
} | |||
} | |||
|
|||
func validateRenameIndex(from, to model.CIStr, tbl *model.TableInfo) (duplicate bool, err error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
duplicate
is not a proper name for the first return value. It confused me. I thought it is the case that the to.L is the same as any other index name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ignore
is better
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reasonable. I've fixed this. :)
LGTM |
/run-all-tests |
/run-all-tests |
for #6405