comparison src/lacweb.grm @ 233:c466678af854

SELECTing arbitrary expressions
author Adam Chlipala <adamc@hcoop.net>
date Thu, 28 Aug 2008 11:17:14 -0400
parents a338da9d82f3
children 82409ef72019
comparison
equal deleted inserted replaced
232:a338da9d82f3 233:c466678af854
40 TRecord c => c 40 TRecord c => c
41 | _ => t 41 | _ => t
42 42
43 datatype select_item = 43 datatype select_item =
44 Field of con * con 44 Field of con * con
45 | Exp of con * exp
45 46
46 datatype select = 47 datatype select =
47 Star 48 Star
48 | Items of select_item list 49 | Items of select_item list
49 50
54 case (c1, c2) of 55 case (c1, c2) of
55 (CVar (ms1, x1), CVar (ms2, x2)) => ms1 = ms2 andalso x1 = x2 56 (CVar (ms1, x1), CVar (ms2, x2)) => ms1 = ms2 andalso x1 = x2
56 | (CName x1, CName x2) => x1 = x2 57 | (CName x1, CName x2) => x1 = x2
57 | _ => false 58 | _ => false
58 59
59 fun amend_select loc (si, tabs) = 60 fun amend_select loc (si, (tabs, exps)) =
60 let 61 case si of
61 val (tx, c) = case si of 62 Field (tx, fx) =>
62 Field (tx, fx) => (tx, (CRecord ([(fx, (CWild (KType, loc), loc))]), loc)) 63 let
63 64 val c = (CRecord ([(fx, (CWild (KType, loc), loc))]), loc)
64 val (tabs, found) = ListUtil.foldlMap (fn ((tx', c'), found) => 65
65 if eqTnames (tx, tx') then 66 val (tabs, found) = ListUtil.foldlMap (fn ((tx', c'), found) =>
66 ((tx', (CConcat (c, c'), loc)), true) 67 if eqTnames (tx, tx') then
67 else 68 ((tx', (CConcat (c, c'), loc)), true)
68 ((tx', c'), found)) 69 else
69 false tabs 70 ((tx', c'), found))
70 in 71 false tabs
71 if found then 72 in
72 () 73 if found then
73 else 74 ()
74 ErrorMsg.errorAt loc "Select of field from unbound table"; 75 else
75 76 ErrorMsg.errorAt loc "Select of field from unbound table";
76 tabs 77
77 end 78 (tabs, exps)
79 end
80 | Exp (c, e) => (tabs, (c, e) :: exps)
78 81
79 fun amend_group loc (gi, tabs) = 82 fun amend_group loc (gi, tabs) =
80 let 83 let
81 val (tx, c) = case gi of 84 val (tx, c) = case gi of
82 GField (tx, fx) => (tx, (CRecord ([(fx, (CWild (KType, loc), loc))]), loc)) 85 GField (tx, fx) => (tx, (CRecord ([(fx, (CWild (KType, loc), loc))]), loc))
679 682
680 query1 : SELECT select FROM tables wopt gopt hopt 683 query1 : SELECT select FROM tables wopt gopt hopt
681 (let 684 (let
682 val loc = s (SELECTleft, tablesright) 685 val loc = s (SELECTleft, tablesright)
683 686
684 val sel = 687 val (sel, exps) =
685 case select of 688 case select of
686 Star => map (fn (nm, _) => 689 Star => (map (fn (nm, _) =>
687 (nm, (CTuple [(CWild (KRecord (KType, loc), loc), 690 (nm, (CTuple [(CWild (KRecord (KType, loc), loc),
688 loc), 691 loc),
689 (CRecord [], loc)], 692 (CRecord [], loc)],
690 loc))) tables 693 loc))) tables,
694 [])
691 | Items sis => 695 | Items sis =>
692 let 696 let
693 val tabs = map (fn (nm, _) => (nm, (CRecord [], loc))) tables 697 val tabs = map (fn (nm, _) => (nm, (CRecord [], loc))) tables
694 val tabs = foldl (amend_select loc) tabs sis 698 val (tabs, exps) = foldl (amend_select loc) (tabs, []) sis
695 in 699 in
696 map (fn (nm, c) => (nm, 700 (map (fn (nm, c) => (nm,
697 (CTuple [c, 701 (CTuple [c,
698 (CWild (KRecord (KType, loc), loc), 702 (CWild (KRecord (KType, loc), loc),
699 loc)], loc))) tabs 703 loc)], loc))) tabs,
704 exps)
700 end 705 end
701 706
702 val sel = (CRecord sel, loc) 707 val sel = (CRecord sel, loc)
703 708
704 val grp = case gopt of 709 val grp = case gopt of
731 grp), 736 grp),
732 ((CName "Having", loc), 737 ((CName "Having", loc),
733 hopt), 738 hopt),
734 ((CName "SelectFields", loc), 739 ((CName "SelectFields", loc),
735 (ECApp ((EVar (["Basis"], "sql_subset"), loc), 740 (ECApp ((EVar (["Basis"], "sql_subset"), loc),
736 sel), loc))], loc) 741 sel), loc)),
742 ((CName "SelectExps", loc),
743 (ERecord exps, loc))], loc)
737 744
738 val e = (EApp (e, re), loc) 745 val e = (EApp (e, re), loc)
739 in 746 in
740 e 747 e
741 end) 748 end)
760 767
761 fident : CSYMBOL (CName CSYMBOL, s (CSYMBOLleft, CSYMBOLright)) 768 fident : CSYMBOL (CName CSYMBOL, s (CSYMBOLleft, CSYMBOLright))
762 | LBRACE cexp RBRACE (cexp) 769 | LBRACE cexp RBRACE (cexp)
763 770
764 seli : tident DOT fident (Field (tident, fident)) 771 seli : tident DOT fident (Field (tident, fident))
772 | sqlexp AS fident (Exp (fident, sqlexp))
765 773
766 selis : seli ([seli]) 774 selis : seli ([seli])
767 | seli COMMA selis (seli :: selis) 775 | seli COMMA selis (seli :: selis)
768 776
769 select : STAR (Star) 777 select : STAR (Star)