aboutsummaryrefslogtreecommitdiffstats
path: root/core/vm
diff options
context:
space:
mode:
authorTing-Wei Lan <tingwei.lan@cobinhood.com>2019-04-29 13:16:18 +0800
committerTing-Wei Lan <tingwei.lan@cobinhood.com>2019-05-14 11:04:15 +0800
commitbdefcc5466888049709b716d847b966f37811cec (patch)
tree51b4384db204b200933b513434abb208a60d6d22 /core/vm
parent9b0110a03491ed6fa99bcf7bb086834406e88d68 (diff)
downloaddexon-bdefcc5466888049709b716d847b966f37811cec.tar
dexon-bdefcc5466888049709b716d847b966f37811cec.tar.gz
dexon-bdefcc5466888049709b716d847b966f37811cec.tar.bz2
dexon-bdefcc5466888049709b716d847b966f37811cec.tar.lz
dexon-bdefcc5466888049709b716d847b966f37811cec.tar.xz
dexon-bdefcc5466888049709b716d847b966f37811cec.tar.zst
dexon-bdefcc5466888049709b716d847b966f37811cec.zip
code backup 23
Diffstat (limited to 'core/vm')
-rw-r--r--core/vm/sqlvm/ast/types.go138
-rw-r--r--core/vm/sqlvm/ast/types_test.go118
-rw-r--r--core/vm/sqlvm/checker/checker.go46
3 files changed, 298 insertions, 4 deletions
diff --git a/core/vm/sqlvm/ast/types.go b/core/vm/sqlvm/ast/types.go
index 826bb754b..caef6375d 100644
--- a/core/vm/sqlvm/ast/types.go
+++ b/core/vm/sqlvm/ast/types.go
@@ -147,6 +147,144 @@ func (v BoolValue) Not() BoolValue {
return boolValueNotTruthTable[v-1]
}
+var boolValueEqualTruthTable = [3][3]BoolValue{
+ BoolValueTrue - 1: {
+ BoolValueTrue - 1: BoolValueTrue,
+ BoolValueFalse - 1: BoolValueFalse,
+ BoolValueUnknown - 1: BoolValueUnknown,
+ },
+ BoolValueFalse - 1: {
+ BoolValueTrue - 1: BoolValueFalse,
+ BoolValueFalse - 1: BoolValueTrue,
+ BoolValueUnknown - 1: BoolValueUnknown,
+ },
+ BoolValueUnknown - 1: {
+ BoolValueTrue - 1: BoolValueUnknown,
+ BoolValueFalse - 1: BoolValueUnknown,
+ BoolValueUnknown - 1: BoolValueUnknown,
+ },
+}
+
+// Equal returns v = v2.
+func (v BoolValue) Equal(v2 BoolValue) BoolValue {
+ return boolValueEqualTruthTable[v-1][v2-1]
+}
+
+var boolValueNotEqualTruthTable = [3][3]BoolValue{
+ BoolValueTrue - 1: {
+ BoolValueTrue - 1: BoolValueFalse,
+ BoolValueFalse - 1: BoolValueTrue,
+ BoolValueUnknown - 1: BoolValueUnknown,
+ },
+ BoolValueFalse - 1: {
+ BoolValueTrue - 1: BoolValueTrue,
+ BoolValueFalse - 1: BoolValueFalse,
+ BoolValueUnknown - 1: BoolValueUnknown,
+ },
+ BoolValueUnknown - 1: {
+ BoolValueTrue - 1: BoolValueUnknown,
+ BoolValueFalse - 1: BoolValueUnknown,
+ BoolValueUnknown - 1: BoolValueUnknown,
+ },
+}
+
+// NotEqual returns v ≠ v2.
+func (v BoolValue) NotEqual(v2 BoolValue) BoolValue {
+ return boolValueNotEqualTruthTable[v-1][v2-1]
+}
+
+var boolValueGreaterTruthTable = [3][3]BoolValue{
+ BoolValueTrue - 1: {
+ BoolValueTrue - 1: BoolValueFalse,
+ BoolValueFalse - 1: BoolValueTrue,
+ BoolValueUnknown - 1: BoolValueUnknown,
+ },
+ BoolValueFalse - 1: {
+ BoolValueTrue - 1: BoolValueFalse,
+ BoolValueFalse - 1: BoolValueFalse,
+ BoolValueUnknown - 1: BoolValueUnknown,
+ },
+ BoolValueUnknown - 1: {
+ BoolValueTrue - 1: BoolValueUnknown,
+ BoolValueFalse - 1: BoolValueUnknown,
+ BoolValueUnknown - 1: BoolValueUnknown,
+ },
+}
+
+// Greater returns v > v2.
+func (v BoolValue) Greater(v2 BoolValue) BoolValue {
+ return boolValueGreaterTruthTable[v-1][v2-1]
+}
+
+var boolValueGreaterOrEqualTruthTable = [3][3]BoolValue{
+ BoolValueTrue - 1: {
+ BoolValueTrue - 1: BoolValueTrue,
+ BoolValueFalse - 1: BoolValueTrue,
+ BoolValueUnknown - 1: BoolValueUnknown,
+ },
+ BoolValueFalse - 1: {
+ BoolValueTrue - 1: BoolValueFalse,
+ BoolValueFalse - 1: BoolValueTrue,
+ BoolValueUnknown - 1: BoolValueUnknown,
+ },
+ BoolValueUnknown - 1: {
+ BoolValueTrue - 1: BoolValueUnknown,
+ BoolValueFalse - 1: BoolValueUnknown,
+ BoolValueUnknown - 1: BoolValueUnknown,
+ },
+}
+
+// GreaterOrEqual returns v ≥ v2.
+func (v BoolValue) GreaterOrEqual(v2 BoolValue) BoolValue {
+ return boolValueGreaterOrEqualTruthTable[v-1][v2-1]
+}
+
+var boolValueLessTruthTable = [3][3]BoolValue{
+ BoolValueTrue - 1: {
+ BoolValueTrue - 1: BoolValueFalse,
+ BoolValueFalse - 1: BoolValueFalse,
+ BoolValueUnknown - 1: BoolValueUnknown,
+ },
+ BoolValueFalse - 1: {
+ BoolValueTrue - 1: BoolValueTrue,
+ BoolValueFalse - 1: BoolValueFalse,
+ BoolValueUnknown - 1: BoolValueUnknown,
+ },
+ BoolValueUnknown - 1: {
+ BoolValueTrue - 1: BoolValueUnknown,
+ BoolValueFalse - 1: BoolValueUnknown,
+ BoolValueUnknown - 1: BoolValueUnknown,
+ },
+}
+
+// Less returns v < v2.
+func (v BoolValue) Less(v2 BoolValue) BoolValue {
+ return boolValueLessTruthTable[v-1][v2-1]
+}
+
+var boolValueLessOrEqualTruthTable = [3][3]BoolValue{
+ BoolValueTrue - 1: {
+ BoolValueTrue - 1: BoolValueTrue,
+ BoolValueFalse - 1: BoolValueFalse,
+ BoolValueUnknown - 1: BoolValueUnknown,
+ },
+ BoolValueFalse - 1: {
+ BoolValueTrue - 1: BoolValueTrue,
+ BoolValueFalse - 1: BoolValueTrue,
+ BoolValueUnknown - 1: BoolValueUnknown,
+ },
+ BoolValueUnknown - 1: {
+ BoolValueTrue - 1: BoolValueUnknown,
+ BoolValueFalse - 1: BoolValueUnknown,
+ BoolValueUnknown - 1: BoolValueUnknown,
+ },
+}
+
+// LessOrEqual returns v ≤ v2.
+func (v BoolValue) LessOrEqual(v2 BoolValue) BoolValue {
+ return boolValueLessOrEqualTruthTable[v-1][v2-1]
+}
+
// DecomposeDataType to major and minor part with given data type.
func DecomposeDataType(t DataType) (DataTypeMajor, DataTypeMinor) {
return DataTypeMajor(t >> 8), DataTypeMinor(t & 0xff)
diff --git a/core/vm/sqlvm/ast/types_test.go b/core/vm/sqlvm/ast/types_test.go
index d5f8e159d..71c543f0f 100644
--- a/core/vm/sqlvm/ast/types_test.go
+++ b/core/vm/sqlvm/ast/types_test.go
@@ -242,7 +242,7 @@ func (s *TypesTestSuite) TestBoolValueValidity() {
s.Require().Panics(func() { _ = v.NullBool() })
}
-func (s *TypesTestSuite) TestBoolValueOperations() {
+func (s *TypesTestSuite) TestBoolValueBooleanOperations() {
and := func(v, v2 BoolValue) BoolValue {
if v == BoolValueFalse || v2 == BoolValueFalse {
return BoolValueFalse
@@ -272,8 +272,7 @@ func (s *TypesTestSuite) TestBoolValueOperations() {
case BoolValueUnknown:
return BoolValueUnknown
}
- // v is invalid.
- return v
+ panic("unreachable")
}
values := [3]BoolValue{BoolValueTrue, BoolValueFalse, BoolValueUnknown}
for _, v := range values {
@@ -300,6 +299,119 @@ func (s *TypesTestSuite) TestBoolValueOperations() {
}
}
+func (s *TypesTestSuite) TestBoolValueEqualityOperations() {
+ equal := func(v, v2 BoolValue) BoolValue {
+ if v == BoolValueUnknown || v2 == BoolValueUnknown {
+ return BoolValueUnknown
+ }
+ if v == v2 {
+ return BoolValueTrue
+ }
+ return BoolValueFalse
+ }
+ notEqual := func(v, v2 BoolValue) BoolValue {
+ if v == BoolValueUnknown || v2 == BoolValueUnknown {
+ return BoolValueUnknown
+ }
+ if v == v2 {
+ return BoolValueFalse
+ }
+ return BoolValueTrue
+ }
+ values := [3]BoolValue{BoolValueTrue, BoolValueFalse, BoolValueUnknown}
+ for _, v := range values {
+ for _, v2 := range values {
+ expected := equal(v, v2)
+ actual := v.Equal(v2)
+ s.Require().Equal(expected, actual,
+ "%v = %v = %v, but %v is returned", v, v2, expected, actual)
+ }
+ }
+ for _, v := range values {
+ for _, v2 := range values {
+ expected := notEqual(v, v2)
+ actual := v.NotEqual(v2)
+ s.Require().Equal(expected, actual,
+ "%v ≠ %v = %v, but %v is returned", v, v2, expected, actual)
+ }
+ }
+}
+
+func (s *TypesTestSuite) TestBoolValueOrderingOperations() {
+ boolValueToInt := func(v BoolValue) int {
+ return [2]int{
+ BoolValueTrue - 1: 1,
+ BoolValueFalse - 1: 0,
+ }[v-1]
+ }
+ boolToBoolValue := func(v bool) BoolValue {
+ switch v {
+ case true:
+ return BoolValueTrue
+ case false:
+ return BoolValueFalse
+ }
+ panic("unreachable")
+ }
+ greater := func(v, v2 BoolValue) BoolValue {
+ if v == BoolValueUnknown || v2 == BoolValueUnknown {
+ return BoolValueUnknown
+ }
+ return boolToBoolValue(boolValueToInt(v) > boolValueToInt(v2))
+ }
+ greaterOrEqual := func(v, v2 BoolValue) BoolValue {
+ if v == BoolValueUnknown || v2 == BoolValueUnknown {
+ return BoolValueUnknown
+ }
+ return boolToBoolValue(boolValueToInt(v) >= boolValueToInt(v2))
+ }
+ less := func(v, v2 BoolValue) BoolValue {
+ if v == BoolValueUnknown || v2 == BoolValueUnknown {
+ return BoolValueUnknown
+ }
+ return boolToBoolValue(boolValueToInt(v) < boolValueToInt(v2))
+ }
+ lessOrEqual := func(v, v2 BoolValue) BoolValue {
+ if v == BoolValueUnknown || v2 == BoolValueUnknown {
+ return BoolValueUnknown
+ }
+ return boolToBoolValue(boolValueToInt(v) <= boolValueToInt(v2))
+ }
+ values := [3]BoolValue{BoolValueTrue, BoolValueFalse, BoolValueUnknown}
+ for _, v := range values {
+ for _, v2 := range values {
+ expected := greater(v, v2)
+ actual := v.Greater(v2)
+ s.Require().Equal(expected, actual,
+ "%v > %v = %v, but %v is returned", v, v2, expected, actual)
+ }
+ }
+ for _, v := range values {
+ for _, v2 := range values {
+ expected := greaterOrEqual(v, v2)
+ actual := v.GreaterOrEqual(v2)
+ s.Require().Equal(expected, actual,
+ "%v ≥ %v = %v, but %v is returned", v, v2, expected, actual)
+ }
+ }
+ for _, v := range values {
+ for _, v2 := range values {
+ expected := less(v, v2)
+ actual := v.Less(v2)
+ s.Require().Equal(expected, actual,
+ "%v < %v < %v, but %v is returned", v, v2, expected, actual)
+ }
+ }
+ for _, v := range values {
+ for _, v2 := range values {
+ expected := lessOrEqual(v, v2)
+ actual := v.LessOrEqual(v2)
+ s.Require().Equal(expected, actual,
+ "%v ≤ %v = %v, but %v is returned", v, v2, expected, actual)
+ }
+ }
+}
+
func TestTypes(t *testing.T) {
suite.Run(t, new(TypesTestSuite))
}
diff --git a/core/vm/sqlvm/checker/checker.go b/core/vm/sqlvm/checker/checker.go
index 792210bed..05e1cb10a 100644
--- a/core/vm/sqlvm/checker/checker.go
+++ b/core/vm/sqlvm/checker/checker.go
@@ -866,7 +866,7 @@ func checkExpr(n ast.ExprNode,
return checkOrOperator(n, s, o, c, el, tr, ta)
case *ast.GreaterOrEqualOperatorNode:
- return n
+ return checkGreaterOrEqualOperator(n, s, o, c, el, tr, ta)
case *ast.LessOrEqualOperatorNode:
return n
@@ -2019,3 +2019,47 @@ func checkOrOperator(n *ast.OrOperatorNode,
}
return r
}
+
+func validateOrderedType(dt ast.DataType, el *errors.ErrorList, n ast.ExprNode,
+ fn, op string) bool {
+
+ if !dt.Pending() {
+ major, _ := ast.DecomposeDataType(dt)
+ switch {
+ case major == ast.DataTypeMajorBool,
+ major == ast.DataTypeMajorAddress,
+ major == ast.DataTypeMajorInt,
+ major == ast.DataTypeMajorUint,
+ major == ast.DataTypeMajorFixedBytes,
+ major == ast.DataTypeMajorDynamicBytes,
+ major.IsFixedRange(),
+ major.IsFixedRange():
+ default:
+ elAppendTypeErrorOperatorDataType(el, n, fn, op, dt)
+ return false
+ }
+ }
+ return true
+}
+
+func checkGreaterOrEqualOperator(n *ast.GreaterOrEqualOperatorNode,
+ s schema.Schema, o CheckOptions, c *schemaCache, el *errors.ErrorList,
+ tr schema.TableRef, ta typeAction) ast.ExprNode {
+
+ fn := "CheckGreaterOrEqualOperator"
+ op := "binary operator >="
+
+ object := n.GetObject()
+ object = checkExpr(object, s, o, c, el, tr, ta)
+ if object == nil {
+ return nil
+ }
+ subject := n.GetSubject()
+ subject = checkExpr(subject, s, o, c, el, tr, ta)
+ if subject == nil {
+ return nil
+ }
+ n.SetObject(object)
+ n.SetSubject(subject)
+ r := ast.ExprNode(n)
+}