diff options
author | Ting-Wei Lan <tingwei.lan@cobinhood.com> | 2019-03-27 17:09:24 +0800 |
---|---|---|
committer | Jhih-Ming Huang <jm.huang@cobinhood.com> | 2019-05-06 10:44:04 +0800 |
commit | 8c4e09207c74294364eefa14159338908bc65f67 (patch) | |
tree | 80b0c08f934b8d0d07aff8d4f42c34c5a0098dbb /core/vm/sqlvm/ast/types_test.go | |
parent | 599f65cc61f985c71d4fa1227fba55287bcb1d98 (diff) | |
download | dexon-8c4e09207c74294364eefa14159338908bc65f67.tar dexon-8c4e09207c74294364eefa14159338908bc65f67.tar.gz dexon-8c4e09207c74294364eefa14159338908bc65f67.tar.bz2 dexon-8c4e09207c74294364eefa14159338908bc65f67.tar.lz dexon-8c4e09207c74294364eefa14159338908bc65f67.tar.xz dexon-8c4e09207c74294364eefa14159338908bc65f67.tar.zst dexon-8c4e09207c74294364eefa14159338908bc65f67.zip |
core: vm: sqlvm: support SQL three-valued logic on AST
We make the zero value invalid by design. Users must be aware of the
difference between SQL boolean and Go boolean and initialize it
explicitly.
Diffstat (limited to 'core/vm/sqlvm/ast/types_test.go')
-rw-r--r-- | core/vm/sqlvm/ast/types_test.go | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/core/vm/sqlvm/ast/types_test.go b/core/vm/sqlvm/ast/types_test.go index 89a000251..d2051c4b5 100644 --- a/core/vm/sqlvm/ast/types_test.go +++ b/core/vm/sqlvm/ast/types_test.go @@ -1,6 +1,7 @@ package ast import ( + "database/sql" "testing" "github.com/shopspring/decimal" @@ -235,6 +236,79 @@ func (s *TypesTestSuite) TestDecimalToUint64() { } } +func (s *TypesTestSuite) TestBoolValueValidity() { + var v BoolValue + s.Require().False(v.Valid()) + s.Require().Panics(func() { _ = v.String() }) + s.Require().Panics(func() { _ = v.NullBool() }) + v = BoolValue(1) + s.Require().True(v.Valid()) + s.Require().Equal("TRUE", v.String()) + s.Require().Equal(sql.NullBool{Valid: true, Bool: true}, v.NullBool()) + v = BoolValue(4) + s.Require().False(v.Valid()) + s.Require().Panics(func() { _ = v.String() }) + s.Require().Panics(func() { _ = v.NullBool() }) +} + +func (s *TypesTestSuite) TestBoolValueOperations() { + and := func(v, v2 BoolValue) BoolValue { + if v == BoolValueFalse || v2 == BoolValueFalse { + return BoolValueFalse + } + if v == BoolValueUnknown || v2 == BoolValueUnknown { + return BoolValueUnknown + } + // v is true. + return v2 + } + or := func(v, v2 BoolValue) BoolValue { + if v == BoolValueTrue || v2 == BoolValueTrue { + return BoolValueTrue + } + if v == BoolValueUnknown || v2 == BoolValueUnknown { + return BoolValueUnknown + } + // v is false. + return v2 + } + not := func(v BoolValue) BoolValue { + switch v { + case BoolValueTrue: + return BoolValueFalse + case BoolValueFalse: + return BoolValueTrue + case BoolValueUnknown: + return BoolValueUnknown + } + // v is invalid. + return v + } + values := [3]BoolValue{BoolValueTrue, BoolValueFalse, BoolValueUnknown} + for _, v := range values { + for _, v2 := range values { + expected := and(v, v2) + actual := v.And(v2) + s.Require().Equalf(expected, actual, + "%v AND %v = %v, but %v is returned", v, v2, expected, actual) + } + } + for _, v := range values { + for _, v2 := range values { + expected := or(v, v2) + actual := v.Or(v2) + s.Require().Equalf(expected, actual, + "%v OR %v = %v, but %v is returned", v, v2, expected, actual) + } + } + for _, v := range values { + expected := not(v) + actual := v.Not() + s.Require().Equalf(expected, actual, + "NOT %v = %v, but %v is returned", v, expected, actual) + } +} + func TestTypes(t *testing.T) { suite.Run(t, new(TypesTestSuite)) } |