Skip to content

Commit

Permalink
Integer/UUID to bytes conversion (#6553)
Browse files Browse the repository at this point in the history
Add `to_bytes(val: int16)`, `to_int16(val: bytes)`, `to_bytes(val: int32)`, `to_int32(val: bytes)`, `to_bytes(val: int64)`, `to_int64(val: bytes)`, `to_bytes(val: uuid)`, `to_uuid(val: bytes)` conversion functions.
Document new conversion functions.
Add tests for the conversion functions.

Co-authored-by: Victor Petrovykh <[email protected]>
  • Loading branch information
mritzerfeld and vpetrovykh authored Feb 17, 2024
1 parent fe5c198 commit df1ae8c
Show file tree
Hide file tree
Showing 6 changed files with 409 additions and 17 deletions.
49 changes: 45 additions & 4 deletions docs/stdlib/bytes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ Bytes
* - :eql:func:`to_str`
- :eql:func-desc:`to_str`

* - :eql:func:`to_int16`
- :eql:func-desc:`to_int16`

* - :eql:func:`to_int32`
- :eql:func-desc:`to_int32`

* - :eql:func:`to_int64`
- :eql:func-desc:`to_int64`

* - :eql:func:`to_uuid`
- :eql:func-desc:`to_uuid`

* - :eql:func:`bytes_get_bit`
- :eql:func-desc:`bytes_get_bit`

Expand Down Expand Up @@ -136,19 +148,48 @@ Bytes
---------

.. eql:function:: std::to_bytes(s: str) -> bytes
std::to_bytes(val: int16) -> bytes
std::to_bytes(val: int32) -> bytes
std::to_bytes(val: int64) -> bytes
std::to_bytes(val: int64) -> bytes
std::to_bytes(val: uuid) -> bytes
:index: encode stringencoder

.. versionadded:: 4.0

Converts a :eql:type:`str` value to :eql:type:`bytes` using
UTF-8 encoding.
Converts a given value into binary representation as :eql:type:`bytes`.

The strings get converted using UTF-8 encoding:

.. code-block:: edgeql-repl
db> select to_bytes('テキスト');
{b'\xe3\x83\x86\xe3\x82\xad\xe3\x82\xb9\xe3\x83\x88'}
The integer values are encoded as big-endian (most significant bit comes
first) byte strings:

.. code-block:: edgeql-repl
db> select to_bytes(<int16>31);
{b'\x00\x1f'}
db> select to_bytes(<int32>31);
{b'\x00\x00\x00\x1f'}
db> select to_bytes(123456789123456789);
{b'\x01\xb6\x9bK\xac\xd0_\x15'}
The UUID values are converted to the underlying string of 16 bytes:

.. code-block:: edgeql-repl
db> select to_bytes(<uuid>'1d70c86e-cc92-11ee-b4c7-a7aa0a34e2ae');
{b'\x1dp\xc8n\xcc\x92\x11\xee\xb4\xc7\xa7\xaa\n4\xe2\xae'}
To perform the reverse conversion there are corresponding functions:
:eql:func:`to_str`, :eql:func:`to_int16`, :eql:func:`to_int32`,
:eql:func:`to_int64`, :eql:func:`to_uuid`.


---------

Expand Down Expand Up @@ -187,12 +228,12 @@ Bytes
.. versionadded:: 4.0

Returns the :eql:type:`bytes` of a Base64-encoded :eql:type:`str`.

Returns an InvalidValueError if input is not valid Base64.

.. code-block:: edgeql-repl
db> select enc::base64_decode('aGVsbG8=');
{b'hello'}
db> select enc::base64_decode('aGVsbG8');
edgedb error: InvalidValueError: invalid base64 end sequence
edgedb error: InvalidValueError: invalid base64 end sequence
73 changes: 61 additions & 12 deletions docs/stdlib/numbers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -814,41 +814,90 @@ from :eql:type:`str` and :eql:type:`json`.


.. eql:function:: std::to_int16(s: str, fmt: optional str={}) -> int16
std::to_int16(val: bytes) -> int16
:index: parse int16

Returns an :eql:type:`int16` value parsed from the given string.
Returns an :eql:type:`int16` value parsed from the given input.

The string parsing function will use an optional format string passed as
*fmt*. See the :ref:`number formatting options
<ref_std_converters_number_fmt>` for help writing a format string.

.. code-block:: edgeql-repl
db> select to_int16('23');
{23}
db> select to_int16('23%', '99%');
{23}
The bytes conversion function expects exactly 2 bytes using big-endian
representation.

.. code-block:: edgeql-repl
db> select to_int16(b'\x00\x07');
{7}
The function will use an optional format string passed as *fmt*. See the
:ref:`number formatting options <ref_std_converters_number_fmt>` for help
writing a format string.
------------


.. eql:function:: std::to_int32(s: str, fmt: optional str={}) -> int32
std::to_int32(val: bytes) -> int32
:index: parse int32

Returns an :eql:type:`int32` value parsed from the given string.
Returns an :eql:type:`int32` value parsed from the given input.

The function will use an optional format string passed as *fmt*. See the
:ref:`number formatting options <ref_std_converters_number_fmt>` for help
writing a format string.
The string parsin function will use an optional format string passed as
*fmt*. See the :ref:`number formatting options
<ref_std_converters_number_fmt>` for help writing a format string.

.. code-block:: edgeql-repl
db> select to_int32('1000023');
{1000023}
db> select to_int32('1000023%', '9999999%');
{1000023}
The bytes conversion function expects exactly 4 bytes using big-endian
representation.

.. code-block:: edgeql-repl
db> select to_int32(b'\x01\x02\x00\x07');
{16908295}
------------


.. eql:function:: std::to_int64(s: str, fmt: optional str={}) -> int64
std::to_int64(val: bytes) -> int64
:index: parse int64

Returns an :eql:type:`int64` value parsed from the given string.
Returns an :eql:type:`int64` value parsed from the given input.

The function will use an optional format string passed as *fmt*. See the
:ref:`number formatting options <ref_std_converters_number_fmt>` for help
writing a format string.
The string parsing function will use an optional format string passed as
*fmt*. See the :ref:`number formatting options
<ref_std_converters_number_fmt>` for help writing a format string.

.. code-block:: edgeql-repl
db> select to_int64('10000234567');
{10000234567}
db> select to_int64('10000234567%', '99999999999%');
{10000234567}
The bytes conversion function expects exactly 8 bytes using big-endian
representation.

.. code-block:: edgeql-repl
db> select to_int64(b'\x01\x02\x00\x07\x11\x22\x33\x44');
{72620574343574340}
------------
Expand Down
26 changes: 26 additions & 0 deletions docs/stdlib/uuid.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ UUIDs
* - :eql:func:`uuid_generate_v4`
- :eql:func-desc:`uuid_generate_v4`

* - :eql:func:`to_uuid`
- :eql:func-desc:`to_uuid`


---------

Expand Down Expand Up @@ -87,3 +90,26 @@ UUIDs
db> select uuid_generate_v4();
{92673afc-9c4f-42b3-8273-afe0053f0f48}
---------


.. eql:function:: std::to_uuid(val: bytes) -> uuid
:index: parse uuid

Returns a :eql:type:`uuid` value parsed from 128-bit input.

The :eql:type:`bytes` string has to be a valid 128-bit UUID
representation.

.. code-block:: edgeql-repl
db> select to_uuid(
... b'\x92\x67\x3a\xfc\
... \x9c\x4f\
... \x42\xb3\
... \x82\x73\
... \xaf\xe0\x05\x3f\x0f\x48');
{92673afc-9c4f-42b3-8273-afe0053f0f48}
2 changes: 1 addition & 1 deletion edb/buildmeta.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@


# Increment this whenever the database layout or stdlib changes.
EDGEDB_CATALOG_VERSION = 2024_02_16_00_00
EDGEDB_CATALOG_VERSION = 2024_02_16_14_00
EDGEDB_MAJOR_VERSION = 5


Expand Down
Loading

0 comments on commit df1ae8c

Please sign in to comment.