Skip to content

Commit

Permalink
Merge branch 'master' of github.com:pingcap/tidb into stats
Browse files Browse the repository at this point in the history
  • Loading branch information
Haibin Xie committed Aug 6, 2018
2 parents 962bb19 + a7fc9c3 commit 8ba5843
Show file tree
Hide file tree
Showing 86 changed files with 1,811 additions and 943 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ y.output
profile.coverprofile
explain_test
cmd/explaintest/explain-test.out
_tools/
49 changes: 33 additions & 16 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
PROJECT=tidb
GOPATH ?= $(shell go env GOPATH)

# Ensure GOPATH is set before running build process.
ifeq "$(GOPATH)" ""
$(error Please set the environment variable GOPATH before running `make`)
endif
FAIL_ON_STDOUT := awk '{ print } END { if (NR > 0) { exit 1 } }'

CURDIR := $(shell pwd)
path_to_add := $(addsuffix /bin,$(subst :,/bin:,$(GOPATH)))
Expand All @@ -18,9 +20,10 @@ GOVERALLS := goveralls
ARCH := "`uname -s`"
LINUX := "Linux"
MAC := "Darwin"
PACKAGES := $$(go list ./...| grep -vE "vendor")
FILES := $$(find . -name "*.go" | grep -vE "vendor")
TOPDIRS := $$(ls -d */ | grep -vE "vendor")
PACKAGE_LIST := go list ./...| grep -vE "vendor"
PACKAGES := $$($(PACKAGE_LIST))
PACKAGE_DIRECTORIES := $(PACKAGE_LIST) | sed 's|github.com/pingcap/$(PROJECT)/||'
FILES := $$(find $$($(PACKAGE_DIRECTORIES)) -name "*.go" | grep -vE "vendor")

GOFAIL_ENABLE := $$(find $$PWD/ -type d | grep -vE "(\.git|vendor)" | xargs gofail enable)
GOFAIL_DISABLE := $$(find $$PWD/ -type d | grep -vE "(\.git|vendor)" | xargs gofail disable)
Expand Down Expand Up @@ -71,30 +74,44 @@ parserlib: parser/parser.go
parser/parser.go: parser/parser.y
make parser

check: fmt errcheck lint vet
# The retool tools.json is setup from hack/retool-install.sh
check-setup:
@which retool >/dev/null 2>&1 || go get github.com/twitchtv/retool
@retool sync

check: check-setup fmt lint vet

# These need to be fixed before they can be ran regularly
check-fail: goword check-static check-slow

fmt:
@echo "gofmt (simplify)"
@ gofmt -s -l -w $(FILES) 2>&1 | grep -v "vendor|parser/parser.go" | awk '{print} END{if(NR>0) {exit 1}}'
@gofmt -s -l -w $(FILES) 2>&1 | grep -v "vendor|parser/parser.go" | $(FAIL_ON_STDOUT)

goword:
go get github.com/chzchzchz/goword
@echo "goword"
@ goword $(FILES) | awk '{print} END{if(NR>0) {exit 1}}'

errcheck:
go get github.com/kisielk/errcheck
@echo "errcheck"
@ GOPATH=$(GOPATH) errcheck -exclude errcheck_excludes.txt -blank $(PACKAGES) | grep -v "_test\.go" | awk '{print} END{if(NR>0) {exit 1}}'
retool do goword $(FILES) 2>&1 | $(FAIL_ON_STDOUT)

check-static:
@ # vet and fmt have problems with vendor when ran through metalinter
CGO_ENABLED=0 retool do gometalinter.v2 --disable-all --deadline 120s \
--enable misspell \
--enable megacheck \
--enable ineffassign \
$$($(PACKAGE_DIRECTORIES))

check-slow:
CGO_ENABLED=0 retool do gometalinter.v2 --disable-all \
--enable errcheck \
$$($(PACKAGE_DIRECTORIES))
CGO_ENABLED=0 retool do gosec $$($(PACKAGE_DIRECTORIES))

lint:
go get github.com/mgechev/revive
@echo "linting"
CGO_ENABLED=0 revive -formatter friendly -config revive.toml $(PACKAGES)
@CGO_ENABLED=0 retool do revive -formatter friendly -config revive.toml $(PACKAGES)

vet:
@echo "vet"
@ go tool vet -all -shadow $(TOPDIRS) 2>&1 | awk '{print} END{if(NR>0) {exit 1}}'
@retool do govet -all -shadow $$($(PACKAGE_DIRECTORIES)) 2>&1 | $(FAIL_ON_STDOUT)

clean:
$(GO) clean -i ./...
Expand Down
1 change: 1 addition & 0 deletions ast/functions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

package ast_test

import (
Expand Down
2 changes: 1 addition & 1 deletion config/config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ enable-streaming = false
lower-case-table-names = 2

# Make "kill query" behavior compatible with MySQL. It's not recommend to
# turn on this option when TiDB server is behand a proxy.
# turn on this option when TiDB server is behind a proxy.
compatible-kill-query = false

[log]
Expand Down
69 changes: 61 additions & 8 deletions ddl/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ func (s *testDBSuite) TestAddMultiColumnsIndex(c *C) {
func (s *testDBSuite) TestAddIndex(c *C) {
s.testAddIndex(c, false, "create table test_add_index (c1 bigint, c2 bigint, c3 bigint, primary key(c1))")
s.testAddIndex(c, true, `create table test_add_index (c1 bigint, c2 bigint, c3 bigint, primary key(c1))
partition by range (c2) (
partition by range (c1) (
partition p0 values less than (3440),
partition p1 values less than (61440),
partition p2 values less than (122880),
Expand All @@ -606,8 +606,7 @@ func (s *testDBSuite) TestAddIndex(c *C) {
func (s *testDBSuite) testAddIndex(c *C, testPartition bool, createTableSQL string) {
s.tk = testkit.NewTestKit(c, s.store)
s.tk.MustExec("use " + s.schemaName)
// TODO: Support delete operation, then uncomment here.
// s.tk.MustExec("set @@tidb_enable_table_partition = 1")
s.tk.MustExec("set @@tidb_enable_table_partition = 1")
s.tk.MustExec("drop table if exists test_add_index")
s.tk.MustExec(createTableSQL)

Expand Down Expand Up @@ -693,18 +692,18 @@ LOOP:
rows := s.mustQuery(c, fmt.Sprintf("select c1 from test_add_index where c3 >= %d order by c1", start))
matchRows(c, rows, expectedRows)

if testPartition {
s.tk.MustExec("admin check table test_add_index")
return
}

// test index range
for i := 0; i < 100; i++ {
index := rand.Intn(len(keys) - 3)
rows := s.mustQuery(c, "select c1 from test_add_index where c3 >= ? limit 3", keys[index])
matchRows(c, rows, [][]interface{}{{keys[index]}, {keys[index+1]}, {keys[index+2]}})
}

if testPartition {
s.tk.MustExec("admin check table test_add_index")
return
}

// TODO: Support explain in future.
// rows := s.mustQuery(c, "explain select c1 from test_add_index where c3 >= 100")

Expand Down Expand Up @@ -2145,6 +2144,60 @@ func (s *testDBSuite) TestYearTypeCreateTable(c *C) {
c.Assert(mysql.HasUnsignedFlag(yearCol.Flag), IsFalse)
}

func (s *testDBSuite) TestCheckColumnDefaultValue(c *C) {
s.tk = testkit.NewTestKit(c, s.store)
s.tk.MustExec("use test;")
s.tk.MustExec("drop table if exists text_default_text;")
s.testErrorCode(c, "create table text_default_text(c1 text not null default '');", tmysql.ErrBlobCantHaveDefault)
s.testErrorCode(c, "create table text_default_text(c1 text not null default 'scds');", tmysql.ErrBlobCantHaveDefault)

s.tk.MustExec("drop table if exists text_default_json;")
s.testErrorCode(c, "create table text_default_json(c1 json not null default '');", tmysql.ErrBlobCantHaveDefault)
s.testErrorCode(c, "create table text_default_json(c1 json not null default 'dfew555');", tmysql.ErrBlobCantHaveDefault)

s.tk.MustExec("drop table if exists text_default_blob;")
s.testErrorCode(c, "create table text_default_blob(c1 blob not null default '');", tmysql.ErrBlobCantHaveDefault)
s.testErrorCode(c, "create table text_default_blob(c1 blob not null default 'scds54');", tmysql.ErrBlobCantHaveDefault)

s.tk.MustExec("set sql_mode='';")
s.tk.MustExec("drop table if exists text_default_text;")
s.tk.MustExec("create table text_default_text(c1 text not null default '');")
s.tk.MustQuery(`show create table text_default_text`).Check(testutil.RowsWithSep("|",
"text_default_text CREATE TABLE `text_default_text` (\n"+
" `c1` text NOT NULL\n"+
") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin",
))
ctx := s.tk.Se.(sessionctx.Context)
is := domain.GetDomain(ctx).InfoSchema()
tblInfo, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("text_default_text"))
c.Assert(err, IsNil)
c.Assert(tblInfo.Meta().Columns[0].DefaultValue, Equals, "")

s.tk.MustExec("drop table if exists text_default_blob;")
s.tk.MustExec("create table text_default_blob(c1 blob not null default '');")
s.tk.MustQuery(`show create table text_default_blob`).Check(testutil.RowsWithSep("|",
"text_default_blob CREATE TABLE `text_default_blob` (\n"+
" `c1` blob NOT NULL\n"+
") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin",
))
is = domain.GetDomain(ctx).InfoSchema()
tblInfo, err = is.TableByName(model.NewCIStr("test"), model.NewCIStr("text_default_blob"))
c.Assert(err, IsNil)
c.Assert(tblInfo.Meta().Columns[0].DefaultValue, Equals, "")

s.tk.MustExec("drop table if exists text_default_json;")
s.tk.MustExec("create table text_default_json(c1 json not null default '');")
s.tk.MustQuery(`show create table text_default_json`).Check(testutil.RowsWithSep("|",
"text_default_json CREATE TABLE `text_default_json` (\n"+
" `c1` json NOT NULL DEFAULT 'null'\n"+
") ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin",
))
is = domain.GetDomain(ctx).InfoSchema()
tblInfo, err = is.TableByName(model.NewCIStr("test"), model.NewCIStr("text_default_json"))
c.Assert(err, IsNil)
c.Assert(tblInfo.Meta().Columns[0].DefaultValue, Equals, `null`)
}

func (s *testDBSuite) TestCharacterSetInColumns(c *C) {
s.tk = testkit.NewTestKit(c, s.store)
s.tk.MustExec("drop database if exists varchar_test;")
Expand Down
2 changes: 1 addition & 1 deletion ddl/ddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ func (d *ddl) start(ctx context.Context, ctxPool *pools.ResourcePool) {
for _, worker := range d.workers {
worker.wg.Add(1)
go worker.start(d.ddlCtx)
metrics.DDLCounter.WithLabelValues(fmt.Sprintf("%s_%s", metrics.CreateDDLWorker, worker.String())).Inc()
metrics.DDLCounter.WithLabelValues(fmt.Sprintf("%s_%s", metrics.CreateDDL, worker.String())).Inc()

// When the start function is called, we will send a fake job to let worker
// checks owner firstly and try to find whether a job exists and run.
Expand Down
34 changes: 24 additions & 10 deletions ddl/ddl_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,16 +251,32 @@ func buildColumnAndConstraint(ctx sessionctx.Context, offset int,
return col, cts, nil
}

// checkColumnCantHaveDefaultValue checks the column can have value as default or not.
// Now, TEXT/BLOB/JSON can't have not null value as default.
func checkColumnCantHaveDefaultValue(col *table.Column, value interface{}) (err error) {
// checkColumnDefaultValue checks the default value of the column.
// In non-strict SQL mode, if the default value of the column is an empty string, the default value can be ignored.
// In strict SQL mode, TEXT/BLOB/JSON can't have not null default values.
func checkColumnDefaultValue(ctx sessionctx.Context, col *table.Column, value interface{}) (bool, interface{}, error) {
hasDefaultValue := true
if value != nil && (col.Tp == mysql.TypeJSON ||
col.Tp == mysql.TypeTinyBlob || col.Tp == mysql.TypeMediumBlob ||
col.Tp == mysql.TypeLongBlob || col.Tp == mysql.TypeBlob) {
// TEXT/BLOB/JSON can't have not null default values.
return errBlobCantHaveDefault.GenByArgs(col.Name.O)
// In non-strict SQL mode.
if !ctx.GetSessionVars().SQLMode.HasStrictMode() && value == "" {
if col.Tp == mysql.TypeBlob || col.Tp == mysql.TypeLongBlob {
// The TEXT/BLOB default value can be ignored.
hasDefaultValue = false
}
// In non-strict SQL mode, if the column type is json and the default value is null, it is initialized to an empty array.
if col.Tp == mysql.TypeJSON {
value = `null`
}
sc := ctx.GetSessionVars().StmtCtx
sc.AppendWarning(errBlobCantHaveDefault.GenByArgs(col.Name.O))
return hasDefaultValue, value, nil
}
// In strict SQL mode or default value is not an empty string.
return hasDefaultValue, value, errBlobCantHaveDefault.GenByArgs(col.Name.O)
}
return nil
return hasDefaultValue, value, nil
}

// isExplicitTimeStamp is used to check if explicit_defaults_for_timestamp is on or off.
Expand Down Expand Up @@ -326,11 +342,10 @@ func columnDefToCol(ctx sessionctx.Context, offset int, colDef *ast.ColumnDef, o
if err != nil {
return nil, nil, ErrColumnBadNull.Gen("invalid default value - %s", err)
}
if err = checkColumnCantHaveDefaultValue(col, value); err != nil {
if hasDefaultValue, value, err = checkColumnDefaultValue(ctx, col, value); err != nil {
return nil, nil, errors.Trace(err)
}
col.DefaultValue = value
hasDefaultValue = true
removeOnUpdateNowFlag(col)
case ast.ColumnOptionOnUpdate:
// TODO: Support other time functions.
Expand Down Expand Up @@ -1462,11 +1477,10 @@ func setDefaultAndComment(ctx sessionctx.Context, col *table.Column, options []*
if err != nil {
return ErrColumnBadNull.Gen("invalid default value - %s", err)
}
if err = checkColumnCantHaveDefaultValue(col, value); err != nil {
if hasDefaultValue, value, err = checkColumnDefaultValue(ctx, col, value); err != nil {
return errors.Trace(err)
}
col.DefaultValue = value
hasDefaultValue = true
case ast.ColumnOptionComment:
err := setColumnComment(ctx, col, opt)
if err != nil {
Expand Down
Loading

0 comments on commit 8ba5843

Please sign in to comment.