Esempio n. 1
0
// GetColDefaultValue gets default value of the column.
func GetColDefaultValue(ctx context.Context, col *model.ColumnInfo) (types.Datum, bool, error) {
	// Check no default value flag.
	if mysql.HasNoDefaultValueFlag(col.Flag) && col.Tp != mysql.TypeEnum {
		return types.Datum{}, false, errors.Errorf("Field '%s' doesn't have a default value", col.Name)
	}

	// Check and get timestamp/datetime default value.
	if col.Tp == mysql.TypeTimestamp || col.Tp == mysql.TypeDatetime {
		if col.DefaultValue == nil {
			return types.Datum{}, true, nil
		}

		value, err := evaluator.GetTimeValue(ctx, col.DefaultValue, col.Tp, col.Decimal)
		if err != nil {
			return types.Datum{}, true, errors.Errorf("Field '%s' get default value fail - %s", col.Name, errors.Trace(err))
		}
		return types.NewDatum(value), true, nil
	} else if col.Tp == mysql.TypeEnum {
		// For enum type, if no default value and not null is set,
		// the default value is the first element of the enum list
		if col.DefaultValue == nil && mysql.HasNotNullFlag(col.Flag) {
			return types.NewDatum(col.FieldType.Elems[0]), true, nil
		}
	}

	return types.NewDatum(col.DefaultValue), true, nil
}
Esempio n. 2
0
func flatten(data types.Datum) (types.Datum, error) {
	switch data.Kind() {
	case types.KindMysqlTime:
		// for mysql datetime, timestamp and date type
		b, err := data.GetMysqlTime().Marshal()
		if err != nil {
			return types.NewDatum(nil), errors.Trace(err)
		}
		return types.NewDatum(b), nil
	case types.KindMysqlDuration:
		// for mysql time type
		data.SetInt64(int64(data.GetMysqlDuration().Duration))
		return data, nil
	case types.KindMysqlDecimal:
		data.SetString(data.GetMysqlDecimal().String())
		return data, nil
	case types.KindMysqlEnum:
		data.SetUint64(data.GetMysqlEnum().Value)
		return data, nil
	case types.KindMysqlSet:
		data.SetUint64(data.GetMysqlSet().Value)
		return data, nil
	case types.KindMysqlBit:
		data.SetUint64(data.GetMysqlBit().Value)
		return data, nil
	case types.KindMysqlHex:
		data.SetInt64(data.GetMysqlHex().Value)
		return data, nil
	default:
		return data, nil
	}
}
Esempio n. 3
0
func getRowCountByTableRange(sc *variable.StatementContext, statsTbl *statistics.Table, ranges []TableRange, offset int) (uint64, error) {
	var rowCount uint64
	for _, rg := range ranges {
		var cnt int64
		var err error
		if rg.LowVal == math.MinInt64 && rg.HighVal == math.MaxInt64 {
			cnt = statsTbl.Count
		} else if rg.LowVal == math.MinInt64 {
			cnt, err = statsTbl.Columns[offset].LessRowCount(sc, types.NewDatum(rg.HighVal))
		} else if rg.HighVal == math.MaxInt64 {
			cnt, err = statsTbl.Columns[offset].GreaterRowCount(sc, types.NewDatum(rg.LowVal))
		} else {
			if rg.LowVal == rg.HighVal {
				cnt, err = statsTbl.Columns[offset].EqualRowCount(sc, types.NewDatum(rg.LowVal))
			} else {
				cnt, err = statsTbl.Columns[offset].BetweenRowCount(sc, types.NewDatum(rg.LowVal), types.NewDatum(rg.HighVal))
			}
		}
		if err != nil {
			return 0, errors.Trace(err)
		}
		rowCount += uint64(cnt)
	}
	if rowCount > uint64(statsTbl.Count) {
		rowCount = uint64(statsTbl.Count)
	}
	return rowCount, nil
}
Esempio n. 4
0
func (e *Evaluator) evalIn(expr *tipb.Expr) (types.Datum, error) {
	if len(expr.Children) != 2 {
		return types.Datum{}, ErrInvalid.Gen("IN need 2 operand, got %d", len(expr.Children))
	}
	target, err := e.Eval(expr.Children[0])
	if err != nil {
		return types.Datum{}, errors.Trace(err)
	}
	if target.IsNull() {
		return types.Datum{}, nil
	}
	valueListExpr := expr.Children[1]
	if valueListExpr.GetTp() != tipb.ExprType_ValueList {
		return types.Datum{}, ErrInvalid.Gen("the second children should be value list type")
	}
	decoded, err := e.decodeValueList(valueListExpr)
	if err != nil {
		return types.Datum{}, errors.Trace(err)
	}
	in, err := checkIn(target, decoded.values)
	if err != nil {
		return types.Datum{}, errors.Trace(err)
	}
	if in {
		return types.NewDatum(1), nil
	}
	if decoded.hasNull {
		return types.Datum{}, nil
	}
	return types.NewDatum(0), nil
}
Esempio n. 5
0
func (e *UpdateExec) fetchRows() error {
	for {
		row, err := e.SelectExec.Next()
		if err != nil {
			return errors.Trace(err)
		}
		if row == nil {
			return nil
		}
		data := make([]types.Datum, len(e.SelectExec.Fields()))
		newData := make([]types.Datum, len(e.SelectExec.Fields()))
		for i, f := range e.SelectExec.Fields() {
			data[i] = types.NewDatum(f.Expr.GetValue())
			newData[i] = data[i]
			if e.OrderedList[i] != nil {
				val, err := evaluator.Eval(e.ctx, e.OrderedList[i].Expr)
				if err != nil {
					return errors.Trace(err)
				}
				newData[i] = types.NewDatum(val)
			}
		}
		row.Data = data
		e.rows = append(e.rows, row)
		e.newRowsData = append(e.newRowsData, newData)
	}
}
Esempio n. 6
0
func (s *testEvaluatorSuite) TestCast(c *C) {
	defer testleak.AfterTest(c)()
	f := types.NewFieldType(mysql.TypeLonglong)

	expr := &ast.FuncCastExpr{
		Expr: ast.NewValueExpr(1),
		Tp:   f,
	}
	ast.SetFlag(expr)
	v, err := Eval(s.ctx, expr)
	c.Assert(err, IsNil)
	c.Assert(v, testutil.DatumEquals, types.NewDatum(int64(1)))

	f.Flag |= mysql.UnsignedFlag
	v, err = Eval(s.ctx, expr)
	c.Assert(err, IsNil)
	c.Assert(v, testutil.DatumEquals, types.NewDatum(uint64(1)))

	f.Tp = mysql.TypeString
	f.Charset = charset.CharsetBin
	v, err = Eval(s.ctx, expr)
	c.Assert(err, IsNil)
	c.Assert(v, testutil.DatumEquals, types.NewDatum([]byte("1")))

	f.Tp = mysql.TypeString
	f.Charset = "utf8"
	v, err = Eval(s.ctx, expr)
	c.Assert(err, IsNil)
	c.Assert(v, testutil.DatumEquals, types.NewDatum("1"))

	expr.Expr = ast.NewValueExpr(nil)
	v, err = Eval(s.ctx, expr)
	c.Assert(err, IsNil)
	c.Assert(v.Kind(), Equals, types.KindNull)
}
Esempio n. 7
0
// getHashKey encodes a requiredProperty to a unique hash code.
func (p *requiredProperty) getHashKey() ([]byte, error) {
	datums := make([]types.Datum, 0, len(p.props)*3+1)
	datums = append(datums, types.NewDatum(p.sortKeyLen))
	for _, c := range p.props {
		datums = append(datums, types.NewDatum(c.desc), types.NewDatum(c.col.FromID), types.NewDatum(c.col.Index))
	}
	bytes, err := codec.EncodeValue(nil, datums...)
	return bytes, errors.Trace(err)
}
Esempio n. 8
0
// Next implements the Executor Next interface.
func (e *ApplyExec) Next() (*Row, error) {
	srcRow, err := e.Src.Next()
	if err != nil {
		return nil, errors.Trace(err)
	}
	if srcRow == nil {
		return nil, nil
	}
	for {
		for _, col := range e.outerSchema {
			idx := col.Index
			*col.Data = srcRow.Data[idx]
		}
		innerRow, err := e.innerExec.Next()
		if err != nil {
			return nil, errors.Trace(err)
		}
		trimLen := len(srcRow.Data)
		if innerRow != nil {
			srcRow.Data = append(srcRow.Data, innerRow.Data...)
		}
		if e.checker == nil {
			e.innerExec.Close()
			return srcRow, nil
		}
		if innerRow == nil {
			// When inner exec finishes, we need to append a result column to true, false or NULL.
			var result types.Datum
			if e.checker.all {
				result = types.NewDatum(true)
			} else {
				// If 'any' meets a null value, the result will be null.
				if e.checker.dataHasNull {
					result = types.NewDatum(nil)
				} else {
					result = types.NewDatum(false)
				}
			}
			srcRow.Data = append(srcRow.Data, result)
			e.checker.reset()
			e.innerExec.Close()
			return srcRow, nil
		}
		finished, data, err := e.checker.check(srcRow.Data)
		if err != nil {
			return nil, errors.Trace(err)
		}
		srcRow.Data = srcRow.Data[:trimLen]
		if finished {
			e.checker.reset()
			e.innerExec.Close()
			srcRow.Data = append(srcRow.Data, data)
			return srcRow, nil
		}
	}
}
Esempio n. 9
0
func (s *testEvaluatorSuite) TestTrim(c *C) {
	defer testleak.AfterTest(c)()
	tbl := []struct {
		str    interface{}
		remstr interface{}
		dir    ast.TrimDirectionType
		result interface{}
	}{
		{"  bar   ", nil, ast.TrimBothDefault, "bar"},
		{"xxxbarxxx", "x", ast.TrimLeading, "barxxx"},
		{"xxxbarxxx", "x", ast.TrimBoth, "bar"},
		{"barxxyz", "xyz", ast.TrimTrailing, "barx"},
		{nil, "xyz", ast.TrimBoth, nil},
		{1, 2, ast.TrimBoth, "1"},
		{"  \t\rbar\n   ", nil, ast.TrimBothDefault, "bar"},
	}
	ctx := mock.NewContext()
	for _, v := range tbl {
		f := &ast.FuncCallExpr{
			FnName: model.NewCIStr("TRIM"),
			Args: []ast.ExprNode{
				ast.NewValueExpr(v.str),
				ast.NewValueExpr(v.remstr),
				ast.NewValueExpr(v.dir),
			},
		}
		r, err := Eval(ctx, f)
		c.Assert(err, IsNil)
		c.Assert(r, testutil.DatumEquals, types.NewDatum(v.result))
	}

	for _, v := range []struct {
		str, result interface{}
		fn          string
	}{
		{"  ", "", "LTRIM"},
		{"  ", "", "RTRIM"},
		{"foo0", "foo0", "LTRIM"},
		{"bar0", "bar0", "RTRIM"},
		{"  foo1", "foo1", "LTRIM"},
		{"bar1  ", "bar1", "RTRIM"},
		{spaceChars + "foo2  ", "foo2  ", "LTRIM"},
		{"  bar2" + spaceChars, "  bar2", "RTRIM"},
		{nil, nil, "LTRIM"},
		{nil, nil, "RTRIM"},
	} {
		f := &ast.FuncCallExpr{
			FnName: model.NewCIStr(v.fn),
			Args:   []ast.ExprNode{ast.NewValueExpr(v.str)},
		}
		r, err := Eval(ctx, f)
		c.Assert(err, IsNil)
		c.Assert(r, testutil.DatumEquals, types.NewDatum(v.result))
	}
}
Esempio n. 10
0
func (s *testEvaluatorSuite) TestCoalesce(c *C) {
	args := types.MakeDatums(1, nil)
	v, err := builtinCoalesce(args, nil)
	c.Assert(err, IsNil)
	c.Assert(v, DatumEquals, types.NewDatum(1))

	args = types.MakeDatums(nil, nil)
	v, err = builtinCoalesce(args, nil)
	c.Assert(err, IsNil)
	c.Assert(v, DatumEquals, types.NewDatum(nil))
}
Esempio n. 11
0
func (s *testEvaluatorSuite) TestCoalesce(c *C) {
	defer testleak.AfterTest(c)()
	args := types.MakeDatums(1, nil)
	v, err := builtinCoalesce(args, nil)
	c.Assert(err, IsNil)
	c.Assert(v, testutil.DatumEquals, types.NewDatum(1))

	args = types.MakeDatums(nil, nil)
	v, err = builtinCoalesce(args, nil)
	c.Assert(err, IsNil)
	c.Assert(v, testutil.DatumEquals, types.NewDatum(nil))
}
Esempio n. 12
0
func inExpr(target interface{}, list ...interface{}) *tipb.Expr {
	targetDatum := types.NewDatum(target)
	var listDatums []types.Datum
	for _, v := range list {
		listDatums = append(listDatums, types.NewDatum(v))
	}
	types.SortDatums(listDatums)
	targetExpr := datumExpr(targetDatum)
	val, _ := codec.EncodeValue(nil, listDatums...)
	listExpr := &tipb.Expr{Tp: tipb.ExprType_ValueList, Val: val}
	return &tipb.Expr{Tp: tipb.ExprType_In, Children: []*tipb.Expr{targetExpr, listExpr}}
}
Esempio n. 13
0
// Next implements the Executor Next interface.
func (e *HashSemiJoinExec) Next() (*Row, error) {
	if !e.prepared {
		if err := e.prepare(); err != nil {
			return nil, errors.Trace(err)
		}
	}

	for {
		bigRow, err := e.bigExec.Next()
		if err != nil {
			return nil, errors.Trace(err)
		}
		if bigRow == nil {
			e.bigExec.Close()
			return nil, nil
		}

		matched := true
		if e.bigFilter != nil {
			matched, err = expression.EvalBool(e.bigFilter, bigRow.Data, e.ctx)
			if err != nil {
				return nil, errors.Trace(err)
			}
		}
		isNull := false
		if matched {
			matched, isNull, err = e.rowIsMatched(bigRow)
			if err != nil {
				return nil, errors.Trace(err)
			}
		}
		if !matched && e.smallTableHasNull {
			isNull = true
		}
		if e.anti && !isNull {
			matched = !matched
		}
		// For the auxMode subquery, we return the row with a Datum indicating if it's a match,
		// For the non-auxMode subquery, we return the matching row only.
		if e.auxMode {
			if isNull {
				bigRow.Data = append(bigRow.Data, types.NewDatum(nil))
			} else {
				bigRow.Data = append(bigRow.Data, types.NewDatum(matched))
			}
			return bigRow, nil
		}
		if matched {
			return bigRow, nil
		}
	}
}
Esempio n. 14
0
// Next implements Executor Next interface.
func (e *ApplyExec) Next() (*Row, error) {
	srcRow, err := e.Src.Next()
	if err != nil {
		return nil, errors.Trace(err)
	}
	if srcRow == nil {
		return nil, nil
	}
	for {
		for _, col := range e.outerSchema {
			idx := col.Index
			col.SetValue(&srcRow.Data[idx])
		}
		innerRow, err := e.innerExec.Next()
		if err != nil {
			return nil, errors.Trace(err)
		}
		trimLen := len(srcRow.Data)
		if innerRow != nil {
			srcRow.Data = append(srcRow.Data, innerRow.Data...)
		}
		if e.checker == nil {
			e.innerExec.Close()
			return srcRow, nil
		}
		if innerRow == nil {
			var d types.Datum
			// If we can't determine the result until the last row comes, the all must be true and any must not be true.
			// If the any have met a null, the result will be null.
			if e.checker.dataHasNull && !e.checker.all {
				d = types.NewDatum(nil)
			} else {
				d = types.NewDatum(e.checker.all)
			}
			srcRow.Data = append(srcRow.Data, d)
			e.checker.dataHasNull = false
			e.innerExec.Close()
			return srcRow, nil
		}
		finished, data, err := e.checker.Check(srcRow.Data)
		if err != nil {
			return nil, errors.Trace(err)
		}
		srcRow.Data = srcRow.Data[:trimLen]
		if finished {
			e.checker.dataHasNull = false
			e.innerExec.Close()
			srcRow.Data = append(srcRow.Data, data)
			return srcRow, nil
		}
	}
}
Esempio n. 15
0
// Next implements Executor Next interface.
func (e *HashSemiJoinExec) Next() (*Row, error) {
	if !e.prepared {
		if err := e.prepare(); err != nil {
			return nil, errors.Trace(err)
		}
	}

	for {
		bigRow, err := e.bigExec.Next()
		if err != nil {
			return nil, errors.Trace(err)
		}
		if bigRow == nil {
			e.bigExec.Close()
			return nil, nil
		}

		matched := true
		if e.bigFilter != nil {
			matched, err = expression.EvalBool(e.bigFilter, bigRow.Data, e.ctx)
			if err != nil {
				return nil, errors.Trace(err)
			}
		}
		isNull := false
		if matched {
			matched, isNull, err = e.rowIsMatched(bigRow)
			if err != nil {
				return nil, errors.Trace(err)
			}
		}
		if !matched && e.smallTableHasNull {
			isNull = true
		}
		if e.anti && !isNull {
			matched = !matched
		}
		if e.withAux {
			if isNull {
				bigRow.Data = append(bigRow.Data, types.NewDatum(nil))
			} else {
				bigRow.Data = append(bigRow.Data, types.NewDatum(matched))
			}
			return bigRow, nil
		} else if matched {
			return bigRow, nil
		}
	}
}
Esempio n. 16
0
func (r *rangeBuilder) buildTableRanges(rangePoints []rangePoint) []TableRange {
	tableRanges := make([]TableRange, 0, len(rangePoints)/2)
	for i := 0; i < len(rangePoints); i += 2 {
		startPoint := rangePoints[i]
		if startPoint.value.IsNull() || startPoint.value.Kind() == types.KindMinNotNull {
			startPoint.value.SetInt64(math.MinInt64)
		}
		startInt, err := startPoint.value.ToInt64()
		if err != nil {
			r.err = errors.Trace(err)
			return tableRanges
		}
		startDatum := types.NewDatum(startInt)
		cmp, err := startDatum.CompareDatum(startPoint.value)
		if err != nil {
			r.err = errors.Trace(err)
			return tableRanges
		}
		if cmp < 0 || (cmp == 0 && startPoint.excl) {
			startInt++
		}
		endPoint := rangePoints[i+1]
		if endPoint.value.IsNull() {
			endPoint.value.SetInt64(math.MinInt64)
		} else if endPoint.value.Kind() == types.KindMaxValue {
			endPoint.value.SetInt64(math.MaxInt64)
		}
		endInt, err := endPoint.value.ToInt64()
		if err != nil {
			r.err = errors.Trace(err)
			return tableRanges
		}
		endDatum := types.NewDatum(endInt)
		cmp, err = endDatum.CompareDatum(endPoint.value)
		if err != nil {
			r.err = errors.Trace(err)
			return tableRanges
		}
		if cmp > 0 || (cmp == 0 && endPoint.excl) {
			endInt--
		}
		if startInt > endInt {
			continue
		}
		tableRanges = append(tableRanges, TableRange{LowVal: startInt, HighVal: endInt})
	}
	return tableRanges
}
Esempio n. 17
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. 18
0
func (s *testEvaluatorSuite) TestBinopBitop(c *C) {
	defer testleak.AfterTest(c)()
	ctx := mock.NewContext()
	tbl := []struct {
		lhs interface{}
		op  opcode.Op
		rhs interface{}
		ret interface{}
	}{
		{1, opcode.And, 1, 1},
		{1, opcode.Or, 1, 1},
		{1, opcode.Xor, 1, 0},
		{1, opcode.LeftShift, 1, 2},
		{2, opcode.RightShift, 1, 1},
		{nil, opcode.And, 1, nil},
		{1, opcode.And, nil, nil},
		{nil, opcode.Or, 1, nil},
		{nil, opcode.Xor, 1, nil},
		{nil, opcode.LeftShift, 1, nil},
		{nil, opcode.RightShift, 1, nil},
	}

	for _, t := range tbl {
		expr := &ast.BinaryOperationExpr{Op: t.op, L: ast.NewValueExpr(t.lhs), R: ast.NewValueExpr(t.rhs)}
		v, err := Eval(ctx, expr)
		c.Assert(err, IsNil)

		switch x := t.ret.(type) {
		case nil:
			c.Assert(v.Kind(), Equals, types.KindNull)
		case int:
			c.Assert(v, testutil.DatumEquals, types.NewDatum(uint64(x)))
		}
	}
}
Esempio n. 19
0
func genValues(handle int64, tbl *simpleTableInfo) []types.Datum {
	values := make([]types.Datum, 0, len(tbl.cTypes))
	for _, tp := range tbl.cTypes {
		switch tp {
		case mysql.TypeLong:
			values = append(values, types.NewDatum(handle))
		case mysql.TypeVarchar:
			values = append(values, types.NewDatum(fmt.Sprintf("varchar:%d", handle)))
		case mysql.TypeDouble:
			values = append(values, types.NewDatum(float64(handle)/10))
		default:
			values = append(values, types.Datum{})
		}
	}
	return values
}
Esempio n. 20
0
func setRow(txn kv.Transaction, handle int64, tbl *simpleTableInfo, gen genValueFunc) error {
	rowKey := tablecodec.EncodeRowKey(tbl.tID, codec.EncodeInt(nil, handle))
	columnValues := gen(handle, tbl)
	value, err := tablecodec.EncodeRow(columnValues, tbl.cIDs)
	if err != nil {
		return errors.Trace(err)
	}
	err = txn.Set(rowKey, value)
	if err != nil {
		return errors.Trace(err)
	}
	for i, idxCol := range tbl.indices {
		idxVal := columnValues[idxCol]
		encoded, err := codec.EncodeKey(nil, idxVal, types.NewDatum(handle))
		if err != nil {
			return errors.Trace(err)
		}
		idxKey := tablecodec.EncodeIndexSeekKey(tbl.tID, tbl.iIDs[i], encoded)
		err = txn.Set(idxKey, []byte{0})
		if err != nil {
			return errors.Trace(err)
		}
	}
	return nil
}
Esempio n. 21
0
func (s *testDecimalSuite) TestDecimalCodec(c *C) {
	defer testleak.AfterTest(c)()
	inputs := []struct {
		Input float64
	}{
		{float64(123400)},
		{float64(1234)},
		{float64(12.34)},
		{float64(0.1234)},
		{float64(0.01234)},
		{float64(-0.1234)},
		{float64(-0.01234)},
		{float64(12.3400)},
		{float64(-12.34)},
		{float64(0.00000)},
		{float64(0)},
		{float64(-0.0)},
		{float64(-0.000)},
	}

	for _, input := range inputs {
		v := types.NewDecFromFloatForTest(input.Input)
		b := EncodeDecimal([]byte{}, types.NewDatum(v))
		_, d, err := DecodeDecimal(b)
		c.Assert(err, IsNil)
		c.Assert(v.Compare(d.GetMysqlDecimal()), Equals, 0)
	}
}
Esempio n. 22
0
// tryToPushDownAgg tries to push down an aggregate function into a join path. If all aggFuncs are first row, we won't
// process it temporarily. If not, We will add additional group by columns and first row functions. We make a new aggregation
// operator.
func (a *aggPushDownSolver) tryToPushDownAgg(aggFuncs []expression.AggregationFunction, gbyCols []*expression.Column, join *Join, childIdx int) LogicalPlan {
	child := join.GetChildByIndex(childIdx).(LogicalPlan)
	if a.allFirstRow(aggFuncs) {
		return child
	}
	agg := a.makeNewAgg(aggFuncs, gbyCols)
	child.SetParents(agg)
	agg.SetChildren(child)
	agg.correlated = agg.correlated || child.IsCorrelated()
	// If agg has no group-by item, it will return a default value, which may cause some bugs.
	// So here we add a group-by item forcely.
	if len(agg.GroupByItems) == 0 {
		agg.GroupByItems = []expression.Expression{&expression.Constant{
			Value:   types.NewDatum(0),
			RetType: types.NewFieldType(mysql.TypeLong)}}
	}
	if (childIdx == 0 && join.JoinType == RightOuterJoin) || (childIdx == 1 && join.JoinType == LeftOuterJoin) {
		var existsDefaultValues bool
		join.DefaultValues, existsDefaultValues = a.getDefaultValues(agg)
		if !existsDefaultValues {
			return child
		}
	}
	return agg
}
Esempio n. 23
0
func (s *testEvaluatorSuite) TestRegexp(c *C) {
	defer testleak.AfterTest(c)()
	tbl := []struct {
		pattern string
		input   string
		match   int64
	}{
		{"^$", "a", 0},
		{"a", "a", 1},
		{"a", "b", 0},
		{"aA", "aA", 1},
		{".", "a", 1},
		{"^.$", "ab", 0},
		{"..", "b", 0},
		{".ab", "aab", 1},
		{".*", "abcd", 1},
	}
	ctx := mock.NewContext()
	for _, v := range tbl {
		pattern := &ast.PatternRegexpExpr{
			Pattern: ast.NewValueExpr(v.pattern),
			Expr:    ast.NewValueExpr(v.input),
		}
		match, err := Eval(ctx, pattern)
		c.Assert(err, IsNil)
		c.Assert(match, testutil.DatumEquals, types.NewDatum(v.match), Commentf("%v", v))
	}
}
Esempio n. 24
0
// Next implements Executor Next interface.
func (e *SelectFieldsExec) Next() (*Row, error) {
	var rowKeys []*RowKeyEntry
	if e.Src != nil {
		srcRow, err := e.Src.Next()
		if err != nil {
			return nil, errors.Trace(err)
		}
		if srcRow == nil {
			return nil, nil
		}
		rowKeys = srcRow.RowKeys
	} else {
		// If Src is nil, only one row should be returned.
		if e.executed {
			return nil, nil
		}
	}
	e.executed = true
	row := &Row{
		RowKeys: rowKeys,
		Data:    make([]types.Datum, len(e.ResultFields)),
	}
	for i, field := range e.ResultFields {
		val, err := evaluator.Eval(e.ctx, field.Expr)
		if err != nil {
			return nil, errors.Trace(err)
		}
		row.Data[i] = types.NewDatum(val)
	}
	return row, nil
}
Esempio n. 25
0
func (s *testEvalSuite) TestEvalIfNull(c *C) {
	colID := int64(1)
	xevaluator := NewEvaluator(new(variable.StatementContext))
	xevaluator.Row[colID] = types.NewDatum(100)
	null, notNull, expr := types.Datum{}, types.NewStringDatum("left"), types.NewStringDatum("right")
	cases := []struct {
		expr   *tipb.Expr
		result types.Datum
	}{
		{
			expr: buildExpr(tipb.ExprType_IfNull,
				null, expr),
			result: expr,
		},
		{
			expr: buildExpr(tipb.ExprType_IfNull,
				notNull, expr),
			result: notNull,
		},
		{
			expr: buildExpr(tipb.ExprType_IfNull,
				notNull, null),
			result: notNull,
		},
	}
	for _, ca := range cases {
		result, err := xevaluator.Eval(ca.expr)
		c.Assert(err, IsNil)
		c.Assert(result.Kind(), Equals, ca.result.Kind())
		cmp, err := result.CompareDatum(xevaluator.sc, ca.result)
		c.Assert(err, IsNil)
		c.Assert(cmp, Equals, 0)
	}
}
Esempio n. 26
0
func (e *Evaluator) caseExpr(v *ast.CaseExpr) bool {
	tmp := types.NewDatum(boolToInt64(true))
	target := &tmp
	if v.Value != nil {
		target = v.Value.GetDatum()
	}
	if !target.IsNull() {
		for _, val := range v.WhenClauses {
			cmp, err := target.CompareDatum(*val.Expr.GetDatum())
			if err != nil {
				e.err = errors.Trace(err)
				return false
			}
			if cmp == 0 {
				v.SetDatum(*val.Result.GetDatum())
				return true
			}
		}
	}
	if v.ElseClause != nil {
		v.SetDatum(*v.ElseClause.GetDatum())
	} else {
		v.SetNull()
	}
	return true
}
Esempio n. 27
0
// Do the real work to evaluate subquery.
func (e *Evaluator) subqueryExec(v ast.SubqueryExec) bool {
	rowCount := 2
	if e.multipleRows {
		rowCount = -1
	} else if e.existRow {
		rowCount = 1
	}
	rows, err := v.EvalRows(e.ctx, rowCount)
	if err != nil {
		e.err = errors.Trace(err)
		return false
	}
	if e.multipleRows || e.existRow {
		v.GetDatum().SetInterface(types.MakeDatums(rows...))
		return true
	}
	switch len(rows) {
	case 0:
		v.GetDatum().SetNull()
	case 1:
		v.SetDatum(types.NewDatum(rows[0]))
	default:
		e.err = errors.New("Subquery returns more than 1 row")
		return false
	}
	return true
}
Esempio n. 28
0
File: index.go Progetto: anywhy/tidb
// GenIndexKey generates storage key for index values. Returned distinct indicates whether the
// indexed values should be distinct in storage (i.e. whether handle is encoded in the key).
func (c *index) GenIndexKey(indexedValues []types.Datum, h int64) (key []byte, distinct bool, err error) {
	if c.unique {
		// See: https://dev.mysql.com/doc/refman/5.7/en/create-index.html
		// A UNIQUE index creates a constraint such that all values in the index must be distinct.
		// An error occurs if you try to add a new row with a key value that matches an existing row.
		// For all engines, a UNIQUE index permits multiple NULL values for columns that can contain NULL.
		distinct = true
		for _, cv := range indexedValues {
			if cv.IsNull() {
				distinct = false
				break
			}
		}
	}

	key = append(key, c.prefix...)
	if distinct {
		key, err = codec.EncodeKey(key, indexedValues...)
	} else {
		key, err = codec.EncodeKey(key, append(indexedValues, types.NewDatum(h))...)
	}
	if err != nil {
		return nil, false, errors.Trace(err)
	}
	return
}
Esempio n. 29
0
func (s *testColumnSuite) checkPublicColumn(c *C, ctx context.Context, d *ddl, tblInfo *model.TableInfo, handle int64, col *column.Col, row []types.Datum, columnValue interface{}) {
	t := testGetTable(c, d, s.dbInfo.ID, tblInfo.ID)

	_, err := ctx.GetTxn(true)
	c.Assert(err, IsNil)

	i := int64(0)
	oldRow := append(row, types.NewDatum(columnValue))
	err = t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []types.Datum, cols []*column.Col) (bool, error) {
		c.Assert(data, DeepEquals, oldRow)
		i++
		return true, nil
	})
	c.Assert(err, IsNil)
	c.Assert(i, Equals, int64(1))

	// Test add a new row.
	_, err = ctx.GetTxn(true)
	c.Assert(err, IsNil)

	newRow := types.MakeDatums(int64(11), int64(22), int64(33), int64(44))
	handle, err = t.AddRecord(ctx, newRow)
	c.Assert(err, IsNil)

	_, err = ctx.GetTxn(true)
	c.Assert(err, IsNil)

	rows := [][]types.Datum{oldRow, newRow}

	i = int64(0)
	t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []types.Datum, cols []*column.Col) (bool, error) {
		c.Assert(data, DeepEquals, rows[i])
		i++
		return true, nil
	})
	c.Assert(i, Equals, int64(2))

	// Test remove a row.
	_, err = ctx.GetTxn(true)
	c.Assert(err, IsNil)

	err = t.RemoveRecord(ctx, handle, newRow)
	c.Assert(err, IsNil)

	_, err = ctx.GetTxn(true)
	c.Assert(err, IsNil)

	i = int64(0)
	t.IterRecords(ctx, t.FirstKey(), t.Cols(), func(h int64, data []types.Datum, cols []*column.Col) (bool, error) {
		c.Assert(data, DeepEquals, oldRow)
		i++
		return true, nil
	})
	c.Assert(i, Equals, int64(1))

	err = ctx.FinishTxn(false)
	c.Assert(err, IsNil)
	s.testGetColumn(c, t, col.Name.L, true)
}
Esempio n. 30
0
func composeEncodedData(size int) []byte {
	values := make([]types.Datum, 0, size)
	for i := 0; i < size; i++ {
		values = append(values, types.NewDatum(i))
	}
	bs, _ := EncodeValue(nil, values...)
	return bs
}