Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 3c5abb4f49
Fetching contributors…

Cannot retrieve contributors at this time

172 lines (148 sloc) 4.923 kb
(** AST processing functions are defined here, including sql_stt *)
open Expr ;;
open Printf ;;
open Postgresql ;;
let sql_schema_query = "SELECT t1.table_name, t2.column_name, t2.ordinal_position FROM information_schema.tables AS t1, information_schema.columns AS t2 WHERE t1.table_schema = 'public' AND t1.table_name = t2.table_name ORDER BY t1.table_name, t2.ordinal_position;";;
let hash_schema = Hashtbl.create 10;;
Hashtbl.replace hash_schema "Dummy" [""];;
Hashtbl.remove hash_schema "Dummy";;
(* Store the schema to a variable *)
let store_schema (conn:Postgresql.connection) res =
match res#status with
| Empty_query -> printf "Empty query\n"
| Tuples_ok ->
for tuple = 0 to res#ntuples - 1 do
let field = 1 in
let table_name = (res#getvalue tuple 0) in
let value = (res#getvalue tuple field) in
begin
try
let cols = Hashtbl.find hash_schema table_name in
Hashtbl.replace hash_schema table_name (List.append cols [value]);
with Not_found ->
(*Init the list in the hash*)
Hashtbl.add hash_schema table_name [value];
end;
done
| Bad_response -> printf "Bad response: %s\n" res#error; conn#reset
| Nonfatal_error -> printf "Non fatal error: %s\n" res#error
| Fatal_error -> printf "Fatal error: %s\n" res#error
| _ -> failwith "error: unexpected status"
;;
(* Iterate over the result *)
let rec load_res_schema (conn:Postgresql.connection) =
match conn#get_result with
| Some res -> store_schema conn res; flush stdout; load_res_schema conn
| None -> ()
;;
let test_sql (conn:Postgresql.connection) =
conn#send_query "aaaa";;
(*val test_sql : Postgresql.connection -> bool = <fun>*)
(* get the query expression *)
let get_query e = match e with
| Prog sttl -> ( let lq = ( List.filter (fun r -> match r with
| Query _ -> true
| _ -> false) sttl ) in
match lq with
| [] -> failwith "error: there is no query"
| h::[] -> h
| h::_ -> failwith "error: there are too many queries"
)
;;
(* get the predicate name of a term *)
let rec get_predname t = match t with
| Rel r -> ( match r with
| Pred (x, vl) -> x
)
| Equal (s, i) -> s
| Not t -> get_predname t
;;
(* get the list of variables of a term *)
let rec get_varlist t = match t with
| Rel r -> ( match r with
| Pred (x, vl) -> vl
)
| Equal (s, i) -> s :: []
| Not t -> get_varlist t
;;
(* check for one single query in the program *)
let is_single e = ignore (get_query e); true
;;
(* retrieve idb's names in a string list *)
let get_idb's e = match e with
| Prog sttl -> ( List.fold_right (fun s acc -> s::acc) (List.map (fun sl ->
match sl with
| Rule (r, t) -> get_predname (Rel r)
| _ -> invalid_arg "get_idb"
) (List.filter (fun r -> match r with
| Rule (_, _) -> true
| _ -> false) sttl)) []
)
;;
(* check for:
- query being an idb predicate
- single output program (one and only one query)
- [valid rules (idb and edb definitions with schemes)]
- [safe rules]
- [to be continued...]
*)
let is_prog e = is_single e && ( let qname =
get_predname (match (get_query e) with
Query p -> Rel p | _ -> invalid_arg "is_prog") in
List.mem qname (get_idb's e) )
;;
(* get relation definition *)
let get_rel e name = match e with
| Prog sttl -> ( List.fold_right (fun s acc -> s::acc) (List.map (fun sl ->
match sl with
| Rule (r, t) -> if ((get_predname (Rel r)) = name) then (
String.concat ":" [get_predname (List.hd t);
(String.concat ", " (get_varlist (List.hd t)));]) else ""
| _ -> invalid_arg "get_idb"
) (List.filter (fun r -> match r with
| Rule (_, _) -> true
| _ -> false) sttl)) []
)
;;
(* Subquery generator *)
let rec get_subquery e name =
Printf.printf "Call %s\n" name; flush stdout;
let l = get_rel e name in
let newname = (String.concat "" l) in
Printf.printf "List (%i): %s\n" (List.length l) newname;
flush stdout;
if (newname = "") then
name
else
(String.concat " " [
"(SELECT";
(List.hd (List.rev (Str.split (Str.regexp ":") newname)));
"FROM ";
( get_subquery e (List.hd (Str.split (Str.regexp ":") newname)));
")";
"AS foo";
]);
;;
let get_column_name table pos =
begin
try
let cols = Hashtbl.find hash_schema table in
List.nth cols pos;
with Not_found ->
""
end;;
(* generate SQL statement from the ast *)
let sql_stt e = String.concat ""
["SELECT ";
(String.concat ", " (get_varlist(match (get_query e) with
Query p -> Rel p | _ -> invalid_arg "is_prog")));
" FROM " ;
(* (get_predname(match (get_query e) with
Query p -> Rel p | _ -> invalid_arg "is_prog"));
".";
(String.concat ", " (get_idb's e));
"----";*)
( get_subquery e (get_predname(match (get_query e) with
Query p -> Rel p | _ -> invalid_arg "is_prog")));
]
;;
Jump to Line
Something went wrong with that request. Please try again.