diff --git a/docs/generated/sql/functions.md b/docs/generated/sql/functions.md index 51c6808db2ae..fbc56f9a5f41 100644 --- a/docs/generated/sql/functions.md +++ b/docs/generated/sql/functions.md @@ -865,6 +865,8 @@ has no relationship with the commit order of concurrent transactions.

from_uuid(val: bytes) → string

Converts the byte string representation of a UUID to its character string representation.

+get_bit(val: varbit, position: int) → int

extract a particular bit from a given array of bits

+
initcap(val: string) → string

Capitalizes the first letter of val.

left(input: bytes, return_set: int) → bytes

Returns the first return_set bytes from input.

@@ -1007,6 +1009,8 @@ has no relationship with the commit order of concurrent transactions.

rtrim(val: string) → string

Removes all spaces from the end (right-hand side) of val.

+set_bit(val: varbit, position: int, toSet: int) → varbit

Set particular bit in a given array of bits

+
sha1(bytes...) → string

Calculates the SHA1 hash value of a set of values.

sha1(string...) → string

Calculates the SHA1 hash value of a set of values.

diff --git a/pkg/sql/logictest/testdata/logic_test/builtin_function b/pkg/sql/logictest/testdata/logic_test/builtin_function index 34f94c34a215..f44f6e581d20 100644 --- a/pkg/sql/logictest/testdata/logic_test/builtin_function +++ b/pkg/sql/logictest/testdata/logic_test/builtin_function @@ -2563,3 +2563,25 @@ query T SELECT getdatabaseencoding() ---- UTF8 + +subtest get_bit + +query I +SELECT get_bit(B'100101110101', 3) UNION SELECT get_bit(B'100101110101', 2) +---- +1 +0 + +query error get_bit\(\): bit index 10 out of valid range \(0..4\) +SELECT get_bit(B'10110', 10) + +subtest set_bit + +query T +SELECT set_bit(B'1101010', 0, 0) UNION SELECT set_bit(B'1101010', 2, 1) +---- +0101010 +1111010 + +query error set_bit\(\): bit index 10 out of valid range \(0..6\) +SELECT set_bit(B'1101010', 10, 1) diff --git a/pkg/sql/sem/builtins/builtins.go b/pkg/sql/sem/builtins/builtins.go index 0b852662d2dd..1f7634036f19 100644 --- a/pkg/sql/sem/builtins/builtins.go +++ b/pkg/sql/sem/builtins/builtins.go @@ -321,6 +321,53 @@ var builtins = map[string]builtinDefinition{ "Supports encodings 'UTF8' and 'LATIN1'.", }), + // https://www.postgresql.org/docs/9.0/functions-binarystring.html#FUNCTIONS-BINARYSTRING-OTHER + "get_bit": makeBuiltin(tree.FunctionProperties{Category: categoryString}, + tree.Overload{ + Types: tree.ArgTypes{{"val", types.VarBit}, {"position", types.Int}}, + ReturnType: tree.FixedReturnType(types.Int), + Fn: func(_ *tree.EvalContext, args tree.Datums) (tree.Datum, error) { + val := tree.MustBeDBitArray(args[0]) + position := tree.MustBeDInt(args[1]) + + // Checking whether index asked is inside array of bits. + if position < 0 || uint(position) >= val.BitLen() { + return nil, pgerror.Newf( + pgcode.ArraySubscript, "bit index %d out of valid range (0..%d)", position, val.BitLen()-1) + } + return tree.NewDInt(tree.DInt(val.BitArray.String()[position] - '0')), nil + }, + Info: "extract a particular bit from a given array of bits", + }), + + // https://www.postgresql.org/docs/9.0/functions-binarystring.html#FUNCTIONS-BINARYSTRING-OTHER + "set_bit": makeBuiltin(tree.FunctionProperties{Category: categoryString}, + tree.Overload{ + Types: tree.ArgTypes{ + {"val", types.VarBit}, + {"position", types.Int}, + {"toSet", types.Int}, + }, + ReturnType: tree.FixedReturnType(types.VarBit), + Fn: func(_ *tree.EvalContext, args tree.Datums) (tree.Datum, error) { + val := tree.MustBeDBitArray(args[0]) + position := tree.MustBeDInt(args[1]) + toSet := tree.MustBeDInt(args[2]) + + // Checking whether index asked is inside array of bits. + if position < 0 || uint(position) >= val.BitLen() { + return nil, pgerror.Newf( + pgcode.ArraySubscript, "bit index %d out of valid range (0..%d)", position, val.BitLen()-1) + } + // Converted BitArray to rune format, and update the given index. + encodedString := []rune(val.BitArray.String()) + encodedString[position] = rune('0' + toSet) + + return tree.ParseDBitArray(string(encodedString)) + }, + Info: "Set particular bit in a given array of bits", + }), + "gen_random_uuid": makeBuiltin( tree.FunctionProperties{ Category: categoryIDGeneration,