Skip to content

Commit 6278150

Browse files
committed
work in progress
1 parent 3cec9d9 commit 6278150

File tree

13 files changed

+112
-63
lines changed

13 files changed

+112
-63
lines changed

bench/tpcds/q38.txt

Whitespace-only changes.

bench/tpcds/q8.txt

Whitespace-only changes.

lib/ast.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ type ('p, 'r) query =
104104
| Dedup of 'r
105105
| Relation of Relation.t
106106
| Range of ('p * 'p)
107-
| Limit of int
107+
| Limit of int * 'r
108108
| AEmpty
109109
| AScalar of 'p scalar
110110
| AList of 'r list_

lib/constructors.ml

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ module Query = struct
4545

4646
let list' = alist
4747
let list a c = list' { l_keys = a; l_values = c }
48+
let limit = limit
4849
end
4950

5051
(** Construct annotated queries. Discards any existing metadata. *)
@@ -110,6 +111,7 @@ module Annot = struct
110111
let list' x = wrap @@ Query.list' (strip_meta_alist x)
111112
let tuple a b = wrap @@ Query.tuple (strip_meta_list a) b
112113
let call a = wrap @@ Query.call a
114+
let limit l r = wrap @@ Query.limit l r
113115

114116
let hash_idx ?key_layout a c d =
115117
wrap

lib/constructors.mli

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ module Annot : sig
5252
val list' : _ annot Ast.list_ -> < > annot
5353
val tuple : _ annot list -> Ast.tuple -> < > annot
5454
val call : string -> < > annot
55+
val limit : int -> < > annot -> < > annot
5556

5657
val hash_idx :
5758
?key_layout:_ annot -> _ annot -> _ annot -> _ pred list -> < > annot

lib/of_sql.ml

+39-27
Original file line numberDiff line numberDiff line change
@@ -28,27 +28,38 @@ let conv_alias = sprintf "%s_%s"
2828
let conv_sql db_schema =
2929
let open Sqlgg in
3030
let open Constructors.Annot in
31-
let aliases = ref (Set.empty (module String)) in
32-
let alias_of_name = ref (Map.empty (module String)) in
31+
let fresh = Fresh.create () in
3332

34-
let conv_order _ q =
35-
Log.warn (fun m -> m "Dropping orderby clause.");
36-
q
37-
in
3833
let conv_limit l q =
39-
if Option.is_some l then Log.warn (fun m -> m "Dropping limit clause.");
40-
q
34+
match l with
35+
| None -> q
36+
| Some (_, true) -> limit 1 q
37+
| Some (_, false) ->
38+
Log.warn (fun m -> m "Dropping limit clause.");
39+
q
4140
in
41+
4242
let conv_distinct d q = if d then dedup q else q in
4343

44-
let rec conv_filter f q =
45-
match f with Some e -> filter (conv_expr e) q | None -> q
44+
let rec conv_order order q subst =
45+
let key =
46+
List.map order ~f:(fun (sql_expr, sql_dir) ->
47+
let dir =
48+
match sql_dir with Some `Asc -> Asc | Some `Desc | None -> Desc
49+
in
50+
(Subst.subst_pred subst (conv_expr sql_expr), dir))
51+
in
52+
order_by key q
53+
and conv_filter f q subst =
54+
match f with
55+
| Some e -> filter (Subst.subst_pred subst (conv_expr e)) q
56+
| None -> q
4657
and conv_source (s, alias) =
4758
let q =
4859
match s with
4960
| `Subquery s -> conv_query s
5061
| `Table t -> relation (Db.Schema.relation db_schema t)
51-
| `Nested n -> conv_nested n
62+
| `Nested n -> conv_nested Map.empty n
5263
in
5364
match alias with
5465
| Some a ->
@@ -62,29 +73,29 @@ let conv_sql db_schema =
6273
in
6374
select select_list q
6475
| None -> q
65-
and conv_nested (q, qs) =
76+
and conv_nested subst (q, qs) =
6677
match qs with
6778
| [] -> conv_source q
6879
| (q', j) :: qs' -> (
6980
match j with
7081
| `Cross | `Default ->
71-
join (bool true) (conv_source q) (conv_nested (q', qs'))
82+
join (bool true) (conv_source q) (conv_nested subst (q', qs'))
7283
| `Search e ->
73-
join (conv_expr e) (conv_source q) (conv_nested (q', qs'))
84+
join (conv_expr subst e) (conv_source q)
85+
(conv_nested subst (q', qs'))
7486
| `Using _ | `Natural -> failwith "Join type not supported")
7587
and conv_subquery q = conv_query q
76-
and conv_column (c : Sql.Col_name.t) =
77-
let n =
88+
and conv_column subst (c : Sql.Col_name.t) =
89+
let name =
7890
match c.tname with
79-
| Some a -> if Set.mem !aliases a then conv_alias a c.cname else c.cname
80-
| None -> (
81-
match Map.find !alias_of_name c.cname with
82-
| Some a -> conv_alias a c.cname
83-
| None -> c.cname)
91+
| Some table_name ->
92+
`Name { Name.name = Name.Attr (table_name, c.cname); type_ = None }
93+
| None -> `Name (Name.create c.cname)
8494
in
85-
Name.create n
86-
and conv_expr e =
87-
let open Pred in
95+
Subst.subst_pred subst name
96+
and conv_expr subst e =
97+
let conv_expr = conv_expr subst in
98+
let module Infix = Pred.Infix in
8899
match e with
89100
| Sql.Value v -> (
90101
match v with
@@ -94,8 +105,9 @@ let conv_sql db_schema =
94105
| Bool x -> `Bool x
95106
| Float x -> `Fixed (Fixed_point.of_float x)
96107
| Null -> `Null None)
97-
| Param _ | Choices (_, _) | Inserted _ | Sequence _ ->
98-
failwith "unsupported"
108+
| Param ((Some name, _), _) -> `Name (Name.create name)
109+
| Param ((None, _), _) -> `Name (Name.create (Fresh.name fresh "param_%d"))
110+
| Choices (_, _) | Inserted _ | Sequence _ -> failwith "unsupported"
99111
| Case (branches, else_) ->
100112
let else_ =
101113
Option.map else_ ~f:conv_expr |> Option.value ~default:(`Null None)
@@ -145,7 +157,7 @@ let conv_sql db_schema =
145157
Error.create "Unsupported op" op [%sexp_of: Sql.op] |> Error.raise)
146158
| Subquery (s, `Exists) -> `Exists (conv_subquery s)
147159
| Subquery (s, `AsValue) -> `First (conv_subquery s)
148-
| Column c -> `Name (conv_column c)
160+
| Column c -> conv_column subst c
149161
and conv_select s =
150162
(* Build query in order. First, FROM *)
151163
let query =

lib/resolve.ml

+3
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,9 @@ let resolve_open resolve stage outer_ctx =
272272
let r, value_ctx = rsame outer_ctx r in
273273
let pred = resolve_pred stage (Ctx.merge outer_ctx value_ctx) pred in
274274
(Filter (pred, r), value_ctx)
275+
| Limit (l, r) ->
276+
let r, value_ctx = rsame outer_ctx r in
277+
(Limit (l, r), value_ctx)
275278
| DepJoin { d_lhs; d_rhs } ->
276279
let d_lhs, lctx = rsame outer_ctx d_lhs in
277280
let lctx = Ctx.zero lctx in

lib/schema.ml

+2-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ let schema_query_open schema r =
4848
| DepJoin { d_rhs = r; _ }
4949
| Filter (_, r)
5050
| Dedup r
51-
| OrderBy { rel = r; _ } ->
51+
| OrderBy { rel = r; _ }
52+
| Limit (_, r) ->
5253
schema r
5354
| AOrderedIdx { oi_keys = lhs; oi_values = rhs; _ }
5455
| AHashIdx { hi_keys = lhs; hi_values = rhs; _ } ->

lib/visitors_gen.ml

+24-16
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,10 @@ class virtual ['self] base_endo =
281281
let r0 = self#visit_string env c0 in
282282
if c0 == r0 then this else Call r0
283283

284-
method visit_Limit env this c0 =
285-
let r0 = self#visit_int env c0 in
286-
if c0 == r0 then this else Limit r0
284+
method visit_Limit env this l r =
285+
let l' = self#visit_int env l in
286+
let r' = self#visit_t env r in
287+
if l == l' && r == r' then this else Limit (l', r')
287288

288289
method visit_query env this =
289290
match this with
@@ -303,7 +304,7 @@ class virtual ['self] base_endo =
303304
| AHashIdx c0 as this -> self#visit_AHashIdx env this c0
304305
| AOrderedIdx c0 as this -> self#visit_AOrderedIdx env this c0
305306
| Call c0 as this -> self#visit_Call env this c0
306-
| Limit c0 as this -> self#visit_Limit env this c0
307+
| Limit (c0, r) as this -> self#visit_Limit env this c0 r
307308

308309
method visit_annot env this =
309310
let r0 = self#visit_query env this.node in
@@ -579,9 +580,10 @@ class virtual ['self] base_map =
579580
let r0 = self#visit_string env c0 in
580581
Call r0
581582

582-
method visit_Limit env c0 =
583-
let r0 = self#visit_int env c0 in
584-
Limit r0
583+
method visit_Limit env l r =
584+
let l' = self#visit_int env l in
585+
let r' = self#visit_t env r in
586+
Limit (l', r')
585587

586588
method visit_query env this =
587589
match this with
@@ -601,7 +603,7 @@ class virtual ['self] base_map =
601603
| AHashIdx c0 -> self#visit_AHashIdx env c0
602604
| AOrderedIdx c0 -> self#visit_AOrderedIdx env c0
603605
| Call c0 -> self#visit_Call env c0
604-
| Limit c0 -> self#visit_Limit env c0
606+
| Limit (l, r) -> self#visit_Limit env l r
605607

606608
method visit_annot env this =
607609
let r0 = self#visit_query env this.node in
@@ -873,7 +875,10 @@ class virtual ['self] base_iter =
873875
()
874876

875877
method visit_Call env c0 = self#visit_string env c0
876-
method visit_Limit env c0 = self#visit_int env c0
878+
879+
method visit_Limit env l r =
880+
self#visit_int env l;
881+
self#visit_t env r
877882

878883
method visit_query env this =
879884
match this with
@@ -893,7 +898,7 @@ class virtual ['self] base_iter =
893898
| AHashIdx c0 -> self#visit_AHashIdx env c0
894899
| AOrderedIdx c0 -> self#visit_AOrderedIdx env c0
895900
| Call c0 -> self#visit_Call env c0
896-
| Limit c0 -> self#visit_Limit env c0
901+
| Limit (l, r) -> self#visit_Limit env l r
897902

898903
method visit_annot env this =
899904
let r0 = self#visit_query env this.node in
@@ -1165,7 +1170,9 @@ class virtual ['self] base_reduce =
11651170
s0
11661171

11671172
method visit_Call env c0 = self#visit_string env c0
1168-
method visit_Limit env c0 = self#visit_int env c0
1173+
1174+
method visit_Limit env l r =
1175+
self#plus (self#visit_int env l) (self#visit_t env r)
11691176

11701177
method visit_query env this =
11711178
match this with
@@ -1185,7 +1192,7 @@ class virtual ['self] base_reduce =
11851192
| AHashIdx c0 -> self#visit_AHashIdx env c0
11861193
| AOrderedIdx c0 -> self#visit_AOrderedIdx env c0
11871194
| Call c0 -> self#visit_Call env c0
1188-
| Limit c0 -> self#visit_Limit env c0
1195+
| Limit (l, r) -> self#visit_Limit env l r
11891196

11901197
method visit_annot env this =
11911198
let s0 = self#visit_query env this.node in
@@ -1466,9 +1473,10 @@ class virtual ['self] base_mapreduce =
14661473
let r0, s0 = self#visit_string env c0 in
14671474
(Call r0, s0)
14681475

1469-
method visit_Limit env c0 =
1470-
let r0, s0 = self#visit_int env c0 in
1471-
(Limit r0, s0)
1476+
method visit_Limit env l r =
1477+
let r0, s0 = self#visit_int env l in
1478+
let r1, s1 = self#visit_t env r in
1479+
(Limit (r0, r1), self#plus s0 s1)
14721480

14731481
method visit_query env this =
14741482
match this with
@@ -1488,7 +1496,7 @@ class virtual ['self] base_mapreduce =
14881496
| AHashIdx c0 -> self#visit_AHashIdx env c0
14891497
| AOrderedIdx c0 -> self#visit_AOrderedIdx env c0
14901498
| Call c0 -> self#visit_Call env c0
1491-
| Limit c0 -> self#visit_Limit env c0
1499+
| Limit (c0, c1) -> self#visit_Limit env c0 c1
14921500

14931501
method visit_annot env this =
14941502
let r0, s0 = self#visit_query env this.node in

sql2code/sql2code.ml

+22-8
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,21 @@ let dataclass_name table =
3333

3434
let singular = String.chop_suffix_if_exists ~suffix:"s"
3535

36-
let emit_dataclass db_schema name : Python_block.t =
37-
let schema = Db.Schema.attrs db_schema name in
36+
let emit_dataclass db_schema table_name : Python_block.t =
37+
let schema = Db.Schema.attrs db_schema table_name in
3838
let fields =
3939
List.filter_map schema ~f:(fun attr ->
4040
match attr.constraints with
4141
| `Foreign_key tbl ->
4242
Some
4343
(Fmt.str "%s : '%s'"
44-
(String.chop_suffix_exn name ~suffix:"_id")
44+
(String.chop_suffix_exn attr.attr_name ~suffix:"_id")
4545
(dataclass_name tbl))
4646
| `None | `Primary_key ->
47-
Some (Fmt.str "%s : %s" name (emit_type attr.type_)))
47+
Some (Fmt.str "%s : %s" attr.attr_name (emit_type attr.type_)))
4848
in
4949
let referrers =
50-
List.map (Db_schema.referrers db_schema name) ~f:(fun tbl ->
50+
List.map (Db_schema.referrers db_schema table_name) ~f:(fun tbl ->
5151
Fmt.str "%s : set['%s'] = field(default_factory=set, compare=False)" tbl
5252
(dataclass_name tbl))
5353
in
@@ -56,7 +56,7 @@ let emit_dataclass db_schema name : Python_block.t =
5656
Stmts [ "@dataclass(frozen=True)" ];
5757
Block
5858
{
59-
header = Fmt.str "class %s:" (dataclass_name name);
59+
header = Fmt.str "class %s:" (dataclass_name table_name);
6060
body = Stmts (fields @ referrers);
6161
};
6262
]
@@ -385,9 +385,9 @@ let emit_expr _db_schema params ctx =
385385
| Column x -> lookup_column_exn ctx x
386386
| Param p ->
387387
List.find_map params ~f:(fun (name, param) ->
388-
if [%compare.equal: Sql.param] p param then Some name else None)
388+
if [%compare.equal: Sql.Param.t] p param then Some name else None)
389389
|> Option.value_exn
390-
~error:(Error.of_lazy_sexp (lazy [%message (p : Sql.param)]))
390+
~error:(Error.of_lazy_sexp (lazy [%message (p : Sql.Param.t)]))
391391
| (Sequence _ | Choices _ | Case _ | Subquery _ | Inserted _) as expr ->
392392
raise_s [%message "unsupported" (expr : Sql.op Sql.expr)]
393393
in
@@ -792,6 +792,7 @@ let emit_select db_schema query_str query_name select =
792792
}
793793

794794
let main () =
795+
Log.setup_log Warning;
795796
let input_str = In_channel.input_all In_channel.stdin in
796797
let queries = load_queries input_str in
797798
let db =
@@ -804,6 +805,19 @@ let main () =
804805
let tables =
805806
Db.Schema.relation_names db |> List.sort ~compare:[%compare: string]
806807
in
808+
List.iter queries ~f:(fun (q, _) ->
809+
match q with
810+
| Select q ->
811+
let castor_query = Of_sql.conv_sql db q in
812+
print_s [%message (castor_query : Ast.t)];
813+
print_s
814+
[%message
815+
(Resolve.resolve_exn
816+
~params:(Set.empty (module Name))
817+
castor_query
818+
: _ Ast.annot)]
819+
| _ -> ());
820+
807821
let dataclasses = List.map tables ~f:(emit_dataclass db) in
808822
let add_methods = List.map tables ~f:(emit_add db) in
809823
let remove_methods = List.map tables ~f:(emit_remove db) in

sql2code/test.ml

Whitespace-only changes.

sqlgg/lib/dune

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
(library
77
(public_name sqlgg)
88
(libraries base stdio)
9-
(preprocess (pps ppx_compare ppx_sexp_conv))
9+
(preprocess (pps ppx_compare ppx_hash ppx_sexp_conv))
1010
)

0 commit comments

Comments
 (0)