From 6fc74eb8f1a5fd3b4ee500c974bc16f2881db8bc Mon Sep 17 00:00:00 2001 From: ygrek Date: Sun, 19 Jul 2009 11:41:36 +0300 Subject: [PATCH] sql: CASE ... END, TODO more polymorphic `Func --- src/sql_lexer.mll | 5 +++++ src/sql_parser.mly | 7 +++++++ src/test.ml | 3 +++ 3 files changed, 15 insertions(+) diff --git a/src/sql_lexer.mll b/src/sql_lexer.mll index 74d0094..6f784b7 100644 --- a/src/sql_lexer.mll +++ b/src/sql_lexer.mll @@ -101,6 +101,11 @@ let keywords = "first",FIRST; "column",COLUMN; "like", LIKE; + "case", CASE; + "when", WHEN; + "then", THEN; + "else", ELSE; + "end", END; ] in (* more *) let all token l = k := !k @ List.map (fun x -> x,token) l in all (FUNCTION T.Int) ["max"; "min"; "length"; "random";"count";"sum";"avg"]; diff --git a/src/sql_parser.mly b/src/sql_parser.mly index b1ff3ed..b317295 100644 --- a/src/sql_parser.mly +++ b/src/sql_parser.mly @@ -49,6 +49,7 @@ PRECISION UNSIGNED ZEROFILL VARYING CHARSET NATIONAL ASCII UNICODE COLLATE BINARY CHARACTER DATETIME_FUNC DATE TIME TIMESTAMP ALTER ADD COLUMN CASCADE RESTRICT DROP GLOBAL LOCAL VALUE REFERENCES CHECK CONSTRAINT IGNORED AFTER INDEX FULLTEXT FIRST + CASE WHEN THEN ELSE END %token NUM_BINARY_OP PLUS MINUS COMPARISON_OP %token T_INTEGER T_BLOB T_TEXT T_FLOAT T_BOOLEAN T_DATETIME @@ -309,7 +310,13 @@ expr: | expr TEST_NULL { $1 } | expr mnot(BETWEEN) expr AND expr { `Func (Int,[$1;$3;$5]) } | mnot(EXISTS) LPAREN select=select_stmt RPAREN { `Func (Bool,params_of select) } + | CASE e1=expr? branches=nonempty_list(case_branch) e2=preceded(ELSE,expr)? END + { + let l = function None -> [] | Some x -> [x] in + `Func (Any,l e1 @ List.flatten branches @ l e2) + } +case_branch: WHEN e1=expr THEN e2=expr { [e1;e2] } like: LIKE | LIKE_OP { } datetime_value: | DATETIME_FUNC | DATETIME_FUNC LPAREN INTEGER? RPAREN { `Value Datetime } diff --git a/src/test.ml b/src/test.ml index b9f10af..eef1e01 100644 --- a/src/test.ml +++ b/src/test.ml @@ -54,6 +54,9 @@ let test () = [p "name" Text]; tt "insert or replace into test values (2,?,?)" [] [param,Text; param,Text;]; tt "replace into test values (2,?,?)" [] [param,Text; param,Text;]; + tt "select str, case when id > @id then name when id < @id then 'qqq' else @def end as q from test" + [attr "str" Text; attr "q" Any] (* FIXME `Func *) + [p "id" Int; p "id" Int; p "def" Any]; wrong "insert into test values (1,2)"; wrong "insert into test (str,name) values (1,'str','name')"; () -- 2.11.4.GIT