diff --git a/ddl/ddl.go b/ddl/ddl.go index 59b2b87081599..d19240f8cf154 100644 --- a/ddl/ddl.go +++ b/ddl/ddl.go @@ -166,7 +166,7 @@ type DDL interface { GetInformationSchema() infoschema.InfoSchema AlterTable(ctx sessionctx.Context, tableIdent ast.Ident, spec []*ast.AlterTableSpec) error TruncateTable(ctx sessionctx.Context, tableIdent ast.Ident) error - RenameTable(ctx sessionctx.Context, oldTableIdent, newTableIdent ast.Ident) error + RenameTable(ctx sessionctx.Context, oldTableIdent, newTableIdent ast.Ident, isAlterTable bool) error // SetLease will reset the lease time for online DDL change, // it's a very dangerous function and you must guarantee that all servers have the same lease time. SetLease(ctx context.Context, lease time.Duration) diff --git a/ddl/ddl_api.go b/ddl/ddl_api.go index 478f1ccad23eb..fe3651c84e23d 100644 --- a/ddl/ddl_api.go +++ b/ddl/ddl_api.go @@ -994,7 +994,8 @@ func (d *ddl) AlterTable(ctx sessionctx.Context, ident ast.Ident, specs []*ast.A err = d.AlterColumn(ctx, ident, spec) case ast.AlterTableRenameTable: newIdent := ast.Ident{Schema: spec.NewTable.Schema, Name: spec.NewTable.Name} - err = d.RenameTable(ctx, ident, newIdent) + isAlterTable := true + err = d.RenameTable(ctx, ident, newIdent, isAlterTable) case ast.AlterTableDropPrimaryKey: err = ErrUnsupportedModifyPrimaryKey.GenByArgs("drop") case ast.AlterTableOption: @@ -1619,7 +1620,7 @@ func (d *ddl) TruncateTable(ctx sessionctx.Context, ti ast.Ident) error { return errors.Trace(err) } -func (d *ddl) RenameTable(ctx sessionctx.Context, oldIdent, newIdent ast.Ident) error { +func (d *ddl) RenameTable(ctx sessionctx.Context, oldIdent, newIdent ast.Ident, isAlterTable bool) error { is := d.GetInformationSchema() oldSchema, ok := is.SchemaByName(oldIdent.Schema) if !ok { @@ -1629,6 +1630,10 @@ func (d *ddl) RenameTable(ctx sessionctx.Context, oldIdent, newIdent ast.Ident) if err != nil { return errFileNotFound.GenByArgs(oldIdent.Schema, oldIdent.Name) } + if isAlterTable && newIdent.Schema.L == oldIdent.Schema.L && newIdent.Name.L == oldIdent.Name.L { + // oldIdent is equal to newIdent, do nothing + return nil + } newSchema, ok := is.SchemaByName(newIdent.Schema) if !ok { return errErrorOnRename.GenByArgs(oldIdent.Schema, oldIdent.Name, newIdent.Schema, newIdent.Name) diff --git a/ddl/ddl_db_test.go b/ddl/ddl_db_test.go index 882fd468cee34..374cfb954f931 100644 --- a/ddl/ddl_db_test.go +++ b/ddl/ddl_db_test.go @@ -1590,14 +1590,16 @@ func (s *testDBSuite) TestTruncateTable(c *C) { } func (s *testDBSuite) TestRenameTable(c *C) { - s.testRenameTable(c, "rename table %s to %s") + isAlterTable := false + s.testRenameTable(c, "rename table %s to %s", isAlterTable) } func (s *testDBSuite) TestAlterTableRenameTable(c *C) { - s.testRenameTable(c, "alter table %s rename to %s") + isAlterTable := true + s.testRenameTable(c, "alter table %s rename to %s", isAlterTable) } -func (s *testDBSuite) testRenameTable(c *C, sql string) { +func (s *testDBSuite) testRenameTable(c *C, sql string, isAlterTable bool) { s.tk = testkit.NewTestKit(c, s.store) s.tk.MustExec("use test") // for different databases @@ -1640,8 +1642,18 @@ func (s *testDBSuite) testRenameTable(c *C, sql string) { s.testErrorCode(c, failSQL, tmysql.ErrFileNotFound) failSQL = fmt.Sprintf(sql, "test1.t2", "test_not_exist.t") s.testErrorCode(c, failSQL, tmysql.ErrErrorOnRename) - failSQL = fmt.Sprintf(sql, "test1.t2", "test1.t2") - s.testErrorCode(c, failSQL, tmysql.ErrTableExists) + + // for the same table name + s.tk.MustExec("use test1") + s.tk.MustExec("create table if not exists t (c1 int, c2 int)") + s.tk.MustExec("create table if not exists t1 (c1 int, c2 int)") + if isAlterTable { + s.tk.MustExec(fmt.Sprintf(sql, "test1.t", "t")) + s.tk.MustExec(fmt.Sprintf(sql, "test1.t1", "test1.T1")) + } else { + s.testErrorCode(c, fmt.Sprintf(sql, "test1.t", "t"), tmysql.ErrTableExists) + s.testErrorCode(c, fmt.Sprintf(sql, "test1.t1", "test1.T1"), tmysql.ErrTableExists) + } s.tk.MustExec("drop database test1") } diff --git a/executor/ddl.go b/executor/ddl.go index 23bf112f73c5c..3bf220eb50d21 100644 --- a/executor/ddl.go +++ b/executor/ddl.go @@ -93,7 +93,8 @@ func (e *DDLExec) executeRenameTable(s *ast.RenameTableStmt) error { } oldIdent := ast.Ident{Schema: s.OldTable.Schema, Name: s.OldTable.Name} newIdent := ast.Ident{Schema: s.NewTable.Schema, Name: s.NewTable.Name} - err := domain.GetDomain(e.ctx).DDL().RenameTable(e.ctx, oldIdent, newIdent) + isAlterTable := false + err := domain.GetDomain(e.ctx).DDL().RenameTable(e.ctx, oldIdent, newIdent, isAlterTable) return errors.Trace(err) } diff --git a/executor/show.go b/executor/show.go index c680ba7a2012c..b327a9684b8f9 100644 --- a/executor/show.go +++ b/executor/show.go @@ -345,19 +345,19 @@ func (e *ShowExec) fetchShowIndex() error { subPart = col.Length } e.appendRow([]interface{}{ - tb.Meta().Name.O, // Table - nonUniq, // Non_unique - idx.Meta().Name.O, // Key_name - i + 1, // Seq_in_index - col.Name.O, // Column_name - "A", // Collation - 0, // Cardinality - subPart, // Sub_part - nil, // Packed - "YES", // Null + tb.Meta().Name.O, // Table + nonUniq, // Non_unique + idx.Meta().Name.O, // Key_name + i + 1, // Seq_in_index + col.Name.O, // Column_name + "A", // Collation + 0, // Cardinality + subPart, // Sub_part + nil, // Packed + "YES", // Null idx.Meta().Tp.String(), // Index_type - "", // Comment - idx.Meta().Comment, // Index_comment + "", // Comment + idx.Meta().Comment, // Index_comment }) } } diff --git a/infoschema/tables.go b/infoschema/tables.go index 51008082648ac..0398c9aaa3855 100644 --- a/infoschema/tables.go +++ b/infoschema/tables.go @@ -775,18 +775,18 @@ func dataForColumnsInTable(schema *model.DBInfo, tbl *model.TableInfo) [][]types columnDefault, // COLUMN_DEFAULT columnDesc.Null, // IS_NULLABLE types.TypeToStr(col.Tp, col.Charset), // DATA_TYPE - colLen, // CHARACTER_MAXIMUM_LENGTH - colLen, // CHARACTER_OCTET_LENGTH - decimal, // NUMERIC_PRECISION - 0, // NUMERIC_SCALE - 0, // DATETIME_PRECISION - col.Charset, // CHARACTER_SET_NAME - col.Collate, // COLLATION_NAME - columnType, // COLUMN_TYPE - columnDesc.Key, // COLUMN_KEY - columnDesc.Extra, // EXTRA - "select,insert,update,references", // PRIVILEGES - columnDesc.Comment, // COLUMN_COMMENT + colLen, // CHARACTER_MAXIMUM_LENGTH + colLen, // CHARACTER_OCTET_LENGTH + decimal, // NUMERIC_PRECISION + 0, // NUMERIC_SCALE + 0, // DATETIME_PRECISION + col.Charset, // CHARACTER_SET_NAME + col.Collate, // COLLATION_NAME + columnType, // COLUMN_TYPE + columnDesc.Key, // COLUMN_KEY + columnDesc.Extra, // EXTRA + "select,insert,update,references", // PRIVILEGES + columnDesc.Comment, // COLUMN_COMMENT ) // In mysql, 'character_set_name' and 'collation_name' are setted to null when column type is non-varchar or non-blob in information_schema. if col.Tp != mysql.TypeVarchar && col.Tp != mysql.TypeBlob { @@ -930,24 +930,24 @@ func dataForTableConstraints(schemas []*model.DBInfo) [][]types.Datum { func dataForPseudoProfiling() [][]types.Datum { var rows [][]types.Datum row := types.MakeDatums( - 0, // QUERY_ID - 0, // SEQ - "", // STATE + 0, // QUERY_ID + 0, // SEQ + "", // STATE types.NewDecFromInt(0), // DURATION types.NewDecFromInt(0), // CPU_USER types.NewDecFromInt(0), // CPU_SYSTEM - 0, // CONTEXT_VOLUNTARY - 0, // CONTEXT_INVOLUNTARY - 0, // BLOCK_OPS_IN - 0, // BLOCK_OPS_OUT - 0, // MESSAGES_SENT - 0, // MESSAGES_RECEIVED - 0, // PAGE_FAULTS_MAJOR - 0, // PAGE_FAULTS_MINOR - 0, // SWAPS - 0, // SOURCE_FUNCTION - 0, // SOURCE_FILE - 0, // SOURCE_LINE + 0, // CONTEXT_VOLUNTARY + 0, // CONTEXT_INVOLUNTARY + 0, // BLOCK_OPS_IN + 0, // BLOCK_OPS_OUT + 0, // MESSAGES_SENT + 0, // MESSAGES_RECEIVED + 0, // PAGE_FAULTS_MAJOR + 0, // PAGE_FAULTS_MINOR + 0, // SWAPS + 0, // SOURCE_FUNCTION + 0, // SOURCE_FILE + 0, // SOURCE_LINE ) rows = append(rows, row) return rows diff --git a/parser/misc.go b/parser/misc.go index 303b5013bdaae..7938f431a9ba2 100644 --- a/parser/misc.go +++ b/parser/misc.go @@ -133,202 +133,202 @@ func init() { } var tokenMap = map[string]int{ - "ACTION": action, - "ADD": add, - "ADDDATE": addDate, - "ADMIN": admin, - "AFTER": after, - "ALL": all, - "ALGORITHM": algorithm, - "ALTER": alter, - "ALWAYS": always, - "ANALYZE": analyze, - "AND": and, - "ANY": any, - "AS": as, - "ASC": asc, - "ASCII": ascii, - "AUTO_INCREMENT": autoIncrement, - "AVG": avg, - "AVG_ROW_LENGTH": avgRowLength, - "BEGIN": begin, - "BETWEEN": between, - "BIGINT": bigIntType, - "BINARY": binaryType, - "BINLOG": binlog, - "BIT": bitType, - "BIT_AND": bitAnd, - "BIT_OR": bitOr, - "BIT_XOR": bitXor, - "BLOB": blobType, - "BOOL": boolType, - "BOOLEAN": booleanType, - "BOTH": both, - "BTREE": btree, - "BY": by, - "BYTE": byteType, - "CANCEL": cancel, - "CASCADE": cascade, - "CASCADED": cascaded, - "CASE": caseKwd, - "CAST": cast, - "CHANGE": change, - "CHAR": charType, - "CHARACTER": character, - "CHARSET": charsetKwd, - "CHECK": check, - "CHECKSUM": checksum, - "CLEANUP": cleanup, - "CLIENT": client, - "COALESCE": coalesce, - "COLLATE": collate, - "COLLATION": collation, - "COLUMN": column, - "COLUMNS": columns, - "COMMENT": comment, - "COMMIT": commit, - "COMMITTED": committed, - "COMPACT": compact, - "COMPRESSED": compressed, - "COMPRESSION": compression, - "CONNECTION": connection, - "CONSISTENT": consistent, - "CONSTRAINT": constraint, - "CONVERT": convert, - "COPY": copyKwd, - "COUNT": count, - "CREATE": create, - "CROSS": cross, - "CURRENT_DATE": currentDate, - "CURRENT_TIME": currentTime, - "CURRENT_TIMESTAMP": currentTs, - "CURRENT_USER": currentUser, - "CURTIME": curTime, - "DATA": data, - "DATABASE": database, - "DATABASES": databases, - "DATE": dateType, - "DATE_ADD": dateAdd, - "DATE_SUB": dateSub, - "DATETIME": datetimeType, - "DAY": day, - "DAY_HOUR": dayHour, - "DAY_MICROSECOND": dayMicrosecond, - "DAY_MINUTE": dayMinute, - "DAY_SECOND": daySecond, - "DDL": ddl, - "DEALLOCATE": deallocate, - "DEC": decimalType, - "DECIMAL": decimalType, - "DEFAULT": defaultKwd, - "DEFINER": definer, - "DELAY_KEY_WRITE": delayKeyWrite, - "DELAYED": delayed, - "DELETE": deleteKwd, - "DESC": desc, - "DESCRIBE": describe, - "DISABLE": disable, - "DISTINCT": distinct, - "DISTINCTROW": distinct, - "DIV": div, - "DO": do, - "DOUBLE": doubleType, - "DROP": drop, - "DUAL": dual, - "DUPLICATE": duplicate, - "DYNAMIC": dynamic, - "ELSE": elseKwd, - "ENABLE": enable, - "ENCLOSED": enclosed, - "END": end, - "ENGINE": engine, - "ENGINES": engines, - "ENUM": enum, - "ESCAPE": escape, - "ESCAPED": escaped, - "EVENT": event, - "EVENTS": events, - "EXCLUSIVE": exclusive, - "EXECUTE": execute, - "EXISTS": exists, - "EXPLAIN": explain, - "EXTRACT": extract, - "FALSE": falseKwd, - "FIELDS": fields, - "FIRST": first, - "FIXED": fixed, - "FLOAT": floatType, - "FLUSH": flush, - "FOR": forKwd, - "FORCE": force, - "FOREIGN": foreign, - "FORMAT": format, - "FROM": from, - "FULL": full, - "FULLTEXT": fulltext, - "FUNCTION": function, - "GENERATED": generated, - "GET_FORMAT": getFormat, - "GLOBAL": global, - "GRANT": grant, - "GRANTS": grants, - "GROUP": group, - "GROUP_CONCAT": groupConcat, - "HASH": hash, - "HAVING": having, - "HIGH_PRIORITY": highPriority, - "HOUR": hour, - "HOUR_MICROSECOND": hourMicrosecond, - "HOUR_MINUTE": hourMinute, - "HOUR_SECOND": hourSecond, - "IDENTIFIED": identified, - "IF": ifKwd, - "IGNORE": ignore, - "IN": in, - "INDEX": index, - "INDEXES": indexes, - "INFILE": infile, - "INNER": inner, - "INPLACE": inplace, - "INSERT": insert, - "INT": intType, - "INT1": int1Type, - "INT2": int2Type, - "INT3": int3Type, - "INT4": int4Type, - "INT8": int8Type, - "INTEGER": integerType, - "INTERVAL": interval, - "INTO": into, - "INVOKER": invoker, - "IS": is, - "ISOLATION": isolation, - "JOBS": jobs, - "JOB": job, - "JOIN": join, - "JSON": jsonType, - "KEY": key, - "KEY_BLOCK_SIZE": keyBlockSize, - "KEYS": keys, - "KILL": kill, - "LEADING": leading, - "LEFT": left, - "LESS": less, - "LEVEL": level, - "LIKE": like, - "LIMIT": limit, - "LINES": lines, - "LOAD": load, - "LOCAL": local, - "LOCALTIME": localTime, - "LOCALTIMESTAMP": localTs, - "LOCK": lock, - "LONG": long, - "LONGBLOB": longblobType, - "LONGTEXT": longtextType, - "LOW_PRIORITY": lowPriority, - "MASTER": master, - "MAX": max, + "ACTION": action, + "ADD": add, + "ADDDATE": addDate, + "ADMIN": admin, + "AFTER": after, + "ALL": all, + "ALGORITHM": algorithm, + "ALTER": alter, + "ALWAYS": always, + "ANALYZE": analyze, + "AND": and, + "ANY": any, + "AS": as, + "ASC": asc, + "ASCII": ascii, + "AUTO_INCREMENT": autoIncrement, + "AVG": avg, + "AVG_ROW_LENGTH": avgRowLength, + "BEGIN": begin, + "BETWEEN": between, + "BIGINT": bigIntType, + "BINARY": binaryType, + "BINLOG": binlog, + "BIT": bitType, + "BIT_AND": bitAnd, + "BIT_OR": bitOr, + "BIT_XOR": bitXor, + "BLOB": blobType, + "BOOL": boolType, + "BOOLEAN": booleanType, + "BOTH": both, + "BTREE": btree, + "BY": by, + "BYTE": byteType, + "CANCEL": cancel, + "CASCADE": cascade, + "CASCADED": cascaded, + "CASE": caseKwd, + "CAST": cast, + "CHANGE": change, + "CHAR": charType, + "CHARACTER": character, + "CHARSET": charsetKwd, + "CHECK": check, + "CHECKSUM": checksum, + "CLEANUP": cleanup, + "CLIENT": client, + "COALESCE": coalesce, + "COLLATE": collate, + "COLLATION": collation, + "COLUMN": column, + "COLUMNS": columns, + "COMMENT": comment, + "COMMIT": commit, + "COMMITTED": committed, + "COMPACT": compact, + "COMPRESSED": compressed, + "COMPRESSION": compression, + "CONNECTION": connection, + "CONSISTENT": consistent, + "CONSTRAINT": constraint, + "CONVERT": convert, + "COPY": copyKwd, + "COUNT": count, + "CREATE": create, + "CROSS": cross, + "CURRENT_DATE": currentDate, + "CURRENT_TIME": currentTime, + "CURRENT_TIMESTAMP": currentTs, + "CURRENT_USER": currentUser, + "CURTIME": curTime, + "DATA": data, + "DATABASE": database, + "DATABASES": databases, + "DATE": dateType, + "DATE_ADD": dateAdd, + "DATE_SUB": dateSub, + "DATETIME": datetimeType, + "DAY": day, + "DAY_HOUR": dayHour, + "DAY_MICROSECOND": dayMicrosecond, + "DAY_MINUTE": dayMinute, + "DAY_SECOND": daySecond, + "DDL": ddl, + "DEALLOCATE": deallocate, + "DEC": decimalType, + "DECIMAL": decimalType, + "DEFAULT": defaultKwd, + "DEFINER": definer, + "DELAY_KEY_WRITE": delayKeyWrite, + "DELAYED": delayed, + "DELETE": deleteKwd, + "DESC": desc, + "DESCRIBE": describe, + "DISABLE": disable, + "DISTINCT": distinct, + "DISTINCTROW": distinct, + "DIV": div, + "DO": do, + "DOUBLE": doubleType, + "DROP": drop, + "DUAL": dual, + "DUPLICATE": duplicate, + "DYNAMIC": dynamic, + "ELSE": elseKwd, + "ENABLE": enable, + "ENCLOSED": enclosed, + "END": end, + "ENGINE": engine, + "ENGINES": engines, + "ENUM": enum, + "ESCAPE": escape, + "ESCAPED": escaped, + "EVENT": event, + "EVENTS": events, + "EXCLUSIVE": exclusive, + "EXECUTE": execute, + "EXISTS": exists, + "EXPLAIN": explain, + "EXTRACT": extract, + "FALSE": falseKwd, + "FIELDS": fields, + "FIRST": first, + "FIXED": fixed, + "FLOAT": floatType, + "FLUSH": flush, + "FOR": forKwd, + "FORCE": force, + "FOREIGN": foreign, + "FORMAT": format, + "FROM": from, + "FULL": full, + "FULLTEXT": fulltext, + "FUNCTION": function, + "GENERATED": generated, + "GET_FORMAT": getFormat, + "GLOBAL": global, + "GRANT": grant, + "GRANTS": grants, + "GROUP": group, + "GROUP_CONCAT": groupConcat, + "HASH": hash, + "HAVING": having, + "HIGH_PRIORITY": highPriority, + "HOUR": hour, + "HOUR_MICROSECOND": hourMicrosecond, + "HOUR_MINUTE": hourMinute, + "HOUR_SECOND": hourSecond, + "IDENTIFIED": identified, + "IF": ifKwd, + "IGNORE": ignore, + "IN": in, + "INDEX": index, + "INDEXES": indexes, + "INFILE": infile, + "INNER": inner, + "INPLACE": inplace, + "INSERT": insert, + "INT": intType, + "INT1": int1Type, + "INT2": int2Type, + "INT3": int3Type, + "INT4": int4Type, + "INT8": int8Type, + "INTEGER": integerType, + "INTERVAL": interval, + "INTO": into, + "INVOKER": invoker, + "IS": is, + "ISOLATION": isolation, + "JOBS": jobs, + "JOB": job, + "JOIN": join, + "JSON": jsonType, + "KEY": key, + "KEY_BLOCK_SIZE": keyBlockSize, + "KEYS": keys, + "KILL": kill, + "LEADING": leading, + "LEFT": left, + "LESS": less, + "LEVEL": level, + "LIKE": like, + "LIMIT": limit, + "LINES": lines, + "LOAD": load, + "LOCAL": local, + "LOCALTIME": localTime, + "LOCALTIMESTAMP": localTs, + "LOCK": lock, + "LONG": long, + "LONGBLOB": longblobType, + "LONGTEXT": longtextType, + "LOW_PRIORITY": lowPriority, + "MASTER": master, + "MAX": max, "MAX_CONNECTIONS_PER_HOUR": maxConnectionsPerHour, "MAX_QUERIES_PER_HOUR": maxQueriesPerHour, "MAX_ROWS": maxRows,