deep typechecking and refactoring n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Deep Typechecking and Refactoring PowerPoint Presentation
Download Presentation
Deep Typechecking and Refactoring

Loading in 2 Seconds...

play fullscreen
1 / 79

Deep Typechecking and Refactoring - PowerPoint PPT Presentation


  • 80 Views
  • Uploaded on

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.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Deep Typechecking and Refactoring' - stacy


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
deep typechecking and refactoring

Deep Typecheckingand Refactoring

Zachary Tatlock, Chris Tucker, David Shuffleton,

RanjitJhala, Sorin Lerner

University of California, San Diego

communicating with databases
Communicating with Databases

String based queries are prevalent:

  • JPA, Hibernate, TopLink

Strings

JAVA

DB

example using jpa to query db
Example: Using JPA to query DB

Query in JPA Query Language:

“SELECT w FROM Weblog w

WHERE w.id = ?1 AND w.link.id = ?2”

Java syntax in query String

  • Mapping Java Classes to DB Tables:
    • Expressed in Object Relational Mapping (ORM)
example using jpa to query db1
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;

}

example using jpa to query db2
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;

}

Build query string

example using jpa to query db3
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;

}

Build query string

Create query

example using jpa to query db4
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;

}

Build query string

Create query

Set parameters

example using jpa to query db5
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;

}

Build query string

Create query

Set parameters

example using jpa to query db6
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;

}

Build query string

Create query

Set parameters

Execute query

example using jpa to query db7
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;

}

Build query string

Create query

Set parameters

Execute query

  • Efficient
  • Flexible

Unsafe

uncaught errors
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;

}

uncaught errors1
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;

}

uncaught errors2
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;

}

Unset parameter

uncaught errors3
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;

}

Unset parameter

uncaught errors4
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;

}

Unset parameter

Unsafe param type

uncaught errors5
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;

}

Unset parameter

Unsafe param type

uncaught errors6
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;

}

Unset parameter

Unsafe param type

Unsafe downcast

uncaught errors7
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;

}

Unset parameter

Unsafe param type

Unsafe downcast

Java compiler does not reason about the query strings; cannot typecheck.

refactor weblog id weblog name
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;

}

Unset parameter

Unsafe param type

Unsafe downcast

refactor weblog id weblog name1
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;

}

Refactor

Unset parameter

Unsafe param type

Unsafe downcast

Don’t Refactor

Need to know type of w and w.link to refactor safely.

refactor weblog id weblog name2
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;

}

Unset parameter

Unsafe param type

Unsafe downcast

Refactoring difficult

string based query challenges
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;

}

Unset parameter

Unsafe param type

Unsafe downcast

Refactoring difficult

contributions
Contributions

Deep Typechecking:

  • All parameters set
  • Parameters correctly set
  • Results safely downcast

Unset parameter

Unsafe param type

Unsafe downcast

Refactoring difficult

  • Deep Refactoring:
    • Builds on Deep Typechecking
    • Enables class and field renaming
outline
Outline
  • Introduction and Motivation
  • Deep Typechecking and Refactoring
    • Straight Line Code
    • Control Flow
    • Multiple Methods
  • Experimental Results
  • Related Work and Conclusion
deep typechecking example
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

Is this query exec safe?

Needto know:

query string

param types

deep typechecking example1
Deep Typechecking Example
  • Bound Query:
  • query string
  • param types

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;

}

Example :

query : “SELECT … ?1 … ?2 … ?3 …”

?1 : String

?2 : Weblog

?3 : unknown

At each program point map each var to a set of BQs.

bound query analysis
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;

}

bound query analysis1
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”

bound query analysis2
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”

bound query analysis3
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”

bound query analysis4
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

bound query analysis5
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

bound query analysis6
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

bound query analysis7
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:

Parse query string

Check all params set

Check param types

Bound Queries:

query : “SELECT …”

?1 : String

?2 : int

bound query analysis8
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:

Infer result type

Propagate result type

Check downcasts

Bound Queries:

query : “SELECT …”

?1 : String

?2 : int

result : Weblog

query : “SELECT …”

?1 : String

?2 : int

bound query analysis9
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;

}

If a query passes Deep Typechecking, then it will not cause an error at runtime.

Therefore, Bound Query Analysis has no silent failures.

deep refactoring example
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;

}

deep refactoring example1
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;

}

deep refactoring example2
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;

}

deep refactoring example3
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;

}

deep refactoring example4
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

deep refactoring example5
Deep Refactoring Example

Refactor Weblog field:

id  name

Refactor full query

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

deep refactoring example6
Deep Refactoring Example

Refactor Weblog field:

id  name

Refactor full query

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

deep refactoring example7
Deep Refactoring Example

Refactor Weblog field:

id  name

Refactor full query

Propagate changes

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

deep refactoring example8
Deep Refactoring Example

Refactor Weblog field:

id  name

Refactor full query

Propagate changes

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

outline1
Outline
  • Introduction and Motivation
  • Deep Typechecking and Refactoring
    • Straight Line Code
    • Control Flow
    • Multiple Methods
  • Experimental Results
  • Related Work and Conclusion
flow sensitivity
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;

}

flow sensitivity1
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;

}

flow sensitivity2
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;

}

flow sensitivity3
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;

}

flow sensitivity4
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;

}

flow sensitivity5
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;

}

flow sensitivity6
Flow Sensitivity

qStr = “SELECT … ?2”

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;

}

flow sensitivity7
Flow Sensitivity

qStr = “SELECT … ?2”

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

flow sensitivity8
Flow Sensitivity

qStr = “SELECT … ?2”

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 … ?2”

?1 : String

?2 : int

flow sensitivity9
Flow Sensitivity

qStr = “SELECT … ?2”

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 … ?2”

?1 : String

?2 : int

flow sensitivity10
Flow Sensitivity

qStr = “SELECT … ?2”

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 … ?2”

?1 : String

?2 : int

flow sensitivity11
Flow Sensitivity

qStr = “SELECT … ?2”

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

flow sensitivity12
Flow Sensitivity

qStr = “SELECT … ?2”

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

“SEL … ?2”

?1 : String

?2 : int

query : “SEL … ?2”

?1 : String

?2 : int

“SEL … ?1”

?1 : String

flow sensitivity13
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;

}

As before, for each bound query:

Check param types

Check result type

In general, we express Bound Query Analysis as a dataflow analysis.

“SEL … ?2”

?1 : String

?2 : int

“SEL … ?1”

?1 : String

loops
Loops

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;

}

loops1
Loops

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

}

loops2
Loops

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

}

loops3
Loops

String getText(String id, List<Link> links) {

String qStr;

Query q;

qStr = “SELECT w FROM Weblog w ”;

qStr += “WHERE w.id = ?1 ”;

for(inti = 0; i < links.size(); i++) {

qStr += “ OR w.link.id = ?” + i;

}

q = createQuery(qStr);

...

}

loops4
Loops

String getText(String id, List<Link> links) {

String qStr;

Query q;

qStr = “SELECT w FROM Weblog w ”;

qStr += “WHERE w.id = ?1 ”;

for(inti = 0; i < links.size(); i++) {

qStr += “ OR w.link.id = ?” + i;

}

q = createQuery(qStr);

...

}

qStr =

“SELECT … w.id = ?1”

( “ OR w.link.id = ?#” )*

qStr = ???

loops5
Loops

String getText(String id, List<Link> links) {

String qStr;

Query q;

qStr = “SELECT w FROM Weblog w ”;

qStr += “WHERE w.id = ?1 ”;

for(inti = 0; i < links.size(); i++) {

qStr += “ OR w.link.id = ?” + i;

}

q = createQuery(qStr);

...

}

qStr =

“SELECT … w.id = ?1”

( “ OR w.link.id = ?#” )*

loops6
Loops
  • Deep Refactoring:
  • know query structure
  • know fragment locs
  • refactor across loops

String getText(String id, List<Link> links) {

String qStr;

Query q;

qStr = “SELECT w FROM Weblog w ”;

qStr += “WHERE w.id = ?1 ”;

for(inti = 0; i < links.size(); i++) {

qStr += “ OR w.link.id = ?” + i;

}

q = createQuery(qStr);

...

}

  • Deep Typechecking:
  • unknown # of params
  • do not check params
  • can still check result

qStr =

“SELECT … w.id = ?1”

( “ OR w.link.id = ?#” )*

outline2
Outline
  • Introduction and Motivation
  • Deep Typechecking and Refactoring
    • Straight Line Code
    • Control Flow
    • Multiple Methods
  • Experimental Results
  • Related Work and Conclusion
multiple methods
Multiple Methods
  • String Analysis :
  • interprocedural
  • compute regexps
  • Bound Query Analysis :
  • intraprocedural
  • no complex aliasing
  • Result Analysis :
  • interprocedural
  • propagate result type

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;

}

outline3
Outline
  • Introduction and Motivation
  • Deep Typechecking and Refactoring
    • Straight Line Code
    • Control Flow
    • Multiple Methods
  • Experimental Results
  • Related Work and Conclusion
results
Results

Implementation: Quail

  • 5700lines of Java in Eclipse plugin

Benchmarks:

Tested,

Stable,

Deployed

JPA Calls:

deep typechecking experiment
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
deep refactoring experiment
Deep Refactoring Experiment
  • Rename 16 most frequently appearing classes / fields
  • Correctlyrefactor 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(inti = 0; i < blacklist.length; i++) {

qStr += “AND w.id != ” + blacklist[i] + “ ”;

}

...

results1
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
outline4
Outline
  • Introduction and Motivation
  • Deep Typechecking and Refactoring
    • Straight Line Code
    • Control Flow
    • Mutliple Methods
  • Experimental Results
  • Related Work and Conclusion
related work
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
related work1
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
conclusion
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