Mercurial > urweb
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) |