diff --git a/pkg/sql/plan2/function/builtin/multi/substr_test.go b/pkg/sql/plan2/function/builtin/multi/substr_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..bd8997923b98eec7be54e18f69f26427da6bea81
--- /dev/null
+++ b/pkg/sql/plan2/function/builtin/multi/substr_test.go
@@ -0,0 +1,278 @@
+// Copyright 2022 Matrix Origin
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package multi
+
+import (
+	"github.com/matrixorigin/matrixone/pkg/container/nulls"
+	"github.com/matrixorigin/matrixone/pkg/container/types"
+	"github.com/matrixorigin/matrixone/pkg/container/vector"
+	"github.com/matrixorigin/matrixone/pkg/vm/mheap"
+	"github.com/matrixorigin/matrixone/pkg/vm/mmu/guest"
+	"github.com/matrixorigin/matrixone/pkg/vm/mmu/host"
+	"github.com/matrixorigin/matrixone/pkg/vm/process"
+	"github.com/stretchr/testify/require"
+	"testing"
+)
+
+func TestSubStr(t *testing.T) {
+	procs := makeProcess()
+	cases := []struct {
+		name       string
+		vecs       []*vector.Vector
+		proc       *process.Process
+		wantBytes  []byte
+		wantScalar bool
+	}{
+		{
+			name:       "TEST01",
+			vecs:       makeSubStrVectors("abcdefghijklmn", 5, 0, false),
+			proc:       procs,
+			wantBytes:  []byte("efghijklmn"),
+			wantScalar: true,
+		},
+		{
+			name:       "TEST02",
+			vecs:       makeSubStrVectors("abcdefghijklmn", 7, 0, false),
+			proc:       procs,
+			wantBytes:  []byte("ghijklmn"),
+			wantScalar: true,
+		},
+		{
+			name:       "TEST03",
+			vecs:       makeSubStrVectors("abcdefghijklmn", 11, 0, false),
+			proc:       procs,
+			wantBytes:  []byte("klmn"),
+			wantScalar: true,
+		},
+		{
+			name:       "TEST04",
+			vecs:       makeSubStrVectors("abcdefghijklmn", 16, 0, false),
+			proc:       procs,
+			wantBytes:  []byte(""),
+			wantScalar: true,
+		},
+		{
+			name:       "TEST05",
+			vecs:       makeSubStrVectors("abcdefghijklmn", 5, 6, true),
+			proc:       procs,
+			wantBytes:  []byte("efghij"),
+			wantScalar: true,
+		},
+		{
+			name:       "TEST06",
+			vecs:       makeSubStrVectors("abcdefghijklmn", 5, 10, true),
+			proc:       procs,
+			wantBytes:  []byte("efghijklmn"),
+			wantScalar: true,
+		},
+		{
+			name:       "TEST07",
+			vecs:       makeSubStrVectors("abcdefghijklmn", 5, 0, true),
+			proc:       procs,
+			wantBytes:  []byte(""),
+			wantScalar: true,
+		},
+		{
+			name:       "TEST08",
+			vecs:       makeSubStrVectors("abcdefghijklmn", 6, -8, true),
+			proc:       procs,
+			wantBytes:  []byte("f"),
+			wantScalar: true,
+		},
+		{
+			name:       "TEST09",
+			vecs:       makeSubStrVectors("abcdefghijklmn", 6, -9, true),
+			proc:       procs,
+			wantBytes:  []byte(""),
+			wantScalar: true,
+		},
+		{
+			name:       "TEST09",
+			vecs:       makeSubStrVectors("abcdefghijklmn", 6, -4, true),
+			proc:       procs,
+			wantBytes:  []byte("fghij"),
+			wantScalar: true,
+		},
+		{
+			name:       "TEST10",
+			vecs:       makeSubStrVectors("abcdefghijklmn", 6, -1, true),
+			proc:       procs,
+			wantBytes:  []byte("fghijklm"),
+			wantScalar: true,
+		},
+		{
+			name:       "Test11",
+			vecs:       makeSubStrVectors("abcdefghijklmn", -4, 0, false),
+			proc:       procs,
+			wantBytes:  []byte("klmn"),
+			wantScalar: true,
+		},
+		{
+			name:       "Test12",
+			vecs:       makeSubStrVectors("abcdefghijklmn", -14, 0, false),
+			proc:       procs,
+			wantBytes:  []byte("abcdefghijklmn"),
+			wantScalar: true,
+		},
+		{
+			name:       "Test13",
+			vecs:       makeSubStrVectors("abcdefghijklmn", -16, 0, false),
+			proc:       procs,
+			wantBytes:  []byte("abcdefghijklmn"),
+			wantScalar: true,
+		},
+		{
+			name:       "Test14",
+			vecs:       makeSubStrVectors("abcdefghijklmn", -4, 3, true),
+			proc:       procs,
+			wantBytes:  []byte("klm"),
+			wantScalar: true,
+		},
+		{
+			name:       "Test15",
+			vecs:       makeSubStrVectors("abcdefghijklmn", -14, 10, true),
+			proc:       procs,
+			wantBytes:  []byte("abcdefghij"),
+			wantScalar: true,
+		},
+		{
+			name:       "Test16",
+			vecs:       makeSubStrVectors("abcdefghijklmn", -14, 15, true),
+			proc:       procs,
+			wantBytes:  []byte("abcdefghijklmn"),
+			wantScalar: true,
+		},
+		{
+			name:       "Test17",
+			vecs:       makeSubStrVectors("abcdefghijklmn", -16, 10, true),
+			proc:       procs,
+			wantBytes:  []byte("abcdefgh"),
+			wantScalar: true,
+		},
+		{
+			name:       "Test18",
+			vecs:       makeSubStrVectors("abcdefghijklmn", -16, 20, true),
+			proc:       procs,
+			wantBytes:  []byte("abcdefghijklmn"),
+			wantScalar: true,
+		},
+		{
+			name:       "Test19",
+			vecs:       makeSubStrVectors("abcdefghijklmn", -16, 2, true),
+			proc:       procs,
+			wantBytes:  []byte(""),
+			wantScalar: true,
+		},
+		{
+			name:       "Test20",
+			vecs:       makeSubStrVectors("abcdefghijklmn", -12, 2, true),
+			proc:       procs,
+			wantBytes:  []byte("cd"),
+			wantScalar: true,
+		},
+		{
+			name:       "Test21",
+			vecs:       makeSubStrVectors("abcdefghijklmn", -12, 14, true),
+			proc:       procs,
+			wantBytes:  []byte("cdefghijklmn"),
+			wantScalar: true,
+		},
+		{
+			name:       "Test22",
+			vecs:       makeSubStrVectors("abcdefghijklmn", -12, 0, true),
+			proc:       procs,
+			wantBytes:  []byte(""),
+			wantScalar: true,
+		},
+		{
+			name:       "Test23",
+			vecs:       makeSubStrVectors("abcdefghijklmn", -6, -5, true),
+			proc:       procs,
+			wantBytes:  []byte("ijk"),
+			wantScalar: true,
+		},
+		{
+			name:       "Test24",
+			vecs:       makeSubStrVectors("abcdefghijklmn", -6, -10, true),
+			proc:       procs,
+			wantBytes:  []byte(""),
+			wantScalar: true,
+		},
+		{
+			name:       "Test25",
+			vecs:       makeSubStrVectors("abcdefghijklmn", -6, -1, true),
+			proc:       procs,
+			wantBytes:  []byte("ijklmn"),
+			wantScalar: true,
+		},
+	}
+
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			substr, err := Substring(c.vecs, c.proc)
+			if err != nil {
+				t.Fatal(err)
+			}
+			col := substr.Col.(*types.Bytes)
+			offset := col.Offsets[0]
+			length := col.Lengths[0]
+			resBytes := col.Data[offset:length]
+			require.Equal(t, c.wantBytes, resBytes)
+			require.Equal(t, c.wantScalar, substr.IsScalar())
+		})
+	}
+}
+
+func makeProcess() *process.Process {
+	hm := host.New(1 << 40)
+	gm := guest.New(1<<40, hm)
+	return process.New(mheap.New(gm))
+}
+
+// Construct vector parameter of substring function
+func makeSubStrVectors(src string, start int64, length int64, withLength bool) []*vector.Vector {
+	vec := make([]*vector.Vector, 2)
+	srcBytes := &types.Bytes{
+		Data:    []byte(src),
+		Offsets: []uint32{0},
+		Lengths: []uint32{uint32(len(src))},
+	}
+
+	vec[0] = &vector.Vector{
+		Col:     srcBytes,
+		Nsp:     &nulls.Nulls{},
+		Typ:     types.Type{Oid: types.T_varchar, Size: 24},
+		IsConst: true,
+		Length:  10,
+	}
+
+	vec[1] = &vector.Vector{
+		Col:     []int64{start},
+		Nsp:     &nulls.Nulls{},
+		Typ:     types.Type{Oid: types.T_int64},
+		IsConst: true,
+		Length:  10,
+	}
+	if withLength {
+		vec = append(vec, &vector.Vector{
+			Col:     []int64{length},
+			Nsp:     &nulls.Nulls{},
+			Typ:     types.Type{Oid: types.T_int64},
+			IsConst: true,
+			Length:  10,
+		})
+	}
+	return vec
+}
diff --git a/pkg/sql/plan2/function/operator/div.go b/pkg/sql/plan2/function/operator/div.go
index 05e7cfe5244498804c1bff230c9c4c8ca8567fef..1fea53547b3d0b23129818abe32acf91e1dfdf67 100644
--- a/pkg/sql/plan2/function/operator/div.go
+++ b/pkg/sql/plan2/function/operator/div.go
@@ -181,7 +181,7 @@ func DivDecimal64(vectors []*vector.Vector, proc *process.Process) (*vector.Vect
 	case lv.IsScalar() && !rv.IsScalar():
 		if !nulls.Any(rv.Nsp) {
 			for _, v := range rvs {
-				if int64(v) != 0 {
+				if int64(v) == 0 {
 					return nil, ErrDivByZero
 				}
 			}
diff --git a/pkg/sql/plan2/function/operator/div_test.go b/pkg/sql/plan2/function/operator/div_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..f81f52be97b7f69a8237d8673589eab84f1bcf2c
--- /dev/null
+++ b/pkg/sql/plan2/function/operator/div_test.go
@@ -0,0 +1,231 @@
+// Copyright 2022 Matrix Origin
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package operator
+
+import (
+	"github.com/matrixorigin/matrixone/pkg/container/nulls"
+	"github.com/matrixorigin/matrixone/pkg/container/types"
+	"github.com/matrixorigin/matrixone/pkg/container/vector"
+	"github.com/matrixorigin/matrixone/pkg/vm/process"
+	"github.com/stretchr/testify/require"
+	"golang.org/x/exp/constraints"
+	"testing"
+)
+
+func TestDiv(t *testing.T) {
+	divFloat[float32](t, types.T_float32, 235, 7.5, 31.333334)
+	divFloat[float64](t, types.T_float64, 235, 7.5, 31.333333333333332)
+
+	leftType1 := types.Type{Oid: types.T_decimal64, Size: 8, Width: 10, Scale: 5}
+	rightType1 := types.Type{Oid: types.T_decimal64, Size: 8, Width: 10, Scale: 5}
+	resType1 := types.Type{Oid: types.T_decimal128, Size: 16, Width: 38, Scale: 5}
+	divDecimal64(t, 33333300, leftType1, -123450000, rightType1, types.Decimal128{Lo: -27001, Hi: -1}, resType1)
+
+	leftType2 := types.Type{Oid: types.T_decimal128, Size: 16, Width: 20, Scale: 5}
+	rightType2 := types.Type{Oid: types.T_decimal128, Size: 16, Width: 20, Scale: 5}
+	resType2 := types.Type{Oid: types.T_decimal128, Size: 16, Width: 38, Scale: 5}
+	divDecimal128(t, types.Decimal128{Lo: 33333300, Hi: 0}, leftType2, types.Decimal128{Lo: -123450000, Hi: -1}, rightType2,
+		types.Decimal128{Lo: -27001, Hi: -1}, resType2)
+}
+
+// Unit test input of int and float parameters of div operator
+func divFloat[T constraints.Float](t *testing.T, typ types.T, left T, right T, res T) {
+	procs := makeProcess()
+	cases := []struct {
+		name       string
+		vecs       []*vector.Vector
+		proc       *process.Process
+		wantBytes  interface{}
+		wantScalar bool
+	}{
+		{
+			name:       "TEST01",
+			vecs:       makeDivVectors[T](left, true, right, true, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: true,
+		},
+		{
+			name:       "TEST02",
+			vecs:       makeDivVectors[T](left, false, right, true, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: false,
+		},
+		{
+			name:       "TEST03",
+			vecs:       makeDivVectors[T](left, true, right, false, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: false,
+		},
+		{
+			name:       "TEST04",
+			vecs:       makeDivVectors[T](left, false, right, false, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: false,
+		},
+	}
+
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			plus, err := Div[T](c.vecs, c.proc)
+			if err != nil {
+				t.Fatal(err)
+			}
+			require.Equal(t, c.wantBytes, plus.Col, 0.000001)
+			require.Equal(t, c.wantScalar, plus.IsScalar())
+		})
+	}
+}
+
+// Construct vector parameters of div operator
+func makeDivVectors[T constraints.Float](left T, leftScalar bool, right T, rightScalar bool, t types.T) []*vector.Vector {
+	vectors := make([]*vector.Vector, 2)
+	vectors[0] = &vector.Vector{
+		Col:     []T{left},
+		Nsp:     &nulls.Nulls{},
+		Typ:     types.Type{Oid: t},
+		IsConst: leftScalar,
+		Length:  1,
+	}
+	vectors[1] = &vector.Vector{
+		Col:     []T{right},
+		Nsp:     &nulls.Nulls{},
+		Typ:     types.Type{Oid: t},
+		IsConst: rightScalar,
+		Length:  1,
+	}
+	return vectors
+}
+
+// Decimal64 parameter unit test input of div operator
+func divDecimal64(t *testing.T, left types.Decimal64, leftType types.Type, right types.Decimal64, rightType types.Type,
+	res types.Decimal128, restType types.Type) {
+	procs := makeProcess()
+	cases := []struct {
+		name       string
+		vecs       []*vector.Vector
+		proc       *process.Process
+		wantBytes  interface{}
+		wantType   types.Type
+		wantScalar bool
+	}{
+		{
+			name:       "TEST01",
+			vecs:       makeDecimal64Vectors(left, leftType, true, right, rightType, true),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   restType,
+			wantScalar: true,
+		},
+		{
+			name:       "TEST02",
+			vecs:       makeDecimal64Vectors(left, leftType, false, right, rightType, true),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   restType,
+			wantScalar: false,
+		},
+		{
+			name:       "TEST03",
+			vecs:       makeDecimal64Vectors(left, leftType, true, right, rightType, false),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   restType,
+			wantScalar: false,
+		},
+		{
+			name:       "TEST04",
+			vecs:       makeDecimal64Vectors(left, leftType, false, right, rightType, false),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   restType,
+			wantScalar: false,
+		},
+	}
+
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			decimalres, err := DivDecimal64(c.vecs, c.proc)
+			if err != nil {
+				t.Fatal(err)
+			}
+			require.Equal(t, c.wantBytes, decimalres.Col)
+			require.Equal(t, c.wantType, decimalres.Typ)
+			require.Equal(t, c.wantScalar, decimalres.IsScalar())
+		})
+	}
+}
+
+// Decimal128 parameter unit test input of div operator
+func divDecimal128(t *testing.T, left types.Decimal128, leftType types.Type, right types.Decimal128, rightType types.Type,
+	res types.Decimal128, restType types.Type) {
+	procs := makeProcess()
+	cases := []struct {
+		name       string
+		vecs       []*vector.Vector
+		proc       *process.Process
+		wantBytes  interface{}
+		wantType   types.Type
+		wantScalar bool
+	}{
+		{
+			name:       "TEST01",
+			vecs:       makeDecimal128Vectors(left, leftType, true, right, rightType, true),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   restType,
+			wantScalar: true,
+		},
+		{
+			name:       "TEST02",
+			vecs:       makeDecimal128Vectors(left, leftType, false, right, rightType, true),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   restType,
+			wantScalar: false,
+		},
+		{
+			name:       "TEST03",
+			vecs:       makeDecimal128Vectors(left, leftType, true, right, rightType, false),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   restType,
+			wantScalar: false,
+		},
+		{
+			name:       "TEST04",
+			vecs:       makeDecimal128Vectors(left, leftType, false, right, rightType, false),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   restType,
+			wantScalar: false,
+		},
+	}
+
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			decimalres, err := DivDecimal128(c.vecs, c.proc)
+			if err != nil {
+				t.Fatal(err)
+			}
+			require.Equal(t, c.wantBytes, decimalres.Col)
+			require.Equal(t, c.wantType, decimalres.Typ)
+			require.Equal(t, c.wantScalar, decimalres.IsScalar())
+		})
+	}
+}
diff --git a/pkg/sql/plan2/function/operator/integerdiv_test.go b/pkg/sql/plan2/function/operator/integerdiv_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..7d608a893d073e4b3d83d6654fa38127c959aea1
--- /dev/null
+++ b/pkg/sql/plan2/function/operator/integerdiv_test.go
@@ -0,0 +1,102 @@
+// Copyright 2022 Matrix Origin
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package operator
+
+import (
+	"github.com/matrixorigin/matrixone/pkg/container/nulls"
+	"github.com/matrixorigin/matrixone/pkg/container/types"
+	"github.com/matrixorigin/matrixone/pkg/container/vector"
+	"github.com/matrixorigin/matrixone/pkg/vm/process"
+	"github.com/stretchr/testify/require"
+	"golang.org/x/exp/constraints"
+	"testing"
+)
+
+func TestIntegerDiv(t *testing.T) {
+	integerDivFloat[float32](t, types.T_float32, 235, 7.5, 31)
+	integerDivFloat[float64](t, types.T_float64, 21.45, 40.55, 0)
+}
+
+// Unit test input of float type parameter of integerdiv operator
+func integerDivFloat[T constraints.Float](t *testing.T, typ types.T, left T, right T, res int64) {
+	procs := makeProcess()
+	cases := []struct {
+		name       string
+		vecs       []*vector.Vector
+		proc       *process.Process
+		wantBytes  interface{}
+		wantScalar bool
+	}{
+		{
+			name:       "TEST01",
+			vecs:       makeIntegerDivVectors[T](left, true, right, true, typ),
+			proc:       procs,
+			wantBytes:  []int64{res},
+			wantScalar: true,
+		},
+		{
+			name:       "TEST02",
+			vecs:       makeIntegerDivVectors[T](left, false, right, true, typ),
+			proc:       procs,
+			wantBytes:  []int64{res},
+			wantScalar: false,
+		},
+		{
+			name:       "TEST03",
+			vecs:       makeIntegerDivVectors[T](left, true, right, false, typ),
+			proc:       procs,
+			wantBytes:  []int64{res},
+			wantScalar: false,
+		},
+		{
+			name:       "TEST04",
+			vecs:       makeIntegerDivVectors[T](left, false, right, false, typ),
+			proc:       procs,
+			wantBytes:  []int64{res},
+			wantScalar: false,
+		},
+	}
+
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			plus, err := IntegerDiv[T](c.vecs, c.proc)
+			if err != nil {
+				t.Fatal(err)
+			}
+			require.Equal(t, c.wantBytes, plus.Col)
+			require.Equal(t, c.wantScalar, plus.IsScalar())
+		})
+	}
+}
+
+// Construct the vector parameters of the integerdiv operator
+func makeIntegerDivVectors[T constraints.Float](left T, leftScalar bool, right T, rightScalar bool, t types.T) []*vector.Vector {
+	vectors := make([]*vector.Vector, 2)
+	vectors[0] = &vector.Vector{
+		Col:     []T{left},
+		Nsp:     &nulls.Nulls{},
+		Typ:     types.Type{Oid: t},
+		IsConst: leftScalar,
+		Length:  1,
+	}
+	vectors[1] = &vector.Vector{
+		Col:     []T{right},
+		Nsp:     &nulls.Nulls{},
+		Typ:     types.Type{Oid: t},
+		IsConst: rightScalar,
+		Length:  1,
+	}
+	return vectors
+}
diff --git a/pkg/sql/plan2/function/operator/minus.go b/pkg/sql/plan2/function/operator/minus.go
index d9e7eeb4c2624858d8d83e638d771b637d74bbf2..a86e3f87d3c4edfdfb20ce0bce251f601f65ada7 100644
--- a/pkg/sql/plan2/function/operator/minus.go
+++ b/pkg/sql/plan2/function/operator/minus.go
@@ -55,7 +55,7 @@ func Minus[T constraints.Integer | constraints.Float](vectors []*vector.Vector,
 		}
 		resultValues := encoding.DecodeFixedSlice[T](resultVector.Data, resultElementSize)
 		nulls.Or(lv.Nsp, rv.Nsp, resultVector.Nsp)
-		vector.SetCol(resultVector, sub.NumericScalar(rvs[0], lvs, resultValues))
+		vector.SetCol(resultVector, sub.NumericByScalar(rvs[0], lvs, resultValues))
 		return resultVector, nil
 	default:
 		resultVector, err := proc.AllocVector(lv.Typ, int64(resultElementSize*len(lvs)))
@@ -109,7 +109,7 @@ func MinusDecimal64(vectors []*vector.Vector, proc *process.Process) (*vector.Ve
 		resultValues = resultValues[:len(lvs)]
 		nulls.Set(resultVector.Nsp, lv.Nsp)
 		nulls.Or(lv.Nsp, rv.Nsp, resultVector.Nsp)
-		vector.SetCol(resultVector, sub.Decimal64SubScalar(rvs[0], lvs, rvScale, lvScale, resultValues))
+		vector.SetCol(resultVector, sub.Decimal64SubByScalar(rvs[0], lvs, rvScale, lvScale, resultValues))
 		return resultVector, nil
 	default:
 		resultVector, err := proc.AllocVector(lv.Typ, int64(resultTyp.Size)*int64(len(lvs)))
@@ -163,7 +163,7 @@ func MinusDecimal128(vectors []*vector.Vector, proc *process.Process) (*vector.V
 		rs := encoding.DecodeDecimal128Slice(vec.Data)
 		rs = rs[:len(lvs)]
 		nulls.Or(lv.Nsp, rv.Nsp, vec.Nsp)
-		vector.SetCol(vec, sub.Decimal128SubScalar(rvs[0], lvs, rvScale, lvScale, rs))
+		vector.SetCol(vec, sub.Decimal128SubByScalar(rvs[0], lvs, rvScale, lvScale, rs))
 		return vec, nil
 	default:
 		vec, err := proc.AllocVector(resultTyp, int64(resultTyp.Size)*int64(len(lvs)))
diff --git a/pkg/sql/plan2/function/operator/minus_test.go b/pkg/sql/plan2/function/operator/minus_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..357ced50237f5a933b6eac3aadcc8d6e02a125e1
--- /dev/null
+++ b/pkg/sql/plan2/function/operator/minus_test.go
@@ -0,0 +1,242 @@
+// Copyright 2022 Matrix Origin
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package operator
+
+import (
+	"github.com/matrixorigin/matrixone/pkg/container/nulls"
+	"github.com/matrixorigin/matrixone/pkg/container/types"
+	"github.com/matrixorigin/matrixone/pkg/container/vector"
+	"github.com/matrixorigin/matrixone/pkg/vm/process"
+	"github.com/stretchr/testify/require"
+	"golang.org/x/exp/constraints"
+	"testing"
+)
+
+func TestMinus(t *testing.T) {
+	minusIntAndFloat[int8](t, types.T_int8, 26, 47, -21)
+	minusIntAndFloat[int16](t, types.T_int16, 26, 47, -21)
+	minusIntAndFloat[int32](t, types.T_int32, 26, 47, -21)
+	minusIntAndFloat[int64](t, types.T_int64, 26, 47, -21)
+
+	minusIntAndFloat[uint8](t, types.T_uint8, 100, 47, 53)
+	minusIntAndFloat[uint16](t, types.T_uint16, 100, 47, 53)
+	minusIntAndFloat[uint32](t, types.T_uint32, 100, 47, 53)
+	minusIntAndFloat[uint64](t, types.T_uint64, 100, 47, 53)
+
+	minusIntAndFloat[float32](t, types.T_float32, 95.46, 20, 75.46)
+	minusIntAndFloat[float64](t, types.T_float64, 95.46, 20, 75.46)
+
+	leftType1 := types.Type{Oid: types.T_decimal64, Size: 8, Width: 10, Scale: 5}
+	rightType1 := types.Type{Oid: types.T_decimal64, Size: 8, Width: 10, Scale: 5}
+	resType1 := types.Type{Oid: types.T_decimal64, Size: 8, Width: 18, Scale: 5}
+	minusDecimal64(t, 33333300, leftType1, -123450000, rightType1, 156783300, resType1)
+
+	leftType2 := types.Type{Oid: types.T_decimal128, Size: 16, Width: 20, Scale: 5}
+	rightType2 := types.Type{Oid: types.T_decimal128, Size: 16, Width: 20, Scale: 5}
+	resType2 := types.Type{Oid: types.T_decimal128, Size: 16, Width: 38, Scale: 5}
+	minusDecimal128(t, types.Decimal128{Lo: 33333300, Hi: 0}, leftType2, types.Decimal128{Lo: -123450000, Hi: -1}, rightType2, types.Decimal128{Lo: 156783300, Hi: 0}, resType2)
+
+}
+
+// Unit test input for int and float type parameters of the minus operator
+func minusIntAndFloat[T constraints.Integer | constraints.Float](t *testing.T, typ types.T, left T, right T, res T) {
+	procs := makeProcess()
+	cases := []struct {
+		name       string
+		vecs       []*vector.Vector
+		proc       *process.Process
+		wantBytes  interface{}
+		wantScalar bool
+	}{
+		{
+			name:       "TEST01",
+			vecs:       makeMinusVectors[T](left, true, right, true, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: true,
+		},
+		{
+			name:       "TEST02",
+			vecs:       makeMinusVectors[T](left, false, right, true, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: false,
+		},
+		{
+			name:       "TEST03",
+			vecs:       makeMinusVectors[T](left, true, right, false, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: false,
+		},
+		{
+			name:       "TEST04",
+			vecs:       makeMinusVectors[T](left, false, right, false, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: false,
+		},
+	}
+
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			plus, err := Minus[T](c.vecs, c.proc)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			require.Equal(t, c.wantBytes, plus.Col)
+			require.Equal(t, c.wantScalar, plus.IsScalar())
+		})
+	}
+}
+
+// Construct the vector parameters of the minus operator
+func makeMinusVectors[T constraints.Integer | constraints.Float](left T, leftScalar bool, right T, rightScalar bool, t types.T) []*vector.Vector {
+	vectors := make([]*vector.Vector, 2)
+	vectors[0] = &vector.Vector{
+		Col:     []T{left},
+		Nsp:     &nulls.Nulls{},
+		Typ:     types.Type{Oid: t},
+		IsConst: leftScalar,
+		Length:  1,
+	}
+	vectors[1] = &vector.Vector{
+		Col:     []T{right},
+		Nsp:     &nulls.Nulls{},
+		Typ:     types.Type{Oid: t},
+		IsConst: rightScalar,
+		Length:  1,
+	}
+	return vectors
+}
+
+// Unit test input of decimal64 parameter of minus operator
+func minusDecimal64(t *testing.T, left types.Decimal64, leftType types.Type, right types.Decimal64, rightType types.Type,
+	res types.Decimal64, restType types.Type) {
+	procs := makeProcess()
+	cases := []struct {
+		name       string
+		vecs       []*vector.Vector
+		proc       *process.Process
+		wantBytes  interface{}
+		wantType   types.Type
+		wantScalar bool
+	}{
+		{
+			name:       "TEST01",
+			vecs:       makeDecimal64Vectors(left, leftType, true, right, rightType, true),
+			proc:       procs,
+			wantBytes:  []types.Decimal64{res},
+			wantType:   restType,
+			wantScalar: true,
+		},
+		{
+			name:       "TEST02",
+			vecs:       makeDecimal64Vectors(left, leftType, false, right, rightType, true),
+			proc:       procs,
+			wantBytes:  []types.Decimal64{res},
+			wantType:   restType,
+			wantScalar: false,
+		},
+		{
+			name:       "TEST03",
+			vecs:       makeDecimal64Vectors(left, leftType, true, right, rightType, false),
+			proc:       procs,
+			wantBytes:  []types.Decimal64{res},
+			wantType:   restType,
+			wantScalar: false,
+		},
+		{
+			name:       "TEST04",
+			vecs:       makeDecimal64Vectors(left, leftType, false, right, rightType, false),
+			proc:       procs,
+			wantBytes:  []types.Decimal64{res},
+			wantType:   leftType,
+			wantScalar: false,
+		},
+	}
+
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			decimalres, err := MinusDecimal64(c.vecs, c.proc)
+			if err != nil {
+				t.Fatal(err)
+			}
+			require.Equal(t, c.wantBytes, decimalres.Col)
+			require.Equal(t, c.wantType, decimalres.Typ)
+			require.Equal(t, c.wantScalar, decimalres.IsScalar())
+		})
+	}
+}
+
+// Unit test input of decimal128 parameter of minus operator
+func minusDecimal128(t *testing.T, left types.Decimal128, leftType types.Type, right types.Decimal128, rightType types.Type,
+	res types.Decimal128, resType types.Type) {
+	procs := makeProcess()
+	cases := []struct {
+		name       string
+		vecs       []*vector.Vector
+		proc       *process.Process
+		wantBytes  interface{}
+		wantType   types.Type
+		wantScalar bool
+	}{
+		{
+			name:       "TEST01",
+			vecs:       makeDecimal128Vectors(left, leftType, true, right, rightType, true),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   resType,
+			wantScalar: true,
+		},
+		{
+			name:       "TEST02",
+			vecs:       makeDecimal128Vectors(left, leftType, false, right, rightType, true),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   resType,
+			wantScalar: false,
+		},
+		{
+			name:       "TEST03",
+			vecs:       makeDecimal128Vectors(left, leftType, true, right, rightType, false),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   resType,
+			wantScalar: false,
+		},
+		{
+			name:       "TEST04",
+			vecs:       makeDecimal128Vectors(left, leftType, false, right, rightType, false),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   resType,
+			wantScalar: false,
+		},
+	}
+
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			decimalres, err := MinusDecimal128(c.vecs, c.proc)
+			if err != nil {
+				t.Fatal(err)
+			}
+			require.Equal(t, c.wantBytes, decimalres.Col)
+			require.Equal(t, c.wantType, decimalres.Typ)
+			require.Equal(t, c.wantScalar, decimalres.IsScalar())
+		})
+	}
+}
diff --git a/pkg/sql/plan2/function/operator/mod.go b/pkg/sql/plan2/function/operator/mod.go
index c68441d2a74ed96b0c9b2002b7ab00d06c6b8618..7f41eaaf2ad60367bc3e544f89118beff80626b6 100644
--- a/pkg/sql/plan2/function/operator/mod.go
+++ b/pkg/sql/plan2/function/operator/mod.go
@@ -104,7 +104,7 @@ func ModInt[T constraints.Integer](vectors []*vector.Vector, proc *process.Proce
 		}
 		rs := encoding.DecodeFixedSlice[T](vec.Data, rtl)
 		nulls.Set(vec.Nsp, lv.Nsp)
-		mod.IntModByScalar(rvs[0], lvs, rs)
+		vector.SetCol(vec, mod.IntModByScalar(rvs[0], lvs, rs))
 		return vec, nil
 	}
 	vec, err := proc.AllocVector(lv.Typ, int64(rtl)*int64(len(lvs)))
@@ -218,7 +218,7 @@ func ModFloat[T constraints.Float](vectors []*vector.Vector, proc *process.Proce
 		}
 		rs := encoding.DecodeFixedSlice[T](vec.Data, rtl)
 		nulls.Set(vec.Nsp, lv.Nsp)
-		mod.FloatModByScalar(rvs[0], lvs, rs)
+		vector.SetCol(vec, mod.FloatModByScalar(rvs[0], lvs, rs))
 		return vec, nil
 	}
 	vec, err := proc.AllocVector(lv.Typ, int64(rtl)*int64(len(lvs)))
diff --git a/pkg/sql/plan2/function/operator/mod_test.go b/pkg/sql/plan2/function/operator/mod_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..5f19de5fa4f6434d9034a57eb06a9aa0e8a74347
--- /dev/null
+++ b/pkg/sql/plan2/function/operator/mod_test.go
@@ -0,0 +1,164 @@
+// Copyright 2022 Matrix Origin
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package operator
+
+import (
+	"github.com/matrixorigin/matrixone/pkg/container/nulls"
+	"github.com/matrixorigin/matrixone/pkg/container/types"
+	"github.com/matrixorigin/matrixone/pkg/container/vector"
+	"github.com/matrixorigin/matrixone/pkg/vm/process"
+	"github.com/stretchr/testify/require"
+	"golang.org/x/exp/constraints"
+	"testing"
+)
+
+func TestMod(t *testing.T) {
+	modInteger[int8](t, types.T_int8, 28, -5, 3)
+	modInteger[int16](t, types.T_int16, 28, -5, 3)
+	modInteger[int32](t, types.T_int32, 28, -5, 3)
+	modInteger[int64](t, types.T_int64, 28, -5, 3)
+
+	modInteger[uint8](t, types.T_uint8, 28, 5, 3)
+	modInteger[uint16](t, types.T_uint16, 28, 5, 3)
+	modInteger[uint32](t, types.T_uint32, 28, 5, 3)
+	modInteger[uint64](t, types.T_uint64, 28, 5, 3)
+
+	modFloater[float32](t, types.T_float32, 24.45, 12.4, 0)
+	modFloater[float64](t, types.T_float64, 24.45, 12.4, 0)
+}
+
+// Integer unit test entry for mod operator
+func modInteger[T constraints.Integer](t *testing.T, typ types.T, left T, right T, res T) {
+	procs := makeProcess()
+	cases := []struct {
+		name       string
+		vecs       []*vector.Vector
+		proc       *process.Process
+		wantBytes  interface{}
+		wantScalar bool
+	}{
+		{
+			name:       "TEST01",
+			vecs:       makeModVectors[T](left, true, right, true, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: true,
+		},
+		{
+			name:       "TEST02",
+			vecs:       makeModVectors[T](left, false, right, true, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: false,
+		},
+		{
+			name:       "TEST03",
+			vecs:       makeModVectors[T](left, true, right, false, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: false,
+		},
+		{
+			name:       "TEST04",
+			vecs:       makeModVectors[T](left, false, right, false, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: false,
+		},
+	}
+
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			plus, err := ModInt[T](c.vecs, c.proc)
+			if err != nil {
+				t.Fatal(err)
+			}
+			require.Equal(t, c.wantBytes, plus.Col)
+			require.Equal(t, c.wantScalar, plus.IsScalar())
+		})
+	}
+}
+
+// Float unit test entry for mod operator
+func modFloater[T constraints.Float](t *testing.T, typ types.T, left T, right T, res T) {
+	procs := makeProcess()
+	cases := []struct {
+		name       string
+		vecs       []*vector.Vector
+		proc       *process.Process
+		wantBytes  interface{}
+		wantScalar bool
+	}{
+		{
+			name:       "TEST01",
+			vecs:       makeModVectors[T](left, true, right, true, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: true,
+		},
+		{
+			name:       "TEST02",
+			vecs:       makeModVectors[T](left, false, right, true, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: false,
+		},
+		{
+			name:       "TEST03",
+			vecs:       makeModVectors[T](left, true, right, false, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: false,
+		},
+		{
+			name:       "TEST04",
+			vecs:       makeModVectors[T](left, false, right, false, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: false,
+		},
+	}
+
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			plus, err := ModFloat[T](c.vecs, c.proc)
+			if err != nil {
+				t.Fatal(err)
+			}
+			require.Equal(t, c.wantBytes, plus.Col)
+			require.Equal(t, c.wantScalar, plus.IsScalar())
+		})
+	}
+}
+
+// Construct vector parameters of mod operator
+func makeModVectors[T constraints.Integer | constraints.Float](left T, leftScalar bool, right T, rightScalar bool, t types.T) []*vector.Vector {
+	vectors := make([]*vector.Vector, 2)
+	vectors[0] = &vector.Vector{
+		Col:     []T{left},
+		Nsp:     &nulls.Nulls{},
+		Typ:     types.Type{Oid: t},
+		IsConst: leftScalar,
+		Length:  1,
+	}
+	vectors[1] = &vector.Vector{
+		Col:     []T{right},
+		Nsp:     &nulls.Nulls{},
+		Typ:     types.Type{Oid: t},
+		IsConst: rightScalar,
+		Length:  1,
+	}
+	return vectors
+}
diff --git a/pkg/sql/plan2/function/operator/mult_test.go b/pkg/sql/plan2/function/operator/mult_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..f229abf6fe43e754288060ada76037dc33ab9a1b
--- /dev/null
+++ b/pkg/sql/plan2/function/operator/mult_test.go
@@ -0,0 +1,281 @@
+// Copyright 2022 Matrix Origin
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package operator
+
+import (
+	"github.com/matrixorigin/matrixone/pkg/container/nulls"
+	"github.com/matrixorigin/matrixone/pkg/container/types"
+	"github.com/matrixorigin/matrixone/pkg/container/vector"
+	"github.com/matrixorigin/matrixone/pkg/vm/process"
+	"github.com/stretchr/testify/require"
+	"golang.org/x/exp/constraints"
+	"testing"
+)
+
+func TestMult(t *testing.T) {
+	multIntAndFloat[int8](t, types.T_int8, 10, -5, -50)
+	multIntAndFloat[int16](t, types.T_int16, 10, -5, -50)
+	multIntAndFloat[int32](t, types.T_int32, 10, -5, -50)
+	multIntAndFloat[int64](t, types.T_int64, 10, -5, -50)
+
+	multIntAndFloat[uint8](t, types.T_uint8, 10, 5, 50)
+	multIntAndFloat[uint16](t, types.T_uint16, 10, 5, 50)
+	multIntAndFloat[uint32](t, types.T_uint32, 10, 5, 50)
+	multIntAndFloat[uint64](t, types.T_uint64, 10, 5, 50)
+
+	multIntAndFloat[float32](t, types.T_float32, 20.85, 12.5, 260.625)
+	multIntAndFloat[float64](t, types.T_float64, 20.85, 12.5, 260.625)
+
+	leftType1 := types.Type{Oid: types.T_decimal64, Size: 8, Width: 10, Scale: 5}
+	rightType1 := types.Type{Oid: types.T_decimal64, Size: 8, Width: 10, Scale: 5}
+	resType1 := types.Type{Oid: types.T_decimal128, Size: 16, Width: 38, Scale: 10}
+	multDecimal64(t, 33333300, leftType1, -123450000, rightType1, types.Decimal128{Lo: -4114995885000000, Hi: -1}, resType1)
+
+	leftType2 := types.Type{Oid: types.T_decimal128, Size: 16, Width: 20, Scale: 5}
+	rightType2 := types.Type{Oid: types.T_decimal128, Size: 16, Width: 20, Scale: 5}
+	resType2 := types.Type{Oid: types.T_decimal128, Size: 16, Width: 38, Scale: 10}
+	multDecimal128(t, types.Decimal128{Lo: 33333300, Hi: 0}, leftType2, types.Decimal128{Lo: -123450000, Hi: -1}, rightType2,
+		types.Decimal128{Lo: -4114995885000000, Hi: -1}, resType2)
+}
+
+// Unit test input of int and float parameters of mult operator
+func multIntAndFloat[T constraints.Integer | constraints.Float](t *testing.T, typ types.T, left T, right T, res T) {
+	procs := makeProcess()
+	cases := []struct {
+		name       string
+		vecs       []*vector.Vector
+		proc       *process.Process
+		wantBytes  interface{}
+		wantScalar bool
+	}{
+		{
+			name:       "TEST01",
+			vecs:       makeMultVectors[T](left, true, right, true, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: true,
+		},
+		{
+			name:       "TEST02",
+			vecs:       makeMultVectors[T](left, false, right, true, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: false,
+		},
+		{
+			name:       "TEST03",
+			vecs:       makeMultVectors[T](left, true, right, false, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: false,
+		},
+		{
+			name:       "TEST04",
+			vecs:       makeMultVectors[T](left, false, right, false, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: false,
+		},
+	}
+
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			plus, err := Mult[T](c.vecs, c.proc)
+			if err != nil {
+				t.Fatal(err)
+			}
+			require.Equal(t, c.wantBytes, plus.Col)
+			require.Equal(t, c.wantScalar, plus.IsScalar())
+		})
+	}
+}
+
+// Construct vector parameter of mult operator
+func makeMultVectors[T constraints.Integer | constraints.Float](left T, leftScalar bool, right T, rightScalar bool, t types.T) []*vector.Vector {
+	vectors := make([]*vector.Vector, 2)
+	vectors[0] = &vector.Vector{
+		Col:     []T{left},
+		Nsp:     &nulls.Nulls{},
+		Typ:     types.Type{Oid: t},
+		IsConst: leftScalar,
+		Length:  1,
+	}
+	vectors[1] = &vector.Vector{
+		Col:     []T{right},
+		Nsp:     &nulls.Nulls{},
+		Typ:     types.Type{Oid: t},
+		IsConst: rightScalar,
+		Length:  1,
+	}
+	return vectors
+}
+
+// Unit test input of decimal64 parameter of mult operator
+func multDecimal64(t *testing.T, left types.Decimal64, leftType types.Type, right types.Decimal64, rightType types.Type,
+	res types.Decimal128, restType types.Type) {
+	procs := makeProcess()
+	cases := []struct {
+		name       string
+		vecs       []*vector.Vector
+		proc       *process.Process
+		wantBytes  interface{}
+		wantType   types.Type
+		wantScalar bool
+	}{
+		{
+			name:       "TEST01",
+			vecs:       makeDecimal64Vectors(left, leftType, true, right, rightType, true),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   restType,
+			wantScalar: true,
+		},
+		{
+			name:       "TEST02",
+			vecs:       makeDecimal64Vectors(left, leftType, false, right, rightType, true),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   restType,
+			wantScalar: false,
+		},
+		{
+			name:       "TEST03",
+			vecs:       makeDecimal64Vectors(left, leftType, true, right, rightType, false),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   restType,
+			wantScalar: false,
+		},
+		{
+			name:       "TEST04",
+			vecs:       makeDecimal64Vectors(left, leftType, false, right, rightType, false),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   restType,
+			wantScalar: false,
+		},
+	}
+
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			decimalres, err := MultDecimal64(c.vecs, c.proc)
+			if err != nil {
+				t.Fatal(err)
+			}
+			require.Equal(t, c.wantBytes, decimalres.Col)
+			require.Equal(t, c.wantType, decimalres.Typ)
+			require.Equal(t, c.wantScalar, decimalres.IsScalar())
+		})
+	}
+}
+
+// Unit test input of decimal128 parameter of mult operator
+func multDecimal128(t *testing.T, left types.Decimal128, leftType types.Type, right types.Decimal128, rightType types.Type,
+	res types.Decimal128, restType types.Type) {
+	procs := makeProcess()
+	cases := []struct {
+		name       string
+		vecs       []*vector.Vector
+		proc       *process.Process
+		wantBytes  interface{}
+		wantType   types.Type
+		wantScalar bool
+	}{
+		{
+			name:       "TEST01",
+			vecs:       makeDecimal128Vectors(left, leftType, true, right, rightType, true),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   restType,
+			wantScalar: true,
+		},
+		{
+			name:       "TEST02",
+			vecs:       makeDecimal128Vectors(left, leftType, false, right, rightType, true),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   restType,
+			wantScalar: false,
+		},
+		{
+			name:       "TEST03",
+			vecs:       makeDecimal128Vectors(left, leftType, true, right, rightType, false),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   restType,
+			wantScalar: false,
+		},
+		{
+			name:       "TEST04",
+			vecs:       makeDecimal128Vectors(left, leftType, false, right, rightType, false),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   restType,
+			wantScalar: false,
+		},
+	}
+
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			decimalres, err := MultDecimal128(c.vecs, c.proc)
+			if err != nil {
+				t.Fatal(err)
+			}
+			require.Equal(t, c.wantBytes, decimalres.Col)
+			require.Equal(t, c.wantType, decimalres.Typ)
+			require.Equal(t, c.wantScalar, decimalres.IsScalar())
+		})
+	}
+}
+
+// Building a vector slice with two decimal64 type elements
+func makeDecimal64Vectors(left types.Decimal64, leftType types.Type, leftScalar bool, right types.Decimal64, rightType types.Type, rightScalar bool) []*vector.Vector {
+	vectors := make([]*vector.Vector, 2)
+	vectors[0] = &vector.Vector{
+		Col:     []types.Decimal64{left},
+		Nsp:     &nulls.Nulls{},
+		Typ:     leftType,
+		IsConst: leftScalar,
+		Length:  1,
+	}
+	vectors[1] = &vector.Vector{
+		Col:     []types.Decimal64{right},
+		Nsp:     &nulls.Nulls{},
+		Typ:     rightType,
+		IsConst: rightScalar,
+		Length:  1,
+	}
+	return vectors
+}
+
+// Building a vector slice with two decimal128 type elements
+func makeDecimal128Vectors(left types.Decimal128, leftType types.Type, leftScalar bool, right types.Decimal128, rightType types.Type, rightScalar bool) []*vector.Vector {
+	vectors := make([]*vector.Vector, 2)
+	vectors[0] = &vector.Vector{
+		Col:     []types.Decimal128{left},
+		Nsp:     &nulls.Nulls{},
+		Typ:     leftType,
+		IsConst: leftScalar,
+		Length:  1,
+	}
+	vectors[1] = &vector.Vector{
+		Col:     []types.Decimal128{right},
+		Nsp:     &nulls.Nulls{},
+		Typ:     rightType,
+		IsConst: rightScalar,
+		Length:  1,
+	}
+	return vectors
+}
diff --git a/pkg/sql/plan2/function/operator/plus_test.go b/pkg/sql/plan2/function/operator/plus_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..eef54901a96d487d1cd7089f1c7aa776ab4b4623
--- /dev/null
+++ b/pkg/sql/plan2/function/operator/plus_test.go
@@ -0,0 +1,243 @@
+// Copyright 2022 Matrix Origin
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package operator
+
+import (
+	"github.com/matrixorigin/matrixone/pkg/container/nulls"
+	"github.com/matrixorigin/matrixone/pkg/container/types"
+	"github.com/matrixorigin/matrixone/pkg/container/vector"
+	"github.com/matrixorigin/matrixone/pkg/vm/process"
+	"github.com/stretchr/testify/require"
+	"golang.org/x/exp/constraints"
+	"testing"
+)
+
+func TestPlus(t *testing.T) {
+	plusIntAndFloat[int8](t, types.T_int8, 21, -41, -20)
+	plusIntAndFloat[int16](t, types.T_int16, 21, -41, -20)
+	plusIntAndFloat[int32](t, types.T_int32, 21, -41, -20)
+	plusIntAndFloat[int64](t, types.T_int64, 21, -41, -20)
+
+	plusIntAndFloat[uint8](t, types.T_uint8, 21, 47, 68)
+	plusIntAndFloat[uint16](t, types.T_uint16, 21, 47, 68)
+	plusIntAndFloat[uint32](t, types.T_uint32, 21, 47, 68)
+	plusIntAndFloat[uint64](t, types.T_uint64, 21, 47, 68)
+
+	plusIntAndFloat[float32](t, types.T_float32, 21.45, 40.55, 62)
+	plusIntAndFloat[float64](t, types.T_float64, 21.45, 40.55, 62)
+
+	leftType1 := types.Type{Oid: types.T_decimal64, Size: 8, Width: 10, Scale: 5}
+	rightType1 := types.Type{Oid: types.T_decimal64, Size: 8, Width: 10, Scale: 5}
+	resType1 := types.Type{Oid: types.T_decimal64, Size: 8, Width: 18, Scale: 5}
+	plusDecimal64(t, 33333300, leftType1, -123450000, rightType1, -90116700, resType1)
+
+	leftType2 := types.Type{Oid: types.T_decimal128, Size: 16, Width: 20, Scale: 5}
+	rightType2 := types.Type{Oid: types.T_decimal128, Size: 16, Width: 20, Scale: 5}
+	resType2 := types.Type{Oid: types.T_decimal128, Size: 16, Width: 38, Scale: 5}
+	plusDecimal128(t, types.Decimal128{Lo: 33333300, Hi: 0}, leftType2, types.Decimal128{Lo: -123450000, Hi: -1}, rightType2, types.Decimal128{Lo: -90116700, Hi: -1}, resType2)
+}
+
+// Unit test input for int and float type parameters of the plus operator
+func plusIntAndFloat[T constraints.Integer | constraints.Float](t *testing.T, typ types.T, left T, right T, res T) {
+	procs := makeProcess()
+	cases := []struct {
+		name       string
+		vecs       []*vector.Vector
+		proc       *process.Process
+		wantBytes  interface{}
+		wantScalar bool
+	}{
+		{
+			name:       "TEST01",
+			vecs:       makePlusVectors[T](left, true, right, true, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: true,
+		},
+		{
+			name:       "TEST02",
+			vecs:       makePlusVectors[T](left, false, right, true, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: false,
+		},
+		{
+			name:       "TEST03",
+			vecs:       makePlusVectors[T](left, true, right, false, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: false,
+		},
+		{
+			name:       "TEST04",
+			vecs:       makePlusVectors[T](left, false, right, false, typ),
+			proc:       procs,
+			wantBytes:  []T{res},
+			wantScalar: false,
+		},
+	}
+
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			plus, err := Plus[T](c.vecs, c.proc)
+			if err != nil {
+				t.Fatal(err)
+			}
+			require.Equal(t, c.wantBytes, plus.Col)
+			require.Equal(t, c.wantScalar, plus.IsScalar())
+		})
+	}
+}
+
+// Construct the vector parameter of the plus operator
+func makePlusVectors[T constraints.Integer | constraints.Float](left T, leftScalar bool, right T, rightScalar bool, t types.T) []*vector.Vector {
+	vectors := make([]*vector.Vector, 2)
+	vectors[0] = &vector.Vector{
+		Col:     []T{left},
+		Nsp:     &nulls.Nulls{},
+		Typ:     types.Type{Oid: t},
+		IsConst: leftScalar,
+		Length:  1,
+	}
+	vectors[1] = &vector.Vector{
+		Col:     []T{right},
+		Nsp:     &nulls.Nulls{},
+		Typ:     types.Type{Oid: t},
+		IsConst: rightScalar,
+		Length:  1,
+	}
+	return vectors
+}
+
+// Unit test input of decimal64 parameters of plus operator
+func plusDecimal64(t *testing.T, left types.Decimal64, leftType types.Type, right types.Decimal64, rightType types.Type,
+	res types.Decimal64, restType types.Type) {
+	procs := makeProcess()
+	cases := []struct {
+		name       string
+		vecs       []*vector.Vector
+		proc       *process.Process
+		wantBytes  interface{}
+		wantType   types.Type
+		wantScalar bool
+	}{
+		{
+			name:       "TEST01",
+			vecs:       makeDecimal64Vectors(left, leftType, true, right, rightType, true),
+			proc:       procs,
+			wantBytes:  []types.Decimal64{res},
+			wantType:   restType,
+			wantScalar: true,
+		},
+		{
+			name:       "TEST02",
+			vecs:       makeDecimal64Vectors(left, leftType, false, right, rightType, true),
+			proc:       procs,
+			wantBytes:  []types.Decimal64{res},
+			wantType:   restType,
+			wantScalar: false,
+		},
+		{
+			name:       "TEST03",
+			vecs:       makeDecimal64Vectors(left, leftType, true, right, rightType, false),
+			proc:       procs,
+			wantBytes:  []types.Decimal64{res},
+			wantType:   restType,
+			wantScalar: false,
+		},
+		{
+			name:       "TEST04",
+			vecs:       makeDecimal64Vectors(left, leftType, false, right, rightType, false),
+			proc:       procs,
+			wantBytes:  []types.Decimal64{res},
+			wantType:   leftType,
+			wantScalar: false,
+		},
+	}
+
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			decimalres, err := PlusDecimal64(c.vecs, c.proc)
+			if err != nil {
+				t.Fatal(err)
+			}
+			require.Equal(t, c.wantBytes, decimalres.Col)
+			require.Equal(t, c.wantType, decimalres.Typ)
+			require.Equal(t, c.wantScalar, decimalres.IsScalar())
+		})
+	}
+}
+
+// Unit test input of decimal128 parameter of plus operator
+func plusDecimal128(t *testing.T, left types.Decimal128, leftType types.Type, right types.Decimal128, rightType types.Type,
+	res types.Decimal128, resType types.Type) {
+	//leftType := types.Type{Oid: types.T_decimal128, Size: 16, Width: 20, Scale: 5}
+	//rightType := types.Type{Oid: types.T_decimal128, Size: 16, Width: 20, Scale: 5}
+
+	procs := makeProcess()
+	cases := []struct {
+		name       string
+		vecs       []*vector.Vector
+		proc       *process.Process
+		wantBytes  interface{}
+		wantType   types.Type
+		wantScalar bool
+	}{
+		{
+			name:       "TEST01",
+			vecs:       makeDecimal128Vectors(left, leftType, true, right, rightType, true),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   resType,
+			wantScalar: true,
+		},
+		{
+			name:       "TEST02",
+			vecs:       makeDecimal128Vectors(left, leftType, false, right, rightType, true),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   resType,
+			wantScalar: false,
+		},
+		{
+			name:       "TEST03",
+			vecs:       makeDecimal128Vectors(left, leftType, true, right, rightType, false),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   resType,
+			wantScalar: false,
+		},
+		{
+			name:       "TEST04",
+			vecs:       makeDecimal128Vectors(left, leftType, false, right, rightType, false),
+			proc:       procs,
+			wantBytes:  []types.Decimal128{res},
+			wantType:   leftType,
+			wantScalar: false,
+		},
+	}
+
+	for _, c := range cases {
+		t.Run(c.name, func(t *testing.T) {
+			decimalres, err := PlusDecimal128(c.vecs, c.proc)
+			if err != nil {
+				t.Fatal(err)
+			}
+			require.Equal(t, c.wantBytes, decimalres.Col)
+			require.Equal(t, c.wantType, decimalres.Typ)
+			require.Equal(t, c.wantScalar, decimalres.IsScalar())
+		})
+	}
+}
diff --git a/pkg/sql/plan2/function/operators.go b/pkg/sql/plan2/function/operators.go
index e625289895fb644cfbcc9756168ee9158173f9c2..2f7cb5792ee27147352ff1a778fed48dbc415943 100644
--- a/pkg/sql/plan2/function/operators.go
+++ b/pkg/sql/plan2/function/operators.go
@@ -1604,7 +1604,7 @@ var operators = map[int][]Function{
 			Index:       8,
 			Flag:        plan.Function_STRICT,
 			Layout:      BINARY_ARITHMETIC_OPERATOR,
-			Args:        []types.T{types.T_float32, types.T_float64},
+			Args:        []types.T{types.T_float32, types.T_float32},
 			ReturnTyp:   types.T_float32,
 			TypeCheckFn: strictTypeCheck,
 			Fn:          operator.Plus[float32],
@@ -1723,7 +1723,7 @@ var operators = map[int][]Function{
 			Index:       8,
 			Flag:        plan.Function_STRICT,
 			Layout:      BINARY_ARITHMETIC_OPERATOR,
-			Args:        []types.T{types.T_float32, types.T_float64},
+			Args:        []types.T{types.T_float32, types.T_float32},
 			ReturnTyp:   types.T_float32,
 			TypeCheckFn: strictTypeCheck,
 			Fn:          operator.Minus[float32],
@@ -1842,7 +1842,7 @@ var operators = map[int][]Function{
 			Index:       8,
 			Flag:        plan.Function_STRICT,
 			Layout:      BINARY_ARITHMETIC_OPERATOR,
-			Args:        []types.T{types.T_float32, types.T_float64},
+			Args:        []types.T{types.T_float32, types.T_float32},
 			ReturnTyp:   types.T_float32,
 			TypeCheckFn: strictTypeCheck,
 			Fn:          operator.Mult[float32],
@@ -2010,7 +2010,7 @@ var operators = map[int][]Function{
 			Index:       8,
 			Flag:        plan.Function_STRICT,
 			Layout:      BINARY_ARITHMETIC_OPERATOR,
-			Args:        []types.T{types.T_float32, types.T_float64},
+			Args:        []types.T{types.T_float32, types.T_float32},
 			ReturnTyp:   types.T_float32,
 			TypeCheckFn: strictTypeCheck,
 			Fn:          operator.ModFloat[float32],