diff options
author | Meng-Ying Yang <garfield@dexon.org> | 2019-05-06 15:49:02 +0800 |
---|---|---|
committer | Meng-Ying Yang <garfield@dexon.org> | 2019-05-06 15:50:03 +0800 |
commit | c8fd7f412af66040d7e1664f292d83a10807cdc4 (patch) | |
tree | 6b63a5aae0fbda299aeee75623a4c705044bb066 /core/vm | |
parent | 1060c8781bac0dd86cb3dbe20be67c3b6a5d5486 (diff) | |
download | dexon-c8fd7f412af66040d7e1664f292d83a10807cdc4.tar dexon-c8fd7f412af66040d7e1664f292d83a10807cdc4.tar.gz dexon-c8fd7f412af66040d7e1664f292d83a10807cdc4.tar.bz2 dexon-c8fd7f412af66040d7e1664f292d83a10807cdc4.tar.lz dexon-c8fd7f412af66040d7e1664f292d83a10807cdc4.tar.xz dexon-c8fd7f412af66040d7e1664f292d83a10807cdc4.tar.zst dexon-c8fd7f412af66040d7e1664f292d83a10807cdc4.zip |
fixup! core: vm: sqlvm: add built-in function SUBSTRING()
Diffstat (limited to 'core/vm')
-rw-r--r-- | core/vm/sqlvm/runtime/functions.go | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/core/vm/sqlvm/runtime/functions.go b/core/vm/sqlvm/runtime/functions.go index a05c791e7..45d6cec65 100644 --- a/core/vm/sqlvm/runtime/functions.go +++ b/core/vm/sqlvm/runtime/functions.go @@ -448,6 +448,12 @@ func fnSubString(ctx *common.Context, ops []*Operand, length uint64) (result *Op return } + if len(ops[0].Data) != len(ops[1].Data) || + len(ops[0].Data) != len(ops[2].Data) { + err = se.ErrorCodeIndexOutOfRange + return + } + op := ops[0] if !metaAllDynBytes(op) { @@ -464,28 +470,34 @@ func fnSubString(ctx *common.Context, ops []*Operand, length uint64) (result *Op result.Meta[i] = dynBytesType } - starts, err := ops[1].toUint64() - if err == nil && len(starts) != 1 { - err = se.ErrorCodeIndexOutOfRange - } - if err != nil { - return - } - - lens, err := ops[2].toUint64() - if err == nil && len(lens) != 1 { - err = se.ErrorCodeIndexOutOfRange - } - if err != nil { - return - } - - start, end := starts[0], starts[0]+lens[0] + starts, ends := ops[1], ops[2] + var start, end uint64 for i := 0; i < len(op.Data); i++ { result.Data[i] = make(Tuple, len(op.Data[i])) + + if starts.IsImmediate { + start, err = ast.DecimalToUint64(starts.Data[0][0].Value) + } else { + start, err = ast.DecimalToUint64(starts.Data[i][0].Value) + } + + if err != nil { + return + } + + if ends.IsImmediate { + end, err = ast.DecimalToUint64(ends.Data[0][0].Value) + } else { + end, err = ast.DecimalToUint64(ends.Data[i][0].Value) + } + + if err != nil { + return + } + for j := 0; j < len(op.Data[i]); j++ { - result.Data[i][j] = &Raw{Bytes: op.Data[i][j].Bytes[start:end]} + result.Data[i][j] = &Raw{Bytes: op.Data[i][j].Bytes[start : start+end]} } } return |