comparison src/lacweb.grm @ 226:b0041cc7e5f7

Basic GROUP BY
author Adam Chlipala <adamc@hcoop.net>
date Thu, 21 Aug 2008 13:59:49 -0400
parents 5ac2cf59b839
children 524e10c91478
comparison
equal deleted inserted replaced
225:5ac2cf59b839 226:b0041cc7e5f7
44 44
45 datatype select = 45 datatype select =
46 Star 46 Star
47 | Items of select_item list 47 | Items of select_item list
48 48
49 datatype group_item =
50 GField of con * con
51
49 fun eqTnames ((c1, _), (c2, _)) = 52 fun eqTnames ((c1, _), (c2, _)) =
50 case (c1, c2) of 53 case (c1, c2) of
51 (CVar (ms1, x1), CVar (ms2, x2)) => ms1 = ms2 andalso x1 = x2 54 (CVar (ms1, x1), CVar (ms2, x2)) => ms1 = ms2 andalso x1 = x2
52 | (CName x1, CName x2) => x1 = x2 55 | (CName x1, CName x2) => x1 = x2
53 | _ => false 56 | _ => false
54 57
55 fun amend_select loc (si, tabs) = 58 fun amend_select loc (si, tabs) =
56 let 59 let
57 val (tx, c) = case si of 60 val (tx, c) = case si of
58 Field (tx, fx) => (tx, (CRecord ([(fx, (CWild (KType, loc), loc))]), loc)) 61 Field (tx, fx) => (tx, (CRecord ([(fx, (CWild (KType, loc), loc))]), loc))
62
63 val (tabs, found) = ListUtil.foldlMap (fn ((tx', c'), found) =>
64 if eqTnames (tx, tx') then
65 ((tx', (CConcat (c, c'), loc)), true)
66 else
67 ((tx', c'), found))
68 false tabs
69 in
70 if found then
71 ()
72 else
73 ErrorMsg.errorAt loc "Select of field from unbound table";
74
75 tabs
76 end
77
78 fun amend_group loc (gi, tabs) =
79 let
80 val (tx, c) = case gi of
81 GField (tx, fx) => (tx, (CRecord ([(fx, (CWild (KType, loc), loc))]), loc))
59 82
60 val (tabs, found) = ListUtil.foldlMap (fn ((tx', c'), found) => 83 val (tabs, found) = ListUtil.foldlMap (fn ((tx', c'), found) =>
61 if eqTnames (tx, tx') then 84 if eqTnames (tx, tx') then
62 ((tx', (CConcat (c, c'), loc)), true) 85 ((tx', (CConcat (c, c'), loc)), true)
63 else 86 else
127 150
128 | XML_BEGIN of string | XML_END 151 | XML_BEGIN of string | XML_END
129 | NOTAGS of string 152 | NOTAGS of string
130 | BEGIN_TAG of string | END_TAG of string 153 | BEGIN_TAG of string | END_TAG of string
131 154
132 | SELECT | FROM | AS | CWHERE 155 | SELECT | FROM | AS | CWHERE | GROUP | BY
133 | TRUE | FALSE | CAND | OR | NOT 156 | TRUE | FALSE | CAND | OR | NOT
134 | NE | LT | LE | GT | GE 157 | NE | LT | LE | GT | GE
135 158
136 %nonterm 159 %nonterm
137 file of decl list 160 file of decl list
192 | attrs of (con * exp) list 215 | attrs of (con * exp) list
193 | attr of con * exp 216 | attr of con * exp
194 | attrv of exp 217 | attrv of exp
195 218
196 | query of exp 219 | query of exp
220 | query1 of exp
197 | tables of (con * exp) list 221 | tables of (con * exp) list
198 | tname of con 222 | tname of con
199 | table of con * exp 223 | table of con * exp
200 | tident of con 224 | tident of con
201 | fident of con 225 | fident of con
202 | seli of select_item 226 | seli of select_item
203 | selis of select_item list 227 | selis of select_item list
204 | select of select 228 | select of select
205 | sqlexp of exp 229 | sqlexp of exp
206 | wopt of exp 230 | wopt of exp
231 | groupi of group_item
232 | groupis of group_item list
233 | gopt of group_item list option
207 234
208 235
209 %verbose (* print summary of errors *) 236 %verbose (* print summary of errors *)
210 %pos int (* positions *) 237 %pos int (* positions *)
211 %start file 238 %start file
613 640
614 attrv : INT (EPrim (Prim.Int INT), s (INTleft, INTright)) 641 attrv : INT (EPrim (Prim.Int INT), s (INTleft, INTright))
615 | FLOAT (EPrim (Prim.Float FLOAT), s (FLOATleft, FLOATright)) 642 | FLOAT (EPrim (Prim.Float FLOAT), s (FLOATleft, FLOATright))
616 | STRING (EPrim (Prim.String STRING), s (STRINGleft, STRINGright)) 643 | STRING (EPrim (Prim.String STRING), s (STRINGleft, STRINGright))
617 | LBRACE eexp RBRACE (eexp) 644 | LBRACE eexp RBRACE (eexp)
645
646 query : query1 (query1)
618 647
619 query : SELECT select FROM tables wopt 648 query1 : SELECT select FROM tables wopt gopt
620 (let 649 (let
621 val loc = s (SELECTleft, tablesright) 650 val loc = s (SELECTleft, tablesright)
622 651
623 val sel = 652 val sel =
624 case select of 653 case select of
638 loc)], loc))) tabs 667 loc)], loc))) tabs
639 end 668 end
640 669
641 val sel = (CRecord sel, loc) 670 val sel = (CRecord sel, loc)
642 671
672 val grp = case gopt of
673 NONE => (ECApp ((EVar (["Basis"], "sql_subset_all"), loc),
674 (CWild (KRecord (KRecord (KType, loc), loc),
675 loc), loc)), loc)
676 | SOME gis =>
677 let
678 val tabs = map (fn (nm, _) =>
679 (nm, (CRecord [], loc))) tables
680 val tabs = foldl (amend_group loc) tabs gis
681
682 val tabs = map (fn (nm, c) =>
683 (nm,
684 (CTuple [c,
685 (CWild (KRecord (KType, loc),
686 loc),
687 loc)], loc))) tabs
688 in
689 (ECApp ((EVar (["Basis"], "sql_subset"), loc),
690 (CRecord tabs, loc)), loc)
691 end
692
643 val hopt = (sql_inject (EVar (["Basis"], "True"), 693 val hopt = (sql_inject (EVar (["Basis"], "True"),
644 EVar (["Basis"], "sql_bool"), 694 EVar (["Basis"], "sql_bool"),
645 loc)) 695 loc))
646 696
647 val e = (EVar (["Basis"], "sql_query"), loc) 697 val e = (EVar (["Basis"], "sql_query"), loc)
648 val re = (ERecord [((CName "From", loc), 698 val re = (ERecord [((CName "From", loc),
649 (ERecord tables, loc)), 699 (ERecord tables, loc)),
650 ((CName "Where", loc), 700 ((CName "Where", loc),
651 wopt), 701 wopt),
652 ((CName "GroupBy", loc), 702 ((CName "GroupBy", loc),
653 (ECApp ((EVar (["Basis"], "sql_subset_all"), loc), 703 grp),
654 (CWild (KRecord (KRecord (KType, loc), loc),
655 loc), loc)), loc)),
656 ((CName "Having", loc), 704 ((CName "Having", loc),
657 hopt), 705 hopt),
658 ((CName "SelectFields", loc), 706 ((CName "SelectFields", loc),
659 (ECApp ((EVar (["Basis"], "sql_subset"), loc), 707 (ECApp ((EVar (["Basis"], "sql_subset"), loc),
660 sel), loc))], loc) 708 sel), loc))], loc)
730 778
731 wopt : (sql_inject (EVar (["Basis"], "True"), 779 wopt : (sql_inject (EVar (["Basis"], "True"),
732 EVar (["Basis"], "sql_bool"), 780 EVar (["Basis"], "sql_bool"),
733 ErrorMsg.dummySpan)) 781 ErrorMsg.dummySpan))
734 | CWHERE sqlexp (sqlexp) 782 | CWHERE sqlexp (sqlexp)
783
784 groupi : tident DOT fident (GField (tident, fident))
785
786 groupis: groupi ([groupi])
787 | groupi COMMA groupis (groupi :: groupis)
788
789 gopt : (NONE)
790 | GROUP BY groupis (SOME groupis)