Skip to content
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

Merged
merged 33 commits into from Jun 7, 2018

Conversation

spongedu
Copy link
Contributor

@spongedu spongedu commented May 5, 2018

for #6405

@zz-jason zz-jason added the DDL label May 5, 2018
@shenli shenli added contribution This PR is from a community contributor. require-LGT3 Indicates that the PR requires three LGTM. labels May 7, 2018
@shenli
Copy link
Member

shenli commented May 7, 2018

@spongedu Thanks!
Please resolve the conflicts.

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
Copy link
Contributor

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 ?

Copy link
Contributor

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 {
Copy link
Contributor

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

Copy link
Contributor

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.

Copy link
Contributor Author

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:

  1. in line 1580, we just do nothing but return if the FromKey and ToKey are exactly the same. (rename key a to a ends here)
  2. 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 and rename 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)

Copy link
Contributor

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.

Copy link
Contributor Author

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)
Copy link
Contributor

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!

Copy link
Contributor Author

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.

// 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'")
Copy link
Contributor

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"?

Copy link
Contributor Author

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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep alignment.

Copy link
Contributor Author

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
Copy link
Contributor

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 {
Copy link
Contributor

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.
Copy link
Contributor

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?

Copy link
Contributor Author

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.

@zimulala zimulala removed the require-LGT3 Indicates that the PR requires three LGTM. label May 9, 2018
@tiancaiamao
Copy link
Contributor

LGTM

@tiancaiamao tiancaiamao added the status/LGT1 Indicates that a PR has LGTM 1. label May 10, 2018
ddl/table.go Outdated
return ver, errors.Trace(err)
}
job.FinishTableJob(model.JobStateDone, model.StatePublic, ver, tblInfo)
return ver, nil
Copy link
Contributor

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)

Copy link
Contributor

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)
Copy link
Contributor

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 ?

Copy link
Contributor Author

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))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

@shenli
Copy link
Member

shenli commented May 20, 2018

@zimulala PTAL

@shenli
Copy link
Member

shenli commented May 20, 2018

/run-all-tests

@spongedu
Copy link
Contributor Author

@ciscoxll PTAL

@zimulala
Copy link
Contributor

zimulala commented Jun 6, 2018

/run-all-tests

ddl/table.go Outdated
}
if err != nil {
job.State = model.JobStateCancelled
return ver, err
Copy link
Contributor

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
Copy link
Contributor

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) {
Copy link
Contributor

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

@spongedu
Copy link
Contributor Author

spongedu commented Jun 6, 2018

Done @zimulala PTAL :)

Copy link
Contributor

@zimulala zimulala left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@zimulala zimulala added status/LGT2 Indicates that a PR has LGTM 2. and removed status/LGT1 Indicates that a PR has LGTM 1. labels Jun 6, 2018
@zimulala
Copy link
Contributor

zimulala commented Jun 6, 2018

PTAL @winkyao @shenli @ciscoxll

Copy link
Member

@shenli shenli left a 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) {
Copy link
Member

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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ignore is better

Copy link
Contributor Author

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. :)

@shenli
Copy link
Member

shenli commented Jun 6, 2018

LGTM

@shenli shenli added status/LGT3 The PR has already had 3 LGTM. and removed status/LGT2 Indicates that a PR has LGTM 2. labels Jun 6, 2018
@shenli
Copy link
Member

shenli commented Jun 6, 2018

/run-all-tests

@shenli
Copy link
Member

shenli commented Jun 7, 2018

/run-all-tests

@XuHuaiyu XuHuaiyu merged commit f56e130 into pingcap:master Jun 7, 2018
@spongedu spongedu deleted the fix_6405 branch June 7, 2018 05:36
@you06 you06 added the sig/sql-infra SIG: SQL Infra label Mar 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contribution This PR is from a community contributor. sig/sql-infra SIG: SQL Infra status/LGT3 The PR has already had 3 LGTM.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants