Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 342532 - Net4j DBAdapter.validateTable() reads whole table, inefficient for H2
Summary: Net4j DBAdapter.validateTable() reads whole table, inefficient for H2
Status: CLOSED FIXED
Alias: None
Product: EMF
Classification: Modeling
Component: cdo.net4j.db (show other bugs)
Version: 4.0   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: ---   Edit
Assignee: Eike Stepper CLA
QA Contact: Eike Stepper CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-04-12 05:56 EDT by Gábor Nagy CLA
Modified: 2011-06-23 03:41 EDT (History)
1 user (show)

See Also:


Attachments
Patch v1 (2.52 KB, patch)
2011-04-12 08:35 EDT, Eike Stepper CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Gábor Nagy CLA 2011-04-12 05:56:53 EDT
Build Identifier: 

DBAdapter validates a table by doing a full query and relies on SQLExceptions to see if a table has already been created.

On most databases this isn't a problem, because they have server-side cursors. H2, on the other hand reads the entire table (tested with H2 1.1), which is quite an expensive operation if table has many rows. H2 reads the whole table into memory which can result in extensive swapping.

Please consider overriding validateTable() in H2Adapter as so:

@Override
protected void validateTable(IDBTable table, Statement statement) throws DBException {
	String sql = null;
    try {
    	StringBuilder builder = new StringBuilder();
    	builder.append("SELECT ");
    	appendFieldNames(builder, table);
    	builder.append(" FROM ");
    	builder.append(table);
    	builder.append(" LIMIT 1"); // Only retrieve the first result
    	sql = builder.toString();

    	ResultSet resultSet = statement.executeQuery(sql);
    	ResultSetMetaData metaData = resultSet.getMetaData();
    	int columnCount = metaData.getColumnCount();
    	if (columnCount != table.getFieldCount()) {
    		throw new DBException("DBTable " + table + " has " + columnCount + " columns instead of " + table.getFieldCount());
    	}
    } catch (SQLException ex) {
    	throw new DBException("Problem with table " + table, ex, sql);
    }
}

... or another similar solution that duplicates less code.


Reproducible: Always
Comment 1 Eike Stepper CLA 2011-04-12 08:35:34 EDT
Created attachment 193040 [details]
Patch v1

What about this vendor-agnostic approach? Can you confirm that it solves the issue with H2?
Comment 2 Gábor Nagy CLA 2011-04-12 09:27:04 EDT
(In reply to comment #1)
> Created attachment 193040 [details]
> Patch v1
> 
> What about this vendor-agnostic approach? Can you confirm that it solves the
> issue with H2?

Yes, this seems to work also. Thanks for the quick reply!
Comment 3 Eike Stepper CLA 2011-04-12 09:28:48 EDT
You're welcome ;-)

Committed revision 7610
Comment 4 Eike Stepper CLA 2011-06-23 03:41:31 EDT
Available in R20110608-1407