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-05-06 10:44:04 +0800
commit3092f54b1c16b45be4fb5e52574e4b9d7a9ebcb8 (patch)
treeafb6a07ba3a0f0423241ff12cb7c30255b19f066
parentbf95a638a345a576486596817f30f9a308810c20 (diff)
downloaddexon-3092f54b1c16b45be4fb5e52574e4b9d7a9ebcb8.tar.gz
dexon-3092f54b1c16b45be4fb5e52574e4b9d7a9ebcb8.tar.zst
dexon-3092f54b1c16b45be4fb5e52574e4b9d7a9ebcb8.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() {