Download presentation
Presentation is loading. Please wait.
Published byJanel Lambert Modified over 9 years ago
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
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.