Skip to content
Snippets Groups Projects
Unverified Commit 46f1fea8 authored by qingxinhome's avatar qingxinhome Committed by GitHub
Browse files

Support UUID function#4019 (#4474)

Support uuid function

Approved by: @aressu1985, @ouyuanning
parent f31effdd
No related branches found
No related tags found
No related merge requests found
......@@ -851,6 +851,11 @@ func bindFuncExprImplByPlanExpr(name string, args []*Expr) (*plan.Expr, error) {
}
}
if function.GetFunctionAppendHideArgByID(funcID) {
// Append a hidden parameter to the function. The default value is constant null
args = append(args, makePlan2NullConstExprWithType())
}
// return new expr
return &Expr{
Expr: &plan.Expr_F{
......
// Copyright 2021 - 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/google/uuid"
"github.com/matrixorigin/matrixone/pkg/common/moerr"
"github.com/matrixorigin/matrixone/pkg/container/types"
"github.com/matrixorigin/matrixone/pkg/container/vector"
"github.com/matrixorigin/matrixone/pkg/vm/process"
)
const UUID_LENGTH uint32 = 36
func UUID(inputVecs []*vector.Vector, proc *process.Process) (*vector.Vector, error) {
if len(inputVecs) != 1 {
return nil, moerr.NewError(moerr.INTERNAL_ERROR, "uuid function requires a hidden parameter")
}
rows := inputVecs[0].Length
resultType := types.T_varchar.ToType()
resultVector := vector.New(resultType)
results := &types.Bytes{
Data: make([]byte, int(UUID_LENGTH)*rows),
Offsets: make([]uint32, rows),
Lengths: make([]uint32, rows),
}
var retCursor uint32 = 0
for i := 0; i < rows; i++ {
id, err := uuid.NewUUID()
if err != nil {
return nil, moerr.NewError(moerr.INTERNAL_ERROR, "generation uuid error")
}
slice := []byte(id.String())
for _, b := range slice {
results.Data[retCursor] = b
retCursor++
}
if i != 0 {
results.Offsets[i] = results.Offsets[i-1] + results.Lengths[i-1]
} else {
results.Offsets[i] = uint32(0)
}
results.Lengths[i] = UUID_LENGTH
}
vector.SetCol(resultVector, results)
return resultVector, nil
}
// Copyright 2021 - 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/types"
"github.com/matrixorigin/matrixone/pkg/container/vector"
"github.com/matrixorigin/matrixone/pkg/testutil"
"github.com/stretchr/testify/require"
"testing"
)
// test return multi line
func TestUUID(t *testing.T) {
//scalar
vec := testutil.MakeScalarNull(5)
proc := testutil.NewProc()
res, err := UUID([]*vector.Vector{vec}, proc)
if err != nil {
t.Fatal(err)
}
bytes := res.Col.(*types.Bytes)
uuids := make([]string, 5)
for i := 0; i < 5; i++ {
offset := bytes.Offsets[i]
length := bytes.Lengths[i]
bytes := bytes.Data[offset : offset+length]
uuid := string(bytes)
uuids[i] = uuid
t.Log(uuid)
}
for i := 0; i < 5; i++ {
for j := 0; j < 5; j++ {
if i == j {
continue
}
require.NotEqual(t, uuids[i], uuids[j])
}
}
}
// test retuan one line
func TestUUID2(t *testing.T) {
//scalar
vec := testutil.MakeScalarInt64(1, 1)
proc := testutil.NewProc()
res, err := UUID([]*vector.Vector{vec}, proc)
if err != nil {
t.Fatal(err)
}
bytes := res.Col.(*types.Bytes)
uuids := make([]string, 1)
for i := 0; i < 1; i++ {
offset := bytes.Offsets[i]
length := bytes.Lengths[i]
bytes := bytes.Data[offset : offset+length]
uuid := string(bytes)
uuids[i] = uuid
t.Log(uuid)
}
}
......@@ -174,6 +174,26 @@ var builtins = map[int]Functions{
},
},
},
UUID: {
// uuid function contains a hidden placeholder parameter
Id: UUID,
TypeCheckFn: func(_ []Function, inputs []types.T) (overloadIndex int32, ts []types.T) {
if len(inputs) == 0 {
return int32(0), nil
}
return wrongFunctionParameters, nil
},
Overloads: []Function{
{
Index: 0,
Flag: plan.Function_STRICT,
Layout: STANDARD_FUNCTION,
Volatile: true,
AppendHideArg: true,
ReturnTyp: types.T_varchar, Fn: multi.UUID,
},
},
},
DATE: {
Id: DATE,
Overloads: []Function{
......
......@@ -115,6 +115,9 @@ type Function struct {
// Volatile function cannot be fold
Volatile bool
// whether the function needs to append a hidden parameter, such as 'uuid'
AppendHideArg bool
Flag plan.Function_FuncFlag
// Layout adapt to plan/function.go, used for `explain SQL`.
......@@ -202,6 +205,15 @@ func GetFunctionIsAggregateByName(name string) bool {
return len(fs) > 0 && fs[0].IsAggregate()
}
// Check whether the function needs to append a hidden parameter
func GetFunctionAppendHideArgByID(overloadID int64) bool {
function, err := GetFunctionByID(overloadID)
if err != nil {
return false
}
return function.AppendHideArg
}
// GetFunctionByName check a function exist or not according to input function name and arg types,
// if matches,
// return the encoded overload id and the overload's return type
......
......@@ -228,6 +228,7 @@ const (
ADD_FAULT_POINT // Add a fault point
REMOVE_FAULT_POINT // Remove
TRIGGER_FAULT_POINT // Trigger.
UUID
// FUNCTION_END_NUMBER is not a function, just a flag to record the max number of function.
// TODO: every one should put the new function id in front of this one if you want to make a new function.
......@@ -373,6 +374,7 @@ var functionIdRegister = map[string]int32{
"add_fault_point": ADD_FAULT_POINT,
"remove_fault_point": REMOVE_FAULT_POINT,
"trigger_fault_point": TRIGGER_FAULT_POINT,
"uuid": UUID,
}
func GetFunctionIsWinfunByName(name string) bool {
......
create table t1(a INT, b float);
insert into t1 values(12124, -4213.413), (12124, -42413.409);
SELECT length(uuid()) FROM t1;
SELECT uuid(1) FROM t1;
drop table t1;
\ No newline at end of file
create table t1(a INT, b float);
insert into t1 values(12124, -4213.413), (12124, -42413.409);
SELECT length(uuid()) FROM t1;
length(uuid())
36
36
SELECT uuid(1) FROM t1;
Function 'uuid' with parameters [BIGINT] will be implemented in future version.
drop table t1;
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