Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

*: fix union result when mix signed/unsigned columns #7112

Merged
merged 16 commits into from
Jul 30, 2018
28 changes: 28 additions & 0 deletions executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2919,3 +2919,31 @@ func (s *testSuite) TestIndexJoinTableDualPanic(c *C) {
tk.MustQuery("select a.* from a inner join (select 1 as k1,'k2-1' as k2) as k on a.f1=k.k1;").
Check(testkit.Rows("1 a"))
}

func (s *testSuite) TestUnionAutoSignedCast(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t1,t2")
tk.MustExec("create table t1 (id int, i int, b bigint, d double, dd decimal)")
tk.MustExec("create table t2 (id int, i int unsigned, b bigint unsigned, d double unsigned, dd decimal unsigned)")
tk.MustExec("insert into t1 values(1, -1, -1, -1.1, -1)")
tk.MustExec("insert into t2 values(2, 1, 1, 1.1, 1)")
tk.MustQuery("select * from t1 union select * from t2 order by id").
Check(testkit.Rows("1 -1 -1 -1.1 -1", "2 1 1 1.1 1"))
tk.MustQuery("select id, i, b, d, dd from t2 union select id, i, b, d, dd from t1 order by id").
Check(testkit.Rows("1 0 0 0 -1", "2 1 1 1.1 1"))
tk.MustQuery("select id, i from t2 union select id, cast(i as unsigned int) from t1 order by id").
Check(testkit.Rows("1 18446744073709551615", "2 1"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it the same as MySQL's?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes~ mysql, cast will got int.Max

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about unsigned double union int? we need a case to cover union different types.

Copy link
Contributor Author

@lysu lysu Jul 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

emma, added and find a bug....o.o~

PTAL~thx

tk.MustQuery("select dd from t2 union all select dd from t2").
Check(testkit.Rows("1", "1"))

tk.MustExec("drop table if exists t3,t4")
tk.MustExec("create table t3 (id int, v int)")
tk.MustExec("create table t4 (id int, v double unsigned)")
tk.MustExec("insert into t3 values (1, -1)")
tk.MustExec("insert into t4 values (2, 1)")
tk.MustQuery("select id, v from t3 union select id, v from t4 order by id").
Check(testkit.Rows("1 -1", "2 1"))
tk.MustQuery("select id, v from t4 union select id, v from t3 order by id").
Check(testkit.Rows("1 0", "2 1"))
}
20 changes: 20 additions & 0 deletions expression/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,26 @@ func (b *baseBuiltinFunc) Clone() builtinFunc {
panic("you should not call this method.")
}

// baseBuiltinCastFunc will be contained in every struct that implement cast builtinFunc.
type baseBuiltinCastFunc struct {
baseBuiltinFunc

// inUnion indicates whether cast is in union context.
inUnion bool
}

func (b *baseBuiltinCastFunc) cloneFrom(from *baseBuiltinCastFunc) {
b.baseBuiltinFunc.cloneFrom(&from.baseBuiltinFunc)
b.inUnion = from.inUnion
}

func newBaseBuiltinCastFunc(builtinFunc baseBuiltinFunc, inUnion bool) baseBuiltinCastFunc {
return baseBuiltinCastFunc{
baseBuiltinFunc: builtinFunc,
inUnion: inUnion,
}
}

// builtinFunc stands for a particular function signature.
type builtinFunc interface {
// evalInt evaluates int result of builtinFunc by given row.
Expand Down
Loading