diff options
Diffstat (limited to 'core/vm/sqlvm/runtime/instructions_op_test.go')
-rw-r--r-- | core/vm/sqlvm/runtime/instructions_op_test.go | 3110 |
1 files changed, 3110 insertions, 0 deletions
diff --git a/core/vm/sqlvm/runtime/instructions_op_test.go b/core/vm/sqlvm/runtime/instructions_op_test.go new file mode 100644 index 000000000..f18fb0181 --- /dev/null +++ b/core/vm/sqlvm/runtime/instructions_op_test.go @@ -0,0 +1,3110 @@ +// Code generated - DO NOT EDIT. + +package runtime + +import ( + "github.com/dexon-foundation/decimal" + + "github.com/dexon-foundation/dexon/core/vm/sqlvm/ast" + "github.com/dexon-foundation/dexon/core/vm/sqlvm/errors" +) + +func (s *instructionSuite) TestOpAdd() { + testcases := []opTestcase{ + { + "None Immediate", + Instruction{ + Op: ADD, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}}, + {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-2)}}, + {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(10)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}}, + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}}, + {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(3)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(4)}}, + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}, + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(20)}}, + {&Raw{Value: decimal.NewFromFloat(-20)}, &Raw{Value: decimal.NewFromFloat(13)}}, + }, + ), + nil, + }, + { + "Immediate", + Instruction{ + Op: ADD, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(11)}, &Raw{Value: decimal.NewFromFloat(8)}, &Raw{Value: decimal.NewFromFloat(0)}}, + {&Raw{Value: decimal.NewFromFloat(-9)}, &Raw{Value: decimal.NewFromFloat(-12)}, &Raw{Value: decimal.NewFromFloat(-20)}}, + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + }, + ), + nil, + }, + { + "Immediate 2", + Instruction{ + Op: ADD, + Input: []*Operand{ + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(11)}, &Raw{Value: decimal.NewFromFloat(8)}, &Raw{Value: decimal.NewFromFloat(0)}}, + {&Raw{Value: decimal.NewFromFloat(-9)}, &Raw{Value: decimal.NewFromFloat(-12)}, &Raw{Value: decimal.NewFromFloat(-20)}}, + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + }, + ), + nil, + }, + { + "Overflow - Immediate", + Instruction{ + Op: ADD, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(127)}}, + {&Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(1)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeOverflow, + }, + { + "Overflow None Immediate", + Instruction{ + Op: ADD, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(126)}}, + {&Raw{Value: decimal.NewFromFloat(126)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(2)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeOverflow, + }, + { + "Underflow - Immediate", + Instruction{ + Op: ADD, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(-128)}}, + {&Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(-1)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(-1)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeUnderflow, + }, + { + "Underflow None Immediate", + Instruction{ + Op: ADD, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(-127)}}, + {&Raw{Value: decimal.NewFromFloat(-127)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(-2)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeUnderflow, + }, + } + + s.run(testcases, opAdd) +} + +func (s *instructionSuite) TestOpSub() { + testcases := []opTestcase{ + { + "None Immediate", + Instruction{ + Op: SUB, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}}, + {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-2)}}, + {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(10)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}}, + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}}, + {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(3)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}, + {&Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(-4)}}, + {&Raw{Value: decimal.NewFromFloat(20)}, &Raw{Value: decimal.NewFromFloat(0)}}, + {&Raw{Value: decimal.NewFromFloat(-20)}, &Raw{Value: decimal.NewFromFloat(7)}}, + }, + ), + nil, + }, + { + "Immediate", + Instruction{ + Op: SUB, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(9)}, &Raw{Value: decimal.NewFromFloat(12)}, &Raw{Value: decimal.NewFromFloat(20)}}, + {&Raw{Value: decimal.NewFromFloat(-11)}, &Raw{Value: decimal.NewFromFloat(-8)}, &Raw{Value: decimal.NewFromFloat(0)}}, + {&Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(4)}, &Raw{Value: decimal.NewFromFloat(10)}}, + }, + ), + nil, + }, + { + "Immediate 2", + Instruction{ + Op: SUB, + Input: []*Operand{ + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(-9)}, &Raw{Value: decimal.NewFromFloat(-12)}, &Raw{Value: decimal.NewFromFloat(-20)}}, + {&Raw{Value: decimal.NewFromFloat(11)}, &Raw{Value: decimal.NewFromFloat(8)}, &Raw{Value: decimal.NewFromFloat(0)}}, + {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-4)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + }, + ), + nil, + }, + { + "Overflow - Immediate", + Instruction{ + Op: SUB, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(127)}}, + {&Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(1)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(-1)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeOverflow, + }, + { + "Overflow None Immediate", + Instruction{ + Op: SUB, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(126)}}, + {&Raw{Value: decimal.NewFromFloat(126)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(-2)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeOverflow, + }, + { + "Underflow - Immediate", + Instruction{ + Op: SUB, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(-128)}}, + {&Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(-1)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeUnderflow, + }, + { + "Underflow None Immediate", + Instruction{ + Op: SUB, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(-127)}}, + {&Raw{Value: decimal.NewFromFloat(-127)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(2)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeUnderflow, + }, + } + + s.run(testcases, opSub) +} + +func (s *instructionSuite) TestOpMul() { + testcases := []opTestcase{ + { + "None Immediate", + Instruction{ + Op: MUL, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(4)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(-4)}, &Raw{Value: decimal.NewFromFloat(-100)}}, + {&Raw{Value: decimal.NewFromFloat(100)}, &Raw{Value: decimal.NewFromFloat(100)}}, + }, + ), + nil, + }, + { + "Immediate", + Instruction{ + Op: MUL, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(-20)}, &Raw{Value: decimal.NewFromFloat(0)}}, + {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(20)}, &Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + nil, + }, + { + "Immediate - 2", + Instruction{ + Op: MUL, + Input: []*Operand{ + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(-20)}, &Raw{Value: decimal.NewFromFloat(0)}}, + {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(20)}, &Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + nil, + }, + { + "Overflow - Immediate", + Instruction{ + Op: MUL, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(127)}}, + {&Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(1)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(2)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeOverflow, + }, + { + "Overflow None Immediate", + Instruction{ + Op: MUL, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(126)}}, + {&Raw{Value: decimal.NewFromFloat(126)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(2)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeOverflow, + }, + { + "Underflow - Immediate", + Instruction{ + Op: MUL, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(-128)}}, + {&Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(-1)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(2)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeUnderflow, + }, + { + "Underflow None Immediate", + Instruction{ + Op: MUL, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(-127)}}, + {&Raw{Value: decimal.NewFromFloat(-127)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(2)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeUnderflow, + }, + } + + s.run(testcases, opMul) +} + +func (s *instructionSuite) TestOpDiv() { + testcases := []opTestcase{ + { + "None Immediate", + Instruction{ + Op: DIV, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(-2)}, &Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}}, + }, + ), + nil, + }, + { + "Immediate", + Instruction{ + Op: DIV, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}, + {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + {&Raw{Value: decimal.NewFromFloat(13)}, &Raw{Value: decimal.NewFromFloat(13)}}, + {&Raw{Value: decimal.NewFromFloat(-13)}, &Raw{Value: decimal.NewFromFloat(-13)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-2)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}, + {&Raw{Value: decimal.NewFromFloat(5)}, &Raw{Value: decimal.NewFromFloat(-5)}}, + {&Raw{Value: decimal.NewFromFloat(-5)}, &Raw{Value: decimal.NewFromFloat(5)}}, + {&Raw{Value: decimal.NewFromFloat(6)}, &Raw{Value: decimal.NewFromFloat(-6)}}, + {&Raw{Value: decimal.NewFromFloat(-6)}, &Raw{Value: decimal.NewFromFloat(6)}}, + }, + ), + nil, + }, + { + "Immediate 2", + Instruction{ + Op: DIV, + Input: []*Operand{ + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(50)}, &Raw{Value: decimal.NewFromFloat(-50)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + {&Raw{Value: decimal.NewFromFloat(9)}, &Raw{Value: decimal.NewFromFloat(9)}}, + {&Raw{Value: decimal.NewFromFloat(-9)}, &Raw{Value: decimal.NewFromFloat(-9)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(5)}, &Raw{Value: decimal.NewFromFloat(-5)}}, + {&Raw{Value: decimal.NewFromFloat(-5)}, &Raw{Value: decimal.NewFromFloat(5)}}, + {&Raw{Value: decimal.NewFromFloat(5)}, &Raw{Value: decimal.NewFromFloat(-5)}}, + {&Raw{Value: decimal.NewFromFloat(-5)}, &Raw{Value: decimal.NewFromFloat(5)}}, + }, + ), + nil, + }, + { + "DivideByZero Immediate", + Instruction{ + Op: DIV, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(10)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeDividedByZero, + }, + { + "DivideByZero None Immediate", + Instruction{ + Op: DIV, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(10)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeDividedByZero, + }, + { + "Overflow - Immediate", + Instruction{ + Op: DIV, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(-128)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(-1)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeOverflow, + }, + { + "Overflow None Immediate", + Instruction{ + Op: DIV, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(-128)}}, + {&Raw{Value: decimal.NewFromFloat(-128)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(-2)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeOverflow, + }, + } + + s.run(testcases, opDiv) +} + +func (s *instructionSuite) TestOpMod() { + testcases := []opTestcase{ + { + "None Immediate", + Instruction{ + Op: MOD, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-2)}}, + {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-2)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(3)}, &Raw{Value: decimal.NewFromFloat(3)}}, + {&Raw{Value: decimal.NewFromFloat(-3)}, &Raw{Value: decimal.NewFromFloat(-3)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}, + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}, + {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-2)}}, + {&Raw{Value: decimal.NewFromFloat(2)}, &Raw{Value: decimal.NewFromFloat(-2)}}, + }, + ), + nil, + }, + { + "Immediate", + Instruction{ + Op: MOD, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}, + {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + {&Raw{Value: decimal.NewFromFloat(13)}, &Raw{Value: decimal.NewFromFloat(13)}}, + {&Raw{Value: decimal.NewFromFloat(-13)}, &Raw{Value: decimal.NewFromFloat(-13)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(3)}, &Raw{Value: decimal.NewFromFloat(-3)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}, + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + }, + ), + nil, + }, + { + "Immediate - 2", + Instruction{ + Op: MOD, + Input: []*Operand{ + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(31)}, &Raw{Value: decimal.NewFromFloat(-31)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(10)}, &Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(-10)}, &Raw{Value: decimal.NewFromFloat(-10)}}, + {&Raw{Value: decimal.NewFromFloat(13)}, &Raw{Value: decimal.NewFromFloat(13)}}, + {&Raw{Value: decimal.NewFromFloat(-13)}, &Raw{Value: decimal.NewFromFloat(-13)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(5)}, &Raw{Value: decimal.NewFromFloat(-5)}}, + {&Raw{Value: decimal.NewFromFloat(5)}, &Raw{Value: decimal.NewFromFloat(-5)}}, + }, + ), + nil, + }, + { + "ModideByZero Immediate", + Instruction{ + Op: MOD, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(10)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeDividedByZero, + }, + { + "ModideByZero None Immediate", + Instruction{ + Op: MOD, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(10)}}, + {&Raw{Value: decimal.NewFromFloat(10)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeDividedByZero, + }, + } + + s.run(testcases, opMod) +} + +func (s *instructionSuite) TestOpLt() { + testcases := []opTestcase{ + { + "None Immediate", + Instruction{ + Op: LT, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}, + {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawFalse, rawTrue, rawTrue}, + {rawFalse, rawFalse, rawTrue}, + {rawFalse, rawFalse, rawFalse}, + }, + ), + nil, + }, + { + "Immediate", + Instruction{ + Op: LT, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawFalse, rawFalse, rawTrue}, + }, + ), + nil, + }, + { + "Immediate - 2", + Instruction{ + Op: LT, + Input: []*Operand{ + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawFalse, rawTrue, rawFalse}, + }, + ), + nil, + }, + } + + s.run(testcases, opLt) +} + +func (s *instructionSuite) TestOpGt() { + testcases := []opTestcase{ + { + "None Immediate", + Instruction{ + Op: GT, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}, + {&Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawFalse, rawFalse, rawFalse}, + {rawTrue, rawFalse, rawFalse}, + {rawTrue, rawTrue, rawFalse}, + }, + ), + nil, + }, + { + "Immediate", + Instruction{ + Op: GT, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawFalse, rawTrue, rawFalse}, + }, + ), + nil, + }, + { + "Immediate - 2", + Instruction{ + Op: GT, + Input: []*Operand{ + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawFalse, rawFalse, rawTrue}, + }, + ), + nil, + }, + } + + s.run(testcases, opGt) +} + +func (s *instructionSuite) TestOpEq() { + testcases := []opTestcase{ + { + "None Immediate", + Instruction{ + Op: EQ, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(1)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawTrue, rawTrue}, + {rawTrue, rawFalse, rawFalse}, + }, + ), + nil, + }, + { + "Immediate", + Instruction{ + Op: EQ, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}, + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(-1)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawTrue, rawTrue}, + {rawTrue, rawFalse, rawFalse}, + }, + ), + nil, + }, + } + + s.run(testcases, opEq) +} + +func (s *instructionSuite) TestOpAnd() { + testcases := []opTestcase{ + { + "None Immediate", + Instruction{ + Op: AND, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawFalse}, + {rawFalse, rawTrue}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawTrue}, + {rawFalse, rawFalse}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawFalse}, + {rawFalse, rawFalse}, + }, + ), + nil, + }, + { + "Immediate", + Instruction{ + Op: AND, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawFalse}, + {rawFalse, rawTrue}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawTrue}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawFalse}, + {rawFalse, rawTrue}, + }, + ), + nil, + }, + { + "Immediate - 2", + Instruction{ + Op: AND, + Input: []*Operand{ + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawTrue}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawFalse}, + {rawFalse, rawTrue}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawFalse}, + {rawFalse, rawTrue}, + }, + ), + nil, + }, + { + "Invalid Data Type", + Instruction{ + Op: AND, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeInvalidDataType, + }, + } + + s.run(testcases, opAnd) +} + +func (s *instructionSuite) TestOpOr() { + testcases := []opTestcase{ + { + "None Immediate", + Instruction{ + Op: OR, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawFalse}, + {rawFalse, rawTrue}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawTrue}, + {rawFalse, rawFalse}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawTrue}, + {rawFalse, rawTrue}, + }, + ), + nil, + }, + { + "Immediate", + Instruction{ + Op: OR, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawFalse}, + {rawFalse, rawTrue}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawTrue}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawTrue}, + {rawTrue, rawTrue}, + }, + ), + nil, + }, + { + "Immediate - 2", + Instruction{ + Op: OR, + Input: []*Operand{ + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawTrue}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawFalse}, + {rawFalse, rawTrue}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawTrue}, + {rawTrue, rawTrue}, + }, + ), + nil, + }, + { + "Invalid Data Type", + Instruction{ + Op: OR, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeInvalidDataType, + }, + } + + s.run(testcases, opOr) +} + +func (s *instructionSuite) TestOpNot() { + testcases := []opTestcase{ + { + "None Immediate", + Instruction{ + Op: NOT, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawFalse}, + {rawFalse, rawTrue}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawFalse, rawTrue}, + {rawTrue, rawFalse}, + }, + ), + nil, + }, + { + "Errors Invalid Data Type", + Instruction{ + Op: NOT, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeInvalidDataType, + }, + } + + s.run(testcases, opNot) +} + +func (s *instructionSuite) TestOpUnion() { + testcases := []opTestcase{ + { + "None Immediate", + Instruction{ + Op: UNION, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawFalse}, + {rawFalse, rawTrue}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawTrue}, + {rawFalse, rawFalse}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawFalse, rawFalse}, + {rawFalse, rawTrue}, + {rawTrue, rawFalse}, + {rawTrue, rawTrue}, + }, + ), + nil, + }, + } + + s.run(testcases, opUnion) +} + +func (s *instructionSuite) TestOpIntxn() { + testcases := []opTestcase{ + { + "None Immediate", + Instruction{ + Op: INTXN, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawFalse}, + {rawFalse, rawTrue}, + {rawTrue, rawTrue}, + {rawFalse, rawFalse}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawTrue}, + {rawFalse, rawFalse}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawFalse, rawFalse}, + {rawTrue, rawTrue}, + }, + ), + nil, + }, + } + + s.run(testcases, opIntxn) +} + +func (s *instructionSuite) TestOpLike() { + testcases := []opTestcase{ + { + "Like %\\%b% escape \\", + Instruction{ + Op: LIKE, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(7, 0), ast.ComposeDataType(7, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte("a%bcdefg")}, &Raw{Bytes: []byte("gfedcba")}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(7, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte("%\\%b%")}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(7, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte("\\")}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawFalse}, + }, + ), + nil, + }, + { + "Like t1 escape t2", + Instruction{ + Op: LIKE, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(7, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte("a%bcdefg")}}, + {&Raw{Bytes: []byte("gfedcba")}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(7, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte("%\\%b%")}}, + {&Raw{Bytes: []byte("_fed%")}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(7, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte("\\")}}, + {&Raw{Bytes: []byte("")}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue}, + {rawTrue}, + }, + ), + nil, + }, + { + "Like with valid and invalid UTF8", + Instruction{ + Op: LIKE, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(7, 0), ast.ComposeDataType(7, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte{226, 40, 161, 228, 189, 160, 229, 165, 189}}, &Raw{Bytes: []byte("gfedcba")}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(7, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte{37, 228, 189, 160, 37}}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawFalse}, + }, + ), + nil, + }, + } + + s.run(testcases, opLike) +} + +func (s *instructionSuite) TestOpZip() { + testcases := []opTestcase{ + { + "Zip two array", + Instruction{ + Op: ZIP, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(7, 0), ast.ComposeDataType(7, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}}, + {&Raw{Bytes: []byte("abcdefg-2")}, &Raw{Bytes: []byte("gfedcba-2")}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, rawTrue}, + {&Raw{Value: decimal.NewFromFloat(2)}, rawFalse}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(7, 0), ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue}, + {&Raw{Bytes: []byte("abcdefg-2")}, &Raw{Bytes: []byte("gfedcba-2")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse}, + }, + ), + nil, + }, + { + "Zip immediate", + Instruction{ + Op: ZIP, + Input: []*Operand{ + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(7, 0), ast.ComposeDataType(7, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, rawTrue}, + {&Raw{Value: decimal.NewFromFloat(2)}, rawFalse}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(7, 0), ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue}, + {&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse}, + }, + ), + nil, + }, + } + + s.run(testcases, opZip) +} + +func (s *instructionSuite) TestOpField() { + testcases := []opTestcase{ + { + "Retrieve 2nd,3rd column", + Instruction{ + Op: FIELD, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(7, 0), ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue}, + {&Raw{Bytes: []byte("abcdefg-2")}, &Raw{Bytes: []byte("gfedcba-2")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(2)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte("gfedcba-1")}, &Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Bytes: []byte("gfedcba-2")}, &Raw{Value: decimal.NewFromFloat(2)}}, + }, + ), + nil, + }, + } + + s.run(testcases, opField) +} + +func (s *instructionSuite) TestOpPrune() { + testcases := []opTestcase{ + { + "Prune 2nd,4th,5th column", + Instruction{ + Op: PRUNE, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(7, 0), ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Bytes: []byte("gfedcba-1")}, &Raw{Value: decimal.NewFromFloat(1)}, rawFalse, rawTrue}, + {&Raw{Bytes: []byte("abcdefg-2")}, &Raw{Bytes: []byte("gfedcba-2")}, &Raw{Value: decimal.NewFromFloat(2)}, rawTrue, rawFalse}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(1)}, &Raw{Value: decimal.NewFromFloat(3)}, &Raw{Value: decimal.NewFromFloat(4)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte("abcdefg-1")}, &Raw{Value: decimal.NewFromFloat(1)}}, + {&Raw{Bytes: []byte("abcdefg-2")}, &Raw{Value: decimal.NewFromFloat(2)}}, + }, + ), + nil, + }, + } + + s.run(testcases, opPrune) +} + +func (s *instructionSuite) TestOpFilter() { + testcases := []opTestcase{ + { + "Filter first 2 rows", + Instruction{ + Op: FILTER, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawFalse}, + {rawFalse, rawTrue}, + {rawTrue, rawTrue}, + {rawFalse, rawFalse}, + }, + ), + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue}, + {rawTrue}, + {rawFalse}, + {rawFalse}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawFalse}, + {rawFalse, rawTrue}, + }, + ), + nil, + }, + } + + s.run(testcases, opFilter) +} + +func (s *instructionSuite) TestOpCast() { + testcases := []opTestcase{ + { + "None Immediate - int", + Instruction{ + Op: CAST, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 1), ast.ComposeDataType(4, 1), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(127)}, &Raw{Value: decimal.NewFromFloat(127)}}, + {&Raw{Value: decimal.NewFromFloat(-128)}, &Raw{Value: decimal.NewFromFloat(-128)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 2), + }, + []Tuple{}, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 0), ast.ComposeDataType(4, 2), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(127)}, &Raw{Value: decimal.NewFromFloat(127)}}, + {&Raw{Value: decimal.NewFromFloat(-128)}, &Raw{Value: decimal.NewFromFloat(-128)}}, + }, + ), + nil, + }, + { + "None Immediate - int2", + Instruction{ + Op: CAST, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 1), ast.ComposeDataType(4, 1), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(-32768)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(5, 1), ast.ComposeDataType(5, 1), + }, + []Tuple{}, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(5, 1), ast.ComposeDataType(5, 1), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(32768)}}, + }, + ), + nil, + }, + { + "None Immediate - int3", + Instruction{ + Op: CAST, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 1), ast.ComposeDataType(4, 1), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(-32768)}}, + {&Raw{Value: decimal.NewFromFloat(0)}, &Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{}, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawTrue}, + {rawFalse, rawFalse}, + }, + ), + nil, + }, + { + "None Immediate - int4", + Instruction{ + Op: CAST, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 1), ast.ComposeDataType(4, 1), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(-32768)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(6, 1), ast.ComposeDataType(3, 0), + }, + []Tuple{}, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(6, 1), ast.ComposeDataType(3, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte{0x7f, 0xff}}, &Raw{Bytes: []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0x80, 0x00}}}, + }, + ), + nil, + }, + { + "None Immediate - uint", + Instruction{ + Op: CAST, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(5, 1), ast.ComposeDataType(5, 1), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(128)}, &Raw{Value: decimal.NewFromFloat(128)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(5, 0), ast.ComposeDataType(5, 2), + }, + []Tuple{}, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(5, 0), ast.ComposeDataType(5, 2), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(128)}, &Raw{Value: decimal.NewFromFloat(128)}}, + }, + ), + nil, + }, + { + "None Immediate - uint2", + Instruction{ + Op: CAST, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(5, 1), ast.ComposeDataType(5, 1), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(32768)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 1), ast.ComposeDataType(6, 1), + }, + []Tuple{}, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 1), ast.ComposeDataType(6, 1), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Bytes: []byte{0x80, 0x00}}}, + }, + ), + nil, + }, + { + "None Immediate - uint3", + Instruction{ + Op: CAST, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(5, 1), ast.ComposeDataType(5, 1), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{}, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue, rawFalse}, + }, + ), + nil, + }, + { + "None Immediate - uint4", + Instruction{ + Op: CAST, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(5, 1), ast.ComposeDataType(5, 1), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(6, 1), ast.ComposeDataType(6, 1), + }, + []Tuple{}, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(6, 1), ast.ComposeDataType(6, 1), + }, + []Tuple{ + {&Raw{Bytes: []byte{0x7f, 0xff}}, &Raw{Bytes: []byte{0x00, 0x00}}}, + }, + ), + nil, + }, + { + "None Immediate - uint5", + Instruction{ + Op: CAST, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(5, 1), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(32767)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(3, 1), + }, + []Tuple{}, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(3, 1), + }, + []Tuple{ + {&Raw{Bytes: []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x7f, 0xff}}}, + }, + ), + nil, + }, + { + "None Immediate - bytes", + Instruction{ + Op: CAST, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(6, 1), ast.ComposeDataType(6, 1), + }, + []Tuple{ + {&Raw{Bytes: []byte{0xff, 0xff}}, &Raw{Bytes: []byte{0xff, 0xff}}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(6, 0), ast.ComposeDataType(6, 2), + }, + []Tuple{}, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(6, 0), ast.ComposeDataType(6, 2), + }, + []Tuple{ + {&Raw{Bytes: []byte{0xff}}, &Raw{Bytes: []byte{0xff, 0xff, 0x00}}}, + }, + ), + nil, + }, + { + "None Immediate - bytes2", + Instruction{ + Op: CAST, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(6, 1), ast.ComposeDataType(6, 1), + }, + []Tuple{ + {&Raw{Bytes: []byte{0x7f, 0xff}}, &Raw{Bytes: []byte{0x80, 0x00}}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(4, 1), ast.ComposeDataType(5, 1), + }, + []Tuple{}, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 1), ast.ComposeDataType(5, 1), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(32767)}, &Raw{Value: decimal.NewFromFloat(32768)}}, + }, + ), + nil, + }, + { + "None Immediate - bytes3", + Instruction{ + Op: CAST, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(6, 1), + }, + []Tuple{ + {&Raw{Bytes: []byte{0x7f, 0xff}}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(7, 1), + }, + []Tuple{}, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(7, 1), + }, + []Tuple{ + {&Raw{Bytes: []byte{0x7f, 0xff}}}, + }, + ), + nil, + }, + { + "Same type", + Instruction{ + Op: CAST, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(2, 0), + }, + []Tuple{}, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(2, 0), + }, + []Tuple{ + {rawTrue}, + }, + ), + nil, + }, + { + "Error Invalid Type", + Instruction{ + Op: CAST, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(4, 2), + }, + []Tuple{ + {&Raw{Value: decimal.NewFromFloat(-32768)}}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(7, 0), + }, + []Tuple{}, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{}, + []Tuple{}, + ), + errors.ErrorCodeInvalidCastType, + }, + } + + s.run(testcases, opCast) +} + +func (s *instructionSuite) TestOpSort() { + testcases := []opTestcase{ + { + "Multi-column sorting", + Instruction{ + Op: SORT, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue}, + {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawTrue}, + {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawTrue}, + {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(1)}, rawFalse}, + {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse}, + {&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}, + {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}, + {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {rawFalse, &Raw{Value: decimal.NewFromFloat(1)}}, + {rawTrue, &Raw{Value: decimal.NewFromFloat(2)}}, + {rawFalse, &Raw{Value: decimal.NewFromFloat(0)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}, + {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}, + {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}, + {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawTrue}, + {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse}, + {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawTrue}, + {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(1)}, rawFalse}, + {&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue}, + }, + ), + nil, + }, + { + "Multi-column sorting - 2", + Instruction{ + Op: SORT, + Input: []*Operand{ + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue}, + {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawTrue}, + {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawTrue}, + {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(1)}, rawFalse}, + {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse}, + {&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}, + {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}, + {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}, + }, + ), + makeOperand( + true, + []ast.DataType{ + ast.ComposeDataType(2, 0), ast.ComposeDataType(4, 0), + }, + []Tuple{ + {rawTrue, &Raw{Value: decimal.NewFromFloat(0)}}, + {rawTrue, &Raw{Value: decimal.NewFromFloat(1)}}, + {rawFalse, &Raw{Value: decimal.NewFromFloat(2)}}, + }, + ), + }, + Output: 0, + }, + makeOperand( + false, + []ast.DataType{ + ast.ComposeDataType(7, 0), ast.ComposeDataType(4, 0), ast.ComposeDataType(2, 0), + }, + []Tuple{ + {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(1)}, rawFalse}, + {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawTrue}, + {&Raw{Bytes: []byte("a")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}, + {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawTrue}, + {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(2)}, rawFalse}, + {&Raw{Bytes: []byte("b")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}, + {&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(1)}, rawTrue}, + {&Raw{Bytes: []byte("c")}, &Raw{Value: decimal.NewFromFloat(3)}, rawFalse}, + }, + ), + nil, + }, + } + + s.run(testcases, opSort) +} |