comparison src/sqlcache.sml @ 2275:ce96e166d938

Fix some table renaming issues.
author Ziv Scully <ziv@mit.edu>
date Sat, 07 Nov 2015 15:16:44 -0500
parents 0730e217fc9c
children c05f9a5e0f0f
comparison
equal deleted inserted replaced
2274:0730e217fc9c 2275:ce96e166d938
1 structure Sqlcache :> SQLCACHE = struct 1 structure Sqlcache (* DEBUG :> SQLCACHE *) = struct
2 2
3 open Mono 3 open Mono
4 4
5 structure IS = IntBinarySet 5 structure IS = IntBinarySet
6 structure IM = IntBinaryMap 6 structure IM = IntBinaryMap
565 ffiInfo = {index = index, params = numArgs} :: #ffiInfo state, 565 ffiInfo = {index = index, params = numArgs} :: #ffiInfo state,
566 index = index + 1} 566 index = index + 1}
567 567
568 end 568 end
569 569
570 (* DEBUG *)
571 val gunk0 : ((Sql.cmp * Sql.sqexp * Sql.sqexp) formula
572 * (Sql.cmp * Sql.sqexp * Sql.sqexp) formula) list ref = ref []
573 val gunk1 : (Sql.cmp * atomExp option * atomExp option) list list list ref = ref []
574 val gunk2 : exp list ref = ref []
575
570 structure UF = UnionFindFn(AtomExpKey) 576 structure UF = UnionFindFn(AtomExpKey)
571 577
572 val rec sqexpToFormula = 578 val rec sqexpToFormula =
573 fn Sql.SqTrue => Combo (Conj, []) 579 fn Sql.SqTrue => Combo (Conj, [])
574 | Sql.SqFalse => Combo (Disj, []) 580 | Sql.SqFalse => Combo (Disj, [])
577 | Sql.Binop (Sql.RLop l, p1, p2) => Combo (case l of Sql.And => Conj | Sql.Or => Disj, 583 | Sql.Binop (Sql.RLop l, p1, p2) => Combo (case l of Sql.And => Conj | Sql.Or => Disj,
578 [sqexpToFormula p1, sqexpToFormula p2]) 584 [sqexpToFormula p1, sqexpToFormula p2])
579 (* ASK: any other sqexps that can be props? *) 585 (* ASK: any other sqexps that can be props? *)
580 | _ => raise Match 586 | _ => raise Match
581 587
588 fun mapSqexpFields f =
589 fn Sql.Field (t, v) => f (t, v)
590 | Sql.SqNot e => Sql.SqNot (mapSqexpFields f e)
591 | Sql.Binop (r, e1, e2) => Sql.Binop (r, mapSqexpFields f e1, mapSqexpFields f e2)
592 | Sql.SqKnown e => Sql.SqKnown (mapSqexpFields f e)
593 | Sql.SqFunc (s, e) => Sql.SqFunc (s, mapSqexpFields f e)
594 | e => e
595
582 fun renameTables tablePairs = 596 fun renameTables tablePairs =
583 let 597 let
584 fun renameString table = 598 fun rename table =
585 case List.find (fn (_, t) => table = t) tablePairs of 599 case List.find (fn (_, t) => table = t) tablePairs of
586 NONE => table 600 NONE => table
587 | SOME (realTable, _) => realTable 601 | SOME (realTable, _) => realTable
588 val renameSqexp = 602 in
589 fn Sql.Field (table, field) => Sql.Field (renameString table, field) 603 mapSqexpFields (fn (t, f) => Sql.Field (rename t, f))
590 | e => e
591 (* fun renameAtom (cmp, e1, e2) = (cmp, renameSqexp e1, renameSqexp e2) *)
592 in
593 mapFormulaExps renameSqexp
594 end 604 end
595 605
596 fun queryToFormula marker = 606 fun queryToFormula marker =
597 fn Sql.Query1 {Select = sitems, From = tablePairs, Where = wher} => 607 fn Sql.Query1 {Select = sitems, From = tablePairs, Where = wher} =>
598 let 608 let
599 val fWhere = case wher of 609 val fWhere = case wher of
600 NONE => Combo (Conj, []) 610 NONE => Combo (Conj, [])
601 | SOME e => sqexpToFormula e 611 | SOME e => sqexpToFormula (renameTables tablePairs e)
602 in 612 in
603 renameTables tablePairs 613 case marker of
604 (case marker of 614 NONE => fWhere
605 NONE => fWhere 615 | SOME markFields =>
606 | SOME markFields => 616 let
607 let 617 val fWhereMarked = mapFormulaExps markFields fWhere
608 val fWhereMarked = mapFormulaExps markFields fWhere 618 val toSqexp =
609 val toSqexp = 619 fn Sql.SqField tf => Sql.Field tf
610 fn Sql.SqField tf => Sql.Field tf 620 | Sql.SqExp (se, _) => se
611 | Sql.SqExp (se, _) => se 621 fun ineq se = Atom (Sql.Ne, se, markFields se)
612 fun ineq se = Atom (Sql.Ne, se, markFields se) 622 val fIneqs = Combo (Disj, map (ineq o renameTables tablePairs o toSqexp) sitems)
613 val fIneqs = Combo (Disj, map (ineq o toSqexp) sitems) 623 in
614 in 624 (Combo (Conj,
615 (Combo (Conj, 625 [fWhere,
616 [fWhere, 626 Combo (Disj,
617 Combo (Disj, 627 [Negate fWhereMarked,
618 [Negate fWhereMarked, 628 Combo (Conj, [fWhereMarked, fIneqs])])]))
619 Combo (Conj, [fWhereMarked, fIneqs])])])) 629 end
620 end)
621 end 630 end
622 | Sql.Union (q1, q2) => Combo (Disj, [queryToFormula marker q1, queryToFormula marker q2]) 631 | Sql.Union (q1, q2) => Combo (Disj, [queryToFormula marker q1, queryToFormula marker q2])
623 632
624 fun valsToFormula (markLeft, markRight) (table, vals) = 633 fun valsToFormula (markLeft, markRight) (table, vals) =
625 Combo (Conj, 634 Combo (Conj,
627 vals) 636 vals)
628 637
629 (* TODO: verify logic for insertion and deletion. *) 638 (* TODO: verify logic for insertion and deletion. *)
630 val rec dmlToFormulaMarker = 639 val rec dmlToFormulaMarker =
631 fn Sql.Insert (table, vals) => (valsToFormula (id, id) (table, vals), NONE) 640 fn Sql.Insert (table, vals) => (valsToFormula (id, id) (table, vals), NONE)
632 | Sql.Delete (table, wher) => (renameTables [(table, "T")] (sqexpToFormula wher), NONE) 641 | Sql.Delete (table, wher) => (sqexpToFormula (renameTables [(table, "T")] wher), NONE)
633 | Sql.Update (table, vals, wher) => 642 | Sql.Update (table, vals, wher) =>
634 let 643 let
635 val fWhere = sqexpToFormula wher 644 val fWhere = sqexpToFormula (renameTables [(table, "T")] wher)
636 fun fVals marks = valsToFormula marks (table, vals) 645 fun fVals marks = valsToFormula marks (table, vals)
637 val modifiedFields = SS.addList (SS.empty, map #1 vals) 646 val modifiedFields = SS.addList (SS.empty, map #1 vals)
638 (* TODO: don't use field name hack. *) 647 (* TODO: don't use field name hack. *)
639 fun markFields table = 648 val markFields =
640 fn e as Sql.Field (t, v) => if t = table andalso SS.member (modifiedFields, v) 649 mapSqexpFields (fn (t, v) => if t = table andalso SS.member (modifiedFields, v)
641 then Sql.Field (t, v ^ "'") 650 then ((* DEBUG *) print ("yep" ^ Int.toString (length (!gunk0)));
642 else e 651 Sql.Field (t, v ^ "'"))
643 | Sql.SqNot e => Sql.SqNot (markFields table e) 652 else ((* DEBUG *) print (table ^ " " ^ t ^ "\n"); Sql.Field (t, v)))
644 | Sql.Binop (r, e1, e2) => Sql.Binop (r, markFields table e1, markFields table e2) 653 val mark = mapFormulaExps markFields
645 | Sql.SqKnown e => Sql.SqKnown (markFields table e) 654 in
646 | Sql.SqFunc (s, e) => Sql.SqFunc (s, markFields table e) 655 ((Combo (Disj, [Combo (Conj, [fVals (id, markFields), mark fWhere]),
647 | e => e 656 Combo (Conj, [fVals (markFields, id), fWhere])])),
648 val mark = mapFormulaExps (markFields "T") 657 SOME markFields)
649 in
650 (* Inside renameTables, we mark with table "T". Outside, we use the real table name. *)
651 (renameTables [(table, "T")]
652 (Combo (Disj, [Combo (Conj, [fVals (id, markFields "T"), mark fWhere]),
653 Combo (Conj, [fVals (markFields "T", id), fWhere])])),
654 SOME (markFields table))
655 end 658 end
656 659
657 fun pairToFormulas (query, dml) = 660 fun pairToFormulas (query, dml) =
658 let 661 let
659 val (fDml, marker) = dmlToFormulaMarker dml 662 val (fDml, marker) = ((* DEBUG *) print "dml\n"; dmlToFormulaMarker dml)
660 in 663 in
664 (* DEBUG *) print "query\n";
661 (queryToFormula marker query, fDml) 665 (queryToFormula marker query, fDml)
662 end 666 end
663
664 (* structure ToFormula = struct *)
665
666 (* val testOfQuery : Sql.query1 -> (Sql.cmp * Sql.sqexp * Sql.sqexp) formula = *)
667 (* fn {From = tablePairs, Where = SOME e, ...} => renameTables tablePairs (sqexpToFormula e) *)
668 (* | {Where = NONE, ...} => Combo (Conj, []) *)
669
670 (* (* If selecting some parsable subset of fields, says which ones. [NONE] *)
671 (* means anything could be selected. *) *)
672 (* fun fieldsOfQuery (q : Sql.query1) = *)
673 (* osequence (map (fn Sql.SqField tf => SOME tf *)
674 (* | Sql.SqExp (Sql.Field tf) => SOME tf *)
675 (* | _ => NONE) (#Select q)) *)
676
677 (* fun fieldsOfVals (table, vals, wher) = *)
678 (* let *)
679 (* val fWhere = renameTables [(table, "T")] (sqexpToFormula wher) *)
680 (* val fVals = valsToFormula (table, vals) *)
681 (* val modifiedFields = SS.addList (SS.empty, map #1 vals) *)
682 (* (* TODO: don't use field name hack. *) *)
683 (* val markField = *)
684 (* fn e as Sql.Field (t, v) => if SS.member (modifiedFields, v) *)
685 (* then Sql.Field (t, v ^ "'") *)
686 (* else e *)
687 (* | e => e *)
688 (* val mark = mapFormula (fn (cmp, e1, e2) => (cmp, markField e1, markField e2)) *)
689 (* in *)
690 (* renameTables [(table, "T")] *)
691 (* (Combo (Disj, [Combo (Conj, [fVals, mark fWhere]), *)
692 (* Combo (Conj, [mark fVals, fWhere])])) *)
693 (* end *)
694 (* end *)
695 667
696 structure ConflictMaps = struct 668 structure ConflictMaps = struct
697 669
698 structure TK = TripleKeyFn(structure I = CmpKey 670 structure TK = TripleKeyFn(structure I = CmpKey
699 structure J = AtomOptionKey 671 structure J = AtomOptionKey
714 val ineqs = List.filter (fn (cmp, _, _) => 686 val ineqs = List.filter (fn (cmp, _, _) =>
715 cmp = Sql.Ne orelse cmp = Sql.Lt orelse cmp = Sql.Gt) 687 cmp = Sql.Ne orelse cmp = Sql.Lt orelse cmp = Sql.Gt)
716 atoms 688 atoms
717 val contradiction = 689 val contradiction =
718 fn (cmp, SOME ae1, SOME ae2) => (cmp = Sql.Ne orelse cmp = Sql.Lt orelse cmp = Sql.Gt) 690 fn (cmp, SOME ae1, SOME ae2) => (cmp = Sql.Ne orelse cmp = Sql.Lt orelse cmp = Sql.Gt)
719 andalso not (UF.together (uf, ae1, ae2)) 691 andalso UF.together (uf, ae1, ae2)
720 (* If we don't know one side of the comparision, not a contradiction. *) 692 (* If we don't know one side of the comparision, not a contradiction. *)
721 | _ => false 693 | _ => false
722 in 694 in
723 not (List.exists contradiction atoms) <\oguard\> SOME (UF.classes uf) 695 not (List.exists contradiction atoms) <\oguard\> SOME (UF.classes uf)
724 end 696 end
812 normalize simplify normalizeAtom Disj (Combo (Conj, [markQuery fQuery, markDml fDml])) 784 normalize simplify normalizeAtom Disj (Combo (Conj, [markQuery fQuery, markDml fDml]))
813 785
814 val conflictMaps = 786 val conflictMaps =
815 List.mapPartial (mergeEqs o map eqsOfClass) 787 List.mapPartial (mergeEqs o map eqsOfClass)
816 o List.mapPartial equivClasses 788 o List.mapPartial equivClasses
789 o (fn x => (gunk1 := x :: !gunk1; x))
817 o dnf 790 o dnf
791 o (fn x => (gunk0 := x :: !gunk0; x))
818 792
819 end 793 end
820 794
821 val conflictMaps = ConflictMaps.conflictMaps 795 val conflictMaps = ConflictMaps.conflictMaps
822 796
1315 1289
1316 end 1290 end
1317 1291
1318 val invalidations = Invalidations.invalidations 1292 val invalidations = Invalidations.invalidations
1319 1293
1320 (* DEBUG *)
1321 (* val gunk : ((Sql.query * int) * Sql.dml) list ref = ref [] *)
1322 (* val gunk' : exp list ref = ref [] *)
1323
1324 fun addFlushing ((file, {tableToIndices, indexToInvalInfo, ffiInfo, ...} : state), effs) = 1294 fun addFlushing ((file, {tableToIndices, indexToInvalInfo, ffiInfo, ...} : state), effs) =
1325 let 1295 let
1326 val flushes = List.concat 1296 val flushes = List.concat
1327 o map (fn (i, argss) => map (fn args => flush (i, args)) argss) 1297 o map (fn (i, argss) => map (fn args => flush (i, args)) argss)
1328 val doExp = 1298 val doExp =
1329 fn dmlExp as EDml (dmlText, failureMode) => 1299 fn dmlExp as EDml (dmlText, failureMode) =>
1330 let 1300 let
1331 (* DEBUG *) 1301 (* DEBUG *)
1332 (* val () = gunk' := origDmlText :: !gunk' *) 1302 (* val () = gunk2 := dmlText :: !gunk2 *)
1333 (* val () = Print.preface ("SQLCACHE: ", (MonoPrint.p_exp MonoEnv.empty origDmlText)) *) 1303 (* val () = Print.preface ("SQLCACHE: ", (MonoPrint.p_exp MonoEnv.empty origDmlText)) *)
1334 val inval = 1304 val inval =
1335 case Sql.parse Sql.dml dmlText of 1305 case Sql.parse Sql.dml dmlText of
1336 SOME dmlParsed => 1306 SOME dmlParsed =>
1337 SOME (map (fn i => (case IM.find (indexToInvalInfo, i) of 1307 SOME (map (fn i => (case IM.find (indexToInvalInfo, i) of
1350 end 1320 end
1351 | e' => e' 1321 | e' => e'
1352 val file = fileMap doExp file 1322 val file = fileMap doExp file
1353 1323
1354 in 1324 in
1355 (* DEBUG *)
1356 (* gunk := []; *)
1357 ffiInfoRef := ffiInfo; 1325 ffiInfoRef := ffiInfo;
1358 file 1326 file
1359 end 1327 end
1360 1328
1361 1329