# HG changeset patch # User Adam Chlipala # Date 1219348208 14400 # Node ID 87d41ac28b30df7c4b57df0c2c3bea68f96fc8ee # Parent 016d71e878c1bb7297b676f804d8aee454e5d201 ORDER BY diff -r 016d71e878c1 -r 87d41ac28b30 lib/basis.lig --- a/lib/basis.lig Thu Aug 21 15:27:04 2008 -0400 +++ b/lib/basis.lig Thu Aug 21 15:50:08 2008 -0400 @@ -50,9 +50,20 @@ -> selected ::: {{Type}} -> sql_query1 tables1 selected -> sql_query1 tables2 selected -> sql_query1 selected selected +type sql_direction +val sql_asc : sql_direction +val sql_desc : sql_direction + +con sql_order_by :: {{Type}} -> Type +val sql_order_by_Nil : tables :: {{Type}} -> sql_order_by tables +val sql_order_by_Cons : tables ::: {{Type}} -> t ::: Type + -> sql_exp tables [] t -> sql_order_by tables + -> sql_order_by tables + val sql_query : tables ::: {{Type}} -> selected ::: {{Type}} - -> sql_query1 tables selected + -> {Rows : sql_query1 tables selected, + OrderBy : sql_order_by tables} -> sql_query selected val sql_field : otherTabs ::: {{Type}} -> otherFields ::: {Type} -> fieldType ::: Type -> agg ::: {{Type}} diff -r 016d71e878c1 -r 87d41ac28b30 src/lacweb.grm --- a/src/lacweb.grm Thu Aug 21 15:27:04 2008 -0400 +++ b/src/lacweb.grm Thu Aug 21 15:50:08 2008 -0400 @@ -30,6 +30,7 @@ open Source val s = ErrorMsg.spanOf +val dummy = ErrorMsg.dummySpan fun capitalize "" = "" | capitalize s = str (Char.toUpper (String.sub (s, 0))) ^ String.extract (s, 1, NONE) @@ -161,7 +162,7 @@ | NOTAGS of string | BEGIN_TAG of string | END_TAG of string - | SELECT | FROM | AS | CWHERE | GROUP | BY | HAVING + | SELECT | FROM | AS | CWHERE | GROUP | ORDER | BY | HAVING | UNION | INTERSECT | EXCEPT | TRUE | FALSE | CAND | OR | NOT | NE | LT | LE | GT | GE @@ -242,6 +243,8 @@ | groupis of group_item list | gopt of group_item list option | hopt of exp + | obopt of exp + | obexps of exp %verbose (* print summary of errors *) @@ -655,10 +658,15 @@ | STRING (EPrim (Prim.String STRING), s (STRINGleft, STRINGright)) | LBRACE eexp RBRACE (eexp) -query : query1 (let +query : query1 obopt (let val loc = s (query1left, query1right) + + val re = (ERecord [((CName "Rows", loc), + query1), + ((CName "OrderBy", loc), + obopt)], loc) in - (EApp ((EVar (["Basis"], "sql_query"), loc), query1), loc) + (EApp ((EVar (["Basis"], "sql_query"), loc), re), loc) end) query1 : SELECT select FROM tables wopt gopt hopt @@ -796,7 +804,7 @@ wopt : (sql_inject (EVar (["Basis"], "True"), EVar (["Basis"], "sql_bool"), - ErrorMsg.dummySpan)) + dummy)) | CWHERE sqlexp (sqlexp) groupi : tident DOT fident (GField (tident, fident)) @@ -809,5 +817,30 @@ hopt : (sql_inject (EVar (["Basis"], "True"), EVar (["Basis"], "sql_bool"), - ErrorMsg.dummySpan)) + dummy)) | HAVING sqlexp (sqlexp) + +obopt : (ECApp ((EVar (["Basis"], "sql_order_by_Nil"), dummy), + (CWild (KRecord (KRecord (KType, dummy), dummy), dummy), dummy)), + dummy) + | ORDER BY obexps (obexps) + +obexps : sqlexp (let + val loc = s (sqlexpleft, sqlexpright) + + val e' = (ECApp ((EVar (["Basis"], "sql_order_by_Nil"), loc), + (CWild (KRecord (KRecord (KType, loc), loc), loc), loc)), + loc) + val e = (EApp ((EVar (["Basis"], "sql_order_by_Cons"), loc), + sqlexp), loc) + in + (EApp (e, e'), loc) + end) + | sqlexp COMMA obexps (let + val loc = s (sqlexpleft, obexpsright) + + val e = (EApp ((EVar (["Basis"], "sql_order_by_Cons"), loc), + sqlexp), loc) + in + (EApp (e, obexps), loc) + end) diff -r 016d71e878c1 -r 87d41ac28b30 src/lacweb.lex --- a/src/lacweb.lex Thu Aug 21 15:27:04 2008 -0400 +++ b/src/lacweb.lex Thu Aug 21 15:50:08 2008 -0400 @@ -306,6 +306,7 @@ "AS" => (Tokens.AS (pos yypos, pos yypos + size yytext)); "WHERE" => (Tokens.CWHERE (pos yypos, pos yypos + size yytext)); "GROUP" => (Tokens.GROUP (pos yypos, pos yypos + size yytext)); + "ORDER" => (Tokens.ORDER (pos yypos, pos yypos + size yytext)); "BY" => (Tokens.BY (pos yypos, pos yypos + size yytext)); "HAVING" => (Tokens.HAVING (pos yypos, pos yypos + size yytext)); diff -r 016d71e878c1 -r 87d41ac28b30 tests/order_by.lac --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/order_by.lac Thu Aug 21 15:50:08 2008 -0400 @@ -0,0 +1,8 @@ +table t1 : {A : int, B : string, C : float} +table t2 : {A : float, D : int} + +val q1 = (SELECT * FROM t1 ORDER BY t1.A, t1.B) +val q2 = (SELECT * FROM t1 GROUP BY t1.A ORDER BY t1.A, t1.B) +val q3 = (SELECT t1.B FROM t1 + UNION SELECT t1.B FROM t1 + ORDER BY t1.B)