Deep Typechecking and Refactoring Zachary Tatlock, Chris Tucker, David Shuffleton, Ranjit Jhala,...
-
Upload
janel-lambert -
Category
Documents
-
view
219 -
download
0
Transcript of Deep Typechecking and Refactoring Zachary Tatlock, Chris Tucker, David Shuffleton, Ranjit Jhala,...
1
Deep Typecheckingand Refactoring
Zachary Tatlock, Chris Tucker, David Shuffleton, Ranjit Jhala, Sorin Lerner
University of California, San Diego
3
Communicating with Databases
String based queries are prevalent:JPA, Hibernate, TopLink
JAVA DBStrings
4
Example: Using JPA to query DB
“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 DBString 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;}
6
Example: Using JPA to query DBString 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
7
Example: Using JPA to query DBString 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
8
Example: Using JPA to query DBString 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
Example: Using JPA to query DBString 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
10
Example: Using JPA to query DBString 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
Example: Using JPA to query DBString 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
• Efficient• Flexible
Unsafe
12
Uncaught ErrorsString 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
Uncaught ErrorsString 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;}
14
Uncaught ErrorsString 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
15
Uncaught ErrorsString 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
16
Uncaught ErrorsString 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
17
Uncaught ErrorsString 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
18
Uncaught ErrorsString 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
19
Uncaught ErrorsString 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
Java compiler does not reason about the query strings; cannot typecheck.
20
Refactor: Weblog.id Weblog.nameString 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: Weblog.id Weblog.nameString 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
Refactor
Don’t Refactor
Need to know type of w and w.link to
refactor safely.
22
Refactor: Weblog.id Weblog.nameString 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
String Based Query ChallengesString 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
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
25
Outline
1. Introduction and Motivation2. Deep Typechecking and Refactoring
Straight Line Code Control Flow Multiple Methods
3. Experimental Results4. Related Work and Conclusion
26
Deep Typechecking ExampleString 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
Is this query exec safe?
Need to know:
1. query string
2. param types
27
Deep Typechecking ExampleString 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
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 AnalysisString 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;}
29
Bound Query AnalysisString 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”
30
Bound Query AnalysisString 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
Bound Query AnalysisString 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
Bound Query AnalysisString 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
33
Bound Query AnalysisString 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
34
Bound Query AnalysisString 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
35
Bound Query AnalysisString 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:
query : “SELECT …”?1 : String?2 : int
36
Bound Query AnalysisString 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:
query : “SELECT …”?1 : String?2 : int
query : “SELECT …”?1 : String?2 : intresult : Weblog
37
Bound Query AnalysisString 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;}
If a query passes Deep Typechecking, then it will not cause an error at runtime.
Therefore, Bound Query Analysis has no silent failures.
39
Deep Refactoring ExampleString 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
Deep Refactoring ExampleString 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;}
Refactor Weblog field:
id name
41
Deep Refactoring ExampleString 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;}
Refactor Weblog field:
id name
42
Deep Refactoring ExampleString 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;}
Refactor Weblog field:
id name
43
Deep Refactoring ExampleRefactor 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
44
Deep Refactoring ExampleString 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
Refactor Weblog field:
id name
1. Refactor full query
45
Deep Refactoring ExampleString 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
Refactor Weblog field:
id name
1. Refactor full query
46
Deep Refactoring ExampleString 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
Refactor Weblog field:
id name
1. Refactor full query
2. Propagate changes
47
Deep Refactoring ExampleString 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
Refactor Weblog field:
id name
1. Refactor full query
2. Propagate changes
48
Outline
1. Introduction and Motivation2. Deep Typechecking and Refactoring
Straight Line Code Control Flow Multiple Methods
3. Experimental Results4. Related Work and Conclusion
49
Flow SensitivityString 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
Flow SensitivityString 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
Flow SensitivityString 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;}
52
Flow SensitivityString 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;}
53
Flow SensitivityString 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
Flow SensitivityString 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;}
55
Flow SensitivityString 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”
56
Flow SensitivityString 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 … ?2”
57
Flow SensitivityString 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”
qStr = “SELECT … ?2”
58
Flow SensitivityString 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”
qStr = “SELECT … ?2”
59
Flow SensitivityString 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”
qStr = “SELECT … ?2”
60
Flow SensitivityString 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
qStr = “SELECT … ?2”
61
Flow SensitivityString 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”
qStr = “SELECT … ?2”
62
Flow SensitivityString 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.
64
LoopsString 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
LoopsString getText(String id, List<Link> 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
LoopsString getText(String id, List<Link> 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
LoopsString getText(String id, List<Link> 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<Link> 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
qStr = ???qStr = “SELECT … w.id = ?1” ( “ OR w.link.id = ?#” )*
69
String getText(String id, List<Link> 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
qStr = “SELECT … w.id = ?1” ( “ OR w.link.id = ?#” )*
70
String getText(String id, List<Link> 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
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 Motivation2. Deep Typechecking and Refactoring
Straight Line Code Control Flow Multiple Methods
3. Experimental Results4. Related Work and Conclusion
72
Multiple MethodsString 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 Motivation2. Deep Typechecking and Refactoring
Straight Line Code Control Flow Multiple Methods
3. Experimental Results4. Related Work and Conclusion
74
Results Implementation: Quail
5700 lines of Java in Eclipse plugin
Benchmarks:Application LOC DescriptionRoller 82,900 Blogging frameworkPlanet 14,500 News aggregatorPetStore 5,440 Example JPA applicationCaveatEmptor 3,370 Online auction systemTotal 106,000
Create Query Set Param Exec Query163 199 136
JPA Calls:
Tested,Stable,
Deployed
75
Deep Typechecking ExperimentCheck 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
76
Deep Refactoring Experiment 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
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 Motivation2. Deep Typechecking and Refactoring
Straight Line Code Control Flow Mutliple Methods
3. Experimental Results4. Related Work and Conclusion
79
Related Work
Query Extraction [Wiedermann, Ibrahim, Cook 08] Infer query from Java code that uses DB root object Not applicable to legacy code
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
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