Esempio n. 1
0
File: ddl.go Progetto: astaxie/tidb
func (d *ddl) AlterTable(ctx context.Context, ident ast.Ident, specs []*ast.AlterTableSpec) (err error) {
	// now we only allow one schema changes at the same time.
	if len(specs) != 1 {
		return errors.New("can't run multi schema changes in one DDL")
	}

	for _, spec := range specs {
		switch spec.Tp {
		case ast.AlterTableAddColumn:
			err = d.AddColumn(ctx, ident, spec)
		case ast.AlterTableDropColumn:
			err = d.DropColumn(ctx, ident, spec.DropColumn.Name)
		case ast.AlterTableDropIndex:
			err = d.DropIndex(ctx, ident, model.NewCIStr(spec.Name))
		case ast.AlterTableAddConstraint:
			constr := spec.Constraint
			switch spec.Constraint.Tp {
			case ast.ConstraintKey, ast.ConstraintIndex:
				err = d.CreateIndex(ctx, ident, false, model.NewCIStr(constr.Name), spec.Constraint.Keys)
			case ast.ConstraintUniq, ast.ConstraintUniqIndex, ast.ConstraintUniqKey:
				err = d.CreateIndex(ctx, ident, true, model.NewCIStr(constr.Name), spec.Constraint.Keys)
			default:
				// nothing to do now.
			}
		default:
			// nothing to do now.
		}

		if err != nil {
			return errors.Trace(err)
		}
	}

	return nil
}
Esempio n. 2
0
func (s *testPlanSuite) TestCoveringIndex(c *C) {
	cases := []struct {
		columnNames []string
		indexNames  []string
		indexLens   []int
		isCovering  bool
	}{
		{[]string{"a"}, []string{"a"}, []int{-1}, true},
		{[]string{"a"}, []string{"a", "b"}, []int{-1, -1}, true},
		{[]string{"a", "b"}, []string{"b", "a"}, []int{-1, -1}, true},
		{[]string{"a", "b"}, []string{"b", "c"}, []int{-1, -1}, false},
		{[]string{"a", "b"}, []string{"a", "b"}, []int{50, -1}, false},
		{[]string{"a", "b"}, []string{"a", "c"}, []int{-1, -1}, false},
	}
	for _, ca := range cases {
		var columns []*model.ColumnInfo
		for _, cn := range ca.columnNames {
			columns = append(columns, &model.ColumnInfo{Name: model.NewCIStr(cn)})
		}
		var indexCols []*model.IndexColumn
		for i := range ca.indexNames {
			icn := ca.indexNames[i]
			icl := ca.indexLens[i]
			indexCols = append(indexCols, &model.IndexColumn{Name: model.NewCIStr(icn), Length: icl})
		}
		covering := isCoveringIndex(columns, indexCols)
		c.Assert(covering, Equals, ca.isCovering)
	}
}
Esempio n. 3
0
func buildResultField(tableName, name string, tp byte, size int) *ast.ResultField {
	cs := charset.CharsetBin
	cl := charset.CharsetBin
	flag := mysql.UnsignedFlag
	if tp == mysql.TypeVarchar || tp == mysql.TypeBlob {
		cs = mysql.DefaultCharset
		cl = mysql.DefaultCollationName
		flag = 0
	}

	fieldType := types.FieldType{
		Charset: cs,
		Collate: cl,
		Tp:      tp,
		Flen:    size,
		Flag:    uint(flag),
	}
	colInfo := &model.ColumnInfo{
		Name:      model.NewCIStr(name),
		FieldType: fieldType,
	}
	expr := &ast.ValueExpr{}
	expr.SetType(&fieldType)

	return &ast.ResultField{
		Column:       colInfo,
		ColumnAsName: colInfo.Name,
		TableAsName:  model.NewCIStr(tableName),
		DBName:       model.NewCIStr(infoschema.Name),
		Expr:         expr,
	}
}
Esempio n. 4
0
func (ts *testSuite) TestConstraintNames(c *C) {
	handle := infoschema.NewHandle(ts.store)
	handle.Set(nil)
	dd := ddl.NewDDL(ts.store, handle)
	se, _ := tidb.CreateSession(ts.store)
	ctx := se.(context.Context)
	schemaName := model.NewCIStr("test")
	tblName := model.NewCIStr("t")
	tbIdent := table.Ident{
		Schema: schemaName,
		Name:   tblName,
	}
	err := dd.CreateSchema(ctx, tbIdent.Schema)
	c.Assert(err, IsNil)
	tbStmt := statement("create table t (a int, b int, index a (a, b), index a (a))").(*stmts.CreateTableStmt)
	err = dd.CreateTable(ctx, tbIdent, tbStmt.Cols, tbStmt.Constraints)
	c.Assert(err, NotNil)

	tbStmt = statement("create table t (a int, b int, index A (a, b), index (a))").(*stmts.CreateTableStmt)
	err = dd.CreateTable(ctx, tbIdent, tbStmt.Cols, tbStmt.Constraints)
	c.Assert(err, IsNil)
	tbl, err := handle.Get().TableByName(schemaName, tblName)
	indices := tbl.Indices()
	c.Assert(len(indices), Equals, 2)
	c.Assert(indices[0].Name.O, Equals, "A")
	c.Assert(indices[1].Name.O, Equals, "a_2")

	err = dd.DropSchema(ctx, tbIdent.Schema)
	c.Assert(err, IsNil)
}
Esempio n. 5
0
func (s *testDDLSuite) TestIndexError(c *C) {
	defer testleak.AfterTest(c)()
	store := testCreateStore(c, "test_index_error")
	defer store.Close()

	d := newDDL(store, nil, nil, testLease)
	defer d.close()

	ctx := testNewContext(c, d)

	doDDLJobErr(c, -1, 1, model.ActionAddIndex, nil, ctx, d)
	doDDLJobErr(c, -1, 1, model.ActionDropIndex, nil, ctx, d)

	dbInfo := testSchemaInfo(c, d, "test")
	tblInfo := testTableInfo(c, d, "t", 3)

	testCreateSchema(c, ctx, d, dbInfo)
	testCreateTable(c, ctx, d, dbInfo, tblInfo)

	doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionAddIndex, []interface{}{1}, ctx, d)
	doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionAddIndex,
		[]interface{}{false, model.NewCIStr("t"), []*ast.IndexColName{{Column: &ast.ColumnName{Name: model.NewCIStr("c")}, Length: 256}}}, ctx, d)
	doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionAddIndex,
		[]interface{}{false, model.NewCIStr("c1_index"), []*ast.IndexColName{{Column: &ast.ColumnName{Name: model.NewCIStr("c")}, Length: 256}}}, ctx, d)

	testCreateIndex(c, ctx, d, dbInfo, tblInfo, false, "c1_index", "c1")

	doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionAddIndex,
		[]interface{}{false, model.NewCIStr("c1_index"), []*ast.IndexColName{{Column: &ast.ColumnName{Name: model.NewCIStr("c1")}, Length: 256}}}, ctx, d)
	doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionDropIndex, []interface{}{1}, ctx, d)

	testDropIndex(c, ctx, d, dbInfo, tblInfo, "c1_index")

	doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionDropIndex, []interface{}{model.NewCIStr("c1_index")}, ctx, d)
}
Esempio n. 6
0
func (b *planBuilder) buildExplain(explain *ast.ExplainStmt) Plan {
	if show, ok := explain.Stmt.(*ast.ShowStmt); ok {
		return b.buildShow(show)
	}
	targetPlan, err := Optimize(b.ctx, explain.Stmt, b.is)
	if err != nil {
		b.err = errors.Trace(err)
		return nil
	}
	p := &Explain{StmtPlan: targetPlan}
	addChild(p, targetPlan)
	schema := make(expression.Schema, 0, 3)
	schema = append(schema, &expression.Column{
		ColName: model.NewCIStr("ID"),
		RetType: types.NewFieldType(mysql.TypeString),
	})
	schema = append(schema, &expression.Column{
		ColName: model.NewCIStr("Json"),
		RetType: types.NewFieldType(mysql.TypeString),
	})
	schema = append(schema, &expression.Column{
		ColName: model.NewCIStr("ParentID"),
		RetType: types.NewFieldType(mysql.TypeString),
	})
	p.SetSchema(schema)
	return p
}
Esempio n. 7
0
// create a test table with num int columns and with no index.
func testTableInfo(c *C, d *ddl, name string, num int) *model.TableInfo {
	var err error
	tblInfo := &model.TableInfo{
		Name: model.NewCIStr(name),
	}
	tblInfo.ID, err = d.genGlobalID()
	c.Assert(err, IsNil)

	cols := make([]*model.ColumnInfo, num)
	for i := range cols {
		col := &model.ColumnInfo{
			Name:         model.NewCIStr(fmt.Sprintf("c%d", i+1)),
			Offset:       i,
			DefaultValue: i + 1,
			State:        model.StatePublic,
		}

		col.FieldType = *types.NewFieldType(mysql.TypeLong)

		col.ID, err = d.genGlobalID()
		c.Assert(err, IsNil)
		cols[i] = col
	}

	tblInfo.Columns = cols

	return tblInfo
}
Esempio n. 8
0
func (t *testGroupBySuite) TestGroupBy(c *C) {
	tblPlan := &testTablePlan{groupByTestData, []string{"id", "name"}}
	// test multiple fields
	sl := &SelectList{
		Fields: []*field.Field{
			{
				Expr: &expressions.Ident{
					CIStr: model.NewCIStr("id"),
				},
			},
			{
				Expr: &expressions.Ident{
					CIStr: model.NewCIStr("name"),
				},
			},
			{
				Expr: &expressions.Call{
					F: "sum",
					Args: []expression.Expression{
						&expressions.Ident{
							CIStr: model.NewCIStr("id"),
						},
					},
				},
			},
		},
		AggFields: map[int]struct{}{2: {}},
	}

	groupbyPlan := &GroupByDefaultPlan{
		SelectList: sl,
		Src:        tblPlan,
		By: []expression.Expression{
			&expressions.Ident{
				CIStr: model.NewCIStr("id"),
			},
		},
	}

	ret := map[int]string{}
	groupbyPlan.Do(nil, func(id interface{}, data []interface{}) (bool, error) {
		ret[data[0].(int)] = data[1].(string)
		return true, nil
	})
	c.Assert(ret, HasLen, 3)
	excepted := map[int]string{
		10: "10",
		40: "40",
		60: "60",
	}
	c.Assert(ret, DeepEquals, excepted)

	// test empty
	tblPlan.rows = []*testRowData{}
	groupbyPlan.Src = tblPlan
	groupbyPlan.By = nil
	groupbyPlan.Do(nil, func(id interface{}, data []interface{}) (bool, error) {
		return true, nil
	})
}
Esempio n. 9
0
func (ts *testMemoryTableSuite) SetUpSuite(c *C) {
	driver := localstore.Driver{Driver: goleveldb.MemoryDriver{}}
	store, err := driver.Open("memory")
	c.Check(err, IsNil)
	ts.store = store
	ts.se, err = tidb.CreateSession(ts.store)
	c.Assert(err, IsNil)

	// create table
	tp1 := types.NewFieldType(mysql.TypeLong)
	col1 := &model.ColumnInfo{
		ID:        1,
		Name:      model.NewCIStr("a"),
		Offset:    0,
		FieldType: *tp1,
	}
	tp2 := types.NewFieldType(mysql.TypeVarchar)
	tp2.Flen = 255
	col2 := &model.ColumnInfo{
		ID:        2,
		Name:      model.NewCIStr("b"),
		Offset:    1,
		FieldType: *tp2,
	}

	tblInfo := &model.TableInfo{
		ID:      100,
		Name:    model.NewCIStr("t"),
		Columns: []*model.ColumnInfo{col1, col2},
	}
	alloc := autoid.NewMemoryAllocator(int64(10))
	ts.tbl, _ = tables.MemoryTableFromMeta(alloc, tblInfo)
}
Esempio n. 10
0
func (s *testForeighKeySuite) testCreateForeignKey(c *C, tblInfo *model.TableInfo, fkName string, keys []string, refTable string, refKeys []string, onDelete ast.ReferOptionType, onUpdate ast.ReferOptionType) *model.Job {
	FKName := model.NewCIStr(fkName)
	Keys := make([]model.CIStr, len(keys))
	for i, key := range keys {
		Keys[i] = model.NewCIStr(key)
	}

	RefTable := model.NewCIStr(refTable)
	RefKeys := make([]model.CIStr, len(refKeys))
	for i, key := range refKeys {
		RefKeys[i] = model.NewCIStr(key)
	}

	fkInfo := &model.FKInfo{
		Name:     FKName,
		RefTable: RefTable,
		RefCols:  RefKeys,
		Cols:     Keys,
		OnDelete: int(onDelete),
		OnUpdate: int(onUpdate),
		State:    model.StateNone,
	}

	job := &model.Job{
		SchemaID: s.dbInfo.ID,
		TableID:  tblInfo.ID,
		Type:     model.ActionAddForeignKey,
		Args:     []interface{}{fkInfo},
	}
	err := s.d.doDDLJob(s.ctx, job)
	c.Assert(err, IsNil)
	return job
}
Esempio n. 11
0
func (ts *testSuite) TestConstraintNames(c *C) {
	se, _ := tidb.CreateSession(ts.store)
	ctx := se.(context.Context)
	schemaName := model.NewCIStr("test_constraint")
	tblName := model.NewCIStr("t")
	tbIdent := table.Ident{
		Schema: schemaName,
		Name:   tblName,
	}

	err := sessionctx.GetDomain(ctx).DDL().CreateSchema(ctx, tbIdent.Schema, ts.charsetInfo)
	c.Assert(err, IsNil)

	tbStmt := statement(ctx, "create table t (a int, b int, index a (a, b), index a (a))").(*stmts.CreateTableStmt)
	err = sessionctx.GetDomain(ctx).DDL().CreateTable(ctx, tbIdent, tbStmt.Cols, tbStmt.Constraints)
	c.Assert(err, NotNil)

	tbStmt = statement(ctx, "create table t (a int, b int, index A (a, b), index (a))").(*stmts.CreateTableStmt)
	err = sessionctx.GetDomain(ctx).DDL().CreateTable(ctx, tbIdent, tbStmt.Cols, tbStmt.Constraints)
	c.Assert(err, IsNil)
	tbl, err := sessionctx.GetDomain(ctx).InfoSchema().TableByName(schemaName, tblName)
	indices := tbl.Indices()
	c.Assert(len(indices), Equals, 2)
	c.Assert(indices[0].Name.O, Equals, "A")
	c.Assert(indices[1].Name.O, Equals, "a_2")

	err = sessionctx.GetDomain(ctx).DDL().DropSchema(ctx, tbIdent.Schema)
	c.Assert(err, IsNil)
}
Esempio n. 12
0
// Make sure that all tables of infomation_schema could be found in infoschema handle.
func (*testSuite) TestInfoTables(c *C) {
	defer testleak.AfterTest(c)()
	driver := localstore.Driver{Driver: goleveldb.MemoryDriver{}}
	store, err := driver.Open("memory")
	c.Assert(err, IsNil)
	defer store.Close()
	handle, err := infoschema.NewHandle(store)
	c.Assert(err, IsNil)
	builder, err := infoschema.NewBuilder(handle).InitWithDBInfos(nil, 0)
	c.Assert(err, IsNil)
	err = builder.Build()
	c.Assert(err, IsNil)
	is := handle.Get()
	c.Assert(is, NotNil)

	info_tables := []string{
		"SCHEMATA",
		"TABLES",
		"COLUMNS",
		"STATISTICS",
		"CHARACTER_SETS",
		"COLLATIONS",
		"FILES",
		"PROFILING",
		"PARTITIONS",
		"KEY_COLUMN_USAGE",
		"REFERENTIAL_CONSTRAINTS",
	}
	for _, t := range info_tables {
		tb, err1 := is.TableByName(model.NewCIStr(infoschema.Name), model.NewCIStr(t))
		c.Assert(err1, IsNil)
		c.Assert(tb, NotNil)
	}
}
Esempio n. 13
0
func (s *testExpressionSuite) TestExpression(c *C) {
	defer testleak.AfterTest(c)()

	var schema Schema
	for i := 0; i < 3; i++ {
		schema = append(schema, &Column{ColName: model.NewCIStr("t"), FromID: "mock", Position: i})
	}
	tc1 := &Column{FromID: "t", ColName: model.NewCIStr("c1")}
	kc1 := &Column{FromID: "k", ColName: model.NewCIStr("c1")}
	tc2 := &Column{FromID: "t", ColName: model.NewCIStr("c2")}
	con := &Constant{Value: types.NewDatum(10)}
	col := &ast.ColumnName{Name: model.NewCIStr("t")}
	// t.c1 as t, t.c2 as t, 10 as t => error
	index, err := getColIndex([]Expression{tc1, tc2, con}, schema, col)
	c.Check(err, NotNil)
	// t.c1 as t, 10 as t, t.c2 as t => 10
	index, err = getColIndex([]Expression{tc1, con, tc2}, schema, col)
	c.Assert(index, Equals, 1)
	// t.c1 as t, t.c1 as t, 10 as t => 10
	index, err = getColIndex([]Expression{tc1, tc1, con}, schema, col)
	c.Assert(index, Equals, 2)
	// t.c1 as t, k.c1 as t, 10 as t => error
	index, err = getColIndex([]Expression{tc1, kc1, con}, schema, col)
	c.Check(err, NotNil)
}
Esempio n. 14
0
func (s *testTableRsetSuite) TestTableSourceString(c *C) {
	tableIdent := table.Ident{Schema: model.NewCIStr(s.dbName), Name: model.NewCIStr(s.tableName)}
	ts := &rsets.TableSource{Source: tableIdent, Name: s.tableName}

	str := ts.String()
	c.Assert(len(str), Greater, 0)

	store := newStore(c)
	se := newSession(c, store, s.dbName)
	ctx, ok := se.(context.Context)
	c.Assert(ok, IsTrue)
	stmtList, err := tidb.Compile(ctx, s.querySql)
	c.Assert(err, IsNil)
	c.Assert(len(stmtList), Greater, 0)

	ts = &rsets.TableSource{Source: stmtList[0], Name: s.tableName}
	str = ts.String()
	c.Assert(len(str), Greater, 0)

	ts = &rsets.TableSource{Source: stmtList[0]}
	str = ts.String()
	c.Assert(len(str), Greater, 0)

	// check panic
	defer func() {
		e := recover()
		c.Assert(e, NotNil)
	}()

	ts = &rsets.TableSource{}
	str = ts.String()
}
Esempio n. 15
0
func (ts *testSuite) TestUniqueIndexMultipleNullEntries(c *C) {
	_, err := ts.se.Execute("CREATE TABLE test.t (a int primary key auto_increment, b varchar(255) unique)")
	c.Assert(err, IsNil)
	ctx := ts.se.(context.Context)
	dom := sessionctx.GetDomain(ctx)
	tb, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t"))
	c.Assert(err, IsNil)
	c.Assert(tb.Meta().ID, Greater, int64(0))
	c.Assert(tb.Meta().Name.L, Equals, "t")
	c.Assert(tb.Meta(), NotNil)
	c.Assert(tb.Indices(), NotNil)
	c.Assert(string(tb.FirstKey()), Not(Equals), "")
	c.Assert(string(tb.IndexPrefix()), Not(Equals), "")
	c.Assert(string(tb.RecordPrefix()), Not(Equals), "")
	c.Assert(tables.FindIndexByColName(tb, "b"), NotNil)

	autoid, err := tb.AllocAutoID()
	c.Assert(err, IsNil)
	c.Assert(autoid, Greater, int64(0))

	_, err = tb.AddRecord(ctx, types.MakeDatums(1, nil))
	c.Assert(err, IsNil)
	_, err = tb.AddRecord(ctx, types.MakeDatums(2, nil))
	c.Assert(err, IsNil)
	_, err = ts.se.Execute("drop table test.t")
	c.Assert(err, IsNil)
}
Esempio n. 16
0
func (p *testFromSuit) SetUpSuite(c *C) {
	store, err := tidb.NewStore(tidb.EngineGoLevelDBMemory)
	c.Assert(err, IsNil)
	p.vars = map[string]interface{}{}
	p.txn, _ = store.Begin()
	p.cols = []*column.Col{
		{
			ColumnInfo: model.ColumnInfo{
				ID:           0,
				Name:         model.NewCIStr("id"),
				Offset:       0,
				DefaultValue: 0,
				FieldType:    *types.NewFieldType(mysql.TypeLonglong),
			},
		},
		{
			ColumnInfo: model.ColumnInfo{
				ID:           1,
				Name:         model.NewCIStr("name"),
				Offset:       1,
				DefaultValue: nil,
				FieldType:    *types.NewFieldType(mysql.TypeVarchar),
			},
		},
	}
	p.tbl = tables.NewTable(1, "t", "test", p.cols, &simpleAllocator{})
	variable.BindSessionVars(p)

	var i int64
	for i = 0; i < 10; i++ {
		p.tbl.AddRecord(p, []interface{}{i * 10, "hello"})
	}
}
Esempio n. 17
0
func (d *ddl) AlterTable(ctx context.Context, ident table.Ident, specs []*AlterSpecification) (err error) {
	// now we only allow one schema changes at the same time.
	if len(specs) != 1 {
		return errors.New("can't run multi schema changes in one DDL")
	}

	for _, spec := range specs {
		switch spec.Action {
		case AlterAddColumn:
			err = d.AddColumn(ctx, ident, spec)
		case AlterDropColumn:
			err = d.DropColumn(ctx, ident, model.NewCIStr(spec.Name))
		case AlterDropIndex:
			err = d.DropIndex(ctx, ident, model.NewCIStr(spec.Name))
		case AlterAddConstr:
			constr := spec.Constraint
			switch spec.Constraint.Tp {
			case coldef.ConstrKey, coldef.ConstrIndex:
				err = d.CreateIndex(ctx, ident, false, model.NewCIStr(constr.ConstrName), spec.Constraint.Keys)
			case coldef.ConstrUniq, coldef.ConstrUniqIndex, coldef.ConstrUniqKey:
				err = d.CreateIndex(ctx, ident, true, model.NewCIStr(constr.ConstrName), spec.Constraint.Keys)
			default:
				// nothing to do now.
			}
		default:
			// nothing to do now.
		}

		if err != nil {
			return errors.Trace(err)
		}
	}

	return nil
}
Esempio n. 18
0
func (s *testDDLSuite) TestColumnError(c *C) {
	defer testleak.AfterTest(c)()
	store := testCreateStore(c, "test_column_error")
	defer store.Close()
	d := newDDL(store, nil, nil, testLease)
	defer d.close()
	ctx := testNewContext(c, d)

	dbInfo := testSchemaInfo(c, d, "test")
	tblInfo := testTableInfo(c, d, "t", 3)
	testCreateSchema(c, ctx, d, dbInfo)
	testCreateTable(c, ctx, d, dbInfo, tblInfo)
	col := &model.ColumnInfo{
		Name:         model.NewCIStr("c4"),
		Offset:       len(tblInfo.Columns),
		DefaultValue: 0,
	}
	col.ID = allocateColumnID(tblInfo)
	col.FieldType = *types.NewFieldType(mysql.TypeLong)
	pos := &ast.ColumnPosition{Tp: ast.ColumnPositionAfter, RelativeColumn: &ast.ColumnName{Name: model.NewCIStr("c5")}}

	// for adding column
	doDDLJobErr(c, -1, tblInfo.ID, model.ActionAddColumn, []interface{}{col, pos, 0}, ctx, d)
	doDDLJobErr(c, dbInfo.ID, -1, model.ActionAddColumn, []interface{}{col, pos, 0}, ctx, d)
	doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionAddColumn, []interface{}{0}, ctx, d)
	doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionAddColumn, []interface{}{col, pos, 0}, ctx, d)

	// for dropping column
	doDDLJobErr(c, -1, tblInfo.ID, model.ActionDropColumn, []interface{}{col, pos, 0}, ctx, d)
	doDDLJobErr(c, dbInfo.ID, -1, model.ActionDropColumn, []interface{}{col, pos, 0}, ctx, d)
	doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionDropColumn, []interface{}{0}, ctx, d)
	doDDLJobErr(c, dbInfo.ID, tblInfo.ID, model.ActionDropColumn, []interface{}{model.NewCIStr("c5")}, ctx, d)
}
Esempio n. 19
0
// buildProjection returns a Projection plan and non-aux columns length.
func (b *planBuilder) buildProjection(p LogicalPlan, fields []*ast.SelectField, mapper map[*ast.AggregateFuncExpr]int) (LogicalPlan, int) {
	proj := &Projection{
		Exprs:           make([]expression.Expression, 0, len(fields)),
		baseLogicalPlan: newBaseLogicalPlan(Proj, b.allocator),
	}
	proj.initID()
	proj.correlated = p.IsCorrelated()
	schema := make(expression.Schema, 0, len(fields))
	oldLen := 0
	for _, field := range fields {
		newExpr, np, correlated, err := b.rewrite(field.Expr, p, mapper, true)
		if err != nil {
			b.err = errors.Trace(err)
			return nil, oldLen
		}
		p = np
		proj.correlated = proj.correlated || correlated
		proj.Exprs = append(proj.Exprs, newExpr)
		var tblName, colName model.CIStr
		if field.AsName.L != "" {
			colName = field.AsName
		} else if c, ok := newExpr.(*expression.Column); ok && !c.IsAggOrSubq {
			if astCol, ok := getInnerFromParentheses(field.Expr).(*ast.ColumnNameExpr); ok {
				colName = astCol.Name.Name
				tblName = astCol.Name.Table
			} else {
				colName = c.ColName
				tblName = c.TblName
			}
		} else {
			// When the query is select t.a from t group by a; The Column Name should be a but not t.a;
			if agg, ok := field.Expr.(*ast.AggregateFuncExpr); ok && agg.F == ast.AggFuncFirstRow {
				if col, ok := agg.Args[0].(*ast.ColumnNameExpr); ok {
					colName = col.Name.Name
				}
			} else {
				innerExpr := getInnerFromParentheses(field.Expr)
				if _, ok := innerExpr.(*ast.ValueExpr); ok && innerExpr.Text() != "" {
					colName = model.NewCIStr(innerExpr.Text())
				} else {
					colName = model.NewCIStr(field.Text())
				}
			}
		}
		schemaCol := &expression.Column{
			FromID:  proj.id,
			TblName: tblName,
			ColName: colName,
			RetType: newExpr.GetType(),
		}
		if !field.Auxiliary {
			oldLen++
		}
		schema = append(schema, schemaCol)
		schemaCol.Position = len(schema)
	}
	proj.SetSchema(schema)
	addChild(proj, p)
	return proj, oldLen
}
Esempio n. 20
0
func (s *testTableRsetSuite) TestTableSourceString(c *C) {
	tableIdent := table.Ident{Schema: model.NewCIStr(s.dbName), Name: model.NewCIStr(s.tableName)}
	ts := &rsets.TableSource{Source: tableIdent, Name: s.tableName}

	str := ts.String()
	c.Assert(len(str), Greater, 0)

	stmtList, err := tidb.Compile(s.querySql)
	c.Assert(err, IsNil)
	c.Assert(len(stmtList), Greater, 0)

	ts = &rsets.TableSource{Source: stmtList[0], Name: s.tableName}
	str = ts.String()
	c.Assert(len(str), Greater, 0)

	ts = &rsets.TableSource{Source: stmtList[0]}
	str = ts.String()
	c.Assert(len(str), Greater, 0)

	// check panic
	defer func() {
		e := recover()
		c.Assert(e, NotNil)
	}()

	ts = &rsets.TableSource{}
	str = ts.String()
}
Esempio n. 21
0
func (ts *testSuite) TestTypes(c *C) {
	_, err := ts.se.Execute("CREATE TABLE test.t (c1 tinyint, c2 smallint, c3 int, c4 bigint, c5 text, c6 blob, c7 varchar(64), c8 time, c9 timestamp not null default CURRENT_TIMESTAMP, c10 decimal)")
	c.Assert(err, IsNil)
	ctx := ts.se.(context.Context)
	dom := sessionctx.GetDomain(ctx)
	_, err = dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t"))
	c.Assert(err, IsNil)
	_, err = ts.se.Execute("insert test.t values (1, 2, 3, 4, '5', '6', '7', '10:10:10', null, 1.4)")
	c.Assert(err, IsNil)
	rs, err := ts.se.Execute("select * from test.t where c1 = 1")
	row, err := rs[0].FirstRow()
	c.Assert(err, IsNil)
	c.Assert(row, NotNil)
	_, err = ts.se.Execute("drop table test.t")
	c.Assert(err, IsNil)

	_, err = ts.se.Execute("CREATE TABLE test.t (c1 tinyint unsigned, c2 smallint unsigned, c3 int unsigned, c4 bigint unsigned, c5 double)")
	c.Assert(err, IsNil)
	_, err = ts.se.Execute("insert test.t values (1, 2, 3, 4, 5)")
	c.Assert(err, IsNil)
	rs, err = ts.se.Execute("select * from test.t where c1 = 1")
	row, err = rs[0].FirstRow()
	c.Assert(err, IsNil)
	c.Assert(row, NotNil)
	_, err = ts.se.Execute("drop table test.t")
	c.Assert(err, IsNil)
}
Esempio n. 22
0
func (*testSuite) TestT(c *C) {
	driver := localstore.Driver{Driver: goleveldb.MemoryDriver{}}
	store, err := driver.Open("memory")
	c.Assert(err, IsNil)
	defer store.Close()

	m := meta.NewMeta(store)
	err = m.RunInNewTxn(false, func(m *meta.TMeta) error {
		err = m.CreateDatabase(&model.DBInfo{ID: 1, Name: model.NewCIStr("a")})
		c.Assert(err, IsNil)
		err = m.CreateTable(1, &model.TableInfo{ID: 1, Name: model.NewCIStr("t")})
		c.Assert(err, IsNil)
		return nil
	})
	c.Assert(err, IsNil)

	alloc := autoid.NewAllocator(m, 1)
	c.Assert(alloc, NotNil)

	id, err := alloc.Alloc(1)
	c.Assert(err, IsNil)
	c.Assert(id, Equals, int64(1))
	id, err = alloc.Alloc(1)
	c.Assert(err, IsNil)
	c.Assert(id, Equals, int64(2))
	id, err = alloc.Alloc(0)
	c.Assert(err, NotNil)
}
Esempio n. 23
0
func (ts *testFunctionsSuite) TestAggregateFuncExtractor(c *C) {
	var expr Node

	extractor := &AggregateFuncExtractor{}
	expr = &AggregateFuncExpr{}
	expr.Accept(extractor)
	c.Assert(extractor.AggFuncs, HasLen, 1)
	c.Assert(extractor.AggFuncs[0], Equals, expr)

	extractor = &AggregateFuncExtractor{}
	expr = &FuncCallExpr{
		FnName: model.NewCIStr("DATE_ARITH"),
	}
	expr.Accept(extractor)
	c.Assert(extractor.AggFuncs, HasLen, 0)

	extractor = &AggregateFuncExtractor{}
	r := &AggregateFuncExpr{}
	expr = &BinaryOperationExpr{
		L: &FuncCallExpr{
			FnName: model.NewCIStr("DATE_ARITH"),
		},
		R: r,
	}
	expr.Accept(extractor)
	c.Assert(extractor.AggFuncs, HasLen, 1)
	c.Assert(extractor.AggFuncs[0], Equals, r)

	// convert ColumnNameExpr to AggregateFuncExpr
	extractor = &AggregateFuncExtractor{}
	expr = &ColumnNameExpr{}
	f := &SelectField{Expr: expr.(ExprNode)}
	f.Accept(extractor)
	c.Assert(extractor.AggFuncs, HasLen, 1)
	e := extractor.AggFuncs[0]
	c.Assert(e, NotNil)
	c.Assert(e.F, Equals, AggFuncFirstRow)

	// select exists(select count(c) from t) from t
	// subquery contains aggregate function
	expr1 := &AggregateFuncExpr{}
	field1 := &SelectField{Expr: expr1}
	fields1 := &FieldList{Fields: []*SelectField{field1}}
	subSel := &SelectStmt{Fields: fields1}

	subExpr := &ExistsSubqueryExpr{
		Sel: &SubqueryExpr{Query: subSel},
	}
	field := &SelectField{Expr: subExpr}
	fields := &FieldList{Fields: []*SelectField{field}}
	sel := &SelectStmt{Fields: fields}

	extractor = &AggregateFuncExtractor{}
	sel.Accept(extractor)
	c.Assert(extractor.AggFuncs, HasLen, 0)
	extractor = &AggregateFuncExtractor{}
	subSel.Accept(extractor)
	c.Assert(extractor.AggFuncs, HasLen, 1)
}
Esempio n. 24
0
func (s *testDBSuite) TestUpdateMultipleTable(c *C) {
	defer testleak.AfterTest(c)
	store, err := tidb.NewStore("memory://update_multiple_table")
	c.Assert(err, IsNil)
	tk := testkit.NewTestKit(c, store)
	tk.MustExec("use test")
	tk.MustExec("create table t1 (c1 int, c2 int)")
	tk.MustExec("insert t1 values (1, 1), (2, 2)")
	tk.MustExec("create table t2 (c1 int, c2 int)")
	tk.MustExec("insert t2 values (1, 3), (2, 5)")
	ctx := tk.Se.(context.Context)
	domain := sessionctx.GetDomain(ctx)
	is := domain.InfoSchema()
	db, ok := is.SchemaByName(model.NewCIStr("test"))
	c.Assert(ok, IsTrue)
	t1Tbl, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("t1"))
	c.Assert(err, IsNil)
	t1Info := t1Tbl.Meta()

	// Add a new column in write only state.
	newColumn := &model.ColumnInfo{
		ID:           100,
		Name:         model.NewCIStr("c3"),
		Offset:       2,
		DefaultValue: 9,
		FieldType:    *types.NewFieldType(mysql.TypeLonglong),
		State:        model.StateWriteOnly,
	}
	t1Info.Columns = append(t1Info.Columns, newColumn)

	kv.RunInNewTxn(store, false, func(txn kv.Transaction) error {
		m := meta.NewMeta(txn)
		_, err = m.GenSchemaVersion()
		c.Assert(err, IsNil)
		c.Assert(m.UpdateTable(db.ID, t1Info), IsNil)
		return nil
	})
	err = domain.Reload()
	c.Assert(err, IsNil)

	tk.MustExec("update t1, t2 set t1.c1 = 8, t2.c2 = 10 where t1.c2 = t2.c1")
	tk.MustQuery("select * from t1").Check(testkit.Rows("8 1", "8 2"))
	tk.MustQuery("select * from t2").Check(testkit.Rows("1 10", "2 10"))

	newColumn.State = model.StatePublic

	kv.RunInNewTxn(store, false, func(txn kv.Transaction) error {
		m := meta.NewMeta(txn)
		_, err = m.GenSchemaVersion()
		c.Assert(err, IsNil)
		c.Assert(m.UpdateTable(db.ID, t1Info), IsNil)
		return nil
	})
	err = domain.Reload()
	c.Assert(err, IsNil)

	tk.MustQuery("select * from t1").Check(testkit.Rows("8 1 9", "8 2 9"))
}
Esempio n. 25
0
func (s *testOrderByRsetSuite) TestOrderByRsetCheckAndUpdateSelectList(c *C) {
	resultFields := s.r.Src.GetFields()

	fields := make([]*field.Field, len(resultFields))
	for i, resultField := range resultFields {
		name := resultField.Name
		fields[i] = &field.Field{Expr: &expressions.Ident{CIStr: model.NewCIStr(name)}, Name: name}
	}

	selectList := &plans.SelectList{
		HiddenFieldOffset: len(resultFields),
		ResultFields:      resultFields,
		Fields:            fields,
	}

	expr := &expressions.Ident{model.NewCIStr("id")}
	orderByItem := OrderByItem{Expr: expr, Asc: true}
	by := []OrderByItem{orderByItem}
	r := &OrderByRset{By: by, SelectList: selectList}

	// `select id, name from t order by id`
	err := r.CheckAndUpdateSelectList(selectList, resultFields)
	c.Assert(err, IsNil)

	// `select id, name as id from t order by id`
	selectList.Fields[1].Name = "id"
	selectList.ResultFields[1].Name = "id"

	err = r.CheckAndUpdateSelectList(selectList, resultFields)
	c.Assert(err, NotNil)

	// `select id, name from t order by count(1) > 1`
	aggExpr, err := expressions.NewCall("count", []expression.Expression{expressions.Value{1}}, false)
	c.Assert(err, IsNil)

	r.By[0].Expr = aggExpr

	err = r.CheckAndUpdateSelectList(selectList, resultFields)
	c.Assert(err, IsNil)

	// `select id, name from t order by count(xxx) > 1`
	aggExpr, err = expressions.NewCall("count", []expression.Expression{&expressions.Ident{model.NewCIStr("xxx")}}, false)
	c.Assert(err, IsNil)

	r.By[0].Expr = aggExpr

	err = r.CheckAndUpdateSelectList(selectList, resultFields)
	c.Assert(err, NotNil)

	// `select id, name from t order by xxx`
	r.By[0].Expr = &expressions.Ident{model.NewCIStr("xxx")}
	selectList.Fields[1].Name = "name"
	selectList.ResultFields[1].Name = "name"

	err = r.CheckAndUpdateSelectList(selectList, resultFields)
	c.Assert(err, NotNil)
}
Esempio n. 26
0
func (p *physicalTableSource) addAggregation(agg *PhysicalAggregation) expression.Schema {
	if p.client == nil {
		return nil
	}
	for _, f := range agg.AggFuncs {
		pb := aggFuncToPBExpr(p.client, f)
		if pb == nil {
			p.clear()
			return nil
		}
		p.AggFuncs = append(p.AggFuncs, pb)
	}
	for _, item := range agg.GroupByItems {
		pb := groupByItemToPB(p.client, item)
		if pb == nil {
			p.clear()
			return nil
		}
		p.GbyItems = append(p.GbyItems, pb)
	}
	p.Aggregated = true
	gk := types.NewFieldType(mysql.TypeBlob)
	gk.Charset = charset.CharsetBin
	gk.Collate = charset.CollationBin
	p.AggFields = append(p.AggFields, gk)
	var schema expression.Schema
	cursor := 0
	schema = append(schema, &expression.Column{Index: cursor, ColName: model.NewCIStr(fmt.Sprint(agg.GroupByItems))})
	agg.GroupByItems = []expression.Expression{schema[cursor]}
	newAggFuncs := make([]expression.AggregationFunction, len(agg.AggFuncs))
	for i, aggFun := range agg.AggFuncs {
		fun := expression.NewAggFunction(aggFun.GetName(), nil, false)
		var args []expression.Expression
		colName := model.NewCIStr(fmt.Sprint(aggFun.GetArgs()))
		if needCount(fun) {
			cursor++
			schema = append(schema, &expression.Column{Index: cursor, ColName: colName})
			args = append(args, schema[cursor])
			ft := types.NewFieldType(mysql.TypeLonglong)
			ft.Flen = 21
			ft.Charset = charset.CharsetBin
			ft.Collate = charset.CollationBin
			p.AggFields = append(p.AggFields, ft)
		}
		if needValue(fun) {
			cursor++
			schema = append(schema, &expression.Column{Index: cursor, ColName: colName})
			args = append(args, schema[cursor])
			p.AggFields = append(p.AggFields, agg.schema[i].GetType())
		}
		fun.SetArgs(args)
		fun.SetMode(expression.FinalMode)
		newAggFuncs[i] = fun
	}
	agg.AggFuncs = newAggFuncs
	return schema
}
Esempio n. 27
0
func (s *testSuite) TestAdmin(c *C) {
	defer testleak.AfterTest(c)()
	tk := testkit.NewTestKit(c, s.store)
	tk.MustExec("use test")
	tk.MustExec("drop table if exists admin_test")
	tk.MustExec("create table admin_test (c1 int, c2 int, c3 int default 1, index (c1))")
	tk.MustExec("insert admin_test (c1) values (1),(2),(NULL)")
	r, err := tk.Exec("admin show ddl")
	c.Assert(err, IsNil)
	row, err := r.Next()
	c.Assert(err, IsNil)
	c.Assert(row.Data, HasLen, 6)
	txn, err := s.store.Begin()
	c.Assert(err, IsNil)
	ddlInfo, err := inspectkv.GetDDLInfo(txn)
	c.Assert(err, IsNil)
	c.Assert(row.Data[0].GetInt64(), Equals, ddlInfo.SchemaVer)
	rowOwnerInfos := strings.Split(row.Data[1].GetString(), ",")
	ownerInfos := strings.Split(ddlInfo.Owner.String(), ",")
	c.Assert(rowOwnerInfos[0], Equals, ownerInfos[0])
	c.Assert(row.Data[2].GetString(), Equals, "")
	bgInfo, err := inspectkv.GetBgDDLInfo(txn)
	c.Assert(err, IsNil)
	c.Assert(row.Data[3].GetInt64(), Equals, bgInfo.SchemaVer)
	rowOwnerInfos = strings.Split(row.Data[4].GetString(), ",")
	ownerInfos = strings.Split(bgInfo.Owner.String(), ",")
	c.Assert(rowOwnerInfos[0], Equals, ownerInfos[0])
	c.Assert(row.Data[5].GetString(), Equals, "")
	row, err = r.Next()
	c.Assert(err, IsNil)
	c.Assert(row, IsNil)

	// check table test
	tk.MustExec("create table admin_test1 (c1 int, c2 int default 1, index (c1))")
	tk.MustExec("insert admin_test1 (c1) values (21),(22)")
	r, err = tk.Exec("admin check table admin_test, admin_test1")
	c.Assert(err, IsNil)
	c.Assert(r, IsNil)
	// error table name
	r, err = tk.Exec("admin check table admin_test_error")
	c.Assert(err, NotNil)
	// different index values
	ctx := tk.Se.(context.Context)
	domain := sessionctx.GetDomain(ctx)
	is := domain.InfoSchema()
	c.Assert(is, NotNil)
	tb, err := is.TableByName(model.NewCIStr("test"), model.NewCIStr("admin_test"))
	c.Assert(err, IsNil)
	c.Assert(tb.Indices(), HasLen, 1)
	_, err = tb.Indices()[0].Create(txn, types.MakeDatums(int64(10)), 1)
	c.Assert(err, IsNil)
	err = txn.Commit()
	c.Assert(err, IsNil)
	r, err = tk.Exec("admin check table admin_test")
	c.Assert(err, NotNil)
}
Esempio n. 28
0
func (ts *testSuite) TestBasic(c *C) {
	_, err := ts.se.Execute("CREATE TABLE test.t (a int primary key auto_increment, b varchar(255) unique)")
	c.Assert(err, IsNil)
	ctx := ts.se.(context.Context)
	dom := sessionctx.GetDomain(ctx)
	tb, err := dom.InfoSchema().TableByName(model.NewCIStr("test"), model.NewCIStr("t"))
	c.Assert(err, IsNil)
	c.Assert(tb.TableID(), Greater, int64(0))
	c.Assert(tb.TableName().L, Equals, "t")
	c.Assert(tb.Meta(), NotNil)
	c.Assert(tb.Indices(), NotNil)
	c.Assert(tb.FirstKey(), Not(Equals), "")
	c.Assert(tb.IndexPrefix(), Not(Equals), "")
	c.Assert(tb.KeyPrefix(), Not(Equals), "")
	c.Assert(tb.FindIndexByColName("b"), NotNil)

	autoid, err := tb.AllocAutoID()
	c.Assert(err, IsNil)
	c.Assert(autoid, Greater, int64(0))

	rid, err := tb.AddRecord(ctx, []interface{}{1, "abc"})
	c.Assert(err, IsNil)
	c.Assert(rid, Greater, int64(0))
	row, err := tb.Row(ctx, rid)
	c.Assert(err, IsNil)
	c.Assert(len(row), Equals, 2)
	c.Assert(row[0].(int64), Equals, int64(1))

	_, err = tb.AddRecord(ctx, []interface{}{1, "aba"})
	c.Assert(err, NotNil)
	_, err = tb.AddRecord(ctx, []interface{}{2, "abc"})
	c.Assert(err, NotNil)

	c.Assert(tb.UpdateRecord(ctx, rid, []interface{}{1, "abc"}, []interface{}{1, "cba"}, []bool{false, true}), IsNil)

	tb.IterRecords(ctx, tb.FirstKey(), tb.Cols(), func(h int64, data []interface{}, cols []*column.Col) (bool, error) {
		return true, nil
	})

	c.Assert(tb.RemoveRowAllIndex(ctx, rid, []interface{}{1, "cba"}), IsNil)

	c.Assert(tb.RemoveRow(ctx, rid), IsNil)
	// Make sure there is index data in the storage.
	prefix := tb.IndexPrefix()
	cnt, err := countEntriesWithPrefix(ctx, prefix)
	c.Assert(err, IsNil)
	//c.Assert(cnt, Greater, 0)  // it is not a correct assert, because after fix issue 463, there is no index in the table anymore
	c.Assert(cnt, Equals, 0)
	c.Assert(tb.Truncate(ctx), IsNil)
	// Make sure index data is also removed after tb.Truncate().
	cnt, err = countEntriesWithPrefix(ctx, prefix)
	c.Assert(err, IsNil)
	c.Assert(cnt, Equals, 0)
	_, err = ts.se.Execute("drop table test.t")
	c.Assert(err, IsNil)
}
Esempio n. 29
0
func (s *testDBSuite) testGetTable(c *C, name string) table.Table {
	ctx := s.s.(context.Context)
	domain := sessionctx.GetDomain(ctx)
	// Make sure the table schema is the new schema.
	err := domain.MustReload()
	c.Assert(err, IsNil)
	tbl, err := domain.InfoSchema().TableByName(model.NewCIStr(s.schemaName), model.NewCIStr(name))
	c.Assert(err, IsNil)
	return tbl
}
Esempio n. 30
0
func composeUserTableRset() *rsets.JoinRset {
	return &rsets.JoinRset{
		Left: &rsets.TableSource{
			Source: table.Ident{
				Name:   model.NewCIStr(mysql.UserTable),
				Schema: model.NewCIStr(mysql.SystemDB),
			},
		},
	}
}