178 lines
4.6 KiB
OCaml
178 lines
4.6 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
|
|
| IntegerLiteral of int
|
|
| FloatLiteral of float
|
|
| 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 ^ "'"
|
|
| IntegerLiteral(i) -> string_of_int i
|
|
| FloatLiteral(f) -> string_of_float f
|
|
| Numeric(n1, s, n2) -> pp_expression n1 ^ pp_sign s ^ pp_expression n2
|
|
| _ -> "Expression not yet supported"
|
|
|
|
and pp_sign sign =
|
|
match sign with
|
|
| Plus -> "+"
|
|
| Minus -> "-"
|
|
| Times -> "*"
|
|
| Divide -> "/"
|
|
|
|
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 -> ">="
|