From d14d0cdd9f20ef0ce52694177d83ab5e4caaa878 Mon Sep 17 00:00:00 2001 From: Victor Petrovykh Date: Fri, 23 Feb 2024 03:11:44 -0500 Subject: [PATCH] Add `bytes` option to `array_join`. The `array_join` function can now also be used to join bytes into a single byte-string. --- docs/stdlib/array.rst | 14 ++++++++++-- edb/buildmeta.py | 2 +- edb/lib/std/30-arrayfuncs.edgeql | 14 ++++++++++++ tests/test_edgeql_functions.py | 37 ++++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 3 deletions(-) diff --git a/docs/stdlib/array.rst b/docs/stdlib/array.rst index 9e800a55dfb..acf313ac607 100644 --- a/docs/stdlib/array.rst +++ b/docs/stdlib/array.rst @@ -33,7 +33,7 @@ Arrays - Finds the index of an element in the array. * - :eql:func:`array_join` - - Renders an array to a string. + - Renders an array to a string or byte-string. * - :eql:func:`array_fill` - :eql:func-desc:`array_fill` @@ -313,10 +313,12 @@ Reference .. eql:function:: std::array_join(array: array, delimiter: str) -> str + std::array_join(array: array, \ + delimiter: bytes) -> bytes :index: join array_to_string implode - Renders an array to a string. + Renders an array to a string or byte-string. Join a string array into a single string using a specified *delimiter*: @@ -325,6 +327,14 @@ Reference db> select array_join(['one', 'two', 'three'], ', '); {'one, two, three'} + Similarly, an array of :eql:type:`bytes` can be joined as a single value + using a specified *delimiter*: + + .. code-block:: edgeql-repl + + db> select array_join([b'\x01', b'\x02', b'\x03'], b'\xff'); + {b'\x01\xff\x02\xff\x03'} + ---------- diff --git a/edb/buildmeta.py b/edb/buildmeta.py index b31c1782b66..a0524a4cdb4 100644 --- a/edb/buildmeta.py +++ b/edb/buildmeta.py @@ -55,7 +55,7 @@ # Increment this whenever the database layout or stdlib changes. -EDGEDB_CATALOG_VERSION = 2024_02_20_00_00 +EDGEDB_CATALOG_VERSION = 2024_02_23_00_00 EDGEDB_MAJOR_VERSION = 5 diff --git a/edb/lib/std/30-arrayfuncs.edgeql b/edb/lib/std/30-arrayfuncs.edgeql index 45105002434..0068eba763a 100644 --- a/edb/lib/std/30-arrayfuncs.edgeql +++ b/edb/lib/std/30-arrayfuncs.edgeql @@ -112,6 +112,20 @@ std::array_join(array: array, delimiter: std::str) -> std::str }; +CREATE FUNCTION +std::array_join(array: array, delimiter: std::bytes) -> std::bytes +{ + CREATE ANNOTATION std::description := 'Render an array to a byte-string.'; + SET volatility := 'Immutable'; + USING SQL $$ + SELECT + COALESCE (string_agg(el, "delimiter"), '\x') + FROM + (SELECT unnest("array") AS el) AS t + $$; +}; + + ## Array operators diff --git a/tests/test_edgeql_functions.py b/tests/test_edgeql_functions.py index f8977d2521b..51740483717 100644 --- a/tests/test_edgeql_functions.py +++ b/tests/test_edgeql_functions.py @@ -3289,6 +3289,43 @@ async def test_edgeql_functions_array_join_01(self): [''], ) + async def test_edgeql_functions_array_join_02(self): + await self.assert_query_result( + r'''SELECT array_join(['one', 'two', 'three'], {', ', '@!'});''', + {'one, two, three', 'one@!two@!three'}, + ) + + async def test_edgeql_functions_array_join_03(self): + await self.assert_query_result( + r'''SELECT array_join([b'one', b'two', b'three'], b', ');''', + [base64.b64encode(b'one, two, three').decode()], + [b'one, two, three'], + ) + + await self.assert_query_result( + r'''SELECT array_join([b'one', b'two', b'three'], b'');''', + [base64.b64encode(b'onetwothree').decode()], + [b'onetwothree'], + ) + + await self.assert_query_result( + r'''SELECT array_join(>[], b', ');''', + [base64.b64encode(b'').decode()], + [b''], + ) + + async def test_edgeql_functions_array_join_04(self): + await self.assert_query_result( + r''' + SELECT array_join([b'one', b'two', b'three'], {b', ', b'@!'}); + ''', + { + base64.b64encode(b'one, two, three').decode(), + base64.b64encode(b'one@!two@!three').decode(), + }, + {b'one, two, three', b'one@!two@!three'}, + ) + async def test_edgeql_functions_str_split_01(self): await self.assert_query_result( r'''SELECT str_split('one, two, three', ', ');''',