diff options
author | Ting-Wei Lan <tingwei.lan@cobinhood.com> | 2019-02-27 17:03:08 +0800 |
---|---|---|
committer | Jhih-Ming Huang <jm.huang@cobinhood.com> | 2019-03-26 17:48:22 +0800 |
commit | d195e3803c103bc9943c68741c0036810a907dc6 (patch) | |
tree | d22a373e999ea705c04b7cf2bd0994cdc36a57f1 | |
parent | d8b728eeac88b0672df0d999a6c93c67ee2705a3 (diff) | |
download | dexon-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.go | 78 | ||||
-rw-r--r-- | core/vm/sqlvm/ast/types_test.go | 36 |
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() { |