Source file sql_public.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
open Sql_internals
open Sql_types
let sql_of_query q =
Sql_printers.string_of_query (Sql_flatten.flatten_query q)
let sql_of_view v = sql_of_query (Select v)
let parse ty =
Sql_parsers.use_unsafe_parser
(Sql_parsers.parser_of_type ty)
module Value = struct
let unit () = Atom (Unit ()), Non_nullable TUnit
let bool b = Atom (Bool b), Non_nullable TBool
let int16 i = Atom (Int16 i), Non_nullable TInt16
let int32 i = Atom (Int32 i), Non_nullable TInt32
let int64 i = Atom (Int64 i), Non_nullable TInt64
let float x = Atom (Float x), Non_nullable TFloat
let string s = Atom (String s), Non_nullable TString
let bytea i = Atom (Bytea i), Non_nullable TBytea
let time i = Atom (Time i), Non_nullable TTime
let date i = Atom (Date i), Non_nullable TDate
let timestamp i = Atom (Timestamp i), Non_nullable TTimestamp
let timestamptz i = Atom (Timestamptz i), Non_nullable TTimestamptz
let interval i = Atom (Interval i), Non_nullable TInterval
let int32_array js = Atom (Int32_array js), Non_nullable TInt32_array
end
type 'a sequence = string * atom_type
module Sequence = struct
let serial seq_name = seq_name, TInt32
let bigserial seq_name = seq_name, TInt64
let sequence = bigserial
end
module Op = struct
open Sql_builders
let nullable (r, t) =
r, match t with
| Non_nullable t -> Nullable (Some t)
| Nullable t -> Nullable t
let null = null
let postfixop value op = Op ([null_workaround value], op, [])
let is_null value = postfixop value "IS NULL", Non_nullable TBool
let is_not_null value = postfixop value "IS NOT NULL", Non_nullable TBool
let of_option = function
| None -> null
| Some v -> nullable v
let same_op op_str = op (fun t -> t) op_str
let mono_op t op_str = op (unify (Non_nullable t)) op_str
let poly_op return_t op_str =
let type_fun = function
| Non_nullable _ -> Non_nullable return_t
| Nullable _ -> Nullable (Some return_t) in
op type_fun op_str
type 'phant arith_op = 'phant binary_op
constraint 'phant = < in_t : #numeric_t as 't; out_t : 't; .. >
let arith op = same_op op
let (+), (-), (/), ( * ) =
arith "+", arith "-", arith "/", arith "*"
type 'phant comp_op = 'phant binary_op
constraint 'phant = < out_t : bool_t; .. >
let comp op = poly_op TBool op
let (<), (<=), (<>), (=), (>=), (>) =
comp "<", comp "<=", comp "<>", comp "=", comp ">=", comp ">"
let is_distinct_from a b =
fixed_op "IS DISTINCT FROM" a b (Non_nullable TBool)
let is_not_distinct_from a b =
fixed_op "IS NOT DISTINCT FROM" a b (Non_nullable TBool)
let in' ((_, t) as v) l =
let change_ty = function
| Non_nullable _ -> Non_nullable TBool
| Nullable None -> Nullable None
| Nullable (Some _) -> Nullable (Some TBool)
in
let v = null_workaround v in
let l = List.map null_workaround l in
let t = List.fold_left (fun acc (_, x) -> unify acc x) t l in
let default = (Atom (Bool false), Non_nullable TBool) in
OpTuple (v, "IN", l, Some default), change_ty t
type 'phant logic_op = 'phant binary_op
constraint 'phant = < in_t : #bool_t as 't; out_t : 't; .. >
let logic op = mono_op TBool op
let (&&), (||) = logic "AND", logic "OR"
let prefixop op v = Op ([], op, [null_workaround v])
let not (value, typ) = prefixop "NOT" (value, typ), typ
let count x = prefixop "count" x, Non_nullable TInt64
let min (v, t) = nullable (prefixop "min" (v, t), t)
let max (v, t) = nullable (prefixop "max" (v, t), t)
let sum (v, t) = nullable (prefixop "sum" (v, t), t)
let md5 (v, t) = prefixop "md5" (v, t), t
let label seq_name = Atom (String seq_name), Non_nullable TString
let nextval (seq_name, typ) =
prefixop "nextval" (label seq_name), Non_nullable typ
let currval (seq_name, typ) =
prefixop "currval" (label seq_name), Non_nullable typ
let current_timestamp u =
check_atom_type (get_type u) TUnit;
Op ([], "current_timestamp", []), Non_nullable TTimestamptz
let localtimestamp u =
check_atom_type (get_type u) TUnit;
Op ([], "localtimestamp", []), Non_nullable TTimestamp
end
module Table_type = struct
let _type t = function
| true -> Nullable (Some t)
| false -> Non_nullable t
let boolean = _type TBool
let smallint = _type TInt16
let integer = _type TInt32
let bigint = _type TInt64
let double = _type TFloat
let text = _type TString
let bytea = _type TBytea
let time = _type TTime
let date = _type TDate
let timestamp = _type TTimestamp
let timestamptz = _type TTimestamptz
let interval = _type TInterval
let int32_array = _type TInt32_array
end
module View = struct
open Sql_builders
let one t = view (simple_select t) [] []
end
module ViewOp = struct
let binop op v1 v2 =
{v1 with
descr = unify_descr v1.descr v2.descr;
data = View_op(v1.data, op, v2.data);
}
let union = binop "UNION"
let union_all = binop "UNION ALL"
let intersect = binop "INTERSECT"
let intersect_all = binop "INTERSECT ALL"
let except = binop "EXCEPT"
let except_all = binop "EXCEPT ALL"
end
type 'a nullable_data = < get : unit; t : 'a; nul : nullable > t
type 'a non_nullable_data = < get : unit; t : 'a; nul : non_nullable > t