Deep Typechecking and Refactoring

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

description

Deep Typechecking and Refactoring. Zachary Tatlock , Chris Tucker, David Shuffleton , Ranjit Jhala , Sorin Lerner. University of California, San Diego. Communicating with Databases. String based queries are prevalent: JPA, Hibernate, TopLink. Strings. JAVA. DB. - PowerPoint PPT Presentation

Transcript of Deep Typechecking and Refactoring

Page 1: Deep  Typechecking and Refactoring

1

Deep Typecheckingand Refactoring

Zachary Tatlock, Chris Tucker, David Shuffleton, Ranjit Jhala, Sorin Lerner

University of California, San Diego

Page 2: Deep  Typechecking and Refactoring

3

Communicating with Databases

String based queries are prevalent:JPA, Hibernate, TopLink

JAVA DBStrings

Page 3: Deep  Typechecking and Refactoring

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

Page 4: Deep  Typechecking and Refactoring

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;}

Page 5: Deep  Typechecking and Refactoring

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

Page 6: Deep  Typechecking and Refactoring

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

Page 7: Deep  Typechecking and Refactoring

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

Page 8: Deep  Typechecking and Refactoring

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

Page 9: Deep  Typechecking and Refactoring

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

Page 10: Deep  Typechecking and Refactoring

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

Page 11: Deep  Typechecking and Refactoring

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;}

Page 12: Deep  Typechecking and Refactoring

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;}

Page 13: Deep  Typechecking and Refactoring

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

Page 14: Deep  Typechecking and Refactoring

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

Page 15: Deep  Typechecking and Refactoring

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

Page 16: Deep  Typechecking and Refactoring

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

Page 17: Deep  Typechecking and Refactoring

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

Page 18: Deep  Typechecking and Refactoring

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.

Page 19: Deep  Typechecking and Refactoring

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

Page 20: Deep  Typechecking and Refactoring

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.

Page 21: Deep  Typechecking and Refactoring

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

Page 22: Deep  Typechecking and Refactoring

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

Page 23: Deep  Typechecking and Refactoring

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

Page 24: Deep  Typechecking and Refactoring

25

Outline

1. Introduction and Motivation2. Deep Typechecking and Refactoring

Straight Line Code Control Flow Multiple Methods

3. Experimental Results4. Related Work and Conclusion

Page 25: Deep  Typechecking and Refactoring

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

Page 26: Deep  Typechecking and Refactoring

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.

Page 27: Deep  Typechecking and Refactoring

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;}

Page 28: Deep  Typechecking and Refactoring

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”

Page 29: Deep  Typechecking and Refactoring

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”

Page 30: Deep  Typechecking and Refactoring

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”

Page 31: Deep  Typechecking and Refactoring

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

Page 32: Deep  Typechecking and Refactoring

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

Page 33: Deep  Typechecking and Refactoring

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

Page 34: Deep  Typechecking and Refactoring

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

Page 35: Deep  Typechecking and Refactoring

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

Page 36: Deep  Typechecking and Refactoring

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.

Page 37: Deep  Typechecking and Refactoring

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;}

Page 38: Deep  Typechecking and Refactoring

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

Page 39: Deep  Typechecking and Refactoring

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

Page 40: Deep  Typechecking and Refactoring

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

Page 41: Deep  Typechecking and Refactoring

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

Page 42: Deep  Typechecking and Refactoring

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

Page 43: Deep  Typechecking and Refactoring

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

Page 44: Deep  Typechecking and Refactoring

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

Page 45: Deep  Typechecking and Refactoring

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

Page 46: Deep  Typechecking and Refactoring

48

Outline

1. Introduction and Motivation2. Deep Typechecking and Refactoring

Straight Line Code Control Flow Multiple Methods

3. Experimental Results4. Related Work and Conclusion

Page 47: Deep  Typechecking and Refactoring

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;}

Page 48: Deep  Typechecking and Refactoring

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;}

Page 49: Deep  Typechecking and Refactoring

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;}

Page 50: Deep  Typechecking and Refactoring

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;}

Page 51: Deep  Typechecking and Refactoring

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;}

Page 52: Deep  Typechecking and Refactoring

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;}

Page 53: Deep  Typechecking and Refactoring

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”

Page 54: Deep  Typechecking and Refactoring

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”

Page 55: Deep  Typechecking and Refactoring

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”

Page 56: Deep  Typechecking and Refactoring

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”

Page 57: Deep  Typechecking and Refactoring

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”

Page 58: Deep  Typechecking and Refactoring

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”

Page 59: Deep  Typechecking and Refactoring

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”

Page 60: Deep  Typechecking and Refactoring

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.

Page 61: Deep  Typechecking and Refactoring

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;}

Page 62: Deep  Typechecking and Refactoring

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;}

Page 63: Deep  Typechecking and Refactoring

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;}

Page 64: Deep  Typechecking and Refactoring

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);

...}

Page 65: Deep  Typechecking and Refactoring

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 = ?#” )*

Page 66: Deep  Typechecking and Refactoring

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 = ?#” )*

Page 67: Deep  Typechecking and Refactoring

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

Page 68: Deep  Typechecking and Refactoring

71

Outline

1. Introduction and Motivation2. Deep Typechecking and Refactoring

Straight Line Code Control Flow Multiple Methods

3. Experimental Results4. Related Work and Conclusion

Page 69: Deep  Typechecking and Refactoring

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

Page 70: Deep  Typechecking and Refactoring

73

Outline

1. Introduction and Motivation2. Deep Typechecking and Refactoring

Straight Line Code Control Flow Multiple Methods

3. Experimental Results4. Related Work and Conclusion

Page 71: Deep  Typechecking and Refactoring

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

Page 72: Deep  Typechecking and Refactoring

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

Page 73: Deep  Typechecking and Refactoring

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] + “ ”;

}

...

Page 74: Deep  Typechecking and Refactoring

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

Page 75: Deep  Typechecking and Refactoring

78

Outline

1. Introduction and Motivation2. Deep Typechecking and Refactoring

Straight Line Code Control Flow Mutliple Methods

3. Experimental Results4. Related Work and Conclusion

Page 76: Deep  Typechecking and Refactoring

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

Page 77: Deep  Typechecking and Refactoring

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

Page 78: Deep  Typechecking and Refactoring

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

Page 79: Deep  Typechecking and Refactoring

82

Thank You