Presentation is loading. Please wait.

Presentation is loading. Please wait.

Deep Typechecking and Refactoring Zachary Tatlock, Chris Tucker, David Shuffleton, Ranjit Jhala, Sorin Lerner 1 University of California, San Diego.

Similar presentations


Presentation on theme: "Deep Typechecking and Refactoring Zachary Tatlock, Chris Tucker, David Shuffleton, Ranjit Jhala, Sorin Lerner 1 University of California, San Diego."— Presentation transcript:

1 Deep Typechecking and Refactoring Zachary Tatlock, Chris Tucker, David Shuffleton, Ranjit Jhala, Sorin Lerner 1 University of California, San Diego

2 Outline 1.Introduction and Motivation 2.Deep Typechecking and Refactoring  Straight Line Code  Control Flow  Multiple Methods 3.Experimental Results 4.Related Work and Conclusion 2

3 Communicating with Databases String based queries are prevalent:  JPA, Hibernate, TopLink JAVADB Strings 3

4 Example: Using JPA to query DB 4 “SELECT w FROM Weblog w WHERE w.id = ?1 AND w.link.id = ?2” Query in JPA Query Language: Mapping Java Classes to DB Tables:  Expressed in Object Relational Mapping (ORM) Java syntax in query String

5 Example: Using JPA to query DB String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 5

6 Example: Using JPA to query DB String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 1.Build query string 6

7 Example: Using JPA to query DB String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 1.Build query string 2.Create query 7

8 Example: Using JPA to query DB String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 1.Build query string 2.Create query 3.Set parameters 8

9 Example: Using JPA to query DB String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 1.Build query string 2.Create query 3.Set parameters 9

10 Example: Using JPA to query DB String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 1.Build query string 2.Create query 3.Set parameters 4.Execute query 10

11 Example: Using JPA to query DB String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 1.Build query string 2.Create query 3.Set parameters 4.Execute query 11 Efficient Flexible Unsafe

12 Uncaught Errors String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 12

13 Uncaught Errors String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); // q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 13

14 Uncaught Errors String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); // q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 1.Unset parameter 14

15 Uncaught Errors String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 15 1.Unset parameter

16 Uncaught Errors String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, new Weblog()); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 1.Unset parameter 2.Unsafe param type 16

17 Uncaught Errors String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 1.Unset parameter 2.Unsafe param type 17

18 Uncaught Errors String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Warranty w = (Warranty) q.execQuery(); return w.text; } 1.Unset parameter 2.Unsafe param type 3.Unsafe downcast 18

19 Uncaught Errors String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 1.Unset parameter 2.Unsafe param type 3.Unsafe downcast 19 Java compiler does not reason about the query strings; cannot typecheck.

20 Refactor: Weblog.id  Weblog.name String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 1.Unset parameter 2.Unsafe param type 3.Unsafe downcast 20

21 Refactor: Weblog.id  Weblog.name String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 1.Unset parameter 2.Unsafe param type 3.Unsafe downcast 21 Refactor Don’t Refactor Need to know type of w and w.link to refactor safely.

22 Refactor: Weblog.id  Weblog.name String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 1.Unset parameter 2.Unsafe param type 3.Unsafe downcast 4.Refactoring difficult 22

23 String Based Query Challenges String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 1.Unset parameter 2.Unsafe param type 3.Unsafe downcast 4.Refactoring difficult 23

24 Contributions Deep Typechecking:  All parameters set  Parameters correctly set  Results safely downcast Deep Refactoring:  Builds on Deep Typechecking  Enables class and field renaming 1.Unset parameter 2.Unsafe param type 3.Unsafe downcast 4.Refactoring difficult 24

25 Outline 1.Introduction and Motivation 2.Deep Typechecking and Refactoring  Straight Line Code  Control Flow  Multiple Methods 3.Experimental Results 4.Related Work and Conclusion 25

26 Deep Typechecking Example String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } Query safety: All params set Params safely set Result safely downcast 26 Is this query exec safe? Need to know: 1.query string 2.param types

27 Deep Typechecking Example String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } Bound Query: query string param types 27 query : “SELECT … ?1 … ?2 … ?3 …” ?1 : String ?2 : Weblog ?3 : unknown Example : At each program point map each var to a set of BQs.

28 Bound Query Analysis String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 28

29 Bound Query Analysis String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } qStr = “SELECT … ?2” 29

30 Bound Query Analysis String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 30 qStr = “SELECT … ?2”

31 Bound Query Analysis String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } qStr = “SELECT … ?2” 31

32 Bound Query Analysis String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } qStr = “SELECT … ?2” 32 query : “SELECT …” ?1 : unknown ?2 : unknown

33 Bound Query Analysis String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } qStr = “SELECT … ?2” 33 query : “SELECT …” ?1 : unknown ?2 : unknown query : “SELECT …” ?1 : String ?2 : unknown

34 Bound Query Analysis String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } qStr = “SELECT … ?2” 34 query : “SELECT …” ?1 : unknown ?2 : unknown query : “SELECT …” ?1 : String ?2 : unknown query : “SELECT …” ?1 : String ?2 : int

35 Bound Query Analysis String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } Checking param types: 1.Parse query string 2.Check all params set 3.Check param types Bound Queries: 35 query : “SELECT …” ?1 : String ?2 : int

36 Bound Query Analysis String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } Checking result type: 1.Infer result type 2.Propagate result type 3.Check downcasts Bound Queries: 36 query : “SELECT …” ?1 : String ?2 : int query : “SELECT …” ?1 : String ?2 : int result : Weblog

37 Bound Query Analysis String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 37 If a query passes Deep Typechecking, then it will not cause an error at runtime. Therefore, Bound Query Analysis has no silent failures.

38 Bound Query Analysis String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } qStr = “SELECT … ?2” query : “SELECT …” ?1 : unknown ?2 : unknown query : “SELECT …” ?1 : String ?2 : unknown query : “SELECT …” ?1 : String ?2 : int 38

39 Deep Refactoring Example String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 39

40 Deep Refactoring Example String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 40 Refactor Weblog field: id  name

41 Deep Refactoring Example String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 41 Refactor Weblog field: id  name

42 Deep Refactoring Example String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 42 Refactor Weblog field: id  name

43 Deep Refactoring Example Refactor Weblog field: id  name String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } query : SELECT w FROM Weblog w WHERE w.id = ?1 AND w.link.id = ?2 ?1 : String ?2 : int 43

44 Deep Refactoring Example String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } query : SELECT w FROM Weblog w WHERE w.id = ?1 AND w.link.id = ?2 ?1 : String ?2 : int 44 Refactor Weblog field: id  name 1.Refactor full query

45 Deep Refactoring Example String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } query : SELECT w FROM Weblog w WHERE w.name = ?1 AND w.link.id = ?2 ?1 : String ?2 : int 45 Refactor Weblog field: id  name 1.Refactor full query

46 Deep Refactoring Example String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } query : SELECT w FROM Weblog w WHERE w.name = ?1 AND w.link.id = ?2 ?1 : String ?2 : int 46 Refactor Weblog field: id  name 1.Refactor full query 2.Propagate changes

47 Deep Refactoring Example String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.name = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } query : SELECT w FROM Weblog w WHERE w.name = ?1 AND w.link.id = ?2 ?1 : String ?2 : int 47 Refactor Weblog field: id  name 1.Refactor full query 2.Propagate changes

48 Outline 1.Introduction and Motivation 2.Deep Typechecking and Refactoring  Straight Line Code  Control Flow  Multiple Methods 3.Experimental Results 4.Related Work and Conclusion 48

49 Flow Sensitivity String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 49

50 Flow Sensitivity String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 50

51 Flow Sensitivity String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; } 51

52 Flow Sensitivity String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; if(link != null) { qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); } else { } Weblog w = (Weblog) q.execQuery(); return w.text; } 52

53 Flow Sensitivity String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; if(link != null) { qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); } else { q = createQuery(qStr); q.setParam(1, id); } Weblog w = (Weblog) q.execQuery(); return w.text; } 53

54 Flow Sensitivity String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; if(link != null) { qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); } else { q = createQuery(qStr); q.setParam(1, id); } Weblog w = (Weblog) q.execQuery(); return w.text; } 54

55 Flow Sensitivity String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; if(link != null) { qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); } else { q = createQuery(qStr); q.setParam(1, id); } Weblog w = (Weblog) q.execQuery(); return w.text; } qStr = “SELECT … ?2” 55

56 Flow Sensitivity String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; if(link != null) { qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); } else { q = createQuery(qStr); q.setParam(1, id); } Weblog w = (Weblog) q.execQuery(); return w.text; } query : “SEL … ?2” ?1 : String ?2 : int 56 qStr = “SELECT … ?2”

57 Flow Sensitivity String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; if(link != null) { qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); } else { q = createQuery(qStr); q.setParam(1, id); } Weblog w = (Weblog) q.execQuery(); return w.text; } query : “SEL … ?2” ?1 : String ?2 : int qStr = “SELECT … ?1” 57 qStr = “SELECT … ?2”

58 Flow Sensitivity String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; if(link != null) { qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); } else { q = createQuery(qStr); q.setParam(1, id); } Weblog w = (Weblog) q.execQuery(); return w.text; } query : “SEL … ?2” ?1 : String ?2 : int qStr = “SELECT … ?1” 58 qStr = “SELECT … ?2”

59 Flow Sensitivity String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; if(link != null) { qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); } else { q = createQuery(qStr); q.setParam(1, id); } Weblog w = (Weblog) q.execQuery(); return w.text; } query : “SEL … ?2” ?1 : String ?2 : int qStr = “SELECT … ?1” 59 qStr = “SELECT … ?2”

60 Flow Sensitivity String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; if(link != null) { qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); } else { q = createQuery(qStr); q.setParam(1, id); } Weblog w = (Weblog) q.execQuery(); return w.text; } qStr = “SELECT … ?1” query : “SEL … ?1” ?1 : String query : “SEL … ?2” ?1 : String ?2 : int 60 qStr = “SELECT … ?2”

61 Flow Sensitivity String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; if(link != null) { qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); } else { q = createQuery(qStr); q.setParam(1, id); } Weblog w = (Weblog) q.execQuery(); return w.text; } query : “SEL … ?1” ?1 : String “SEL … ?2” ?1 : String ?2 : int “SEL … ?1” ?1 : String query : “SEL … ?2” ?1 : String ?2 : int qStr = “SELECT … ?1” 61 qStr = “SELECT … ?2”

62 Flow Sensitivity String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; if(link != null) { qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); } else { q = createQuery(qStr); q.setParam(1, id); } Weblog w = (Weblog) q.execQuery(); return w.text; } “SEL … ?2” ?1 : String ?2 : int “SEL … ?1” ?1 : String As before, for each bound query: 1.Check param types 2.Check result type In general, we express Bound Query Analysis as a dataflow analysis. 62

63 Flow Sensitivity String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; if(link != null) { qStr += “AND w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); } else { q = createQuery(qStr); q.setParam(1, id); } Weblog w = (Weblog) q.execQuery(); return w.text; } query : “SEL … ?2” ?1 : String ?2 : int qStr = “SELECT … ?1” query : “SEL … ?1” ?1 : String “SEL … ?2” ?1 : String ?2 : int “SEL … ?1” ?1 : String 63 qStr = “SELECT … ?2”

64 Loops 64 String getText(String id, Link link) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “OR w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; }

65 Loops 65 String getText(String id, List links) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “OR w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; }

66 Loops 66 String getText(String id, List links) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; qStr += “OR w.link.id = ?2”; q = createQuery(qStr); q.setParam(1, id); q.setParam(2, link.id); Weblog w = (Weblog) q.execQuery(); return w.text; }

67 Loops 67 String getText(String id, List links) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; for(int i = 0; i < links.size(); i++) { qStr += “ OR w.link.id = ?” + i; } q = createQuery(qStr);... }

68 String getText(String id, List links) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; for(int i = 0; i < links.size(); i++) { qStr += “ OR w.link.id = ?” + i; } q = createQuery(qStr);... } Loops 68 qStr = ??? qStr = “SELECT … w.id = ?1” ( “ OR w.link.id = ?#” )*

69 String getText(String id, List links) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; for(int i = 0; i < links.size(); i++) { qStr += “ OR w.link.id = ?” + i; } q = createQuery(qStr);... } Loops 69 qStr = “SELECT … w.id = ?1” ( “ OR w.link.id = ?#” )*

70 String getText(String id, List links) { String qStr; Query q; qStr = “SELECT w FROM Weblog w ”; qStr += “WHERE w.id = ?1 ”; for(int i = 0; i < links.size(); i++) { qStr += “ OR w.link.id = ?” + i; } q = createQuery(qStr);... } Loops 70 qStr = “SELECT … w.id = ?1” ( “ OR w.link.id = ?#” )* Deep Refactoring: know query structure know fragment locs refactor across loops Deep Typechecking: unknown # of params do not check params can still check result

71 Outline 1.Introduction and Motivation 2.Deep Typechecking and Refactoring  Straight Line Code  Control Flow  Multiple Methods 3.Experimental Results 4.Related Work and Conclusion 71

72 Multiple Methods 72 String mainQueryStr() { return “SELECT... ?1”; } Object getMain() { String qStr = mainQueryStr(); Query q = createQuery(qStr); q.setParam(1, “main”); return q.execQuery(); } String mainId() { return ((Weblog) getMain()).id; } String Analysis : interprocedural compute regexps Bound Query Analysis : intraprocedural no complex aliasing Result Analysis : interprocedural propagate result type

73 Outline 1.Introduction and Motivation 2.Deep Typechecking and Refactoring  Straight Line Code  Control Flow  Multiple Methods 3.Experimental Results 4.Related Work and Conclusion 73

74 Results 74 Implementation: Quail  5700 lines of Java in Eclipse plugin Benchmarks: ApplicationLOCDescription Roller82,900Blogging framework Planet14,500News aggregator PetStore 5,440Example JPA application CaveatEmptor 3,370Online auction system Total106,000 Create QuerySet ParamExec Query 163199136 JPA Calls: Tested, Stable, Deployed

75 Deep Typechecking Experiment Check for all query execution sites:  All parameters set  Parameters safely set  Query results safely downcast Show 84% of query executions are safe Remaining 16% due to imprecision:  Queries built with loops or data structures  Path sensitivity  Reflection 75

76 Deep Refactoring Experiment 76  Rename 16 most frequently appearing classes / fields  Correctly refactor 98% of refactorable locations  Remaining 2% from heap based strings in query String[] blacklist = getBlacklist(); String qStr = “SELECT w FROM Weblog w WHERE w.id = ?1 ”; for(int i = 0; i < blacklist.length; i++) { qStr += “AND w.id != ” + blacklist[i] + “ ”; }...

77 Results 77 Typechecking and Refactoring Experiments:  No silent failures  Show user exactly where to check  2% vs 16% imprecision:  Refactoring does not depend on parameter types

78 Outline 1.Introduction and Motivation 2.Deep Typechecking and Refactoring  Straight Line Code  Control Flow  Mutliple Methods 3.Experimental Results 4.Related Work and Conclusion 78

79 Related Work Query Extraction [Wiedermann, Ibrahim, Cook 08]  Infer query from Java code that uses DB root object  Not applicable to legacy code 79 Static Query Checking [Gould, Su, Devanbu 04]  Typechecks JDBC queries against DB schema  Not applied to source language type system

80 Related Work Language Based [Matthes 95, Schmidt 94]  Syntax extension for queries  Not applicable to legacy code Orthogonal Persistence [Atkinson 96, Liskov 96]  Map DB to collection of persisted objects  Must express queries in non-query language 80

81 Conclusion String based queries can be safe and flexible. Deep Typechecking ensures:  All parameters are set  Parameters are set to correct type  Query results are safely downcast Deep Refactoring enables:  Class and field renaming 81

82 Thank You 82


Download ppt "Deep Typechecking and Refactoring Zachary Tatlock, Chris Tucker, David Shuffleton, Ranjit Jhala, Sorin Lerner 1 University of California, San Diego."

Similar presentations


Ads by Google