SQL DOM: Compile Time Checking of Dynamic SQL Statements Russel A. McClure Ingolf H. Krüger ICSE...

Preview:

Citation preview

SQL DOM: Compile Time Checking of Dynamic SQL Statements

Russel A. McClureIngolf H. Krüger

ICSE 2005University of California, San Diego

Department of Computer Science and Engineering

“Impedance Mismatch” Huh?

• OO = Software Engineering Principles• Relational = Mathematical Principles.• Impedance Mismatch: An SQL “select” in Java.

– In OO you traverse pointers, and send messages.– In Relational, you apply operators to relations:

• Select• Cartesian Product• Project• Union• Set Difference

Tedious Composition of SQL statements

Challenge: generate a simple SQL query on customers relation:

SELECT * FROM CustomersWHERE companyName = ‘<company name>’AND …

public string GetCustomers(string companyName, …. ){

bool firstCondition = true;StringBuilder sql= new StringBuilder(“SELECT *

FROM Customers “);if ((companyName!= null) && (companyName.Length

> 0) {if (firstCondition) {

firstCondition=false;sql,Append (“ WHERE “);

} else sql.Append(“ AND”);

sql.Append(“CompnyName=‘”);sql.Append(companyName);sql.Append(“’”);

}return sql.ToString();

}

Tedious Composition of SQL statements

misspelled name !

SQL syntax errorCan you find the bugs?

(Sorry, the compiler won’t help you)

Type Translation Horrors

public string SetUnitsInStock (int productID, int unitsInStock)

{

string sql = “UPDATE Products “ + “ SET UnitsInStock = “ + unitsInStock.ToString() + “ WHERE ProductID = “ + productID.ToString();

return sql;

} UnitsInStock is 16-bit integer. Runtime error if

unitsInStock (32-bit integer) is too big.

The SQL DOM solution

database DOMsqldomgen

the SQL DOM generator

sqldomgen – an executable, executed against a database.

Output: a DLL (Dynamic Link Library). Classes are referred to

as SQL DOM – SQL Domain Object Model.

How about now?public string GetCustomers (string companyName,

… ){

CustomersTblSelectSQLStmt sql= new CustomersTblSelectSQLStmt ();

if ((companyName!= null) && (companyName.Length > 0){

sql.AddWhereCondition( new CompanyNameWhereCond(companyName));

}return sql.GetSQL();

}

The DOM works its wonders in mysterious ways…

3 steps for DOM generation:

• Obtain database schema (through methods from OLEDB provider)

• Iterate through tables and columns (produce source files)

• Compile… (produce DLL)

The Object Model

Three main types of classes:

• SQL statements– select– update– insert– delete

• columns• where conditions

SQL Statements

SQLStmt

InsertSQLStmt UpdateSQLStmtSelectSQLStmt

CustomersTblSelectSQLStmt OrdersTblSelectSQLStmt

CustomersTblSelectSQLStmt()

JoinToOrders()

JoinTo()

AddWhereCondition()

AddOrderBy()

OrdersTblSelectSQLStmt()

JoinToOrderDetails()

JoinToCustomers()

JoinTo()

Column classes

CustomersTblColumn

CustomersTblInsertColumn CustomersTblUpdateColumn

CustomersTblSelectColumn

Column

Remember “nasty bug”?

This is what would happen now

public string SetUnitsInStock(int productID, int unitsInStock)

{…sql.UnitsInStock = |

…}

Where condition classes

CustomersTblWhereCond

CustomerIDWhereCond CompanyNameWhereCond

WhereCond

So this the answer…

public string GetCustomers (string companyName, … )

{CustomersTblSelectSQLStmt sql= new

CustomersTblSelectSQLStmt ();if ((companyName!= null) && (companyName.Length > 0){

sql.AddWhereCondition( new

CompanyNameWhereCond(companyName));}return sql.GetSQL();

}

Advantages

• Problems solved:

– type mismatch

– syntax errors (and spelling errors)

– semantic (structural) errors

and more…

Databases Change!!

Question: What’ll happen when there is a change in the database?

Answer: Re-run sqldomgen. May get errors:

•No such class exists – if table/column is renamed/removed

•Data type conversion error – if data type of column is changed

•Missing constructor parameter – if a new column is added to a table

Convenient IDE

public string GetallCustomers()

{

new CustomersTblSelectSQLStmt( ECustomersTblColumns.CustomerID, ECustomersTblColumns.

SQL injection protection

example: malicious SQL statements inserted into database through web form.e.g. submission of parameter

“Bad Guy’ drop table Customers”

• non-string data types are now safe

• string types are checked and proofed

Disadvantages

We do not enjoy the full power of SQL.

• What about GROUP BY and aggregate functions?

• EXISTS keyword?

• Nested queries? Co-dependent queries?

Can we do this?

SELECT column1,column2

FROM Table T

WHERE column2 >

(SELECT AVG(column2)

FROM Table T1

WHERE T.column1=T1.column1)

Disadvantages

• Performance (??)

– Query generation takes up to x100 longer

– But…Actual figures are in thousands of ms per 10,000 generations of queries.

– Query generation time << query runtime

Other existing developments

• SQLJ/Embedded SQL – do not support dynamic SQL statements.

• Object/relational mapping and persistent object systems – reduce expressive power.

Conclusion

• Many runtime problems become compile-time problems.

• More convenient

• Less powerful

• Slight overhead

Recommended