Skip to content

Commit

Permalink
LDEV-5023 test case for qoq regression
Browse files Browse the repository at this point in the history
  • Loading branch information
zspitzer committed Jul 16, 2024
1 parent a5318fc commit fa195b2
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 7 deletions.
24 changes: 17 additions & 7 deletions core/src/main/java/lucee/runtime/db/HSQLDBHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
import lucee.runtime.type.StructImpl;
import lucee.runtime.type.dt.TimeSpan;
import lucee.runtime.type.util.CollectionUtil;

import lucee.aprint;
/**
* class to reexecute queries on the resultset object inside the cfml environment
*/
Expand Down Expand Up @@ -374,6 +374,8 @@ private static Struct getUsedColumnsForQuery(Connection conn, SQL sql) {

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

aprint.o(sql.toString());

try {
Statement stat = conn.createStatement();
stat.execute("CREATE VIEW " + view + " AS " + sql.toString()); // + StringUtil.toUpperCase(sql.toString()));
Expand Down Expand Up @@ -403,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 @@ -569,27 +571,35 @@ 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);
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());
while (it.hasNext()) {
cfQueryName = it.next().toString();// tables.get(i).toString();
dbTableName = cfQueryName.replace('.', '_');
if (qoqTables.contains(dbTableName)){
aprint.o("duplicate table name!!");
}

// this could match the wrong strings??
modSql = StringUtil.replace(sql.getSQLString(), cfQueryName, dbTableName, false);
sql.setSQLString(modSql);
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);
}
if (sql.getItems() != null && sql.getItems().length > 0) sql = new SQLImpl(sql.toString());
// temp tables still get created will all the source columns,
// only populateTables is driven by the required columns calculated from the view
createTable(conn, pc, dbTableName, cfQueryName, doSimpleTypes);
qoqTables.add(dbTableName);
}

// SystemOut.print("QoQ HSQLDB CREATED TABLES: " + sql.toString());


// create the sql as a view, to find out which table columns are needed
Struct allTableColumns = getUsedColumnsForQuery(conn, sql);
Expand Down
105 changes: 105 additions & 0 deletions test/tickets/LDEV5023.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
component extends="org.lucee.cfml.test.LuceeTestCase" labels="qoq" {

function run( testResults , testBox ) {

describe( title='QofQ' , body=function(){

it( title='QoQ select * from table same source table name HSQLDB', body=function() {
var q = extensionList();
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);
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 );
});

it( title='QoQ select * from table same source table name (arguments) HSQLDB', body=function() {
var q = extensionList();
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",
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 );
});

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

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

}

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 fa195b2

Please sign in to comment.