Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions lib/sql.ml
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ type col_name = {
tname : table_name option;
} [@@deriving show]
type logical_op = And | Or | Xor [@@deriving show]
type comparison_op = Comp_equal | Comp_num_cmp | Comp_num_eq | Not_distinct_op | Is_null | Is_not_null [@@deriving eq, show]
type comparison_op = Comp_equal | Comp_num_cmp | Comp_text_cmp | Comp_num_eq | Not_distinct_op | Is_null | Is_not_null [@@deriving eq, show]

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i was going to say i would expect some typing changes involving new ctor, but then i see there is nothing like this for comp_num_cmp either. Not for this PR but it means this is a missed opportunity to have better inference @jongleb ?

type null_handling_fn_kind = Coalesce of Type.tyvar * Type.tyvar | Null_if | If_null [@@deriving show]
type source_alias = { table_name : table_name; column_aliases : schema option } [@@deriving show]
type select_row_locking_kind = For_update | For_share [@@deriving show]
Expand Down Expand Up @@ -1176,7 +1176,10 @@ let () =
"uuid_short" |> monomorphic int [];
"is_uuid" |> monomorphic bool [text];
"makedate" |> monomorphic datetime [int; int];
(*
"similarity" |> monomorphic float [text; text];
"word_similarity" |> monomorphic float [text; text];
"strict_word_similarity" |> monomorphic float [text; text];
(*
Any is used instead of Var because MySQL JSON functions have unique semantics:

1. ACCEPT ANY DATA TYPE: MySQL JSON functions accept values of any type
Expand Down
14 changes: 8 additions & 6 deletions lib/sql_lexer.mll
Original file line number Diff line number Diff line change
Expand Up @@ -282,8 +282,8 @@ let cmnt = "--" | "//" | "#"
rule ruleStatement = parse
| ['\n' ' ' '\r' '\t']+ as tok { `Space tok }
| cmnt wsp* "[sqlgg]" wsp+ (ident+ as n) wsp* "=" wsp* ([^'\n']* as v) '\n' { `Props [(n, String.trim v)] }
| cmnt wsp* "@" (ident+ as name) wsp* "|" ([^'\n']* as v) '\n'
{
| cmnt wsp* "@" (ident+ as name) wsp* "|" ([^'\n']* as v) '\n'
{
let props = rulePropList [] (Lexing.from_string v) in
let all_props = ("name", name) :: props in
`Props all_props
Expand All @@ -302,8 +302,8 @@ rule ruleStatement = parse
(* Parse a list of key:value properties *)
and
rulePropList acc = parse
| wsp* (ident+ as prop) wsp* ':' wsp* ([^',' '\n']+ as value) wsp*
{
| wsp* (ident+ as prop) wsp* ':' wsp* ([^',' '\n']+ as value) wsp*
{
let new_acc = (String.trim prop, String.trim value) :: acc in
rulePropListNext new_acc lexbuf
}
Expand All @@ -312,7 +312,7 @@ rulePropList acc = parse
| _ { error lexbuf "rulePropList" }
(* Parse continuation after comma *)
and
rulePropListNext acc = parse
rulePropListNext acc = parse
| ',' { rulePropList acc lexbuf }
| wsp* '\n' { List.rev acc }
| wsp* eof { List.rev acc }
Expand Down Expand Up @@ -346,13 +346,15 @@ ruleMain = parse
| "+" { PLUS }
| "-" { MINUS }

| "/" | "%" { NUM_DIV_OP }
| "/" | "%" { NUM_DIV_OP } (* FIXME: in PostgreSQL, "%" is both int modulo and a trigram comparison operator *)
| "<<" | ">>" { NUM_BIT_SHIFT }
| "|" { NUM_BIT_OR }
| "&" { NUM_BIT_AND }
| ">" | ">=" | "<=" | "<" { NUM_CMP_OP }
| "<>" | "!=" | "==" { NUM_EQ_OP }
| "<=>" { NOT_DISTINCT_OP }
| "<%" | "%>" | "<<%" | "%>>" { TEXT_CMP_OP }
| "<->" | "<<->" | "<->>" | "<<<->" | "<->>>" { TEXT_DIST_OP }

| "->" { JSON_EXTRACT_OP }
| "->>" { JSON_UNQUOTE_EXTRACT_OP }
Expand Down
5 changes: 4 additions & 1 deletion lib/sql_parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
%token GROUP_CONCAT SEPARATOR
%token JSON_ARRAYAGG
%token NUM_DIV_OP NUM_EQ_OP NUM_CMP_OP PLUS MINUS NOT_DISTINCT_OP NUM_BIT_SHIFT NUM_BIT_OR NUM_BIT_AND
%token TEXT_CMP_OP TEXT_DIST_OP
%token JSON_EXTRACT_OP JSON_UNQUOTE_EXTRACT_OP
%token <Sql.int_size option> T_INTEGER
%token T_TEXT T_TINYTEXT T_MEDIUMTEXT T_LONGTEXT T_CHAR T_VARCHAR T_VARCHAR2
Expand All @@ -73,7 +74,7 @@
%nonassoc NOT
%nonassoc BETWEEN CASE (* WHEN THEN ELSE *) (* never useful *)
%nonassoc EQUAL NUM_EQ_OP NOT_DISTINCT_OP IS LIKE LIKE_OP IN
%nonassoc NUM_CMP_OP
%nonassoc NUM_CMP_OP TEXT_CMP_OP TEXT_DIST_OP
%left NUM_BIT_OR
%left NUM_BIT_AND
%left NUM_BIT_SHIFT
Expand Down Expand Up @@ -495,6 +496,7 @@ expr:
e1=expr numeric_bin_op e2=expr %prec PLUS { Fun { fn_name = "numeric_bin_op"; kind = (Ret (Source_type.depends Any)); parameters = [e1;e2]; is_over_clause = false } } (* TODO default Int *)
| MOD LPAREN e1=expr COMMA e2=expr RPAREN { Fun { fn_name = "mod"; kind = (Ret (Source_type.depends Any)); parameters = [e1;e2]; is_over_clause = false } } (* mysql special *)
| e1=expr NUM_DIV_OP e2=expr %prec PLUS { Fun { fn_name = "num_div"; kind = (Ret (Source_type.depends Float)); parameters = [e1;e2]; is_over_clause = false } }
| e1=expr TEXT_DIST_OP e2=expr { Fun { fn_name = "text_dist"; kind = (Ret (Source_type.depends Float)); parameters = [e1;e2]; is_over_clause = false } }
| e1=expr DIV e2=expr %prec PLUS { Fun { fn_name = "div"; kind = (Ret (Source_type.depends Int)); parameters = [e1;e2]; is_over_clause = false } }
| e1=expr bool_op=boolean_bin_op e2=expr %prec AND { Fun { fn_name = "boolean_bin_op"; kind = (Logical bool_op); parameters = [e1;e2]; is_over_clause = false } }
| e1=expr comp_op=comparison_op anyall? e2=expr %prec EQUAL { Fun { fn_name = "comparison"; kind = Comparison comp_op; parameters = [e1; e2]; is_over_clause = false } }
Expand Down Expand Up @@ -641,6 +643,7 @@ numeric_bin_op: PLUS | MINUS | ASTERISK | MOD | NUM_BIT_OR | NUM_BIT_AND | NUM_B
comparison_op:
| EQUAL { Comp_equal }
| NUM_CMP_OP { Comp_num_cmp }
| TEXT_CMP_OP { Comp_text_cmp }
| NOT_DISTINCT_OP { Not_distinct_op }
| NUM_EQ_OP {
(* it would be nice to go into num_eq_op,
Expand Down