changeset 230:87d41ac28b30

ORDER BY
author Adam Chlipala <adamc@hcoop.net>
date Thu, 21 Aug 2008 15:50:08 -0400
parents 016d71e878c1
children eadeea528f75
files lib/basis.lig src/lacweb.grm src/lacweb.lex tests/order_by.lac
diffstat 4 files changed, 59 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- 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}}
--- 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)
--- 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 @@
 <INITIAL> "AS"        => (Tokens.AS (pos yypos, pos yypos + size yytext));
 <INITIAL> "WHERE"     => (Tokens.CWHERE (pos yypos, pos yypos + size yytext));
 <INITIAL> "GROUP"     => (Tokens.GROUP (pos yypos, pos yypos + size yytext));
+<INITIAL> "ORDER"     => (Tokens.ORDER (pos yypos, pos yypos + size yytext));
 <INITIAL> "BY"        => (Tokens.BY (pos yypos, pos yypos + size yytext));
 <INITIAL> "HAVING"    => (Tokens.HAVING (pos yypos, pos yypos + size yytext));
 
--- /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)