aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTing-Wei Lan <tingwei.lan@cobinhood.com>2019-02-27 17:03:08 +0800
committerJhih-Ming Huang <jm.huang@cobinhood.com>2019-03-26 17:48:22 +0800
commitd195e3803c103bc9943c68741c0036810a907dc6 (patch)
treed22a373e999ea705c04b7cf2bd0994cdc36a57f1
parentd8b728eeac88b0672df0d999a6c93c67ee2705a3 (diff)
downloaddexon-d195e3803c103bc9943c68741c0036810a907dc6.tar.gz
dexon-d195e3803c103bc9943c68741c0036810a907dc6.tar.zst
dexon-d195e3803c103bc9943c68741c0036810a907dc6.zip
core: vm: sqlvm: ast: use non-empty interfaces in DataType{En,De}code
In addition to changes required to move DataTypeEncode and DataTypeDecode to use TypeNode interface, this commit also unifies the meaning of 'Size' field in 'FixedBytesTypeNode'. It always counts the length in bytes now.
-rw-r--r--core/vm/sqlvm/ast/types.go78
-rw-r--r--core/vm/sqlvm/ast/types_test.go36
2 files changed, 34 insertions, 80 deletions
diff --git a/core/vm/sqlvm/ast/types.go b/core/vm/sqlvm/ast/types.go
index 0742bbc14..19bcf6314 100644
--- a/core/vm/sqlvm/ast/types.go
+++ b/core/vm/sqlvm/ast/types.go
@@ -3,11 +3,11 @@ package ast
import (
"errors"
"math/big"
- "reflect"
"github.com/shopspring/decimal"
"github.com/dexon-foundation/dexon/common"
+ se "github.com/dexon-foundation/dexon/core/vm/sqlvm/errors"
)
var (
@@ -92,101 +92,55 @@ func (d DataTypeMajor) IsUfixedRange() bool {
}
// DataTypeEncode encodes data type node into DataType.
-func DataTypeEncode(n interface{}) (DataType, error) {
+func DataTypeEncode(n TypeNode) (DataType, error) {
if n == nil {
return DataTypeUnknown, ErrDataTypeEncode
}
- if reflect.TypeOf(n).Kind() == reflect.Ptr {
- return DataTypeEncode(reflect.ValueOf(n).Elem())
+ t, code := n.GetType()
+ if code == se.ErrorCodeNil {
+ return t, nil
}
-
- switch t := n.(type) {
- case BoolTypeNode:
- return ComposeDataType(DataTypeMajorBool, 0), nil
-
- case AddressTypeNode:
- return ComposeDataType(DataTypeMajorAddress, 0), nil
-
- case IntTypeNode:
- if t.Size%8 != 0 || t.Size > 256 {
- return DataTypeUnknown, ErrDataTypeEncode
- }
-
- minor := DataTypeMinor((t.Size / 8) - 1)
- if t.Unsigned {
- return ComposeDataType(DataTypeMajorUint, minor), nil
- }
- return ComposeDataType(DataTypeMajorInt, minor), nil
-
- case FixedBytesTypeNode:
- if t.Size%8 != 0 || t.Size > 256 {
- return DataTypeUnknown, ErrDataTypeEncode
- }
-
- minor := DataTypeMinor((t.Size / 8) - 1)
- return ComposeDataType(DataTypeMajorFixedBytes, minor), nil
-
- case DynamicBytesTypeNode:
- return ComposeDataType(DataTypeMajorDynamicBytes, 0), nil
-
- case FixedTypeNode:
- if t.Size%8 != 0 || t.Size > 256 {
- return DataTypeUnknown, ErrDataTypeEncode
- }
-
- if t.FractionalDigits > 80 {
- return DataTypeUnknown, ErrDataTypeEncode
- }
-
- major := DataTypeMajor((t.Size / 8) - 1)
- minor := DataTypeMinor(t.FractionalDigits)
- if t.Unsigned {
- return ComposeDataType(DataTypeMajorUfixed+major, minor), nil
- }
- return ComposeDataType(DataTypeMajorFixed+major, minor), nil
- }
-
- return DataTypeUnknown, ErrDataTypeEncode
+ return t, code
}
// DataTypeDecode decodes DataType into data type node.
-func DataTypeDecode(t DataType) (interface{}, error) {
+func DataTypeDecode(t DataType) (TypeNode, error) {
major, minor := DecomposeDataType(t)
switch major {
// TODO(wmin0): define unsupported error for special type.
case DataTypeMajorBool:
if minor == 0 {
- return BoolTypeNode{}, nil
+ return &BoolTypeNode{}, nil
}
case DataTypeMajorAddress:
if minor == 0 {
- return AddressTypeNode{}, nil
+ return &AddressTypeNode{}, nil
}
case DataTypeMajorInt:
if minor <= 0x1f {
size := (uint32(minor) + 1) * 8
- return IntTypeNode{Unsigned: false, Size: size}, nil
+ return &IntTypeNode{Unsigned: false, Size: size}, nil
}
case DataTypeMajorUint:
if minor <= 0x1f {
size := (uint32(minor) + 1) * 8
- return IntTypeNode{Unsigned: true, Size: size}, nil
+ return &IntTypeNode{Unsigned: true, Size: size}, nil
}
case DataTypeMajorFixedBytes:
if minor <= 0x1f {
- size := (uint32(minor) + 1) * 8
- return FixedBytesTypeNode{Size: size}, nil
+ size := uint32(minor) + 1
+ return &FixedBytesTypeNode{Size: size}, nil
}
case DataTypeMajorDynamicBytes:
if minor == 0 {
- return DynamicBytesTypeNode{}, nil
+ return &DynamicBytesTypeNode{}, nil
}
}
switch {
case major.IsFixedRange():
if minor <= 80 {
size := (uint32(major-DataTypeMajorFixed) + 1) * 8
- return FixedTypeNode{
+ return &FixedTypeNode{
Unsigned: false,
Size: size,
FractionalDigits: uint32(minor),
@@ -195,7 +149,7 @@ func DataTypeDecode(t DataType) (interface{}, error) {
case major.IsUfixedRange():
if minor <= 80 {
size := (uint32(major-DataTypeMajorUfixed) + 1) * 8
- return FixedTypeNode{
+ return &FixedTypeNode{
Unsigned: true,
Size: size,
FractionalDigits: uint32(minor),
diff --git a/core/vm/sqlvm/ast/types_test.go b/core/vm/sqlvm/ast/types_test.go
index 8280cf73f..efdea17bc 100644
--- a/core/vm/sqlvm/ast/types_test.go
+++ b/core/vm/sqlvm/ast/types_test.go
@@ -21,7 +21,7 @@ func (s *TypesTestSuite) requireEncodeAndDecodeDecimalNoError(
}
func (s *TypesTestSuite) requireEncodeAndDecodeNoError(
- d DataType, t interface{}) {
+ d DataType, t TypeNode) {
encode, err := DataTypeEncode(t)
s.Require().NoError(err)
s.Require().Equal(d, encode)
@@ -30,7 +30,7 @@ func (s *TypesTestSuite) requireEncodeAndDecodeNoError(
s.Require().Equal(t, decode)
}
-func (s *TypesTestSuite) requireEncodeError(input interface{}) {
+func (s *TypesTestSuite) requireEncodeError(input TypeNode) {
_, err := DataTypeEncode(input)
s.Require().Error(err)
}
@@ -43,39 +43,39 @@ func (s *TypesTestSuite) requireDecodeError(input DataType) {
func (s *TypesTestSuite) TestEncodeAndDecode() {
s.requireEncodeAndDecodeNoError(
ComposeDataType(DataTypeMajorBool, 0),
- BoolTypeNode{})
+ &BoolTypeNode{})
s.requireEncodeAndDecodeNoError(
ComposeDataType(DataTypeMajorAddress, 0),
- AddressTypeNode{})
+ &AddressTypeNode{})
s.requireEncodeAndDecodeNoError(
ComposeDataType(DataTypeMajorInt, 1),
- IntTypeNode{Size: 16})
+ &IntTypeNode{Size: 16})
s.requireEncodeAndDecodeNoError(
ComposeDataType(DataTypeMajorUint, 2),
- IntTypeNode{Unsigned: true, Size: 24})
+ &IntTypeNode{Unsigned: true, Size: 24})
s.requireEncodeAndDecodeNoError(
ComposeDataType(DataTypeMajorFixedBytes, 3),
- FixedBytesTypeNode{Size: 32})
+ &FixedBytesTypeNode{Size: 4})
s.requireEncodeAndDecodeNoError(
ComposeDataType(DataTypeMajorDynamicBytes, 0),
- DynamicBytesTypeNode{})
+ &DynamicBytesTypeNode{})
s.requireEncodeAndDecodeNoError(
ComposeDataType(DataTypeMajorFixed, 1),
- FixedTypeNode{Size: 8, FractionalDigits: 1})
+ &FixedTypeNode{Size: 8, FractionalDigits: 1})
s.requireEncodeAndDecodeNoError(
ComposeDataType(DataTypeMajorUfixed+1, 2),
- FixedTypeNode{Unsigned: true, Size: 16, FractionalDigits: 2})
+ &FixedTypeNode{Unsigned: true, Size: 16, FractionalDigits: 2})
}
func (s *TypesTestSuite) TestEncodeError() {
- s.requireEncodeError(struct{}{})
- s.requireEncodeError(IntTypeNode{Size: 1})
- s.requireEncodeError(IntTypeNode{Size: 257})
- s.requireEncodeError(FixedBytesTypeNode{Size: 1})
- s.requireEncodeError(FixedBytesTypeNode{Size: 257})
- s.requireEncodeError(FixedTypeNode{Size: 1, FractionalDigits: 0})
- s.requireEncodeError(FixedTypeNode{Size: 257, FractionalDigits: 0})
- s.requireEncodeError(FixedTypeNode{Size: 8, FractionalDigits: 81})
+ s.requireEncodeError(nil)
+ s.requireEncodeError(&IntTypeNode{Size: 1})
+ s.requireEncodeError(&IntTypeNode{Size: 257})
+ s.requireEncodeError(&FixedBytesTypeNode{Size: 0})
+ s.requireEncodeError(&FixedBytesTypeNode{Size: 257})
+ s.requireEncodeError(&FixedTypeNode{Size: 1, FractionalDigits: 0})
+ s.requireEncodeError(&FixedTypeNode{Size: 257, FractionalDigits: 0})
+ s.requireEncodeError(&FixedTypeNode{Size: 8, FractionalDigits: 81})
}
func (s *TypesTestSuite) TestDecodeError() {