Kota UENISHI avatar Kota UENISHI committed db1d1f6

add prettyprinter of query

Comments (0)

Files changed (4)

       print_endline (Printexc.to_string exn);
       raise exn;;
 
-let sample_query = "select * from mytable";;
+let sample_query = "select * from mytable where colA == 'foo'";;
 
 let _ =
   print_endline sample_query;
 
-type columns = All_col | Columns of string list
-type query = Select of columns * string (* columns, table *)
+type columns   = All_col | Columns of string list
+type condition = And of condition * condition
+                 | Or of condition * condition
+                 | Not of condition
+                 | Gt_f of string * float
+                 | Gt_i of string * int
+                 | Lt_f of string * float
+                 | Lt_i of string * int
+                 | Equal_i of string * int
+                 | Equal_s of string * string
+                 | Regexp  of string * string
+  
+type query = Select of columns * string * condition list
+             (* columns, table *)
+
+let pp_cols = function
+  | All_col -> "*";
+  | Columns(cols) -> (String.concat "," cols);;
+
+let rec pp_cond = function
+  | And(c0, c1) -> (pp_cond c0) ^ " and " ^ (pp_cond c1);
+  | Or(c0, c1)  -> (pp_cond c0) ^ " or " ^ (pp_cond c1);
+  | Not(c)      -> "(NOT "^(pp_cond c)^")";
+  | Gt_f(s, v)  -> Printf.sprintf "(%s < %f)" s v;
+  | Gt_i(s, i)  -> Printf.sprintf "(%s < %d)" s i;
+  | Lt_f(s, v)  -> Printf.sprintf "(%s > %f)" s v;
+  | Lt_i(s, i)  -> Printf.sprintf "(%s > %d)" s i;
+  | Equal_i(s, i) -> Printf.sprintf "(%s == %d)" s i;
+  | Equal_s(s0,s1)-> Printf.sprintf "(%s == '%s')" s0 s1;
+  | Regexp(s,r) -> Printf.sprintf "(%s ~ %s)" s r;;
+
+let rec pp_where = function
+  | [] -> "";
+  | hd::tl -> (pp_cond hd)^" "^(pp_where tl);;
 
 let pp_query = function
-  | Select(All_col, table) ->
-    Printf.printf "select: * from %s\n" table;
-  | Select(Columns(columns), table) ->
-    Printf.printf "select: %s from %s\n" (String.concat "," columns) table;;
+  | Select(columns, table, where) ->
+    Printf.printf "select: %s from %s where %s\n" (pp_cols columns) table (pp_where where);

sql/sql_lexer.mll

 let debugprint = ref true;;
 let print str =  if !debugprint then print_endline str;;
 
+let quote_buf = String.create 8192;;
+let quote_ptr = ref 0;;
+let in_quote = ref false;;
+
 }
 
 let digit = ['0'-'9']*
   | "SELECT" { SELECT }
   | "from"   { FROM }
   | "FROM"   { FROM }
+  | "where"  { WHERE }
+  | "WHERE"  { WHERE }
   | ","      { COMMA }
   | "*"      { ASTERISK }
+  | "=="     { EQUAL }
+  | "'"      {
+    print "quote =======>";
+    in_quote := true;
+    quote_ptr := 0;
+    quote lexbuf;
+    in_quote := false;
+    print " <============= quote";
+    QUOTE (String.sub quote_buf 0 (!quote_ptr))
+  }
   | literal as s { LITERAL(s) }
   | "\n"         { print "f"; token lexbuf }
 (*  | eof	         { print "eof."; EOF } *)
   | _            { token lexbuf }
+and quote = parse
+  | "'"  { () }
+  | _ as c {
+    (* print_char c; *)
+    String.set quote_buf (!quote_ptr) c;
+    quote_ptr := (!quote_ptr) + 1;
+    quote lexbuf
+  }
+
+
+{}

sql/sql_parser.mly

 %{
 
   open Printf
-  let _ = Parsing.set_trace false;;
+  let _ = Parsing.set_trace true;;
   let debugprint = ref true;;
   
   let print str = if !debugprint then print_endline str;;
 %token COMMA
 %token ASTERISK
 %token GT LT EQ NEQ NOT
-%token EOF
+%token EQUAL
 
 %token <int> INT
 
 %token <string> LITERAL
+%token <string> QUOTE
 
 %start input
 %type <Sql.query> input
 input: | exp { $1 };
 
 exp:
-  | SELECT ASTERISK FROM LITERAL { Sql.Select(Sql.All_col, $4) };
-  | SELECT columns  FROM LITERAL { Sql.Select(Sql.Columns($2), $4) };
+  | SELECT ASTERISK FROM LITERAL { Sql.Select(Sql.All_col, $4, []) }
+  | SELECT columns  FROM LITERAL { Sql.Select(Sql.Columns($2), $4, []) }
+  | SELECT ASTERISK FROM LITERAL where_clause { Sql.Select(Sql.All_col, $4, $5) }
+  | SELECT columns  FROM LITERAL where_clause { Sql.Select(Sql.Columns($2), $4, $5) }
 
 columns:
   | LITERAL  { [$1] }
   | LITERAL COMMA columns { $1::$3 }
-;
+
+where_clause:
+  | WHERE LITERAL EQUAL QUOTE { [ Sql.Equal_s($2, $4)] }
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.