-- -- MULTI_JSON_AGG -- SET citus.next_shard_id TO 520000; SET citus.coordinator_aggregation_strategy TO 'disabled'; SELECT run_command_on_master_and_workers($r$ CREATE OR REPLACE FUNCTION array_sort (json) RETURNS json LANGUAGE SQL AS $$ SELECT json_agg(value) FROM ( SELECT value FROM json_array_elements($1) ORDER BY value::jsonb ) t $$; $r$); run_command_on_master_and_workers --------------------------------------------------------------------- (1 row) -- Check multi_cat_agg() aggregate which is used to implement json_agg() SELECT json_cat_agg(i) FROM (VALUES ('[1,{"a":2}]'::json), ('[null]'::json), (NULL), ('["3",5,4]'::json)) AS t(i); json_cat_agg --------------------------------------------------------------------- [1, {"a":2}, null, "3", 5, 4] (1 row) -- Check that we don't support distinct and order by with json_agg() SELECT json_agg(distinct l_orderkey) FROM lineitem; ERROR: json_agg (distinct) is unsupported SELECT json_agg(l_orderkey ORDER BY l_partkey) FROM lineitem; ERROR: json_agg with order by is unsupported SELECT json_agg(distinct l_orderkey ORDER BY l_orderkey) FROM lineitem; ERROR: json_agg with order by is unsupported -- Check json_agg() for different data types and LIMIT clauses SELECT array_sort(json_agg(l_partkey)) FROM lineitem GROUP BY l_orderkey ORDER BY l_orderkey LIMIT 10; array_sort --------------------------------------------------------------------- [2132, 15635, 24027, 63700, 67310, 155190] [106170] [4297, 19036, 29380, 62143, 128449, 183095] [88035] [37531, 108570, 123927] [139636] [79251, 94780, 145243, 151894, 157238, 163073, 182052] [2743, 11615, 44161, 82704, 85811, 197921] [33918, 60519, 61336, 137469] [88362, 89414, 169544] (10 rows) SELECT array_sort(json_agg(l_extendedprice)) FROM lineitem GROUP BY l_orderkey ORDER BY l_orderkey LIMIT 10; array_sort --------------------------------------------------------------------- [13309.60, 21168.23, 22824.48, 28955.64, 45983.16, 49620.16] [44694.46] [2618.76, 28733.64, 32986.52, 39890.88, 46796.47, 54058.05] [30690.90] [23678.55, 50723.92, 73426.50] [61998.31] [6476.15, 11594.16, 13608.60, 31809.96, 43058.75, 73943.82, 81639.88] [2210.32, 6582.96, 9159.66, 47227.60, 64605.44, 79059.64] [7532.30, 40217.23, 47344.32, 75928.31] [9681.24, 17554.68, 30875.02] (10 rows) SELECT array_sort(json_agg(l_shipdate)) FROM lineitem GROUP BY l_orderkey ORDER BY l_orderkey LIMIT 10; array_sort --------------------------------------------------------------------- ["1996-01-29", "1996-01-30", "1996-03-13", "1996-03-30", "1996-04-12", "1996-04-21"] ["1997-01-28"] ["1993-10-29", "1993-11-09", "1993-12-04", "1993-12-14", "1994-01-16", "1994-02-02"] ["1996-01-10"] ["1994-08-08", "1994-10-16", "1994-10-31"] ["1992-04-27"] ["1996-01-15", "1996-01-16", "1996-02-01", "1996-02-10", "1996-02-11", "1996-03-21", "1996-05-07"] ["1995-07-21", "1995-08-04", "1995-08-07", "1995-08-14", "1995-08-28", "1995-10-23"] ["1993-10-29", "1993-11-09", "1993-12-09", "1993-12-09"] ["1998-10-09", "1998-10-23", "1998-10-30"] (10 rows) SELECT array_sort(json_agg(l_shipmode)) FROM lineitem GROUP BY l_orderkey ORDER BY l_orderkey LIMIT 10; array_sort --------------------------------------------------------------------- ["AIR ", "FOB ", "MAIL ", "MAIL ", "REG AIR ", "TRUCK "] ["RAIL "] ["AIR ", "FOB ", "RAIL ", "RAIL ", "SHIP ", "TRUCK "] ["REG AIR "] ["AIR ", "AIR ", "FOB "] ["TRUCK "] ["FOB ", "FOB ", "FOB ", "FOB ", "MAIL ", "SHIP ", "TRUCK "] ["AIR ", "AIR ", "AIR ", "RAIL ", "REG AIR ", "TRUCK "] ["AIR ", "MAIL ", "MAIL ", "TRUCK "] ["FOB ", "FOB ", "REG AIR "] (10 rows) -- Check that we can execute json_agg() within other functions SELECT json_array_length(json_agg(l_orderkey)) FROM lineitem; json_array_length --------------------------------------------------------------------- 12000 (1 row) -- Check that we can execute json_agg() on select queries that hit multiple -- shards and contain different aggregates, filter clauses and other complex -- expressions. Note that the l_orderkey ranges are such that the matching rows -- lie in different shards. SELECT l_quantity, count(*), avg(l_extendedprice), array_sort(json_agg(l_orderkey)) FROM lineitem WHERE l_quantity < 5 AND l_orderkey > 5500 AND l_orderkey < 9500 GROUP BY l_quantity ORDER BY l_quantity; l_quantity | count | avg | array_sort --------------------------------------------------------------------- 1.00 | 17 | 1477.1258823529411765 | [5543, 5633, 5634, 5698, 5766, 5856, 5857, 5986, 8997, 9026, 9158, 9184, 9220, 9222, 9348, 9383, 9476] 2.00 | 19 | 3078.4242105263157895 | [5506, 5540, 5573, 5669, 5703, 5730, 5798, 5831, 5893, 5920, 5923, 9030, 9058, 9123, 9124, 9188, 9344, 9441, 9476] 3.00 | 14 | 4714.0392857142857143 | [5509, 5543, 5605, 5606, 5827, 9124, 9157, 9184, 9223, 9254, 9349, 9414, 9475, 9477] 4.00 | 19 | 5929.7136842105263158 | [5504, 5507, 5508, 5511, 5538, 5764, 5766, 5826, 5829, 5862, 5959, 5985, 9091, 9120, 9281, 9347, 9382, 9440, 9473] (4 rows) SELECT l_quantity, array_sort(json_agg(extract (month FROM o_orderdate))) AS my_month FROM lineitem, orders WHERE l_orderkey = o_orderkey AND l_quantity < 5 AND l_orderkey > 5500 AND l_orderkey < 9500 GROUP BY l_quantity ORDER BY l_quantity; l_quantity | my_month --------------------------------------------------------------------- 1.00 | [2, 3, 4, 4, 4, 5, 5, 5, 6, 7, 7, 7, 7, 9, 9, 11, 11] 2.00 | [1, 3, 5, 5, 5, 5, 6, 6, 6, 7, 7, 8, 10, 10, 11, 11, 11, 12, 12] 3.00 | [3, 4, 5, 6, 7, 7, 8, 8, 8, 9, 9, 10, 11, 11] 4.00 | [1, 1, 1, 2, 2, 2, 5, 5, 6, 6, 6, 6, 8, 9, 10, 10, 11, 11, 12] (4 rows) SELECT l_quantity, array_sort(json_agg(l_orderkey * 2 + 1)) FROM lineitem WHERE l_quantity < 5 AND octet_length(l_comment) + octet_length('randomtext'::text) > 40 AND l_orderkey > 5500 AND l_orderkey < 9500 GROUP BY l_quantity ORDER BY l_quantity; l_quantity | array_sort --------------------------------------------------------------------- 1.00 | [11269, 11397, 11713, 11715, 11973, 18317, 18445] 2.00 | [11847, 18061, 18247, 18953] 3.00 | [18249, 18315, 18699, 18951, 18955] 4.00 | [11653, 11659, 18241, 18765] (4 rows) -- Check that we can execute json_agg() with an expression containing NULL values SELECT array_sort(json_agg(case when l_quantity > 20 then l_quantity else NULL end)) FROM lineitem WHERE l_orderkey < 5; array_sort --------------------------------------------------------------------- [null, null, null, 24.00, 26.00, 27.00, 28.00, 28.00, 30.00, 32.00, 36.00, 38.00, 45.00, 49.00] (1 row) -- Check that we can execute json_agg() with an expression containing different types SELECT array_sort(json_agg(case when l_quantity > 20 then to_json(l_quantity) else '"f"'::json end)) FROM lineitem WHERE l_orderkey < 5; array_sort --------------------------------------------------------------------- ["f", "f", "f", 24.00, 26.00, 27.00, 28.00, 28.00, 30.00, 32.00, 36.00, 38.00, 45.00, 49.00] (1 row) -- Check that we can execute json_agg() with an expression containing json arrays SELECT array_sort(json_agg(json_build_array(l_quantity, l_shipdate))) FROM lineitem WHERE l_orderkey < 3; array_sort --------------------------------------------------------------------- [[8.00, "1996-01-29"], [17.00, "1996-03-13"], [24.00, "1996-03-30"], [28.00, "1996-04-21"], [32.00, "1996-01-30"], [36.00, "1996-04-12"], [38.00, "1997-01-28"]] (1 row) -- Check that we can execute json_agg() with an expression containing arrays SELECT array_sort(json_agg(ARRAY[l_quantity, l_orderkey])) FROM lineitem WHERE l_orderkey < 3; array_sort --------------------------------------------------------------------- [[8.00,1], [17.00,1], [24.00,1], [28.00,1], [32.00,1], [36.00,1], [38.00,2]] (1 row) -- Check that we return NULL in case there are no input rows to json_agg() SELECT array_sort(json_agg(l_orderkey)) FROM lineitem WHERE l_quantity < 0; array_sort --------------------------------------------------------------------- (1 row)