Skip to content

Commit

Permalink
Use temp session tables (but we are reusing sessions)
Browse files Browse the repository at this point in the history
  • Loading branch information
zspitzer committed Jul 16, 2024
1 parent fa195b2 commit b1aebaf
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 44 deletions.
21 changes: 8 additions & 13 deletions core/src/main/java/lucee/runtime/db/HSQLDBHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ private static void createTable(Connection conn, PageContext pc, String dbTableN
String escape = "";

// TODO use DECLARE LOCAL TEMPORARY TABLE
StringBuilder create = new StringBuilder("CREATE TABLE ").append(escape).append(StringUtil.toUpperCase(dbTableName)).append(escape).append(" (");
StringBuilder create = new StringBuilder("DECLARE LOCAL TEMPORARY TABLE ").append(escape).append(StringUtil.toUpperCase(dbTableName)).append(escape).append(" (");

for (int i = 0; i < cols.length; i++) {
String col = StringUtil.toUpperCase(cols[i].getString()); // quoted objects are case insensitive
Expand Down Expand Up @@ -374,7 +374,7 @@ private static Struct getUsedColumnsForQuery(Connection conn, SQL sql) {

// TODO consider if worth doing, if recordcount / column count is too small

aprint.o(sql.toString());
//aprint.o(sql.toString());

try {
Statement stat = conn.createStatement();
Expand Down Expand Up @@ -405,8 +405,8 @@ private static Struct getUsedColumnsForQuery(Connection conn, SQL sql) {
Struct tableCols = ((Struct) tables.get(tableName));
tableCols.setEL(Caster.toKey(rs.getString(colPos)), null);
}
aprint.o(rs);
aprint.o(tables);
//aprint.o(rs);
//aprint.o(tables);
// don't need the view anymore, bye bye
stat.execute("DROP VIEW " + view);
}
Expand Down Expand Up @@ -571,26 +571,23 @@ public static QueryImpl __execute(PageContext pc, SQL sql, int maxrows, int fetc
try {
// we now only lock the data loading, not the execution of the query, but should this be done via
// cflock by the developer?
aprint.out(tables);
//aprint.out(tables);
synchronized (lock) {
Iterator<String> it = tables.iterator();
String cfQueryName = null; // name of the source query variable
String dbTableName = null; // name of the table in the database
String modSql = null;
// int len=tables.size();
SystemOut.print("QoQ HSQLDB CREATED TABLES: " + sql.toString());
//SystemOut.print("QoQ HSQLDB CREATED TABLES: " + sql.toString());
while (it.hasNext()) {
cfQueryName = it.next().toString();// tables.get(i).toString();
dbTableName = cfQueryName.replace('.', '_');
if (qoqTables.contains(dbTableName)){
aprint.o("duplicate table name!!");
}

if (!cfQueryName.toLowerCase().equals(dbTableName.toLowerCase())){
// TODO this could match the wrong strings??
modSql = StringUtil.replace(sql.getSQLString(), cfQueryName, dbTableName, false);
sql.setSQLString(modSql);
SystemOut.print("QoQ HSQLDB CREATED TABLES: " + modSql);
//SystemOut.print("QoQ HSQLDB CREATED TABLES: " + modSql);
}
if (sql.getItems() != null && sql.getItems().length > 0) sql = new SQLImpl(sql.toString());
// temp tables still get created will all the source columns,
Expand All @@ -599,8 +596,6 @@ public static QueryImpl __execute(PageContext pc, SQL sql, int maxrows, int fetc
qoqTables.add(dbTableName);
}



// create the sql as a view, to find out which table columns are needed
Struct allTableColumns = getUsedColumnsForQuery(conn, sql);
Struct tableColumns = null;
Expand Down Expand Up @@ -657,7 +652,7 @@ public static QueryImpl __execute(PageContext pc, SQL sql, int maxrows, int fetc
finally {
if (conn != null) {
removeAll(conn, qoqTables);
// executeStatement(conn, "DISCONNECT"); // close HSQLDB session with temp tables
//executeStatement(conn, "DISCONNECT"); // close HSQLDB session with temp tables
DBUtil.setAutoCommitEL(conn, true);
}
if (dc != null) ((DatasourceConnectionPro) dc).release();
Expand Down
51 changes: 20 additions & 31 deletions test/tickets/LDEV5023.cfc
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,17 @@ component extends="org.lucee.cfml.test.LuceeTestCase" labels="qoq" {
var cols = replaceNoCase( q.columnList, ",unique", "" ); // cleanup reserved word
// native engine
cols = "name, id";
systemOutput("native [#cols#]", true);
var q_native = QueryExecute(
sql = "SELECT #cols# FROM q",
options = { dbtype: 'query', maxrows=5 }
);
var q_stash = duplicate( q_native );
expect( q_stash.recordcount ).toBe( q_native.recordcount );
// hsqldb engine, coz join
systemOutput("hsqldb", true);
var q_hsqlb = QueryExecute(
sql = "SELECT t1.name FROM q_native t1, q_native t2 WHERE t1.id = t2.id",
options = { dbtype: 'query' }
);
systemOutput( q_hsqlb, true );
expect( q_stash.recordcount ).toBe( q_hsqlb.recordcount );
expect( q_native.recordcount ).toBe( q_hsqlb.recordcount );
expect( q_stash.recordcount ).toBe( q_native.recordcount );
Expand All @@ -32,14 +30,12 @@ component extends="org.lucee.cfml.test.LuceeTestCase" labels="qoq" {
var cols = replaceNoCase( q.columnList, ",unique", "" ); // cleanup reserved word
// native engine
cols = "name, id";
systemOutput("native [#cols#]", true);
var q_native = QueryExecute(
sql = "SELECT #cols# FROM q",
options = { dbtype: 'query', maxrows=5 }
);
var q_stash = duplicate( q_native );
// hsqldb engine, coz join
systemOutput("hsqldb", true);
arguments.q_native = q_native;
var q_hsqlb = QueryExecute(
sql = "SELECT t1.name FROM q_native t1, arguments.q_native t2 WHERE t1.id = t2.id",
Expand All @@ -55,14 +51,12 @@ component extends="org.lucee.cfml.test.LuceeTestCase" labels="qoq" {
var q = extensionList();
var cols = replaceNoCase( q.columnList, ",unique", "" ); // cleanup reserved word
// native engine
systemOutput("native [#cols#]", true);
var q_native = QueryExecute(
sql = "SELECT #cols# FROM q",
options = { dbtype: 'query', maxrows=5 }
);
var q_stash = duplicate( q_native );
// hsqldb engine, coz join
systemOutput("hsqldb", true);
var q_hsqlb = QueryExecute(
sql = "SELECT t1.name FROM q_native t1, q_native t2 WHERE t1.id = t2.id",
options = { dbtype: 'query' }
Expand All @@ -73,33 +67,28 @@ component extends="org.lucee.cfml.test.LuceeTestCase" labels="qoq" {
expect( q_stash.recordcount ).toBe( q_native.recordcount );
});

it( title='QoQ select * from table same source table name (all cols) HSQLDB', body=function() {
var q = extensionList();
var cols = replaceNoCase( q.columnList, ",unique", "" ); // cleanup reserved word
// native engine
q = QueryExecute(
sql = "SELECT #cols# FROM q",
options = { dbtype: 'query' }
);
// hsqldb engine, coz join
q = QueryExecute(
sql = "SELECT t1.name FROM q t1, q t2 WHERE t1.id = t2.id",
options = { dbtype: 'query' }
);
it( title='QoQ select * from table same source table name (all cols) HSQLDB, 5000 threads', body=function() {

var arr = [];
ArraySet(arr, 1, 1000, 0);
arrayEach(arr, function(){
var q = extensionList();
var cols = replaceNoCase( q.columnList, ",unique", "" ); // cleanup reserved word
// native engine
q = QueryExecute(
sql = "SELECT #cols# FROM q",
options = { dbtype: 'query' }
);
// hsqldb engine, coz join
q = QueryExecute(
sql = "SELECT t1.name FROM q t1, q t2 WHERE t1.id = t2.id",
options = { dbtype: 'query' }
);
}, true);

});
});

}

private function getDummyData (){
var q = queryNew("id,name,data","integer,varchar, varchar");
loop list="micha,zac,brad,pothys,gert" item="n" index="i" {
var r = queryAddRow(q);
querySetCell(q, "id", r, r)
querySetCell(q, "name", n, r)
querySetCell(q, "data", repeatString("lucee",1000), r);
}
return q;
}

}

0 comments on commit b1aebaf

Please sign in to comment.