Skip to content

Commit ae9493c

Browse files
authored
Merge pull request #254 from jongleb/support-json_arrayagg
Support `JSON_ARRAYAGG`
2 parents 3463a8d + 1b0bce5 commit ae9493c

File tree

5 files changed

+451
-2
lines changed

5 files changed

+451
-2
lines changed

lib/sql.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,7 @@ and row_values = {
588588
and order = (expr * direction option) list
589589
and agg_with_order_kind =
590590
| Group_concat
591+
| Json_arrayagg
591592
and agg_fun = Self (* self means that it returns the same type what aggregated columns have. ie: max, min *)
592593
| Count (* count it's count function which never returns null *)
593594
| Avg (* avg it's avg function that returns float *)
@@ -715,6 +716,7 @@ let pp_func pp f =
715716
| Agg Avg -> fprintf pp "|'a| -> float"
716717
| Agg Count -> fprintf pp "|'a| -> int"
717718
| Agg (With_order { with_order_kind = Group_concat; _ }) -> fprintf pp "|'a| -> text"
719+
| Agg (With_order { with_order_kind = Json_arrayagg; _ }) -> fprintf pp "|'a| -> json"
718720
| Ret ret -> fprintf pp "_ -> %s" (Type.show ret)
719721
| F (ret, args) -> fprintf pp "%s -> %s" (String.concat " -> " @@ List.map Type.string_of_tyvar args) (Type.string_of_tyvar ret)
720722
| Col_assign { ret_t=ret; col_t; arg_t } -> aux (F (ret, [col_t; arg_t]))

lib/sql_lexer.mll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ let keywords =
9191
"group",GROUP;
9292
"group_concat", GROUP_CONCAT;
9393
"having",HAVING;
94+
"json_arrayagg", JSON_ARRAYAGG;
9495
"hour_microsecond", HOUR_MICROSECOND;
9596
"hour_minute", HOUR_MINUTE;
9697
"hour_second", HOUR_SECOND;

lib/sql_parser.mly

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
DAY_MICROSECOND DAY_SECOND DAY_MINUTE DAY_HOUR EXTRACT
5252
YEAR_MONTH FALSE TRUE DUPLICATE
5353
%token GROUP_CONCAT SEPARATOR
54+
%token JSON_ARRAYAGG
5455
%token NUM_DIV_OP NUM_EQ_OP NUM_CMP_OP PLUS MINUS NOT_DISTINCT_OP NUM_BIT_SHIFT NUM_BIT_OR NUM_BIT_AND
5556
%token JSON_EXTRACT_OP JSON_UNQUOTE_EXTRACT_OP
5657
%token T_INTEGER T_BIG_INTEGER T_BLOB T_TEXT T_FLOAT T_BOOLEAN T_DATETIME T_UUID T_DECIMAL T_JSON
@@ -503,6 +504,10 @@ expr:
503504
{
504505
Fun { kind = Agg ( With_order({ with_order_kind = Group_concat; order })); parameters = p; is_over_clause = false }
505506
}
507+
| JSON_ARRAYAGG LPAREN p=func_params order=loption(order) limit_t? RPAREN
508+
{
509+
Fun { kind = Agg ( With_order({ with_order_kind = Json_arrayagg; order })); parameters = p; is_over_clause = false }
510+
}
506511
| CAST LPAREN e=expr AS f=cast_as RPAREN { f e }
507512
| f=table_name LPAREN p=func_params RPAREN { Fun { kind = (Function.lookup f.tn (List.length p)); parameters = p; is_over_clause = false } }
508513
| e=expr IS NOT? NULL { poly (strict Bool) [e] }

lib/syntax.ml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -629,8 +629,12 @@ and assign_types env expr =
629629
| Agg Count, ([] (* asterisk *) | [_]) -> strict Int, types
630630
| Agg Avg, [_] -> consider_agg_nullability @@ nullable Float, types
631631
| Agg Self, [typ] -> consider_agg_nullability typ, types
632-
| Agg (With_order { with_order_kind = Group_concat; _ }), [t1] ->
632+
| Agg (With_order { with_order_kind = Group_concat; _ }), ((_ :: _) as params) ->
633633
let ret = depends Text in
634+
let nullability = common_nullability (ret :: params) in
635+
consider_agg_nullability @@ (undepend ret nullability), types
636+
| Agg (With_order { with_order_kind = Json_arrayagg; _ }), [t1] ->
637+
let ret = depends Json in
634638
let nullability = common_nullability [ret; t1] in
635639
consider_agg_nullability @@ (undepend ret nullability), types
636640
| Agg _, _ -> fail "cannot use this grouping function with %d parameters" (List.length types)
@@ -810,7 +814,7 @@ and get_params_of_res_expr env (e:res_expr) =
810814
| ResInparam (p, m) -> SingleIn (p, m)::acc
811815
| ResFun { parameters; kind; _ } ->
812816
let p1 = match kind with
813-
| Agg (With_order { with_order_kind = Group_concat; order; _ }) -> List.rev @@ params_of_order order [] env
817+
| Agg (With_order { order; _ }) -> List.rev @@ params_of_order order [] env
814818
| _ -> [] in
815819
p1 @ List.fold_left loop acc parameters
816820
| ResInTupleList _

0 commit comments

Comments
 (0)