aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTing-Wei Lan <tingwei.lan@cobinhood.com>2019-03-28 15:54:17 +0800
committerJhih-Ming Huang <jm.huang@cobinhood.com>2019-05-06 10:44:04 +0800
commitaa7a9f5170fff9cc7040cb8794d6c3c5e36066ac (patch)
treeaa57c6b402dc276f3084aded1074e7eb42b71261
parent10861508f90fa45ad65f5f15163614cdaec8f9f8 (diff)
downloaddexon-aa7a9f5170fff9cc7040cb8794d6c3c5e36066ac.tar.gz
dexon-aa7a9f5170fff9cc7040cb8794d6c3c5e36066ac.tar.zst
dexon-aa7a9f5170fff9cc7040cb8794d6c3c5e36066ac.zip
core: vm: sqlvm: schema: make foreign key constraints a slice
It is allowed to declare multiple foreign key constraints on a column.
-rw-r--r--core/vm/sqlvm/runtime/instructions_test.go2
-rw-r--r--core/vm/sqlvm/schema/schema.go30
-rw-r--r--core/vm/sqlvm/schema/schema_test.go37
3 files changed, 52 insertions, 17 deletions
diff --git a/core/vm/sqlvm/runtime/instructions_test.go b/core/vm/sqlvm/runtime/instructions_test.go
index b316943bb..4d2e0b153 100644
--- a/core/vm/sqlvm/runtime/instructions_test.go
+++ b/core/vm/sqlvm/runtime/instructions_test.go
@@ -54,7 +54,7 @@ func createSchema(storage *common.Storage, raws []*raw) {
storage.Schema[1].Columns[i] = schema.NewColumn(
[]byte{byte(i)},
ast.ComposeDataType(raws[i].major, raws[i].minor),
- 0, 0, 0, 0,
+ 0, nil, 0,
)
}
storage.Schema.SetupColumnOffset()
diff --git a/core/vm/sqlvm/schema/schema.go b/core/vm/sqlvm/schema/schema.go
index 0d40a9612..d50a3ff46 100644
--- a/core/vm/sqlvm/schema/schema.go
+++ b/core/vm/sqlvm/schema/schema.go
@@ -158,14 +158,13 @@ type Index struct {
}
type column struct {
- Name []byte
- Type ast.DataType
- Attr ColumnAttr
- ForeignTable TableRef
- ForeignColumn ColumnRef
- Sequence SequenceRef
- SlotOffset uint8
- ByteOffset uint8
+ Name []byte
+ Type ast.DataType
+ Attr ColumnAttr
+ ForeignKeys []ColumnDescriptor
+ Sequence SequenceRef
+ SlotOffset uint8
+ ByteOffset uint8
// Rest is a special field reserved for use in EncodeRLP. The value stored
// in it will be overwritten every time EncodeRLP is called.
Rest interface{}
@@ -178,15 +177,14 @@ type Column struct {
}
// NewColumn return a Column instance.
-func NewColumn(Name []byte, Type ast.DataType, Attr ColumnAttr, Sequence SequenceRef,
- FT TableRef, FC ColumnRef) Column {
+func NewColumn(Name []byte, Type ast.DataType, Attr ColumnAttr,
+ ForeignKeys []ColumnDescriptor, Sequence SequenceRef) Column {
c := column{
- Name: Name,
- Type: Type,
- Attr: Attr,
- Sequence: Sequence,
- ForeignTable: FT,
- ForeignColumn: FC,
+ Name: Name,
+ Type: Type,
+ Attr: Attr,
+ ForeignKeys: ForeignKeys,
+ Sequence: Sequence,
}
return Column{
diff --git a/core/vm/sqlvm/schema/schema_test.go b/core/vm/sqlvm/schema/schema_test.go
index 0c75b0cb6..71f0ee6d3 100644
--- a/core/vm/sqlvm/schema/schema_test.go
+++ b/core/vm/sqlvm/schema/schema_test.go
@@ -4,6 +4,7 @@ import (
"bufio"
"bytes"
"io/ioutil"
+ "reflect"
"testing"
"github.com/shopspring/decimal"
@@ -16,6 +17,39 @@ import (
type SchemaTestSuite struct{ suite.Suite }
+func (s *SchemaTestSuite) normalizeEmptySlice(i interface{}) {
+ var process func(reflect.Type, reflect.Value)
+ process = func(t reflect.Type, v reflect.Value) {
+ switch t.Kind() {
+ case reflect.Ptr:
+ process(t.Elem(), v.Elem())
+ case reflect.Array:
+ l := v.Len()
+ for i := 0; i < l; i++ {
+ process(t.Elem(), v.Index(i))
+ }
+ case reflect.Slice:
+ if v.IsNil() {
+ s := reflect.MakeSlice(t, 0, 0)
+ v.Set(s)
+ } else {
+ l := v.Len()
+ for i := 0; i < l; i++ {
+ process(t.Elem(), v.Index(i))
+ }
+ }
+ case reflect.Struct:
+ l := t.NumField()
+ for i := 0; i < l; i++ {
+ ft := t.Field(i).Type
+ fv := v.Field(i)
+ process(ft, fv)
+ }
+ }
+ }
+ process(reflect.TypeOf(i), reflect.ValueOf(i))
+}
+
func (s *SchemaTestSuite) requireEncodeAndDecodeColumnNoError(c Column) {
buffer := bytes.Buffer{}
w := bufio.NewWriter(&buffer)
@@ -25,6 +59,9 @@ func (s *SchemaTestSuite) requireEncodeAndDecodeColumnNoError(c Column) {
c2 := Column{}
r := ioutil.NopCloser(bufio.NewReader(&buffer))
s.Require().NoError(rlp.Decode(r, &c2))
+
+ s.normalizeEmptySlice(&c.column)
+ s.normalizeEmptySlice(&c2.column)
s.Require().Equal(c, c2)
}