comparison src/iflow.sml @ 1227:1d8fba74e7f5

Iflow working with a UNION
author Adam Chlipala <adamc@hcoop.net>
date Sun, 11 Apr 2010 16:06:16 -0400
parents df5bd4115267
children 7dfa67560916
comparison
equal deleted inserted replaced
1226:df5bd4115267 1227:1d8fba74e7f5
967 ((*Print.prefaces "Can't prove" 967 ((*Print.prefaces "Can't prove"
968 [("a", p_atom a), 968 [("a", p_atom a),
969 ("hyps", Print.p_list p_atom hyps), 969 ("hyps", Print.p_list p_atom hyps),
970 ("db", Cc.p_database cc)];*) 970 ("db", Cc.p_database cc)];*)
971 false)) acc 971 false)) acc
972 (*andalso (Print.preface ("Finding", Cc.p_database cc); true)*) 972 andalso ((*Print.preface ("Finding", Cc.p_database cc);*) true)
973 andalso (case outs of 973 andalso (case outs of
974 NONE => true 974 NONE => true
975 | SOME outs => Cc.builtFrom (cc, {Derived = Var 0, 975 | SOME outs => Cc.builtFrom (cc, {Derived = Var 0,
976 Base = outs}))) 976 Base = outs})))
977 handle Cc.Contradiction => false 977 handle Cc.Contradiction => false
1127 fun ws p = wrap (follow (skip (fn ch => ch = #" ")) 1127 fun ws p = wrap (follow (skip (fn ch => ch = #" "))
1128 (follow p (skip (fn ch => ch = #" ")))) (#1 o #2) 1128 (follow p (skip (fn ch => ch = #" ")))) (#1 o #2)
1129 1129
1130 fun log name p chs = 1130 fun log name p chs =
1131 (if !debug then 1131 (if !debug then
1132 case chs of 1132 (print (name ^ ": ");
1133 String s :: _ => print (name ^ ": " ^ s ^ "\n") 1133 app (fn String s => print s
1134 | _ => print (name ^ ": blocked!\n") 1134 | _ => print "???") chs;
1135 print "\n")
1135 else 1136 else
1136 (); 1137 ();
1137 p chs) 1138 p chs)
1138 1139
1139 fun list p chs = 1140 fun list p chs =
1300 (fn ((), ls) => ls)) 1301 (fn ((), ls) => ls))
1301 1302
1302 val wher = wrap (follow (ws (const "WHERE ")) sqexp) 1303 val wher = wrap (follow (ws (const "WHERE ")) sqexp)
1303 (fn ((), ls) => ls) 1304 (fn ((), ls) => ls)
1304 1305
1305 val query = log "query" 1306 type query1 = {Select : sitem list,
1307 From : (string * string) list,
1308 Where : sqexp option}
1309
1310 val query1 = log "query1"
1306 (wrap (follow (follow select from) (opt wher)) 1311 (wrap (follow (follow select from) (opt wher))
1307 (fn ((fs, ts), wher) => {Select = fs, From = ts, Where = wher})) 1312 (fn ((fs, ts), wher) => {Select = fs, From = ts, Where = wher}))
1313
1314 datatype query =
1315 Query1 of query1
1316 | Union of query * query
1317
1318 fun query chs = log "query"
1319 (alt (wrap (follow (const "((")
1320 (follow query
1321 (follow (const ") UNION (")
1322 (follow query (const "))")))))
1323 (fn ((), (q1, ((), (q2, ())))) => Union (q1, q2)))
1324 (wrap query1 Query1))
1325 chs
1308 1326
1309 datatype dml = 1327 datatype dml =
1310 Insert of string * (string * sqexp) list 1328 Insert of string * (string * sqexp) list
1311 | Delete of string * sqexp 1329 | Delete of string * sqexp
1312 | Update of string * (string * sqexp) list * sqexp 1330 | Update of string * (string * sqexp) list * sqexp
1429 1447
1430 fun queryProp env rvN rv oe e = 1448 fun queryProp env rvN rv oe e =
1431 let 1449 let
1432 fun default () = (print ("Warning: Information flow checker can't parse SQL query at " 1450 fun default () = (print ("Warning: Information flow checker can't parse SQL query at "
1433 ^ ErrorMsg.spanToString (#2 e) ^ "\n"); 1451 ^ ErrorMsg.spanToString (#2 e) ^ "\n");
1434 (rvN, Unknown, Unknown, [], [])) 1452 (rvN, Unknown, [], []))
1435 in 1453 in
1436 case parse query e of 1454 case parse query e of
1437 NONE => default () 1455 NONE => default ()
1438 | SOME r => 1456 | SOME q =>
1439 let 1457 let
1440 val (rvs, rvN) = ListUtil.foldlMap (fn ((_, v), rvN) => 1458 fun doQuery (q, rvN) =
1441 let 1459 case q of
1442 val (rvN, e) = rv rvN 1460 Query1 r =>
1443 in
1444 ((v, e), rvN)
1445 end) rvN (#From r)
1446
1447 fun rvOf v =
1448 case List.find (fn (v', _) => v' = v) rvs of
1449 NONE => raise Fail "Iflow.queryProp: Bad table variable"
1450 | SOME (_, e) => e
1451
1452 fun usedFields e =
1453 case e of
1454 SqConst _ => []
1455 | Field (v, f) => [(v, f)]
1456 | Binop (_, e1, e2) => removeDups (usedFields e1 @ usedFields e2)
1457 | SqKnown _ => []
1458 | Inj _ => []
1459 | SqFunc (_, e) => usedFields e
1460 | Count => []
1461
1462 val p =
1463 foldl (fn ((t, v), p) => And (p, Reln (Sql t, [rvOf v]))) True (#From r)
1464
1465 val expIn = expIn rv env rvOf
1466
1467 val (p, rvN) = case #Where r of
1468 NONE => (p, rvN)
1469 | SOME e =>
1470 case expIn (e, rvN) of
1471 (inr p', rvN) => (And (p, p'), rvN)
1472 | _ => (p, rvN)
1473
1474 fun normal () =
1475 case oe of
1476 SomeCol =>
1477 let 1461 let
1478 val (sis, rvN) = 1462 val (rvs, rvN) = ListUtil.foldlMap (fn ((_, v), rvN) =>
1479 ListUtil.foldlMap 1463 let
1480 (fn (si, rvN) => 1464 val (rvN, e) = rv rvN
1481 case si of 1465 in
1482 SqField (v, f) => (Proj (rvOf v, f), rvN) 1466 ((v, e), rvN)
1483 | SqExp (e, f) => 1467 end) rvN (#From r)
1484 case expIn (e, rvN) of 1468
1485 (inr _, _) => 1469 fun rvOf v =
1486 let 1470 case List.find (fn (v', _) => v' = v) rvs of
1487 val (rvN, e) = rv rvN 1471 NONE => raise Fail "Iflow.queryProp: Bad table variable"
1488 in 1472 | SOME (_, e) => e
1489 (e, rvN) 1473
1490 end 1474 fun usedFields e =
1491 | (inl e, rvN) => (e, rvN)) rvN (#Select r) 1475 case e of
1476 SqConst _ => []
1477 | Field (v, f) => [(v, f)]
1478 | Binop (_, e1, e2) => removeDups (usedFields e1 @ usedFields e2)
1479 | SqKnown _ => []
1480 | Inj _ => []
1481 | SqFunc (_, e) => usedFields e
1482 | Count => []
1483
1484 val p =
1485 foldl (fn ((t, v), p) => And (p, Reln (Sql t, [rvOf v]))) True (#From r)
1486
1487 val expIn = expIn rv env rvOf
1488
1489 val (p, rvN) = case #Where r of
1490 NONE => (p, rvN)
1491 | SOME e =>
1492 case expIn (e, rvN) of
1493 (inr p', rvN) => (And (p, p'), rvN)
1494 | _ => (p, rvN)
1495
1496 fun normal () =
1497 case oe of
1498 SomeCol =>
1499 let
1500 val (sis, rvN) =
1501 ListUtil.foldlMap
1502 (fn (si, rvN) =>
1503 case si of
1504 SqField (v, f) => (Proj (rvOf v, f), rvN)
1505 | SqExp (e, f) =>
1506 case expIn (e, rvN) of
1507 (inr _, _) =>
1508 let
1509 val (rvN, e) = rv rvN
1510 in
1511 (e, rvN)
1512 end
1513 | (inl e, rvN) => (e, rvN)) rvN (#Select r)
1514 in
1515 (rvN, p, True, sis)
1516 end
1517 | AllCols oe =>
1518 let
1519 val (ts, es, rvN) =
1520 foldl (fn (si, (ts, es, rvN)) =>
1521 case si of
1522 SqField (v, f) =>
1523 let
1524 val fs = getOpt (SM.find (ts, v), SM.empty)
1525 in
1526 (SM.insert (ts, v, SM.insert (fs, f, Proj (rvOf v, f))), es, rvN)
1527 end
1528 | SqExp (e, f) =>
1529 let
1530 val (e, rvN) =
1531 case expIn (e, rvN) of
1532 (inr _, rvN) =>
1533 let
1534 val (rvN, e) = rv rvN
1535 in
1536 (e, rvN)
1537 end
1538 | (inl e, rvN) => (e, rvN)
1539 in
1540 (ts, SM.insert (es, f, e), rvN)
1541 end)
1542 (SM.empty, SM.empty, rvN) (#Select r)
1543
1544 val p' = Reln (Eq, [oe, Recd (map (fn (t, fs) => (t, Recd (SM.listItemsi fs)))
1545 (SM.listItemsi ts)
1546 @ SM.listItemsi es)])
1547 in
1548 (rvN, And (p, p'), True, [])
1549 end
1550
1551 val (rvN, p, wp, outs) =
1552 case #Select r of
1553 [SqExp (Binop (Exps bo, Count, SqConst (Prim.Int 0)), f)] =>
1554 (case bo (Const (Prim.Int 1), Const (Prim.Int 2)) of
1555 Reln (Gt, [Const (Prim.Int 1), Const (Prim.Int 2)]) =>
1556 (case oe of
1557 SomeCol =>
1558 let
1559 val (rvN, oe) = rv rvN
1560 in
1561 (rvN,
1562 Or (Reln (Eq, [oe, Func (DtCon0 "Basis.bool.False", [])]),
1563 And (Reln (Eq, [oe, Func (DtCon0 "Basis.bool.True", [])]),
1564 p)),
1565 Reln (Eq, [oe, Func (DtCon0 "Basis.bool.True", [])]),
1566 [oe])
1567 end
1568 | AllCols oe =>
1569 let
1570 fun oeEq e = Reln (Eq, [oe, Recd [(f, e)]])
1571 in
1572 (rvN,
1573 Or (oeEq (Func (DtCon0 "Basis.bool.False", [])),
1574 And (oeEq (Func (DtCon0 "Basis.bool.True", [])),
1575 p)),
1576 oeEq (Func (DtCon0 "Basis.bool.True", [])),
1577 [])
1578 end)
1579 | _ => normal ())
1580 | _ => normal ()
1492 in 1581 in
1493 (rvN, p, True, sis) 1582 (rvN, p, map (fn x => (wp, x))
1583 (case #Where r of
1584 NONE => []
1585 | SOME e => map (fn (v, f) => Proj (rvOf v, f)) (usedFields e)), outs)
1494 end 1586 end
1495 | AllCols oe => 1587 | Union (q1, q2) =>
1496 let 1588 let
1497 val (ts, es, rvN) = 1589 val (rvN, p1, used1, outs1) = doQuery (q1, rvN)
1498 foldl (fn (si, (ts, es, rvN)) => 1590 val (rvN, p2, used2, outs2) = doQuery (q2, rvN)
1499 case si of
1500 SqField (v, f) =>
1501 let
1502 val fs = getOpt (SM.find (ts, v), SM.empty)
1503 in
1504 (SM.insert (ts, v, SM.insert (fs, f, Proj (rvOf v, f))), es, rvN)
1505 end
1506 | SqExp (e, f) =>
1507 let
1508 val (e, rvN) =
1509 case expIn (e, rvN) of
1510 (inr _, rvN) =>
1511 let
1512 val (rvN, e) = rv rvN
1513 in
1514 (e, rvN)
1515 end
1516 | (inl e, rvN) => (e, rvN)
1517 in
1518 (ts, SM.insert (es, f, e), rvN)
1519 end)
1520 (SM.empty, SM.empty, rvN) (#Select r)
1521
1522 val p' = Reln (Eq, [oe, Recd (map (fn (t, fs) => (t, Recd (SM.listItemsi fs)))
1523 (SM.listItemsi ts)
1524 @ SM.listItemsi es)])
1525 in 1591 in
1526 (rvN, And (p, p'), True, []) 1592 case (outs1, outs2) of
1593 ([], []) => (rvN, Or (p1, p2),
1594 map (fn (p, e) => (And (p1, p), e)) used1
1595 @ map (fn (p, e) => (And (p2, p), e)) used2, [])
1596 | _ => default ()
1527 end 1597 end
1528 1598 in
1529 val (rvN, p, wp, outs) = 1599 doQuery (q, rvN)
1530 case #Select r of
1531 [SqExp (Binop (Exps bo, Count, SqConst (Prim.Int 0)), f)] =>
1532 (case bo (Const (Prim.Int 1), Const (Prim.Int 2)) of
1533 Reln (Gt, [Const (Prim.Int 1), Const (Prim.Int 2)]) =>
1534 (case oe of
1535 SomeCol =>
1536 let
1537 val (rvN, oe) = rv rvN
1538 in
1539 (rvN,
1540 Or (Reln (Eq, [oe, Func (DtCon0 "Basis.bool.False", [])]),
1541 And (Reln (Eq, [oe, Func (DtCon0 "Basis.bool.True", [])]),
1542 p)),
1543 Reln (Eq, [oe, Func (DtCon0 "Basis.bool.True", [])]),
1544 [oe])
1545 end
1546 | AllCols oe =>
1547 let
1548 fun oeEq e = Reln (Eq, [oe, Recd [(f, e)]])
1549 in
1550 (rvN,
1551 Or (oeEq (Func (DtCon0 "Basis.bool.False", [])),
1552 And (oeEq (Func (DtCon0 "Basis.bool.True", [])),
1553 p)),
1554 oeEq (Func (DtCon0 "Basis.bool.True", [])),
1555 [])
1556 end)
1557 | _ => normal ())
1558 | _ => normal ()
1559 in
1560 (rvN, p, wp, case #Where r of
1561 NONE => []
1562 | SOME e => map (fn (v, f) => Proj (rvOf v, f)) (usedFields e), outs)
1563 end 1600 end
1564 end 1601 end
1565 1602
1566 fun insertProp rvN rv e = 1603 fun insertProp rvN rv e =
1567 let 1604 let
1568 fun default () = (print ("Warning: Information flow checker can't parse SQL query at " 1605 fun default () = (print ("Warning: Information flow checker can't parse SQL query at "
1569 ^ ErrorMsg.spanToString (#2 e) ^ "\n"); 1606 ^ ErrorMsg.spanToString (#2 e) ^ "\n");
1570 Unknown) 1607 Unknown)
1571 in 1608 in
1572 case parse query e of 1609 case parse query e of
1573 NONE => default () 1610 SOME (Query1 r) =>
1574 | SOME r =>
1575 let 1611 let
1576 val (rvs, rvN) = ListUtil.foldlMap (fn ((_, v), rvN) => 1612 val (rvs, rvN) = ListUtil.foldlMap (fn ((_, v), rvN) =>
1577 let 1613 let
1578 val (rvN, e) = rv rvN 1614 val (rvN, e) = rv rvN
1579 in 1615 in
1603 | SOME e => 1639 | SOME e =>
1604 case expIn (e, rvN) of 1640 case expIn (e, rvN) of
1605 (inr p', _) => And (p, p') 1641 (inr p', _) => And (p, p')
1606 | _ => p 1642 | _ => p
1607 end 1643 end
1644 | _ => default ()
1608 end 1645 end
1609 1646
1610 fun deleteProp rvN rv e = 1647 fun deleteProp rvN rv e =
1611 let 1648 let
1612 fun default () = (print ("Warning: Information flow checker can't parse SQL query at " 1649 fun default () = (print ("Warning: Information flow checker can't parse SQL query at "
1613 ^ ErrorMsg.spanToString (#2 e) ^ "\n"); 1650 ^ ErrorMsg.spanToString (#2 e) ^ "\n");
1614 Unknown) 1651 Unknown)
1615 in 1652 in
1616 case parse query e of 1653 case parse query e of
1617 NONE => default () 1654 SOME (Query1 r) =>
1618 | SOME r =>
1619 let 1655 let
1620 val (rvs, rvN) = ListUtil.foldlMap (fn ((_, v), rvN) => 1656 val (rvs, rvN) = ListUtil.foldlMap (fn ((_, v), rvN) =>
1621 let 1657 let
1622 val (rvN, e) = rv rvN 1658 val (rvN, e) = rv rvN
1623 in 1659 in
1640 | SOME e => 1676 | SOME e =>
1641 case expIn (e, rvN) of 1677 case expIn (e, rvN) of
1642 (inr p', _) => And (p, p') 1678 (inr p', _) => And (p, p')
1643 | _ => p) 1679 | _ => p)
1644 end 1680 end
1681 | _ => default ()
1645 end 1682 end
1646 1683
1647 fun updateProp rvN rv e = 1684 fun updateProp rvN rv e =
1648 let 1685 let
1649 fun default () = (print ("Warning: Information flow checker can't parse SQL query at " 1686 fun default () = (print ("Warning: Information flow checker can't parse SQL query at "
1650 ^ ErrorMsg.spanToString (#2 e) ^ "\n"); 1687 ^ ErrorMsg.spanToString (#2 e) ^ "\n");
1651 Unknown) 1688 Unknown)
1652 in 1689 in
1653 case parse query e of 1690 case parse query e of
1654 NONE => default () 1691 SOME (Query1 r) =>
1655 | SOME r =>
1656 let 1692 let
1657 val (rvs, rvN) = ListUtil.foldlMap (fn ((_, v), rvN) => 1693 val (rvs, rvN) = ListUtil.foldlMap (fn ((_, v), rvN) =>
1658 let 1694 let
1659 val (rvN, e) = rv rvN 1695 val (rvN, e) = rv rvN
1660 in 1696 in
1685 | SOME e => 1721 | SOME e =>
1686 case expIn (e, rvN) of 1722 case expIn (e, rvN) of
1687 (inr p', _) => And (p, p') 1723 (inr p', _) => And (p, p')
1688 | _ => p) 1724 | _ => p)
1689 end 1725 end
1726 | _ => default ()
1690 end 1727 end
1691 1728
1692 fun evalPat env e (pt, _) = 1729 fun evalPat env e (pt, _) =
1693 case pt of 1730 case pt of
1694 PWild => (env, True) 1731 PWild => (env, True)
2065 val (st', r) = St.nextVar st 2102 val (st', r) = St.nextVar st
2066 val (st', acc) = St.nextVar st' 2103 val (st', acc) = St.nextVar st'
2067 2104
2068 val (b, st') = evalExp (Var acc :: Var r :: env) (b, st') 2105 val (b, st') = evalExp (Var acc :: Var r :: env) (b, st')
2069 2106
2070 val (st', qp, qwp, used, _) = 2107 val (st', qp, used, _) =
2071 queryProp env 2108 queryProp env
2072 st' (fn st' => 2109 st' (fn st' =>
2073 let 2110 let
2074 val (st', rv) = St.nextVar st' 2111 val (st', rv) = St.nextVar st'
2075 in 2112 in
2096 (St.setAmbient (st, p), Var out) 2133 (St.setAmbient (st, p), Var out)
2097 end 2134 end
2098 2135
2099 val sent = map (fn ((loc, e, p), fl) => ((loc, e, And (qp, p)), fl)) (St.sent st') 2136 val sent = map (fn ((loc, e, p), fl) => ((loc, e, And (qp, p)), fl)) (St.sent st')
2100 2137
2101 val p' = And (p', qwp) 2138 val paths = map (fn (p'', e) => ((loc, e, And (p', p'')), Where)) used
2102 val paths = map (fn e => ((loc, e, p'), Where)) used
2103 in 2139 in
2104 (res, St.addPaths (St.setSent (st, sent), paths)) 2140 (res, St.addPaths (St.setSent (st, sent), paths))
2105 end 2141 end
2106 | EDml e => 2142 | EDml e =>
2107 (case parse dml e of 2143 (case parse dml e of
2296 fun rv rvN = (rvN + 1, Lvar rvN) 2332 fun rv rvN = (rvN + 1, Lvar rvN)
2297 in 2333 in
2298 case pol of 2334 case pol of
2299 PolClient e => 2335 PolClient e =>
2300 let 2336 let
2301 val (_, p, _, _, outs) = queryProp [] 0 rv SomeCol e 2337 val (_, p, _, outs) = queryProp [] 0 rv SomeCol e
2302 in 2338 in
2303 (vals, inserts, deletes, updates, (p, outs) :: client, insert, delete, update) 2339 (vals, inserts, deletes, updates, (p, outs) :: client, insert, delete, update)
2304 end 2340 end
2305 | PolInsert e => 2341 | PolInsert e =>
2306 let 2342 let