toc
[sqlgg.git] / rA.ml
blob84f4ed22669d57d59db56598cb0a4a07339d9ef9
1 (*
2 Relational Algebra
3 *)
5 open ListMore
6 open Printf
7 open Operators
9 module Type = Sql.Type
11 type attr = {name : string; domain : Type.t;}
12 deriving (Show)
14 let attr n d = {name=n;domain=d}
16 module Scheme =
17 struct
18 type t = attr list
19 deriving (Show)
21 exception Error of t * string
23 let find t name =
24 match List.find_all (fun attr -> attr.name = name) t with
25 | [x] -> x
26 | [] -> raise (Error (t,"missing attribute : " ^ name))
27 | _ -> raise (Error (t,"duplicate attribute : " ^ name))
29 let is_unique t =
30 let t1 = List.unique ~cmp:(fun a1 a2 -> a1.name = a2.name) t in
31 List.length t1 = List.length t
33 let check_unique t = is_unique t || raise (Error (t,"duplicate attributes"))
35 let project names t = List.map (find t) names
37 let rename t before after =
38 List.map (fun attr ->
39 match attr.name with
40 | x when x = before -> { attr with name=after }
41 | _ -> attr ) t
43 let cross t1 t2 = t1 @ t2
45 (** [contains t attr] tests whether schema [t] contains attribute [attr] *)
46 let contains t attr = find t attr.name = attr
48 let check_contains t attr =
49 if not (contains t attr) then
50 raise (Error (t,"type mismatch for attribute " ^ attr.name))
52 let sub l a = List.filter (fun x -> not (List.mem x a)) l
54 let natural t1 t2 =
55 let (common,t1only) = List.partition (fun x -> List.mem x t2) t1 in
56 let t2only = sub t2 common in
57 common @ t1only @ t2only
59 let join_using l t1 t2 =
60 let common = List.map (find t1) l in
61 List.iter (check_contains t2) common;
62 common @ sub t1 common @ sub t2 common
64 (* FIXME? should be less strict -- check only types *)
65 let compound t1 t2 =
66 if t1 <> t2 then
67 raise (Error (t1, (Show.show<t>(t1)) ^ " not equal to " ^ (Show.show<t>(t2))))
68 else
71 let to_string x = Show.show<t>(x)
72 let print x = prerr_endline (to_string x)
74 end
76 type table = string * Scheme.t deriving (Show)
78 let print_table t = print_endline (Show.show<table>(t))
81 open Scheme
83 let test = [{name="a";domain=Type.Int}; {name="b";domain=Type.Int}; {name="c";domain=Type.Text};];;
85 let () = print test
86 let () = print (project ["b";"c";"b"] test)
87 let () = print (project ["b";"d"] test)
88 let () = print (rename test "a" "new_a")