diff --git a/pkg/sql/plan/base_binder.go b/pkg/sql/plan/base_binder.go
index 3d3b2103e1929f496b0ea91e533494c2caff3566..d7b96790fa81dde9d471a388955c14d4105808b3 100644
--- a/pkg/sql/plan/base_binder.go
+++ b/pkg/sql/plan/base_binder.go
@@ -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{
diff --git a/pkg/sql/plan/function/builtin/multi/uuid.go b/pkg/sql/plan/function/builtin/multi/uuid.go
new file mode 100644
index 0000000000000000000000000000000000000000..bf71227288b01a2b8cc53ed8dcc57e5e3e17ca4e
--- /dev/null
+++ b/pkg/sql/plan/function/builtin/multi/uuid.go
@@ -0,0 +1,60 @@
+// 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
+}
diff --git a/pkg/sql/plan/function/builtin/multi/uuid_test.go b/pkg/sql/plan/function/builtin/multi/uuid_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..ae4a049b413dff222eb0dd54420ee2a62f1d6129
--- /dev/null
+++ b/pkg/sql/plan/function/builtin/multi/uuid_test.go
@@ -0,0 +1,78 @@
+// 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)
+	}
+}
diff --git a/pkg/sql/plan/function/builtins.go b/pkg/sql/plan/function/builtins.go
index 245d24864908561e62f14c6a50b8e33ec28c8e64..8f1552fb8e5f1620efa5517b5a8378002b60669e 100644
--- a/pkg/sql/plan/function/builtins.go
+++ b/pkg/sql/plan/function/builtins.go
@@ -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{
diff --git a/pkg/sql/plan/function/function.go b/pkg/sql/plan/function/function.go
index c69c9b506f6360133de0ddc367acf259769dc244..80482b2e4d6749b03a3f153dcecfe6d624ab59bc 100644
--- a/pkg/sql/plan/function/function.go
+++ b/pkg/sql/plan/function/function.go
@@ -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
diff --git a/pkg/sql/plan/function/function_id.go b/pkg/sql/plan/function/function_id.go
index 286bf94c6c5b1a58a4852fcb21e28c5f223c5174..a307d69e67de3b63ffb6d748a56217ffe03c83de 100644
--- a/pkg/sql/plan/function/function_id.go
+++ b/pkg/sql/plan/function/function_id.go
@@ -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 {
diff --git a/test/cases/function/func_string_uuid.test b/test/cases/function/func_string_uuid.test
new file mode 100644
index 0000000000000000000000000000000000000000..4b6b85ff19ab8e896a34efee76d020a268b15894
--- /dev/null
+++ b/test/cases/function/func_string_uuid.test
@@ -0,0 +1,5 @@
+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
diff --git a/test/result/function/func_string_uuid.result b/test/result/function/func_string_uuid.result
new file mode 100644
index 0000000000000000000000000000000000000000..f972c3044e66c36a4c071d0ab87abc8acd5671b5
--- /dev/null
+++ b/test/result/function/func_string_uuid.result
@@ -0,0 +1,9 @@
+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;