comparison src/sqlcache.sml @ 2261:f81f1930c5d6

Fix SQL-parsing and declaration-ordering bugs.
author Ziv Scully <ziv@mit.edu>
date Wed, 30 Sep 2015 00:33:52 -0400
parents 03b10c7fab9a
children 34ad83d9b729
comparison
equal deleted inserted replaced
2260:03b10c7fab9a 2261:f81f1930c5d6
497 497
498 fun cacheWrap (env, exp, resultTyp, args, i) = 498 fun cacheWrap (env, exp, resultTyp, args, i) =
499 let 499 let
500 val loc = dummyLoc 500 val loc = dummyLoc
501 val rel0 = (ERel 0, loc) 501 val rel0 = (ERel 0, loc)
502 (* DEBUG *)
503 val () = print (Int.toString i ^ "\n")
502 in 504 in
503 case MonoFooify.urlify env (rel0, resultTyp) of 505 case MonoFooify.urlify env (rel0, resultTyp) of
504 NONE => NONE 506 NONE => NONE
505 | SOME urlified => 507 | SOME urlified =>
506 let 508 let
507 val () = ffiInfo := {index = i, params = length args} :: !ffiInfo 509 val () = ffiInfo := {index = i, params = length args} :: !ffiInfo
508 (* We ensure before this step that all arguments aren't effectful. 510 (* We ensure before this step that all arguments aren't effectful.
509 by turning them into local variables as needed. *) 511 by turning them into local variables as needed. *)
510 val argsInc = map (incRels 1) args 512 val argsInc = map (incRels 1) args
511 val check = (check (i, args), loc) 513 val check = (check (i, args), loc)
512 val store = (store (i, argsInc, urlified), loc) 514 val store = (store (i, argsInc, urlified), loc)
513 in 515 in
514 SOME (ECase 516 SOME (ECase
613 IM.insert (indexToQueryNumArgs, index, (queryParsed, numArgs)), 615 IM.insert (indexToQueryNumArgs, index, (queryParsed, numArgs)),
614 index + 1))))) 616 index + 1)))))
615 in 617 in
616 case attempt of 618 case attempt of
617 SOME pair => pair 619 SOME pair => pair
618 | NONE => (e', queryInfo) 620 (* We have to increment index conservatively. *)
621 (* TODO: just use a reference for current index.... *)
622 | NONE => (e', (tableToIndices, indexToQueryNumArgs, index + 1))
619 end 623 end
620 | e' => (e', queryInfo) 624 | e' => (e', queryInfo)
621 in 625 in
622 (fileMapfoldB (fn env => fn exp => fn state => doExp env state exp) 626 (fileMapfoldB (fn env => fn exp => fn state => doExp env state exp)
623 file 627 file
670 674
671 val invalidations = Invalidations.invalidations 675 val invalidations = Invalidations.invalidations
672 676
673 (* DEBUG *) 677 (* DEBUG *)
674 val gunk : ((Sql.query * int) * Sql.dml) list ref = ref [] 678 val gunk : ((Sql.query * int) * Sql.dml) list ref = ref []
679 val gunk' : exp list ref = ref []
675 680
676 fun addFlushing ((file, (tableToIndices, indexToQueryNumArgs, index)), effs) = 681 fun addFlushing ((file, (tableToIndices, indexToQueryNumArgs, index)), effs) =
677 let 682 let
678 val flushes = List.concat 683 val flushes = List.concat
679 o map (fn (i, argss) => map (fn args => flush (i, args)) argss) 684 o map (fn (i, argss) => map (fn args => flush (i, args)) argss)
680 val doExp = 685 val doExp =
681 fn EDml (origDmlText, failureMode) => 686 fn EDml (origDmlText, failureMode) =>
682 let 687 let
688 (* DEBUG *)
689 val () = gunk' := origDmlText :: !gunk'
683 val (newDmlText, wrapLets, numArgs) = factorOutNontrivial origDmlText 690 val (newDmlText, wrapLets, numArgs) = factorOutNontrivial origDmlText
684 val dmlText = incRels numArgs newDmlText 691 val dmlText = incRels numArgs newDmlText
685 val dmlExp = EDml (dmlText, failureMode) 692 val dmlExp = EDml (dmlText, failureMode)
686 (* DEBUG *) 693 (* DEBUG *)
687 (* val () = Print.preface ("sqlcache> ", (MonoPrint.p_exp MonoEnv.empty dmlText)) *) 694 val () = Print.preface ("sqlcache> ", (MonoPrint.p_exp MonoEnv.empty origDmlText))
688 val invs = 695 val inval =
689 case Sql.parse Sql.dml dmlText of 696 case Sql.parse Sql.dml dmlText of
690 SOME dmlParsed => 697 SOME dmlParsed =>
691 map (fn i => (case IM.find (indexToQueryNumArgs, i) of 698 SOME (map (fn i => (case IM.find (indexToQueryNumArgs, i) of
692 SOME queryNumArgs => 699 SOME queryNumArgs =>
693 (* DEBUG *) 700 (* DEBUG *)
694 (gunk := (queryNumArgs, dmlParsed) :: !gunk; 701 (gunk := (queryNumArgs, dmlParsed) :: !gunk;
695 (i, invalidations (queryNumArgs, dmlParsed))) 702 (i, invalidations (queryNumArgs, dmlParsed)))
696 (* TODO: fail more gracefully. *) 703 (* TODO: fail more gracefully. *)
697 | NONE => raise Match)) 704 | NONE => raise Match))
698 (SIMM.findList (tableToIndices, tableDml dmlParsed)) 705 (SIMM.findList (tableToIndices, tableDml dmlParsed)))
699 (* TODO: fail more gracefully. *) 706 | NONE => NONE
700 | NONE => raise Match
701 in 707 in
702 wrapLets (sequence (flushes invs @ [dmlExp])) 708 case inval of
709 (* TODO: fail more gracefully. *)
710 NONE => raise Match
711 | SOME invs => wrapLets (sequence (flushes invs @ [dmlExp]))
703 end 712 end
704 | e' => e' 713 | e' => e'
705 in 714 in
706 (* DEBUG *) 715 (* DEBUG *)
707 gunk := []; 716 gunk := [];
799 808
800 val expSize = MonoUtil.Exp.fold {typ = #2, exp = fn (_, n) => n+1} 0 809 val expSize = MonoUtil.Exp.fold {typ = #2, exp = fn (_, n) => n+1} 0
801 810
802 structure InvalidationInfo :> sig 811 structure InvalidationInfo :> sig
803 type t 812 type t
813 val empty : t
804 val fromList : int list -> t 814 val fromList : int list -> t
805 val toList : t -> int list 815 val toList : t -> int list
806 val union : t * t -> t 816 val union : t * t -> t
807 val unbind : t * int -> t option 817 val unbind : t * int -> t option
808 end = struct 818 end = struct
814 List.foldl 824 List.foldl
815 (fn (n, NONE) => SOME (n, IS.singleton n) 825 (fn (n, NONE) => SOME (n, IS.singleton n)
816 | (n', SOME (n, ns)) => SOME (Int.min (n, n'), IS.add (ns, n'))) 826 | (n', SOME (n, ns)) => SOME (Int.min (n, n'), IS.add (ns, n')))
817 NONE 827 NONE
818 828
829 val empty = fromList []
830
819 val toList = 831 val toList =
820 fn NONE => [] 832 fn NONE => []
821 | SOME (_, ns) => IS.listItems ns 833 | SOME (_, ns) => IS.listItems ns
822 834
823 val union = 835 val union =
824 fn (SOME (n1, ns1), SOME (n2, ns2)) => SOME (Int.min (n1, n2), IS.union (ns1, ns2)) 836 fn (SOME (n1, ns1), SOME (n2, ns2)) => SOME (Int.min (n1, n2), IS.union (ns1, ns2))
825 | (NONE, x) => x 837 | (NONE, info) => info
826 | (x, NONE) => x 838 | (info, NONE) => info
827 839
828 val unbind = 840 val unbind =
829 fn (SOME (n, ns), unbound) => 841 fn (SOME (n, ns), unbound) =>
830 let 842 let
831 val n = n - unbound 843 val n = n - unbound
835 else SOME (SOME (n, IS.map (fn n => n - unbound) ns)) 847 else SOME (SOME (n, IS.map (fn n => n - unbound) ns))
836 end 848 end
837 | _ => SOME NONE 849 | _ => SOME NONE
838 850
839 end 851 end
852
853 val unionUnbind =
854 List.foldl
855 (fn (_, NONE) => NONE
856 | ((info, unbound), SOME infoAcc) =>
857 case InvalidationInfo.unbind (info, unbound) of
858 NONE => NONE
859 | SOME info => SOME (InvalidationInfo.union (info, infoAcc)))
860 (SOME InvalidationInfo.empty)
840 861
841 datatype subexp = Pure of unit -> exp | Impure of exp 862 datatype subexp = Pure of unit -> exp | Impure of exp
842 863
843 val isImpure = 864 val isImpure =
844 fn Pure _ => false 865 fn Pure _ => false
934 | SOME e' => e', 955 | SOME e' => e',
935 loc)), 956 loc)),
936 index + 1) 957 index + 1)
937 end 958 end
938 959
939 fun addPure ((decls, sideInfo), index, effs) = 960 fun addPure ((decls, sideInfo), indexStart, effs) =
940 let 961 let
941 fun doVal ((x, n, t, exp, s), index) = 962 fun doVal env ((x, n, t, exp, s), index) =
942 let 963 let
943 val (subexp, index) = pureCache effs ((MonoEnv.empty, exp), index) 964 val (subexp, index) = pureCache effs ((env, exp), index)
944 in 965 in
945 ((x, n, t, expOfSubexp subexp, s), index) 966 ((x, n, t, expOfSubexp subexp, s), index)
946 end 967 end
947 fun doDecl' (decl', index) = 968 fun doDecl' env (decl', index) =
948 case decl' of 969 case decl' of
949 DVal v => 970 DVal v =>
950 let 971 let
951 val (v, index) = (doVal (v, index)) 972 val (v, index) = doVal env (v, index)
952 in 973 in
953 (DVal v, index) 974 (DVal v, index)
954 end 975 end
955 | DValRec vs => 976 | DValRec vs =>
956 let 977 let
957 val (vs, index) = ListUtil.foldlMap doVal index vs 978 val (vs, index) = ListUtil.foldlMap (doVal env) index vs
958 in 979 in
959 (DValRec vs, index) 980 (DValRec vs, index)
960 end 981 end
961 | _ => (decl', index) 982 | _ => (decl', index)
962 fun doDecl ((decl', loc), index) = 983 fun doDecl (decl as (decl', loc), (revDecls, env, index)) =
963 let 984 let
964 val (decl', index) = doDecl' (decl', index) 985 val env = MonoEnv.declBinds env decl
986 val (decl', index) = doDecl' env (decl', index)
987 (* Important that this happens after [MonoFooify.urlify] calls! *)
988 val fmDecls = MonoFooify.getNewFmDecls ()
965 in 989 in
966 ((decl', loc), index) 990 ((decl', loc) :: (fmDecls @ revDecls), env, index)
967 end 991 end
968 val decls = #1 (ListUtil.foldlMap doDecl index decls) 992 in
969 (* Important that this happens after the MonoFooify.urlify calls! *) 993 (rev (#1 (List.foldl doDecl ([], MonoEnv.empty, indexStart) decls)), sideInfo)
970 val fmDecls = MonoFooify.getNewFmDecls () 994 end
971 in 995
972 (* ASK: fmDecls before or after? *) 996 val go' = addPure o addFlushing o addChecking (* DEBUG: add back [o inlineSql]. *)
973 (fmDecls @ decls, sideInfo)
974 end
975
976 val go' = addPure o addFlushing o addChecking o inlineSql
977 997
978 fun go file = 998 fun go file =
979 let 999 let
980 (* TODO: do something nicer than [Sql] being in one of two modes. *) 1000 (* TODO: do something nicer than [Sql] being in one of two modes. *)
981 val () = (resetFfiInfo (); Sql.sqlcacheMode := true) 1001 val () = (resetFfiInfo (); Sql.sqlcacheMode := true)