Skip to content
Snippets Groups Projects
Unverified Commit f5ebc6dc authored by ou yuanning's avatar ou yuanning Committed by GitHub
Browse files

Add bit or/and/xor function (#4471)

Add bit or/and/xor function support.
(they are bit operator, not bool, not agg)

Approved by: @aressu1985, @aunjgr
parent 76a720f0
No related branches found
No related tags found
No related merge requests found
......@@ -409,6 +409,12 @@ func (b *baseBinder) bindBinaryExpr(astExpr *tree.BinaryExpr, depth int32, isRoo
return b.bindFuncExprImplByAstExpr("/", []tree.Expr{astExpr.Left, astExpr.Right}, depth)
case tree.INTEGER_DIV:
return b.bindFuncExprImplByAstExpr("div", []tree.Expr{astExpr.Left, astExpr.Right}, depth)
case tree.BIT_XOR:
return b.bindFuncExprImplByAstExpr("^", []tree.Expr{astExpr.Left, astExpr.Right}, depth)
case tree.BIT_OR:
return b.bindFuncExprImplByAstExpr("|", []tree.Expr{astExpr.Left, astExpr.Right}, depth)
case tree.BIT_AND:
return b.bindFuncExprImplByAstExpr("&", []tree.Expr{astExpr.Left, astExpr.Right}, depth)
}
return nil, errors.New("", fmt.Sprintf("'%v' operator is not supported now", astExpr.Op.ToString()))
}
......
......@@ -50,6 +50,9 @@ const (
ISNOT //ISNOT
ISNULL //ISNULL
ISNOTNULL //ISNOTNULL
OP_BIT_AND // &
OP_BIT_OR // |
OP_BIT_XOR // ^
ABS // ABS
ACOS // ACOS
......@@ -273,6 +276,9 @@ var functionIdRegister = map[string]int32{
"ifnull": ISNULL,
"is_not_null": ISNOTNULL,
"isnotnull": ISNOTNULL,
"&": OP_BIT_AND,
"|": OP_BIT_OR,
"^": OP_BIT_XOR,
// aggregate
"max": MAX,
"min": MIN,
......
// 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/vector"
"github.com/matrixorigin/matrixone/pkg/vm/process"
"golang.org/x/exp/constraints"
)
type opBitT interface {
constraints.Integer
}
type opBitFun[T opBitT] func(v1, v2 T) T
func opBitXor[T opBitT](v1, v2 T) T {
return v1 ^ v2
}
func opBitOr[T opBitT](v1, v2 T) T {
return v1 | v2
}
func opBitAnd[T opBitT](v1, v2 T) T {
return v1 & v2
}
func OpBitAndFun[T opBitT](args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
return Arith[T, T](args, proc, args[0].GetType(), func(xs, ys, rs *vector.Vector) error {
return goOpBitGeneral(xs, ys, rs, opBitAnd[T])
})
}
func OpBitOrFun[T opBitT](args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
return Arith[T, T](args, proc, args[0].GetType(), func(xs, ys, rs *vector.Vector) error {
return goOpBitGeneral(xs, ys, rs, opBitOr[T])
})
}
func OpBitXorFun[T opBitT](args []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
return Arith[T, T](args, proc, args[0].GetType(), func(xs, ys, rs *vector.Vector) error {
return goOpBitGeneral(xs, ys, rs, opBitXor[T])
})
}
func goOpBitGeneral[T opBitT](xs, ys, rs *vector.Vector, bfn opBitFun[T]) error {
xt, yt, rt := vector.MustTCols[T](xs), vector.MustTCols[T](ys), vector.MustTCols[T](rs)
if xs.IsScalar() {
if nulls.Any(ys.Nsp) {
for i, y := range yt {
if !nulls.Contains(rs.Nsp, uint64(i)) {
rt[i] = bfn(xt[0], y)
}
}
} else {
for i, y := range yt {
rt[i] = bfn(xt[0], y)
}
}
return nil
} else if ys.IsScalar() {
if nulls.Any(xs.Nsp) {
for i, x := range xt {
if !nulls.Contains(rs.Nsp, uint64(i)) {
rt[i] = bfn(x, yt[0])
}
}
} else {
for i, x := range xt {
rt[i] = bfn(x, yt[0])
}
}
return nil
} else {
if nulls.Any(rs.Nsp) {
for i, x := range xt {
if !nulls.Contains(rs.Nsp, uint64(i)) {
rt[i] = bfn(x, yt[i])
}
}
} else {
for i, x := range xt {
rt[i] = bfn(x, yt[i])
}
}
return nil
}
}
// 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 (
"fmt"
"testing"
"github.com/matrixorigin/matrixone/pkg/container/vector"
"github.com/matrixorigin/matrixone/pkg/testutil"
"github.com/stretchr/testify/require"
)
func TestOpXorGeneral(t *testing.T) {
testCases := []arg{
{
info: "1 ^ 2", proc: testutil.NewProc(),
vs: []*vector.Vector{
testutil.MakeScalarInt64(1, 1),
testutil.MakeScalarInt64(2, 1),
},
match: true,
err: false,
expect: testutil.MakeScalarInt64(3, 1),
},
{
info: "-1 ^ 2", proc: testutil.NewProc(),
vs: []*vector.Vector{
testutil.MakeScalarInt64(-1, 1),
testutil.MakeScalarInt64(2, 1),
},
match: true,
err: false,
expect: testutil.MakeScalarInt64(-3, 1),
},
{
info: "null ^ 2", proc: testutil.NewProc(),
vs: []*vector.Vector{
testutil.MakeScalarNull(1),
testutil.MakeScalarInt64(2, 1),
},
match: true,
err: false,
expect: testutil.MakeScalarNull(1),
},
{
info: "a ^ 2", proc: testutil.NewProc(),
vs: []*vector.Vector{
testutil.MakeInt64Vector([]int64{-1, 0, 3, 0}, []uint64{1, 3}),
testutil.MakeScalarInt64(2, 1),
},
match: true,
err: false,
expect: testutil.MakeInt64Vector([]int64{-3, 0, 1, 0}, []uint64{1, 3}),
},
{
info: "a ^ b", proc: testutil.NewProc(),
vs: []*vector.Vector{
testutil.MakeInt64Vector([]int64{-1, 0, 3, 0}, []uint64{1, 3}),
testutil.MakeInt64Vector([]int64{2, 3, 2, 4}, []uint64{1, 3}),
},
match: true,
err: false,
expect: testutil.MakeInt64Vector([]int64{-3, 0, 1, 0}, []uint64{1, 3}),
},
}
for i, tc := range testCases {
t.Run(tc.info, func(t *testing.T) {
got, ergot := OpBitXorFun[int64](tc.vs, tc.proc)
if tc.err {
require.Errorf(t, ergot, fmt.Sprintf("case '%d' expected error, but no error happens", i))
} else {
require.NoError(t, ergot)
require.True(t, testutil.CompareVectors(tc.expect, got), "got vector is different with expected")
}
})
}
}
func TestOpOrGeneral(t *testing.T) {
testCases := []arg{
{
info: "1 | 2", proc: testutil.NewProc(),
vs: []*vector.Vector{
testutil.MakeScalarInt64(1, 1),
testutil.MakeScalarInt64(2, 1),
},
match: true,
err: false,
expect: testutil.MakeScalarInt64(3, 1),
},
{
info: "-1 | 2", proc: testutil.NewProc(),
vs: []*vector.Vector{
testutil.MakeScalarInt64(-1, 1),
testutil.MakeScalarInt64(2, 1),
},
match: true,
err: false,
expect: testutil.MakeScalarInt64(-1, 1),
},
{
info: "null | 2", proc: testutil.NewProc(),
vs: []*vector.Vector{
testutil.MakeScalarNull(1),
testutil.MakeScalarInt64(2, 1),
},
match: true,
err: false,
expect: testutil.MakeScalarNull(1),
},
{
info: "a | 2", proc: testutil.NewProc(),
vs: []*vector.Vector{
testutil.MakeInt64Vector([]int64{1, 0, 3, 0}, []uint64{1, 3}),
testutil.MakeScalarInt64(2, 1),
},
match: true,
err: false,
expect: testutil.MakeInt64Vector([]int64{3, 0, 3, 0}, []uint64{1, 3}),
},
{
info: "a | b", proc: testutil.NewProc(),
vs: []*vector.Vector{
testutil.MakeInt64Vector([]int64{1, 0, 3, 0}, []uint64{1, 3}),
testutil.MakeInt64Vector([]int64{2, 3, 2, 4}, []uint64{1, 3}),
},
match: true,
err: false,
expect: testutil.MakeInt64Vector([]int64{3, 0, 3, 0}, []uint64{1, 3}),
},
}
for i, tc := range testCases {
t.Run(tc.info, func(t *testing.T) {
got, ergot := OpBitOrFun[int64](tc.vs, tc.proc)
if tc.err {
require.Errorf(t, ergot, fmt.Sprintf("case '%d' expected error, but no error happens", i))
} else {
require.NoError(t, ergot)
require.True(t, testutil.CompareVectors(tc.expect, got), "got vector is different with expected")
}
})
}
}
func TestOpAndGeneral(t *testing.T) {
testCases := []arg{
{
info: "1 & 2", proc: testutil.NewProc(),
vs: []*vector.Vector{
testutil.MakeScalarInt64(1, 1),
testutil.MakeScalarInt64(2, 1),
},
match: true,
err: false,
expect: testutil.MakeScalarInt64(0, 1),
},
{
info: "-1 & 2", proc: testutil.NewProc(),
vs: []*vector.Vector{
testutil.MakeScalarInt64(-1, 1),
testutil.MakeScalarInt64(2, 1),
},
match: true,
err: false,
expect: testutil.MakeScalarInt64(2, 1),
},
{
info: "null & 2", proc: testutil.NewProc(),
vs: []*vector.Vector{
testutil.MakeScalarNull(1),
testutil.MakeScalarInt64(2, 1),
},
match: true,
err: false,
expect: testutil.MakeScalarNull(1),
},
{
info: "a & 2", proc: testutil.NewProc(),
vs: []*vector.Vector{
testutil.MakeInt64Vector([]int64{1, 0, 3, 0}, []uint64{1, 3}),
testutil.MakeScalarInt64(2, 1),
},
match: true,
err: false,
expect: testutil.MakeInt64Vector([]int64{0, 0, 2, 0}, []uint64{1, 3}),
},
{
info: "a & b", proc: testutil.NewProc(),
vs: []*vector.Vector{
testutil.MakeInt64Vector([]int64{1, 0, 3, 0}, []uint64{1, 3}),
testutil.MakeInt64Vector([]int64{2, 3, 2, 4}, []uint64{1, 3}),
},
match: true,
err: false,
expect: testutil.MakeInt64Vector([]int64{0, 0, 2, 0}, []uint64{1, 3}),
},
}
for i, tc := range testCases {
t.Run(tc.info, func(t *testing.T) {
got, ergot := OpBitAndFun[int64](tc.vs, tc.proc)
if tc.err {
require.Errorf(t, ergot, fmt.Sprintf("case '%d' expected error, but no error happens", i))
} else {
require.NoError(t, ergot)
require.True(t, testutil.CompareVectors(tc.expect, got), "got vector is different with expected")
}
})
}
}
......@@ -427,6 +427,288 @@ var operators = map[int]Functions{
},
},
OP_BIT_XOR: {
Id: OP_BIT_XOR,
Overloads: []Function{
{
Index: 0,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_uint8,
types.T_uint8,
},
ReturnTyp: types.T_uint8,
Fn: operator.OpBitXorFun[uint8],
},
{
Index: 1,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_int8,
types.T_int8,
},
ReturnTyp: types.T_int8,
Fn: operator.OpBitXorFun[int8],
},
{
Index: 2,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_uint16,
types.T_uint16,
},
ReturnTyp: types.T_uint16,
Fn: operator.OpBitXorFun[uint16],
},
{
Index: 3,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_int16,
types.T_int16,
},
ReturnTyp: types.T_int16,
Fn: operator.OpBitXorFun[int16],
},
{
Index: 4,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_uint32,
types.T_uint32,
},
ReturnTyp: types.T_uint32,
Fn: operator.OpBitXorFun[uint32],
},
{
Index: 5,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_int32,
types.T_int32,
},
ReturnTyp: types.T_int32,
Fn: operator.OpBitXorFun[int32],
},
{
Index: 6,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_uint64,
types.T_uint64,
},
ReturnTyp: types.T_uint64,
Fn: operator.OpBitXorFun[uint64],
},
{
Index: 7,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_int64,
types.T_int64,
},
ReturnTyp: types.T_int64,
Fn: operator.OpBitXorFun[int64],
},
},
},
OP_BIT_OR: {
Id: OP_BIT_OR,
Overloads: []Function{
{
Index: 0,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_uint8,
types.T_uint8,
},
ReturnTyp: types.T_uint8,
Fn: operator.OpBitOrFun[uint8],
},
{
Index: 1,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_int8,
types.T_int8,
},
ReturnTyp: types.T_int8,
Fn: operator.OpBitOrFun[int8],
},
{
Index: 2,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_uint16,
types.T_uint16,
},
ReturnTyp: types.T_uint16,
Fn: operator.OpBitOrFun[uint16],
},
{
Index: 3,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_int16,
types.T_int16,
},
ReturnTyp: types.T_int16,
Fn: operator.OpBitOrFun[int16],
},
{
Index: 4,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_uint32,
types.T_uint32,
},
ReturnTyp: types.T_uint32,
Fn: operator.OpBitOrFun[uint32],
},
{
Index: 5,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_int32,
types.T_int32,
},
ReturnTyp: types.T_int32,
Fn: operator.OpBitOrFun[int32],
},
{
Index: 6,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_uint64,
types.T_uint64,
},
ReturnTyp: types.T_uint64,
Fn: operator.OpBitOrFun[uint64],
},
{
Index: 7,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_int64,
types.T_int64,
},
ReturnTyp: types.T_int64,
Fn: operator.OpBitOrFun[int64],
},
},
},
OP_BIT_AND: {
Id: OP_BIT_AND,
Overloads: []Function{
{
Index: 0,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_uint8,
types.T_uint8,
},
ReturnTyp: types.T_uint8,
Fn: operator.OpBitAndFun[uint8],
},
{
Index: 1,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_int8,
types.T_int8,
},
ReturnTyp: types.T_int8,
Fn: operator.OpBitAndFun[int8],
},
{
Index: 2,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_uint16,
types.T_uint16,
},
ReturnTyp: types.T_uint16,
Fn: operator.OpBitAndFun[uint16],
},
{
Index: 3,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_int16,
types.T_int16,
},
ReturnTyp: types.T_int16,
Fn: operator.OpBitAndFun[int16],
},
{
Index: 4,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_uint32,
types.T_uint32,
},
ReturnTyp: types.T_uint32,
Fn: operator.OpBitAndFun[uint32],
},
{
Index: 5,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_int32,
types.T_int32,
},
ReturnTyp: types.T_int32,
Fn: operator.OpBitAndFun[int32],
},
{
Index: 6,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_uint64,
types.T_uint64,
},
ReturnTyp: types.T_uint64,
Fn: operator.OpBitAndFun[uint64],
},
{
Index: 7,
Flag: plan.Function_STRICT,
Layout: COMPARISON_OPERATOR,
Args: []types.T{
types.T_int64,
types.T_int64,
},
ReturnTyp: types.T_int64,
Fn: operator.OpBitAndFun[int64],
},
},
},
ISNOT: {
Id: ISNOT,
Overloads: []Function{
......
......@@ -89,7 +89,7 @@ SELECT ((+0) IN
(32767.1)));
-- @bvt:issue#3619
-- @bvt:issue#3588
SELECT ((rpad(1.0,2048,1)) = ('4(') ^ (0.1));
-- @bvt:issue
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment