Skip to content

Commit a2b6c52

Browse files
authored
Merge pull request #6 from bglid/feature/min-execution
Feature/min execution
2 parents dc3d6f6 + c43a3e4 commit a2b6c52

14 files changed

Lines changed: 391 additions & 159 deletions

docs/roadmap.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Roadmap
2+
3+
- A more detailed set of things to get done. Mainly for personal use/reference:
4+
- *Note, this was created mid-way through so the first parts have been summarized to point 1 & 2*
5+
6+
| # | Step | Status |
7+
| :-: | ------------------------------------------------------- | :----: |
8+
| 1 | Basic REPL and interpreter setup | Done |
9+
| 2 | Disk-writing API | Done |
10+
| 3 | Basic Top-level SQL Parsing |*in progress* |
11+
| 4 | Improve interpreter tests (meta prepare exec.) | *in progress* |
12+
| 5 | Minimal row format and execution | |
13+
| 6 | B+ leaf insertion, search and splitting | |
14+
| 7 | B+ Tree sorted scan | |
15+
| 8 | B+ tree delete | |
16+
17+
18+
- - -

lib/ast.ml renamed to lib/ast/ast.ml

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ type binop_t =
1212
| Comp
1313
[@@deriving show]
1414

15-
type column_types =
16-
| Int_col
17-
| Float_col
18-
| String_col
19-
| Bool_col
20-
[@@deriving show]
15+
(* type column_types = *)
16+
(* | Int_col *)
17+
(* | Float_col *)
18+
(* | String_col *)
19+
(* | Bool_col *)
20+
(* [@@deriving show] *)
2121

2222
(** Our Abstract Syntax Tree for interpreter, hooray! *)
2323
type expr =
@@ -28,26 +28,19 @@ type expr =
2828
| Binop of binop_t * expr * expr
2929
[@@deriving show]
3030

31+
(*NOTE: MOVE TO OWN MODULE*)
3132
type create_t = {
3233
table_name : string;
33-
columns : (string * column_types) list;
34+
columns : string list;
3435
}
3536
[@@deriving show]
3637
(** Handles creating new tables *)
3738

38-
type insert_t = {
39-
table_name : string;
40-
columns : string list option;
41-
values : expr list;
42-
}
43-
[@@deriving show]
44-
(** Handles inserting into existing tables *)
45-
4639
(** Statments like INSERT *)
4740
type statement =
4841
| Create of create_t
49-
| Insert of insert_t
50-
| Select of expr
42+
| Insert of Insert.t
43+
| Select of Select.t
5144
| Expr of expr
5245
| Unk_stmt of string
5346
[@@deriving show]

lib/ast/insert.ml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
(* abstraction to make a module for preparing and executing insert statement*)
2+
3+
type t = {
4+
table : Table.t;
5+
fields : string list;
6+
values : Constant.t list;
7+
}
8+
[@@deriving show]
9+
10+
(* HACKY for now, new table each time *)
11+
let make (tablename : string) (fields : string list) (values : Constant.t list)
12+
: t =
13+
{ table = Table.create_table ~id:777 ~table_name:tablename; fields; values }
14+
15+
let execute_insert (preped_insert : t) : string =
16+
(* let new_table = Table.add_row ~table:temp_table ~row:new_row in *)
17+
let new_fields =
18+
List.fold_left
19+
(fun acc l ->
20+
match l with
21+
| Constant.ConstStr s -> acc ^ " " ^ s
22+
| Constant.ConstInt d -> acc ^ " " ^ Int.to_string (Int32.to_int d))
23+
"" preped_insert.values
24+
in
25+
(* new_fields *)
26+
"Inserted" ^ new_fields ^ " into " ^ preped_insert.table.table_name
27+
28+
(* Printf.printf "Inserted %d %s %s into Table %d" id stop_name rail_name *)
29+
(* preped_insert.table.table_name *)

lib/ast/select.ml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
(* abstraction to make a module for preparing and executing select statement*)
2+
3+
type t = {
4+
fields : string list;
5+
table : Table.t;
6+
}
7+
[@@deriving show]
8+
9+
(* HACKY for now, new table each time *)
10+
let make (fields : string list) (tablename : string) : t =
11+
{ table = Table.create_table ~id:777 ~table_name:tablename; fields }
12+
13+
let execute_select (preped_select : t) : string =
14+
let selected_fields =
15+
List.fold_left
16+
(fun acc l ->
17+
match l with
18+
| "id" -> acc ^ " 1"
19+
| "stop_name" -> acc ^ "englewood"
20+
| "rail_line" -> acc ^ " G"
21+
| _ -> "not a valid field in the table")
22+
"" preped_select.fields
23+
in
24+
selected_fields

lib/ast/table.ml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
(* Starting with a minimal row struct *)
2+
type row_t = {
3+
id : int;
4+
stop_name : string;
5+
rail_line : string;
6+
}
7+
[@@deriving show]
8+
9+
(* probably need to adjust this*)
10+
type t = {
11+
table_id : int;
12+
table_name : string;
13+
table_fields : string list;
14+
rows : row_t list;
15+
}
16+
[@@deriving show]
17+
18+
let make_row ~id ~stop_name ~rail_line : row_t = { id; stop_name; rail_line }
19+
20+
let create_table ~(id : int) ~(table_name : string) : t =
21+
{ table_id = id; table_name; table_fields = []; rows = [] }
22+
23+
(* let open_table ~(table_name : string) : t = *)
24+
(* match table_name with *)
25+
(* | *)
26+
27+
let already_in_table ~(table : t) ~(row : row_t) : bool =
28+
(* List.mem row table.rows *)
29+
let rec search (table_rows : row_t list) (id : int) : bool =
30+
match table_rows with
31+
| [] -> false
32+
| h :: tail ->
33+
if h.id = id then
34+
true
35+
else
36+
search tail id
37+
in
38+
search table.rows row.id
39+
40+
(* currently this is a bit functional in it's nature
41+
always returning a new table rather than adjusting the existing one.
42+
May want to consider changing rows to be mutable, or need to consider disk
43+
writes here - TBD *)
44+
let add_row ~(table : t) ~(row : row_t) : t =
45+
if already_in_table ~table ~row then
46+
table
47+
else
48+
(* let new_row_list = List.fold_left (fun acc l -> acc :: l) table.rows [row] in *)
49+
let new_row_list = table.rows @ [ row ] in
50+
{
51+
table_id = table.table_id;
52+
table_name = table.table_name;
53+
table_fields = table.table_fields;
54+
rows = new_row_list;
55+
}

lib/constant.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
(** Used to represent non AST plain values in SQL queries. More of help than
2+
anything*)
3+
4+
type t =
5+
| ConstInt of Int32.t
6+
| ConstStr of string
7+
[@@deriving show]
8+
9+
let make_int (i32 : Int32.t) : t = ConstInt i32
10+
let make_string (str : string) : t = ConstStr str

lib/interpreter.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,10 @@ let execute_statement stmt : execution_t =
124124
(* Need to improve this once the B+ is implemented *)
125125
match stmt with
126126
| Ast.Create _ -> Ok
127-
| Ast.Insert _ -> Ok
128-
| Ast.Select e -> Message (e |> eval |> string_of_val)
127+
| Ast.Insert i -> Message (Insert.execute_insert i)
128+
| Ast.Select s -> Message (Select.execute_select s)
129129
| Ast.Expr e -> Message (e |> eval |> string_of_val)
130-
| Ast.Unk_stmt _ -> Message "unk statment: Failure"
130+
| Ast.Unk_stmt u -> Message u
131131

132132
(** [interpret input] interprets [input] by lexing + parsing it into a toplevel,
133133
evaluating it, and converting it to a string*)

lib/lexer.mll

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
open Parser
3+
exception Lexing_error of string
34
let meta_cmds = Hashtbl.create 20
45
let () =
56
List.iter (fun (strcmd, mcmd) -> Hashtbl.add meta_cmds strcmd mcmd)
@@ -14,6 +15,9 @@
1415
[
1516
"INSERT", INSERT;
1617
"SELECT", SELECT;
18+
"INTO", INTO;
19+
"VALUES", VALUES;
20+
"FROM", FROM;
1721
]
1822
}
1923

@@ -23,7 +27,8 @@ let frac = '.'digit*
2327
let float = digit* frac?
2428
let white = [' ' '\t']+
2529
let meta_command = ['.']['a'-'z' 'A'-'Z' '_']+
26-
let statement = ['a'-'z' 'A'-'Z' '_']+
30+
let statement = ['A'-'Z' '_']['A'-'Z' '_']+
31+
let id = ['A'-'Z' 'a'-'z' '_' ]['a'-'z' '_' '0'-'9']*
2732
let newline = '\r' | '\n' | "\r\n"
2833

2934

@@ -42,25 +47,31 @@ rule read =
4247
| "FALSE" { FALSE }
4348
| "==" { STRUCT_COMP }
4449
| "<>" { NEQ }
45-
| "<" { LT }
46-
| ">" { GT }
4750
| "<=" { LEQ }
4851
| ">=" { GEQ }
49-
| ";;" { ENTER }
52+
| "<" { LT }
53+
| ">" { GT }
54+
| "," { COMMA }
5055
| white { read lexbuf}
5156
| int { INT (int_of_string(Lexing.lexeme lexbuf))}
5257
| float { FLOAT (float_of_string(Lexing.lexeme lexbuf))}
5358
| meta_command as md
5459
{try Hashtbl.find meta_cmds md
55-
with Not_found -> IDENTIFIER md}
60+
with Not_found -> UNK_COM md}
5661
| statement as s
57-
{try Hashtbl.find stmts (String.uppercase_ascii s)
58-
with Not_found -> IDENTIFIER s}
62+
{try Hashtbl.find stmts s
63+
with Not_found -> UNK_COM s}
64+
| id as s { IDENTIFIER s }
5965
| newline { Lexing.new_line lexbuf; read lexbuf }
66+
| "'" { read_string (Buffer.create 16) lexbuf}
6067
| eof { EOF }
61-
(* | _ { raise (Failure ("Char not allowed in text: " ^Lexing.lexeme lexbuf^)} *)
68+
| _ { raise (Lexing_error ("bad char, error"))}
6269
and comment =
6370
parse
6471
| newline { Lexing.new_line lexbuf; read lexbuf}
6572
| eof { EOF }
6673
| _ { comment lexbuf }
74+
and read_string buff = parse
75+
| "'" { STRING (Buffer.contents buff)}
76+
| _ as c { Buffer.add_char buff c; read_string buff lexbuf }
77+
| eof { raise (Lexing_error ("String not finished, error"))}

lib/parser.mly

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@
66
%token EXIT HELP
77

88
/* statements */
9-
%token INSERT SELECT
9+
%token INSERT SELECT INTO VALUES FROM
10+
%token <string> UNK_COM
1011

1112
/* Operators */
1213
%token LPAREN "("
1314
%token RPAREN ")"
15+
%token COMMA
1416
%token SUM
1517
%token MULT
1618
%token DIV
1719
%token SUBT
1820
%token EOF
19-
%token ENTER
2021
%token TRUE
2122
%token FALSE
2223
%token STRUCT_COMP
@@ -30,6 +31,7 @@
3031
%token <int> INT
3132
%token <float> FLOAT
3233
%token <string> IDENTIFIER
34+
%token <string> STRING
3335

3436
%left LT
3537
%left GT
@@ -47,8 +49,6 @@
4749
%%
4850

4951
prog:
50-
| meta ENTER { $1 }
51-
| statement; ENTER { $1 }
5252
| meta EOF { $1 }
5353
| statement; EOF { $1 }
5454
| e = expr; EOF { Statement (Expr e ) }
@@ -58,26 +58,32 @@ meta:
5858
| EXIT { Meta_command (Exit)}
5959
| HELP { Meta_command (Help)}
6060

61-
62-
statement:
63-
(* | create { $1 } *)
64-
(* | query { $1 } *)
65-
| SELECT; e = expr { Statement (Select e) }
66-
| INSERT; e = expr { Statement (Expr e) }
67-
(* | INSERT IDENTIFIER field_list {} *)
68-
6961
field:
7062
| IDENTIFIER { $1 }
7163
;
7264

65+
constant:
66+
| STRING { Constant.make_string $1 }
67+
| INT { Constant.make_int (Int32.of_int $1) }
68+
69+
70+
constant_list:
71+
| constant { [$1] }
72+
| constant COMMA constant_list {$1 :: $3}
73+
74+
75+
statement:
76+
(* | SELECT; e = expr { Statement (Select e) } *)
77+
| SELECT field_list FROM IDENTIFIER {Statement (Select (Select.make $2 $4))}
78+
| INSERT INTO IDENTIFIER LPAREN field_list RPAREN VALUES LPAREN constant_list RPAREN { Statement ( Insert (Insert.make $3 $5 $9))}
79+
| unk = UNK_COM; {Statement (Unk_stmt ("error: " ^ unk ^ " is an unknown command") )}
80+
81+
7382
field_list:
7483
| field { [$1] }
75-
| field field_list { $1 :: $2 }
84+
| field COMMA field_list { $1 :: $3 }
7685
;
7786

78-
(* create: *)
79-
(* | INSERT IDENTIFIER field_list {} *)
80-
8187

8288
expr:
8389
| i = INT { Int i }

0 commit comments

Comments
 (0)