ocaml_sql_parser/lib/ast.ml

167 lines
4.3 KiB
OCaml

type query =
(*| Select of column list * table list option * filter option*)
| Select of column list * table_expression
| CreateSchema of string
| CreateTable of table_scope option * table
| DropSchema of string
| DropTable of table
| DropColumn of string
and table_scope =
| Global
| Local
and column =
| Asterisk
| Column of expression_primary * as_clause option
and as_clause =
| As of string
and table_expression =
| TableExpression of table list option * filter option * group option
and table =
| Table of string
| Join of table * join_type * table * condition option
and join_type =
| Inner
| Left
| Right
| Full
| Cross
| Union
| Natural
and condition =
| Condition of expression_primary * predicate
| And of condition * condition
| Or of condition * condition
| Not of condition
and predicate =
| Comparison of operator * expression_primary
| Between of expression_primary * expression_primary
| NotBetween of expression_primary * expression_primary
| In of expression_primary list
| NotIn of expression_primary list
| Like of expression_primary
| NotLike of expression_primary
and operator =
| Equals
| NotEquals
| LessThan
| GreaterThan
| LessEquals
| GreaterEquals
and filter = condition
and group =
| Group of quantifier option * expression_primary list option
and aggregate =
| Aggregate of func * filter option
and func =
| Function of function_type * quantifier option * expression_primary
and function_type =
| Avg
| Max
| Min
| Sum
| Count
and quantifier =
| All
| Distinct
and expression_primary =
| Ref of string
| StringLiteral of string
| DateLiteral of string
| TimeLiteral of string
| TimestampLiteral of string
| Concatenation of expression_primary * expression_primary
| Numeric of expression_primary * sign * expression_primary
| Signed of sign * expression_primary
| Substring of expression_primary * expression_primary
and sign =
| Plus
| Minus
| Times
| Divide
let rec pp_query fmt ast =
match ast with
| Select(cols, table_exp) -> Format.fprintf fmt "%s" (String.cat "SELECT " (pp_columns cols) ^ pp_table_expression table_exp)
| _ -> failwith "not yet supported"
and pp_columns cols =
match cols with
| [] -> ""
| [col] -> pp_column col
| col::l -> pp_column col ^ ", " ^ pp_columns l
and pp_column col =
match col with
| Column(exp,_) -> pp_expression exp
| Asterisk -> "*"
and pp_expression exp =
match exp with
| Ref(name) -> name
| StringLiteral(s) -> "'" ^ s ^ "'"
| DateLiteral(d) -> "'" ^ d ^ "'"
| TimeLiteral(t) -> "'" ^ t ^ "'"
| TimestampLiteral(ts) -> "'" ^ ts ^ "'"
| _ -> "Expression not yet supported"
and pp_table_expression table_exp =
match table_exp with
| TableExpression(tables, filter, _) -> pp_tables tables ^ pp_filter filter
and pp_tables tables =
let rec aux t =
match t with
| [] -> ""
| table::[] -> pp_table table
| table::l -> pp_table table ^ ", " ^ aux l
in
match tables with
| None -> ""
| Some(t) -> " FROM " ^ aux t
and pp_table table =
match table with
| Table(table) -> table
| Join(t1, j, t2, _) -> pp_table t1 ^ pp_join_type j ^ pp_table t2
and pp_join_type j =
match j with
| Inner -> "inner"
| Left -> "left"
| Right -> "right"
| Full -> "full"
| Cross -> "cross"
| Union -> "union"
| Natural -> "natural"
and pp_filter filter =
let rec aux f =
match f with
| Condition(exp, pred) -> pp_expression exp ^ " " ^ pp_predicate pred
| And(c1, c2) -> aux c1 ^ " AND " ^ aux c2
| Or(c1, c2) -> aux c1 ^ " OR " ^ aux c2
| Not(c) -> "NOT" ^ aux c
in
match filter with
| None -> ""
| Some(f) -> " WHERE " ^ aux f
and pp_predicate pred =
match pred with
| Comparison(op, exp) -> pp_operator op ^ pp_expression exp
| Between(exp1, exp2) -> "BETWEEN " ^ pp_expression exp1 ^ " AND " ^pp_expression exp2
| NotBetween(exp1, exp2) -> "NOT BETWEEN " ^ pp_expression exp1 ^ " AND " ^pp_expression exp2
(*| Like(exp) -> "LIKE " ^ pp_expression exp
| NotLike(exp) -> " NOT LIKE " ^ pp_expression exp*)
| _ -> failwith "Predicate not supported"
and pp_operator op =
match op with
| Equals -> "="
| NotEquals -> "!="
| LessThan -> "<"
| GreaterThan -> ">"
| LessEquals -> "<="
| GreaterEquals -> ">="