Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/pingcap/tidb into ddl-reo…
Browse files Browse the repository at this point in the history
…rg-variable
  • Loading branch information
crazycs520 committed Jan 8, 2019
2 parents 49176eb + 106bc7e commit ece7943
Show file tree
Hide file tree
Showing 14 changed files with 242 additions and 34 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ A Contributor refers to the person who contributes to the following projects:

## How to become a TiDB Contributor?

If a PR (Pull Request) submitted to the TiDB / TiKV / TiSpark / PD / DocsDocs-cn projects by you is approved and merged, then you become a TiDB Contributor.
If a PR (Pull Request) submitted to the TiDB/TiKV/TiSpark/PD/Docs/Docs-cn projects by you is approved and merged, then you become a TiDB Contributor.

You are also encouraged to participate in the projects in the following ways:
- Actively answer technical questions asked by community users.
Expand Down
43 changes: 18 additions & 25 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ PACKAGES := $$($(PACKAGE_LIST))
PACKAGE_DIRECTORIES := $(PACKAGE_LIST) | sed 's|github.com/pingcap/$(PROJECT)/||'
FILES := $$(find $$($(PACKAGE_DIRECTORIES)) -name "*.go")

GOFAIL_ENABLE := $$(find $$PWD/ -type d | grep -vE "(\.git|tools)" | xargs gofail enable)
GOFAIL_DISABLE := $$(find $$PWD/ -type d | grep -vE "(\.git|tools)" | xargs gofail disable)
GOFAIL_ENABLE := $$(find $$PWD/ -type d | grep -vE "(\.git|tools)" | xargs tools/bin/gofail enable)
GOFAIL_DISABLE := $$(find $$PWD/ -type d | grep -vE "(\.git|tools)" | xargs tools/bin/gofail disable)

LDFLAGS += -X "github.com/pingcap/parser/mysql.TiDBReleaseVersion=$(shell git describe --tags --dirty)"
LDFLAGS += -X "github.com/pingcap/tidb/util/printer.TiDBBuildTS=$(shell date -u '+%Y-%m-%d %I:%M:%S')"
Expand Down Expand Up @@ -123,11 +123,7 @@ ifeq ("$(TRAVIS_COVERAGE)", "1")
bash <(curl -s https://codecov.io/bash)
endif

gotest:
@rm -rf $GOPATH/bin/gofail
$(GO) get github.com/pingcap/gofail
@which gofail
@$(GOFAIL_ENABLE)
gotest: gofail-enable
ifeq ("$(TRAVIS_COVERAGE)", "1")
@echo "Running in TRAVIS_COVERAGE mode."
@export log_level=error; \
Expand All @@ -140,23 +136,17 @@ else
endif
@$(GOFAIL_DISABLE)

race:
$(GO) get github.com/pingcap/gofail
@$(GOFAIL_ENABLE)
race: gofail-enable
@export log_level=debug; \
$(GOTEST) -timeout 20m -race $(PACKAGES) || { $(GOFAIL_DISABLE); exit 1; }
@$(GOFAIL_DISABLE)

leak:
$(GO) get github.com/pingcap/gofail
@$(GOFAIL_ENABLE)
leak: gofail-enable
@export log_level=debug; \
$(GOTEST) -tags leak $(PACKAGES) || { $(GOFAIL_DISABLE); exit 1; }
@$(GOFAIL_DISABLE)

tikv_integration_test:
$(GO) get github.com/pingcap/gofail
@$(GOFAIL_ENABLE)
tikv_integration_test: gofail-enable
$(GOTEST) ./store/tikv/. -with-tikv=true || { $(GOFAIL_DISABLE); exit 1; }
@$(GOFAIL_DISABLE)

Expand Down Expand Up @@ -200,37 +190,40 @@ importer:
checklist:
cat checklist.md

gofail-enable:
gofail-enable: tools/bin/gofail
# Converting gofail failpoints...
@$(GOFAIL_ENABLE)

gofail-disable:
gofail-disable: tools/bin/gofail
# Restoring gofail failpoints...
@$(GOFAIL_DISABLE)

checkdep:
$(GO) list -f '{{ join .Imports "\n" }}' github.com/pingcap/tidb/store/tikv | grep ^github.com/pingcap/parser$$ || exit 0; exit 1

tools/bin/megacheck:
tools/bin/megacheck: tools/check/go.mod
cd tools/check; \
$go build -o ../bin/megacheck honnef.co/go/tools/cmd/megacheck
$(GO) build -o ../bin/megacheck honnef.co/go/tools/cmd/megacheck

tools/bin/revive:
tools/bin/revive: tools/check/go.mod
cd tools/check; \
$(GO) build -o ../bin/revive github.com/mgechev/revive

tools/bin/goword:
tools/bin/goword: tools/check/go.mod
cd tools/check; \
$(GO) build -o ../bin/goword github.com/chzchzchz/goword

tools/bin/gometalinter:
tools/bin/gometalinter: tools/check/go.mod
cd tools/check; \
$(GO) build -o ../bin/gometalinter gopkg.in/alecthomas/gometalinter.v2

tools/bin/gosec:
tools/bin/gosec: tools/check/go.mod
cd tools/check; \
$(GO) build -o ../bin/gosec github.com/securego/gosec/cmd/gosec

tools/bin/errcheck:
tools/bin/errcheck: tools/check/go.mod
cd tools/check; \
$(GO) build -o ../bin/errcheck github.com/kisielk/errcheck

tools/bin/gofail: go.mod
$(GO) build -o $@ github.com/pingcap/gofail
41 changes: 38 additions & 3 deletions ddl/db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1619,14 +1619,49 @@ func (s *testDBSuite) testRenameTable(c *C, sql string, isAlterTable bool) {

// for failure case
failSQL := fmt.Sprintf(sql, "test_not_exist.t", "test_not_exist.t")
s.testErrorCode(c, failSQL, tmysql.ErrFileNotFound)
if isAlterTable {
s.testErrorCode(c, failSQL, tmysql.ErrNoSuchTable)
} else {
s.testErrorCode(c, failSQL, tmysql.ErrFileNotFound)
}
failSQL = fmt.Sprintf(sql, "test.test_not_exist", "test.test_not_exist")
s.testErrorCode(c, failSQL, tmysql.ErrFileNotFound)
if isAlterTable {
s.testErrorCode(c, failSQL, tmysql.ErrNoSuchTable)
} else {
s.testErrorCode(c, failSQL, tmysql.ErrFileNotFound)
}
failSQL = fmt.Sprintf(sql, "test.t_not_exist", "test_not_exist.t")
s.testErrorCode(c, failSQL, tmysql.ErrFileNotFound)
if isAlterTable {
s.testErrorCode(c, failSQL, tmysql.ErrNoSuchTable)
} else {
s.testErrorCode(c, failSQL, tmysql.ErrFileNotFound)
}
failSQL = fmt.Sprintf(sql, "test1.t2", "test_not_exist.t")
s.testErrorCode(c, failSQL, tmysql.ErrErrorOnRename)

s.tk.MustExec("use test1")
s.tk.MustExec("create table if not exists t_exist (c1 int, c2 int)")
failSQL = fmt.Sprintf(sql, "test1.t2", "test1.t_exist")
s.testErrorCode(c, failSQL, tmysql.ErrTableExists)
failSQL = fmt.Sprintf(sql, "test.t_not_exist", "test1.t_exist")
if isAlterTable {
s.testErrorCode(c, failSQL, tmysql.ErrNoSuchTable)
} else {
s.testErrorCode(c, failSQL, tmysql.ErrTableExists)
}
failSQL = fmt.Sprintf(sql, "test_not_exist.t", "test1.t_exist")
if isAlterTable {
s.testErrorCode(c, failSQL, tmysql.ErrNoSuchTable)
} else {
s.testErrorCode(c, failSQL, tmysql.ErrTableExists)
}
failSQL = fmt.Sprintf(sql, "test_not_exist.t", "test1.t_not_exist")
if isAlterTable {
s.testErrorCode(c, failSQL, tmysql.ErrNoSuchTable)
} else {
s.testErrorCode(c, failSQL, tmysql.ErrFileNotFound)
}

// for the same table name
s.tk.MustExec("use test1")
s.tk.MustExec("create table if not exists t (c1 int, c2 int)")
Expand Down
12 changes: 12 additions & 0 deletions ddl/ddl_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2283,10 +2283,22 @@ func (d *ddl) RenameTable(ctx sessionctx.Context, oldIdent, newIdent ast.Ident,
is := d.GetInformationSchema(ctx)
oldSchema, ok := is.SchemaByName(oldIdent.Schema)
if !ok {
if isAlterTable {
return infoschema.ErrTableNotExists.GenWithStackByArgs(oldIdent.Schema, oldIdent.Name)
}
if is.TableExists(newIdent.Schema, newIdent.Name) {
return infoschema.ErrTableExists.GenWithStackByArgs(newIdent)
}
return errFileNotFound.GenWithStackByArgs(oldIdent.Schema, oldIdent.Name)
}
oldTbl, err := is.TableByName(oldIdent.Schema, oldIdent.Name)
if err != nil {
if isAlterTable {
return infoschema.ErrTableNotExists.GenWithStackByArgs(oldIdent.Schema, oldIdent.Name)
}
if is.TableExists(newIdent.Schema, newIdent.Name) {
return infoschema.ErrTableExists.GenWithStackByArgs(newIdent)
}
return errFileNotFound.GenWithStackByArgs(oldIdent.Schema, oldIdent.Name)
}
if isAlterTable && newIdent.Schema.L == oldIdent.Schema.L && newIdent.Name.L == oldIdent.Name.L {
Expand Down
19 changes: 19 additions & 0 deletions executor/ddl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/pingcap/tidb/ddl"
ddlutil "github.com/pingcap/tidb/ddl/util"
"github.com/pingcap/tidb/domain"
"github.com/pingcap/tidb/meta/autoid"
plannercore "github.com/pingcap/tidb/planner/core"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/table"
Expand Down Expand Up @@ -470,6 +471,24 @@ func (s *testSuite3) TestShardRowIDBits(c *C) {
_, err = tk.Exec("alter table auto shard_row_id_bits = 4")
c.Assert(err, NotNil)
tk.MustExec("alter table auto shard_row_id_bits = 0")

// Test overflow
tk.MustExec("drop table if exists t1")
tk.MustExec("create table t1 (a int) shard_row_id_bits = 15")
defer tk.MustExec("drop table if exists t1")

tbl, err = domain.GetDomain(tk.Se).InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t1"))
c.Assert(err, IsNil)
maxID := 1<<(64-15-1) - 1
err = tbl.RebaseAutoID(tk.Se, int64(maxID)-1, false)
c.Assert(err, IsNil)
tk.MustExec("insert into t1 values(1)")

// continue inserting will fail.
_, err = tk.Exec("insert into t1 values(2)")
c.Assert(autoid.ErrAutoincReadFailed.Equal(err), IsTrue, Commentf("err:%v", err))
_, err = tk.Exec("insert into t1 values(3)")
c.Assert(autoid.ErrAutoincReadFailed.Equal(err), IsTrue, Commentf("err:%v", err))
}

func (s *testSuite3) TestMaxHandleAddIndex(c *C) {
Expand Down
2 changes: 1 addition & 1 deletion executor/seqtest/prepared_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ func (s *seqTestSuite) TestPrepared(c *C) {
tk.MustExec("create table prepare1 (a decimal(1))")
tk.MustExec("insert into prepare1 values(1);")
_, err = tk.Exec("prepare stmt FROM @sql1")
c.Assert(err.Error(), Equals, "line 1 column 4 near \"\" (total length 4)")
c.Assert(err.Error(), Equals, "line 1 column 4 near \"NULL\" (total length 4)")
tk.MustExec("SET @sql = 'update prepare1 set a=5 where a=?';")
_, err = tk.Exec("prepare stmt FROM @sql")
c.Assert(err, IsNil)
Expand Down
2 changes: 1 addition & 1 deletion expression/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3702,7 +3702,7 @@ func (s *testIntegrationSuite) TestUnknowHintIgnore(c *C) {
tk.MustExec("USE test")
tk.MustExec("create table t(a int)")
tk.MustQuery("select /*+ unknown_hint(c1)*/ 1").Check(testkit.Rows("1"))
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 line 1 column 29 near \" 1\" (total length 31)"))
tk.MustQuery("show warnings").Check(testkit.Rows("Warning 1105 line 1 column 29 near \"select /*+ unknown_hint(c1)*/ 1\" (total length 31)"))
_, err := tk.Exec("select 1 from /*+ test1() */ t")
c.Assert(err, NotNil)
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ require (
github.com/pingcap/gofail v0.0.0-20181217135706-6a951c1e42c3
github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e
github.com/pingcap/kvproto v0.0.0-20181203065228-c14302da291c
github.com/pingcap/parser v0.0.0-20190103131433-5d5a6dd34655
github.com/pingcap/parser v0.0.0-20190106063416-3483d83d44bd
github.com/pingcap/pd v2.1.0-rc.4+incompatible
github.com/pingcap/tidb-tools v2.1.1-0.20181218072513-b2235d442b06+incompatible
github.com/pingcap/tipb v0.0.0-20181012112600-11e33c750323
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e h1:P73/4dPCL96rG
github.com/pingcap/goleveldb v0.0.0-20171020122428-b9ff6c35079e/go.mod h1:O17XtbryoCJhkKGbT62+L2OlrniwqiGLSqrmdHCMzZw=
github.com/pingcap/kvproto v0.0.0-20181203065228-c14302da291c h1:Qf5St5XGwKgKQLar9lEXoeO0hJMVaFBj3JqvFguWtVg=
github.com/pingcap/kvproto v0.0.0-20181203065228-c14302da291c/go.mod h1:Ja9XPjot9q4/3JyCZodnWDGNXt4pKemhIYCvVJM7P24=
github.com/pingcap/parser v0.0.0-20190103131433-5d5a6dd34655 h1:nAGxJRuzO6T7mL/uAaOOZSVl9x+Vmy6cTYuzQjFDRw4=
github.com/pingcap/parser v0.0.0-20190103131433-5d5a6dd34655/go.mod h1:1FNvfp9+J0wvc4kl8eGNh7Rqrxveg15jJoWo/a0uHwA=
github.com/pingcap/parser v0.0.0-20190106063416-3483d83d44bd h1:FWAAGBZWj5oL4XwYF3p2rfhMSH5JeApOyW2c7ggCsUY=
github.com/pingcap/parser v0.0.0-20190106063416-3483d83d44bd/go.mod h1:1FNvfp9+J0wvc4kl8eGNh7Rqrxveg15jJoWo/a0uHwA=
github.com/pingcap/pd v2.1.0-rc.4+incompatible h1:/buwGk04aHO5odk/+O8ZOXGs4qkUjYTJ2UpCJXna8NE=
github.com/pingcap/pd v2.1.0-rc.4+incompatible/go.mod h1:nD3+EoYes4+aNNODO99ES59V83MZSI+dFbhyr667a0E=
github.com/pingcap/tidb-tools v2.1.1-0.20181218072513-b2235d442b06+incompatible h1:Bsd+NHosPVowEGB3BCx+2d8wUQGDTXSSC5ljeNS6cXo=
Expand Down
18 changes: 18 additions & 0 deletions planner/core/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ const (
codePrivilegeCheckFail = mysql.ErrUnknown
codeWindowInvalidWindowFuncUse = mysql.ErrWindowInvalidWindowFuncUse
codeWindowInvalidWindowFuncAliasUse = mysql.ErrWindowInvalidWindowFuncAliasUse
codeWindowNoSuchWindow = mysql.ErrWindowNoSuchWindow
codeWindowCircularityInWindowGraph = mysql.ErrWindowCircularityInWindowGraph
codeWindowNoChildPartitioning = mysql.ErrWindowNoChildPartitioning
codeWindowNoInherentFrame = mysql.ErrWindowNoInherentFrame
codeWindowNoRedefineOrderBy = mysql.ErrWindowNoRedefineOrderBy
codeWindowDuplicateName = mysql.ErrWindowDuplicateName
)

// error definitions.
Expand Down Expand Up @@ -94,6 +100,12 @@ var (
ErrPrivilegeCheckFail = terror.ClassOptimizer.New(codePrivilegeCheckFail, "privilege check fail")
ErrWindowInvalidWindowFuncUse = terror.ClassOptimizer.New(codeWindowInvalidWindowFuncUse, mysql.MySQLErrName[mysql.ErrWindowInvalidWindowFuncUse])
ErrWindowInvalidWindowFuncAliasUse = terror.ClassOptimizer.New(codeWindowInvalidWindowFuncAliasUse, mysql.MySQLErrName[mysql.ErrWindowInvalidWindowFuncAliasUse])
ErrWindowNoSuchWindow = terror.ClassOptimizer.New(codeWindowNoSuchWindow, mysql.MySQLErrName[mysql.ErrWindowNoSuchWindow])
ErrWindowCircularityInWindowGraph = terror.ClassOptimizer.New(codeWindowCircularityInWindowGraph, mysql.MySQLErrName[mysql.ErrWindowCircularityInWindowGraph])
ErrWindowNoChildPartitioning = terror.ClassOptimizer.New(codeWindowNoChildPartitioning, mysql.MySQLErrName[mysql.ErrWindowNoChildPartitioning])
ErrWindowNoInherentFrame = terror.ClassOptimizer.New(codeWindowNoInherentFrame, mysql.MySQLErrName[mysql.ErrWindowNoInherentFrame])
ErrWindowNoRedefineOrderBy = terror.ClassOptimizer.New(codeWindowNoRedefineOrderBy, mysql.MySQLErrName[mysql.ErrWindowNoRedefineOrderBy])
ErrWindowDuplicateName = terror.ClassOptimizer.New(codeWindowDuplicateName, mysql.MySQLErrName[mysql.ErrWindowDuplicateName])
)

func init() {
Expand Down Expand Up @@ -124,6 +136,12 @@ func init() {

codeWindowInvalidWindowFuncUse: mysql.ErrWindowInvalidWindowFuncUse,
codeWindowInvalidWindowFuncAliasUse: mysql.ErrWindowInvalidWindowFuncAliasUse,
codeWindowNoSuchWindow: mysql.ErrWindowNoSuchWindow,
codeWindowCircularityInWindowGraph: mysql.ErrWindowCircularityInWindowGraph,
codeWindowNoChildPartitioning: mysql.ErrWindowNoChildPartitioning,
codeWindowNoInherentFrame: mysql.ErrWindowNoInherentFrame,
codeWindowNoRedefineOrderBy: mysql.ErrWindowNoRedefineOrderBy,
codeWindowDuplicateName: mysql.ErrWindowDuplicateName,
}
terror.ErrClassToMySQLCodes[terror.ClassOptimizer] = mysqlErrCodeMap
}
77 changes: 77 additions & 0 deletions planner/core/logical_plan_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1878,6 +1878,11 @@ func (b *PlanBuilder) buildSelect(sel *ast.SelectStmt) (p LogicalPlan, err error
}
}

b.windowSpecs, err = buildWindowSpecs(sel.WindowSpecs)
if err != nil {
return nil, err
}

if hasWindowFuncField {
// Now we build the window function fields.
p, oldLen, err = b.buildProjection(p, sel.Fields.Fields, windowMap, true)
Expand Down Expand Up @@ -2592,6 +2597,16 @@ func (b *PlanBuilder) buildProjectionForWindow(p LogicalPlan, expr *ast.WindowFu

var items []*ast.ByItem
spec := expr.Spec
if spec.Ref.L != "" {
ref, ok := b.windowSpecs[spec.Ref.L]
if !ok {
return nil, nil, nil, ErrWindowNoSuchWindow.GenWithStackByArgs(spec.Ref.O)
}
err := mergeWindowSpec(&spec, &ref)
if err != nil {
return nil, nil, nil, err
}
}
if spec.PartitionBy != nil {
items = append(items, spec.PartitionBy.Items...)
}
Expand Down Expand Up @@ -2679,6 +2694,68 @@ func (b *PlanBuilder) buildWindowFunction(p LogicalPlan, expr *ast.WindowFuncExp
return window, nil
}

// resolveWindowSpec resolve window specifications for sql like `select ... from t window w1 as (w2), w2 as (partition by a)`.
// We need to resolve the referenced window to get the definition of current window spec.
func resolveWindowSpec(spec *ast.WindowSpec, specs map[string]ast.WindowSpec, inStack map[string]bool) error {
if inStack[spec.Name.L] {
return errors.Trace(ErrWindowCircularityInWindowGraph)
}
if spec.Ref.L == "" {
return nil
}
ref, ok := specs[spec.Ref.L]
if !ok {
return ErrWindowNoSuchWindow.GenWithStackByArgs(spec.Ref.O)
}
inStack[spec.Name.L] = true
err := resolveWindowSpec(&ref, specs, inStack)
if err != nil {
return err
}
inStack[spec.Name.L] = false
return mergeWindowSpec(spec, &ref)
}

func mergeWindowSpec(spec, ref *ast.WindowSpec) error {
if ref.Frame != nil {
return ErrWindowNoInherentFrame.GenWithStackByArgs(ref.Name.O)
}
if ref.OrderBy != nil {
if spec.OrderBy != nil {
name := spec.Name.O
if name == "" {
name = "<unnamed window>"
}
return ErrWindowNoRedefineOrderBy.GenWithStackByArgs(name, ref.Name.O)
}
spec.OrderBy = ref.OrderBy
}
if spec.PartitionBy != nil {
return errors.Trace(ErrWindowNoChildPartitioning)
}
spec.PartitionBy = ref.PartitionBy
spec.Ref = model.NewCIStr("")
return nil
}

func buildWindowSpecs(specs []ast.WindowSpec) (map[string]ast.WindowSpec, error) {
specsMap := make(map[string]ast.WindowSpec, len(specs))
for _, spec := range specs {
if _, ok := specsMap[spec.Name.L]; ok {
return nil, ErrWindowDuplicateName.GenWithStackByArgs(spec.Name.O)
}
specsMap[spec.Name.L] = spec
}
inStack := make(map[string]bool, len(specs))
for _, spec := range specs {
err := resolveWindowSpec(&spec, specsMap, inStack)
if err != nil {
return nil, err
}
}
return specsMap, nil
}

// extractTableList extracts all the TableNames from node.
func extractTableList(node ast.ResultSetNode, input []*ast.TableName) []*ast.TableName {
switch x := node.(type) {
Expand Down
Loading

0 comments on commit ece7943

Please sign in to comment.