Skip to content

Commit 0befa35

Browse files
authored
Merge branch 'master' into adjust-add-index-worker
2 parents 216c58f + 7056bb0 commit 0befa35

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+978
-298
lines changed

circle.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ version: 2
33
jobs:
44
build:
55
docker:
6-
- image: golang:1.11
6+
- image: golang:1.11.3
77
working_directory: /go/src/github.com/pingcap/tidb
88
steps:
99
- checkout

cmd/explaintest/r/tpch.result

+117-117
Large diffs are not rendered by default.

ddl/column.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ package ddl
1515

1616
import (
1717
"fmt"
18+
"sync/atomic"
1819

1920
"github.com/pingcap/errors"
2021
"github.com/pingcap/parser/ast"
@@ -482,7 +483,7 @@ func allocateColumnID(tblInfo *model.TableInfo) int64 {
482483
}
483484

484485
func checkAddColumnTooManyColumns(oldCols int) error {
485-
if oldCols > TableColumnCountLimit {
486+
if uint32(oldCols) > atomic.LoadUint32(&TableColumnCountLimit) {
486487
return errTooManyFields
487488
}
488489
return nil

ddl/column_change_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ func getCurrentTable(d *ddl, schemaID, tableID int64) (table.Table, error) {
347347
if err != nil {
348348
return nil, errors.Trace(err)
349349
}
350-
alloc := autoid.NewAllocator(d.store, schemaID)
350+
alloc := autoid.NewAllocator(d.store, schemaID, false)
351351
tbl, err := table.TableFromMeta(alloc, tblInfo)
352352
if err != nil {
353353
return nil, errors.Trace(err)

ddl/column_test.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,7 @@ func (s *testColumnSuite) colDefStrToFieldType(c *C, str string) *types.FieldTyp
945945
func (s *testColumnSuite) TestFieldCase(c *C) {
946946
var fields = []string{"field", "Field"}
947947
var colDefs = make([]*ast.ColumnDef, len(fields))
948+
var colObjects []interface{}
948949
for i, name := range fields {
949950
colDefs[i] = &ast.ColumnDef{
950951
Name: &ast.ColumnName{
@@ -953,6 +954,7 @@ func (s *testColumnSuite) TestFieldCase(c *C) {
953954
Name: model.NewCIStr(name),
954955
},
955956
}
957+
colObjects = append(colObjects, colDefs[i])
956958
}
957-
c.Assert(checkDuplicateColumn(colDefs), NotNil)
959+
c.Assert(checkDuplicateColumn(colObjects), NotNil)
958960
}

ddl/db_integration_test.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"fmt"
1919
"math"
2020
"strings"
21+
"sync/atomic"
2122
"time"
2223

2324
. "github.com/pingcap/check"
@@ -903,11 +904,11 @@ func (s *testIntegrationSuite) TestCreateTableTooLarge(c *C) {
903904
sql += ");"
904905
s.testErrorCode(c, s.tk, sql, tmysql.ErrTooManyFields)
905906

906-
originLimit := ddl.TableColumnCountLimit
907-
ddl.TableColumnCountLimit = cnt * 4
907+
originLimit := atomic.LoadUint32(&ddl.TableColumnCountLimit)
908+
atomic.StoreUint32(&ddl.TableColumnCountLimit, uint32(cnt*4))
908909
_, err := s.tk.Exec(sql)
909910
c.Assert(kv.ErrEntryTooLarge.Equal(err), IsTrue, Commentf("err:%v", err))
910-
ddl.TableColumnCountLimit = originLimit
911+
atomic.StoreUint32(&ddl.TableColumnCountLimit, originLimit)
911912
}
912913

913914
func (s *testIntegrationSuite) TestChangeColumnPosition(c *C) {
@@ -1027,7 +1028,7 @@ func (s *testIntegrationSuite) TestAddAnonymousIndex(c *C) {
10271028
func (s *testIntegrationSuite) TestAddColumnTooMany(c *C) {
10281029
s.tk = testkit.NewTestKit(c, s.store)
10291030
s.tk.MustExec("use test")
1030-
count := ddl.TableColumnCountLimit - 1
1031+
count := int(atomic.LoadUint32(&ddl.TableColumnCountLimit) - 1)
10311032
var cols []string
10321033
for i := 0; i < count; i++ {
10331034
cols = append(cols, fmt.Sprintf("a%d int", i))

ddl/db_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"strconv"
2323
"strings"
2424
"sync"
25+
"sync/atomic"
2526
"time"
2627

2728
. "github.com/pingcap/check"
@@ -933,7 +934,7 @@ func (s *testDBSuite) TestColumn(c *C) {
933934
func (s *testDBSuite) TestAddColumnTooMany(c *C) {
934935
s.tk = testkit.NewTestKit(c, s.store)
935936
s.tk.MustExec("use test")
936-
count := ddl.TableColumnCountLimit - 1
937+
count := int(atomic.LoadUint32(&ddl.TableColumnCountLimit) - 1)
937938
var cols []string
938939
for i := 0; i < count; i++ {
939940
cols = append(cols, fmt.Sprintf("a%d int", i))

ddl/ddl.go

+12-7
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,21 @@ const (
5454
ddlPrompt = "ddl"
5555

5656
shardRowIDBitsMax = 15
57+
58+
// PartitionCountLimit is limit of the number of partitions in a table.
59+
// Mysql maximum number of partitions is 8192, our maximum number of partitions is 1024.
60+
// Reference linking https://dev.mysql.com/doc/refman/5.7/en/partitioning-limitations.html.
61+
PartitionCountLimit = 1024
5762
)
5863

5964
var (
6065
// TableColumnCountLimit is limit of the number of columns in a table.
6166
// It's exported for testing.
62-
TableColumnCountLimit = 512
67+
TableColumnCountLimit = uint32(512)
6368
// EnableSplitTableRegion is a flag to decide whether to split a new region for
6469
// a newly created table. It takes effect only if the Storage supports split
6570
// region.
66-
EnableSplitTableRegion = false
67-
68-
// PartitionCountLimit is limit of the number of partitions in a table.
69-
// Mysql maximum number of partitions is 8192, our maximum number of partitions is 1024.
70-
// Reference linking https://dev.mysql.com/doc/refman/5.7/en/partitioning-limitations.html.
71-
PartitionCountLimit = 1024
71+
EnableSplitTableRegion = uint32(0)
7272
)
7373

7474
var (
@@ -201,13 +201,16 @@ var (
201201
ErrWarnDataTruncated = terror.ClassDDL.New(codeWarnDataTruncated, mysql.MySQLErrName[mysql.WarnDataTruncated])
202202
// ErrCoalesceOnlyOnHashPartition returns coalesce partition can only be used on hash/key partitions.
203203
ErrCoalesceOnlyOnHashPartition = terror.ClassDDL.New(codeCoalesceOnlyOnHashPartition, mysql.MySQLErrName[mysql.ErrCoalesceOnlyOnHashPartition])
204+
// ErrViewWrongList returns create view must include all columns in the select clause
205+
ErrViewWrongList = terror.ClassDDL.New(codeViewWrongList, mysql.MySQLErrName[mysql.ErrViewWrongList])
204206
)
205207

206208
// DDL is responsible for updating schema in data store and maintaining in-memory InfoSchema cache.
207209
type DDL interface {
208210
CreateSchema(ctx sessionctx.Context, name model.CIStr, charsetInfo *ast.CharsetOpt) error
209211
DropSchema(ctx sessionctx.Context, schema model.CIStr) error
210212
CreateTable(ctx sessionctx.Context, stmt *ast.CreateTableStmt) error
213+
CreateView(ctx sessionctx.Context, stmt *ast.CreateViewStmt) error
211214
CreateTableWithLike(ctx sessionctx.Context, ident, referIdent ast.Ident, ifNotExists bool) error
212215
DropTable(ctx sessionctx.Context, tableIdent ast.Ident) (err error)
213216
CreateIndex(ctx sessionctx.Context, tableIdent ast.Ident, unique bool, indexName model.CIStr,
@@ -621,6 +624,7 @@ const (
621624
codeWrongKeyColumn = 1167
622625
codeBlobKeyWithoutLength = 1170
623626
codeInvalidOnUpdate = 1294
627+
codeViewWrongList = 1353
624628
codeUnsupportedOnGeneratedColumn = 3106
625629
codeGeneratedColumnNonPrior = 3107
626630
codeDependentByGeneratedColumn = 3108
@@ -679,6 +683,7 @@ func init() {
679683
codeTableMustHaveColumns: mysql.ErrTableMustHaveColumns,
680684
codeTooManyFields: mysql.ErrTooManyFields,
681685
codeErrTooLongIndexComment: mysql.ErrTooLongIndexComment,
686+
codeViewWrongList: mysql.ErrViewWrongList,
682687
codeUnknownCharacterSet: mysql.ErrUnknownCharacterSet,
683688
codePartitionsMustBeDefined: mysql.ErrPartitionsMustBeDefined,
684689
codePartitionMgmtOnNonpartitioned: mysql.ErrPartitionMgmtOnNonpartitioned,

ddl/ddl_api.go

+122-15
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"bytes"
2222
"fmt"
2323
"strings"
24+
"sync/atomic"
2425
"time"
2526

2627
"github.com/cznic/mathutil"
@@ -37,6 +38,7 @@ import (
3738
"github.com/pingcap/tidb/table"
3839
"github.com/pingcap/tidb/types"
3940
"github.com/pingcap/tidb/util/schemautil"
41+
"github.com/pingcap/tidb/util/set"
4042
)
4143

4244
func (d *ddl) CreateSchema(ctx sessionctx.Context, schema model.CIStr, charsetInfo *ast.CharsetOpt) (err error) {
@@ -568,14 +570,22 @@ func checkColumnValueConstraint(col *table.Column) error {
568570
return nil
569571
}
570572

571-
func checkDuplicateColumn(colDefs []*ast.ColumnDef) error {
572-
colNames := map[string]bool{}
573-
for _, colDef := range colDefs {
574-
nameLower := colDef.Name.Name.L
575-
if colNames[nameLower] {
576-
return infoschema.ErrColumnExists.GenWithStackByArgs(colDef.Name.Name)
573+
func checkDuplicateColumn(cols []interface{}) error {
574+
colNames := set.StringSet{}
575+
var nameLower string
576+
for _, col := range cols {
577+
switch x := col.(type) {
578+
case *ast.ColumnDef:
579+
nameLower = x.Name.Name.L
580+
case model.CIStr:
581+
nameLower = x.L
582+
default:
583+
nameLower = ""
584+
}
585+
if colNames.Exist(nameLower) {
586+
return infoschema.ErrColumnExists.GenWithStackByArgs(nameLower)
577587
}
578-
colNames[nameLower] = true
588+
colNames.Insert(nameLower)
579589
}
580590
return nil
581591
}
@@ -606,17 +616,26 @@ func checkGeneratedColumn(colDefs []*ast.ColumnDef) error {
606616
return nil
607617
}
608618

609-
func checkTooLongColumn(colDefs []*ast.ColumnDef) error {
610-
for _, colDef := range colDefs {
611-
if len(colDef.Name.Name.O) > mysql.MaxColumnNameLength {
612-
return ErrTooLongIdent.GenWithStackByArgs(colDef.Name.Name)
619+
func checkTooLongColumn(cols []interface{}) error {
620+
var colName string
621+
for _, col := range cols {
622+
switch x := col.(type) {
623+
case *ast.ColumnDef:
624+
colName = x.Name.Name.O
625+
case model.CIStr:
626+
colName = x.O
627+
default:
628+
colName = ""
629+
}
630+
if len(colName) > mysql.MaxColumnNameLength {
631+
return ErrTooLongIdent.GenWithStackByArgs(colName)
613632
}
614633
}
615634
return nil
616635
}
617636

618637
func checkTooManyColumns(colDefs []*ast.ColumnDef) error {
619-
if len(colDefs) > TableColumnCountLimit {
638+
if uint32(len(colDefs)) > atomic.LoadUint32(&TableColumnCountLimit) {
620639
return errTooManyFields
621640
}
622641
return nil
@@ -887,16 +906,21 @@ func (d *ddl) CreateTable(ctx sessionctx.Context, s *ast.CreateTableStmt) (err e
887906
}
888907
return infoschema.ErrTableExists.GenWithStackByArgs(ident)
889908
}
909+
910+
var colObjects []interface{}
911+
for _, col := range colDefs {
912+
colObjects = append(colObjects, col)
913+
}
890914
if err = checkTooLongTable(ident.Name); err != nil {
891915
return errors.Trace(err)
892916
}
893-
if err = checkDuplicateColumn(colDefs); err != nil {
917+
if err = checkDuplicateColumn(colObjects); err != nil {
894918
return errors.Trace(err)
895919
}
896920
if err = checkGeneratedColumn(colDefs); err != nil {
897921
return errors.Trace(err)
898922
}
899-
if err = checkTooLongColumn(colDefs); err != nil {
923+
if err = checkTooLongColumn(colObjects); err != nil {
900924
return errors.Trace(err)
901925
}
902926
if err = checkTooManyColumns(colDefs); err != nil {
@@ -980,6 +1004,89 @@ func (d *ddl) CreateTable(ctx sessionctx.Context, s *ast.CreateTableStmt) (err e
9801004
return errors.Trace(err)
9811005
}
9821006

1007+
func (d *ddl) CreateView(ctx sessionctx.Context, s *ast.CreateViewStmt) (err error) {
1008+
ident := ast.Ident{Name: s.ViewName.Name, Schema: s.ViewName.Schema}
1009+
is := d.GetInformationSchema(ctx)
1010+
schema, ok := is.SchemaByName(ident.Schema)
1011+
if !ok {
1012+
return infoschema.ErrDatabaseNotExists.GenWithStackByArgs(ident.Schema)
1013+
}
1014+
if is.TableExists(ident.Schema, ident.Name) {
1015+
return infoschema.ErrTableExists.GenWithStackByArgs(ident)
1016+
}
1017+
if err = checkTooLongTable(ident.Name); err != nil {
1018+
return err
1019+
}
1020+
viewInfo, cols := buildViewInfoWithTableColumns(ctx, s)
1021+
1022+
var colObjects []interface{}
1023+
for _, col := range viewInfo.Cols {
1024+
colObjects = append(colObjects, col)
1025+
}
1026+
1027+
if err = checkTooLongColumn(colObjects); err != nil {
1028+
return err
1029+
}
1030+
if err = checkDuplicateColumn(colObjects); err != nil {
1031+
return err
1032+
}
1033+
1034+
tbInfo, err := buildTableInfo(ctx, d, ident.Name, cols, nil)
1035+
if err != nil {
1036+
return err
1037+
}
1038+
tbInfo.View = viewInfo
1039+
1040+
job := &model.Job{
1041+
SchemaID: schema.ID,
1042+
TableID: tbInfo.ID,
1043+
Type: model.ActionCreateView,
1044+
BinlogInfo: &model.HistoryInfo{},
1045+
Args: []interface{}{tbInfo, s.OrReplace},
1046+
}
1047+
err = d.doDDLJob(ctx, job)
1048+
1049+
return d.callHookOnChanged(err)
1050+
}
1051+
1052+
func buildViewInfoWithTableColumns(ctx sessionctx.Context, s *ast.CreateViewStmt) (*model.ViewInfo, []*table.Column) {
1053+
viewInfo := &model.ViewInfo{Definer: s.Definer, Algorithm: s.Algorithm,
1054+
Security: s.Security, SelectStmt: s.Select.Text(), CheckOption: s.CheckOption}
1055+
1056+
if s.Definer.CurrentUser {
1057+
viewInfo.Definer = ctx.GetSessionVars().User
1058+
}
1059+
1060+
var schemaCols = s.Select.(*ast.SelectStmt).Fields.Fields
1061+
viewInfo.Cols = make([]model.CIStr, len(schemaCols))
1062+
for i, v := range schemaCols {
1063+
viewInfo.Cols[i] = v.AsName
1064+
}
1065+
1066+
var tableColumns = make([]*table.Column, len(schemaCols))
1067+
if s.Cols == nil {
1068+
for i, v := range schemaCols {
1069+
tableColumns[i] = table.ToColumn(&model.ColumnInfo{
1070+
Name: v.AsName,
1071+
ID: int64(i),
1072+
Offset: i,
1073+
State: model.StatePublic,
1074+
})
1075+
}
1076+
} else {
1077+
for i, v := range s.Cols {
1078+
tableColumns[i] = table.ToColumn(&model.ColumnInfo{
1079+
Name: v,
1080+
ID: int64(i),
1081+
Offset: i,
1082+
State: model.StatePublic,
1083+
})
1084+
}
1085+
}
1086+
1087+
return viewInfo, tableColumns
1088+
}
1089+
9831090
func checkPartitionByHash(pi *model.PartitionInfo) error {
9841091
if err := checkAddPartitionTooManyPartitions(pi.Num); err != nil {
9851092
return errors.Trace(err)
@@ -1025,7 +1132,7 @@ func checkCharsetAndCollation(cs string, co string) error {
10251132
// handleAutoIncID handles auto_increment option in DDL. It creates a ID counter for the table and initiates the counter to a proper value.
10261133
// For example if the option sets auto_increment to 10. The counter will be set to 9. So the next allocated ID will be 10.
10271134
func (d *ddl) handleAutoIncID(tbInfo *model.TableInfo, schemaID int64) error {
1028-
alloc := autoid.NewAllocator(d.store, tbInfo.GetDBID(schemaID))
1135+
alloc := autoid.NewAllocator(d.store, tbInfo.GetDBID(schemaID), tbInfo.IsAutoIncColUnsigned())
10291136
tbInfo.State = model.StatePublic
10301137
tb, err := table.TableFromMeta(alloc, tbInfo)
10311138
if err != nil {

ddl/ddl_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func (d *ddl) restartWorkers(ctx context.Context) {
8989
}
9090
}
9191

92-
// TestLeakCheckCnt is the check count in the pacakge of ddl.
92+
// TestLeakCheckCnt is the check count in the package of ddl.
9393
// In this package CustomParallelSuiteFlag is true, so we need to increase check count.
9494
const TestLeakCheckCnt = 1000
9595

ddl/ddl_worker.go

+2
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,8 @@ func (w *worker) runDDLJob(d *ddlCtx, t *meta.Meta, job *model.Job) (ver int64,
468468
ver, err = onDropSchema(t, job)
469469
case model.ActionCreateTable:
470470
ver, err = onCreateTable(d, t, job)
471+
case model.ActionCreateView:
472+
ver, err = onCreateView(d, t, job)
471473
case model.ActionDropTable:
472474
ver, err = onDropTable(t, job)
473475
case model.ActionDropTablePartition:

0 commit comments

Comments
 (0)