Skip to content

Commit

Permalink
LDEV-4868 LDEV-4869 query listener null params
Browse files Browse the repository at this point in the history
  • Loading branch information
zspitzer committed May 23, 2024
1 parent c38997d commit 0667a3f
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 8 deletions.
18 changes: 12 additions & 6 deletions core/src/main/java/lucee/runtime/tag/Query.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import lucee.runtime.config.ConfigWeb;
import lucee.runtime.config.ConfigWebPro;
import lucee.runtime.config.Constants;
import lucee.runtime.config.NullSupportHelper;
import lucee.runtime.db.DataSource;
import lucee.runtime.db.DataSourceImpl;
import lucee.runtime.db.DataSourceSupport;
Expand Down Expand Up @@ -570,7 +571,7 @@ public static int _doEndTag(PageContext pageContext, QueryBean data, String strS

// listener before
if (data.listener != null) {
String res = writeBackArgs(pageContext, data, data.listener.before(pageContext, createArgStruct(data, strSQL, tl)));
String res = writeBackArgs(pageContext, data, data.listener.before(pageContext, createArgStruct(pageContext, data, strSQL, tl)));
if (!StringUtil.isEmpty(res)) strSQL = res;
}

Expand Down Expand Up @@ -778,7 +779,7 @@ else if ((queryResult.getColumncount() + queryResult.getRecordcount()) > 0 && !S
catch (PageException pe) {
if (data.listener != null && data.listener.hasError()) {
long addExe = System.nanoTime();
Struct args = createArgStruct(data, strSQL, tl);
Struct args = createArgStruct(pageContext, data, strSQL, tl);
args.set(KeyConstants._exception, pe.getCatchBlock(pageContext.getConfig()));
ResMeta rm = writeBackResult(pageContext, data, data.listener.error(pageContext, args), setVars);
if (data.result == null || (rm.meta == null && rm.asQueryResult() != null))
Expand Down Expand Up @@ -809,6 +810,8 @@ private static Struct createMetaData(PageContext pageContext, QueryBean data, Qu
Struct meta;
if (data.result != null && queryResult != null) {
meta = new StructImpl();
boolean fns = ((PageContextImpl) pageContext).getFullNullSupport();

meta.setEL(KeyConstants._cached, Caster.toBoolean(queryResult.isCached()));
if ((queryResult.getColumncount() + queryResult.getRecordcount()) > 0) {
String list = ListUtil.arrayToList(queryResult instanceof lucee.runtime.type.Query ? ((lucee.runtime.type.Query) queryResult).getColumnNamesAsString()
Expand Down Expand Up @@ -856,7 +859,8 @@ private static Struct createMetaData(PageContext pageContext, QueryBean data, Qu
Array arr = new ArrayImpl();
meta.setEL(SQL_PARAMETERS, arr);
for (int i = 0; i < params.length; i++) {
arr.append(params[i].getValue());
if (fns) arr.append(params[i].isNulls() ? null: params[i].getValue());
else arr.append(params[i].isNulls() ? "" : params[i].getValue());
}
}
}
Expand All @@ -872,16 +876,18 @@ private static Struct createMetaData(PageContext pageContext, QueryBean data, Qu

private static void callAfter(PageContext pc, QueryBean data, String strSQL, TemplateLine tl, boolean setResult, Object queryResult, Object meta, boolean setVars)
throws PageException {
Struct args = createArgStruct(data, strSQL, tl);
Struct args = createArgStruct(pc, data, strSQL, tl);
if (setResult && queryResult != null) args.set(KeyConstants._result, queryResult);
if (meta != null) args.set(KeyConstants._meta, meta);
writeBackResult(pc, data, data.listener.after(pc, args), setVars);
}

private static Struct createArgStruct(QueryBean data, String strSQL, TemplateLine tl) throws PageException {
private static Struct createArgStruct(PageContext pc, QueryBean data, String strSQL, TemplateLine tl) throws PageException {
Struct rtn = new StructImpl(Struct.TYPE_LINKED);
Struct args = new StructImpl(Struct.TYPE_LINKED);

boolean fns = ((PageContextImpl) pc).getFullNullSupport();

// TODO add missing attrs
set(args, "cachedAfter", data.cachedAfter);
set(args, "cachedWithin", data.cachedWithin);
Expand Down Expand Up @@ -912,7 +918,7 @@ else if (data.items != null) {
SQLItem item;
while (it.hasNext()) {
item = it.next();
params.appendEL(QueryParamConverter.toStruct(item));
params.appendEL(QueryParamConverter.toStruct(item, fns));
}
set(args, KeyConstants._params, params);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,17 @@ public static SQL convert(String sql, Array params) throws PageException {
return convert(sql, items, namedItems);
}

public static Struct toStruct(SQLItem item) {
public static Struct toStruct(SQLItem item, boolean fns) {
Struct sct = new StructImpl();
if (item instanceof NamedSQLItem) {
NamedSQLItem nsi = (NamedSQLItem) item;
sct.setEL(KeyConstants._name, nsi.getName());
}
sct.setEL(KeyConstants._value, item.getValue());
if (fns || item.getValue() != null) sct.setEL(KeyConstants._value, item.getValue() );
else sct.setEL(KeyConstants._value, "");
sct.setEL(KeyConstants._type, SQLCaster.toStringType(item.getType(), null));
sct.setEL(KeyConstants._scale, item.getScale());
sct.setEL(KeyConstants._null, item.isNulls());
return sct;
}

Expand Down
76 changes: 76 additions & 0 deletions test/tickets/LDEV4868.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
component extends="org.lucee.cfml.test.LuceeTestCase" labels="query" {

function beforeAll(){
application enableNullSupport=false;
}


function afterAll(){
application enableNullSupport=true;
}

function run( testResults , testBox ) {
describe( title='LDEV-4868' , body=function(){
it( title='test null query param with value' , body=function() {
var ds = server.getDatasource( service="h2", dbFile=server._getTempDir( "LDEV4868" ) );
var queryArgs = "";
var listener = {
before=function (caller,args) {
queryArgs = args;
}
};
```
<cfquery name="local.q" datasource="#ds#" listener="#listener#" result="local.result">
select <cfqueryparam cfsqltype="cf_sql_integer" null="true" value="5">
</cfquery>
```
/*
systemOutput( queryArgs, true );
systemOutput( "", true );
systemOutput( local.q );
systemOutput( "", true );
systemOutput( local.result );
*/

expect( queryArgs.params[ 1 ] ).toHaveKey( "null" );
expect( queryArgs.params[ 1 ].null ).toBeTrue();
expect( queryArgs.params[ 1 ].value ).toBe( "5" );
expect( result.sqlParameters[1] ).toBe( "" );
expect( q[ q.columnlist ][1] ).toBe( "" );

});

it( title='test null query param with value, full null support' , body=function() {
application enableNullSupport=true;
var ds = server.getDatasource( service="h2", dbFile=server._getTempDir( "LDEV4868" ) );
var queryArgs = "";
var listener = {
before=function ( caller, args ) {
queryArgs = args;
}
};
```
<cfquery name="local.q" datasource="#ds#" listener="#listener#" result="local.result">
select <cfqueryparam cfsqltype="cf_sql_integer" null="true" value="5">
</cfquery>
```
/*
systemOutput( queryArgs, true) ;
systemOutput( "", true );
systemOutput( local.q );
systemOutput( "", true );
systemOutput( local.result );
*/

expect( queryArgs.params[ 1 ] ).toHaveKey( "null" );
expect( queryArgs.params[ 1 ].null ).toBeTrue();
expect( queryArgs.params[ 1 ].value ).toBe( "5" );
expect( isNull( result.sqlParameters[ 1 ] ) ).toBeTrue();
expect( isNull( q[ q.columnlist ][ 1 ] ) ).toBeTrue();

});

});
}

}
76 changes: 76 additions & 0 deletions test/tickets/LDEV4869.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
component extends="org.lucee.cfml.test.LuceeTestCase" labels="query" {

function beforeAll(){
application enableNullSupport=false;
}


function afterAll(){
application enableNullSupport=true;
}

function run( testResults , testBox ) {
describe( title='LDEV-4869' , body=function(){
it( title='test null query param without value' , body=function() {
var ds = server.getDatasource( service="h2", dbFile=server._getTempDir( "LDEV4868" ) );
var queryArgs = "";
var listener = {
before=function (caller,args) {
queryArgs = args;
}
};
```
<cfquery name="local.q" datasource="#ds#" listener="#listener#" result="local.result">
select <cfqueryparam cfsqltype="cf_sql_integer" null="true">
</cfquery>
```
/*
systemOutput( queryArgs, true );
systemOutput( "", true );
systemOutput( local.q );
systemOutput( "", true );
systemOutput( local.result );
*/

expect( queryArgs.params[ 1 ] ).toHaveKey( "null" );
expect( queryArgs.params[ 1 ].null ).toBeTrue();
expect( queryArgs.params[ 1 ].value ).toBe( "" );
expect( result.sqlParameters[1] ).toBe( "" );
expect( q[ q.columnlist ][1] ).toBe( "" );

});

it( title='test null query param without value, full null support' , body=function() {
application enableNullSupport=true;
var ds = server.getDatasource( service="h2", dbFile=server._getTempDir( "LDEV4868" ) );
var queryArgs = "";
var listener = {
before=function ( caller, args ) {
queryArgs = args;
}
};
```
<cfquery name="local.q" datasource="#ds#" listener="#listener#" result="local.result">
select <cfqueryparam cfsqltype="cf_sql_integer" null="true">
</cfquery>
```
/*
systemOutput( queryArgs, true) ;
systemOutput( "", true );
systemOutput( local.q );
systemOutput( "", true );
systemOutput( local.result );
*/

expect( queryArgs.params[ 1 ] ).toHaveKey( "null" );
expect( queryArgs.params[ 1 ].null ).toBeTrue();
expect( isNull( queryArgs.params[ 1 ].value ) ).toBeTrue();
expect( isNull( result.sqlParameters[ 1 ] ) ).toBeTrue();
expect( isNull( q[ q.columnlist ][ 1 ] ) ).toBeTrue();

});

});
}

}

0 comments on commit 0667a3f

Please sign in to comment.