Skip to content

Commit

Permalink
sql: add get_bit() and set_bit() builtin functions for bits.
Browse files Browse the repository at this point in the history
refs cockroachdb#45851

This commit adds builtin function get_bit() and set_bit() for varbits,
along with thier respective testcases.

Characteristics of the above builtin functions are:
    * get_bit() allows us to extracts a bit at given index in
      the bit array.
    * set_bit() enable us updates a bit at given index in the
      bit array.

Release justification: low-risk addition of builtin functions.

Release note (sql change): This PR is introduced to add get_bits()
and set_bit() builtin functions for bits.
  • Loading branch information
abhishek20123g committed Mar 18, 2020
1 parent ae597d3 commit f114b42
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 0 deletions.
4 changes: 4 additions & 0 deletions docs/generated/sql/functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,8 @@ has no relationship with the commit order of concurrent transactions.</p>
</span></td></tr>
<tr><td><a name="from_uuid"></a><code>from_uuid(val: <a href="bytes.html">bytes</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Converts the byte string representation of a UUID to its character string representation.</p>
</span></td></tr>
<tr><td><a name="get_bit"></a><code>get_bit(bit_string: varbit, index: <a href="int.html">int</a>) &rarr; <a href="int.html">int</a></code></td><td><span class="funcdesc"><p>Extracts a bit at given index in the bit array</p>
</span></td></tr>
<tr><td><a name="initcap"></a><code>initcap(val: <a href="string.html">string</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Capitalizes the first letter of <code>val</code>.</p>
</span></td></tr>
<tr><td><a name="left"></a><code>left(input: <a href="bytes.html">bytes</a>, return_set: <a href="int.html">int</a>) &rarr; <a href="bytes.html">bytes</a></code></td><td><span class="funcdesc"><p>Returns the first <code>return_set</code> bytes from <code>input</code>.</p>
Expand Down Expand Up @@ -1007,6 +1009,8 @@ has no relationship with the commit order of concurrent transactions.</p>
</span></td></tr>
<tr><td><a name="rtrim"></a><code>rtrim(val: <a href="string.html">string</a>) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Removes all spaces from the end (right-hand side) of <code>val</code>.</p>
</span></td></tr>
<tr><td><a name="set_bit"></a><code>set_bit(bit_string: varbit, index: <a href="int.html">int</a>, to_set: <a href="int.html">int</a>) &rarr; varbit</code></td><td><span class="funcdesc"><p>Updates a bit at given index in the bit array</p>
</span></td></tr>
<tr><td><a name="sha1"></a><code>sha1(<a href="bytes.html">bytes</a>...) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Calculates the SHA1 hash value of a set of values.</p>
</span></td></tr>
<tr><td><a name="sha1"></a><code>sha1(<a href="string.html">string</a>...) &rarr; <a href="string.html">string</a></code></td><td><span class="funcdesc"><p>Calculates the SHA1 hash value of a set of values.</p>
Expand Down
43 changes: 43 additions & 0 deletions pkg/sql/logictest/testdata/logic_test/builtin_function
Original file line number Diff line number Diff line change
Expand Up @@ -2563,3 +2563,46 @@ query T
SELECT getdatabaseencoding()
----
UTF8

subtest get_bit

query I rowsort
SELECT get_bit(B'100101110101', 3) UNION SELECT get_bit(B'100101110101', 2)
----
1
0

query I rowsort
SELECT get_bit('000000'::varbit, 5) UNION SELECT get_bit('1111111'::varbit, 5)
----
1
0

query error get_bit\(\): GetBitAtIndex: bit index 10 out of valid range \(0..4\)
SELECT get_bit(B'10110', 10)

query error get_bit\(\): GetBitAtIndex: bit index 0 out of valid range \(0..-1\)
SELECT get_bit(B'', 0);

subtest set_bit

query T rowsort
SELECT set_bit(B'1101010', 0, 0) UNION SELECT set_bit(B'1101010', 2, 1)
----
0101010
1111010

query T rowsort
SELECT set_bit('000000'::varbit, 5, 1) UNION SELECT set_bit('111111'::varbit, 5, 0)
----
000001
111110

query error set_bit\(\): SetBitAtIndex: bit index 10 out of valid range \(0..6\)
SELECT set_bit(B'1101010', 10, 1)

query error set_bit\(\): new bit must be 0 or 1.
SELECT set_bit(B'1001010', 0, 2)

query error set_bit\(\): SetBitAtIndex: bit index 0 out of valid range \(0..-1\)
SELECT set_bit(B'', 0, 1)
45 changes: 45 additions & 0 deletions pkg/sql/sem/builtins/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,51 @@ 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{{"bit_string", types.VarBit}, {"index", types.Int}},
ReturnType: tree.FixedReturnType(types.Int),
Fn: func(_ *tree.EvalContext, args tree.Datums) (tree.Datum, error) {
bitString := tree.MustBeDBitArray(args[0])
index := int(tree.MustBeDInt(args[1]))
bit, err := bitString.GetBitAtIndex(index)
if err != nil {
return nil, err
}
return tree.NewDInt(tree.DInt(bit)), nil
},
Info: "Extracts a bit at given index in the bit array",
}),

// 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{
{"bit_string", types.VarBit},
{"index", types.Int},
{"to_set", types.Int},
},
ReturnType: tree.FixedReturnType(types.VarBit),
Fn: func(_ *tree.EvalContext, args tree.Datums) (tree.Datum, error) {
bitString := tree.MustBeDBitArray(args[0])
index := int(tree.MustBeDInt(args[1]))
toSet := int(tree.MustBeDInt(args[2]))

// Value of bit can only be set to 1 or 0.
if toSet != 0 && toSet != 1 {
return nil, pgerror.Newf(pgcode.InvalidParameterValue,
"new bit must be 0 or 1.")
}
updatedBitString, err := bitString.SetBitAtIndex(index, toSet)
if err != nil {
return nil, err
}
return &tree.DBitArray{BitArray: updatedBitString}, nil
},
Info: "Updates a bit at given index in the bit array",
}),

"gen_random_uuid": makeBuiltin(
tree.FunctionProperties{
Category: categoryIDGeneration,
Expand Down

0 comments on commit f114b42

Please sign in to comment.