Community
Participate
Working Groups
Note: The following example is nonsense (the actual report where the problem was noticed is too complex to explain or attach here). Consider a master-detail report with an outer List DEPT and an inner Table EMP, bound to corresponding DataSets DEPT resp EMP. (Imagine Oracle's DEPT/EMP demo database) The Table EMP contains a binding named DEPTNO bound to the expression row._outer["DEPTNO"] (so the value is taken from the outer List). The Table EMP also contains an aggregate binding named Count with an aggregate function COUNT and the expression row["DEPTNO"]. The visibility expression for Table EMP is !row["Count"], e.g. we want to show the table iff row["Count"] is empty/zero. Again: This is a non-sensical report, just to demonstrate the error. This report will run into an endless recursion and finally end with a StackOverflowError! The traceback will look like this: Invalid javascript expression: row._outer["DEPTNO"] or StackOverflowError ... at org.eclipse.birt.data.engine.impl.ServiceForQueryResults$EventHandler.popAggrRefFromScriptExpr(ServiceForQueryResults.java:872) at org.eclipse.birt.data.engine.impl.ServiceForQueryResults$EventHandler.popAggrRefFromBaseExpr(ServiceForQueryResults.java:801) at org.eclipse.birt.data.engine.impl.ServiceForQueryResults$EventHandler.popAggrRefFromScriptExpr(ServiceForQueryResults.java:872) at org.eclipse.birt.data.engine.impl.ServiceForQueryResults$EventHandler.popAggrRefFromBaseExpr(ServiceForQueryResults.java:801) at org.eclipse.birt.data.engine.impl.ServiceForQueryResults$EventHandler.popAggrRefFromScriptExpr(ServiceForQueryResults.java:872) at org.eclipse.birt.data.engine.impl.ServiceForQueryResults$EventHandler.popAggrRefFromBaseExpr(ServiceForQueryResults.java:801) and so on. The reason for this seems to be this code in org.eclipse.birt.data.engine.impl/ServiceForQueryResults: private boolean popAggrRefFromScriptExpr( Set aggrReferences, IScriptExpression expr, Map aggrMap ) throws DataException { try { List usedRowReferences = ExpressionUtil.extractColumnExpressions( expr.getText( ) ); boolean result = this.hasDataSetRowReference( expr ); for ( int i = 0; i < usedRowReferences.size( ); i++ ) { Object o = aggrMap.get( ( (IColumnBinding) usedRowReferences.get( i ) ).getResultSetColumnName( ) ); if ( o != null ) { aggrReferences.add( o ); }else { result = result || popAggrRefFromBaseExpr( aggrReferences, this.getBinding( ( (IColumnBinding) usedRowReferences.get( i ) ).getResultSetColumnName( ) ) .getExpression( ), aggrMap ); } } return result; } catch ( BirtException be ) { throw DataException.wrap( be ); } } Since our Aggregate function does not count a column from the dataset (instead, it counts something from _outer indirectly), o is null and popAggrRefFromBaseExpr is called which in turn calls popAggrRefFromScriptExpr and so on forever. I propose to either explicitly support this case or to check this at design time and show an appropriate error message.