Bug 438257 - Visibility expression on table based on COUNT aggregate not working since BIRT 4.3.0
Summary: Visibility expression on table based on COUNT aggregate not working since BIR...
Status: NEW
Alias: None
Product: z_Archived
Classification: Eclipse Foundation
Component: BIRT (show other bugs)
Version: 4.3.0   Edit
Hardware: PC Windows 7
: P3 major with 2 votes (vote)
Target Milestone: ---   Edit
Assignee: Birt-ReportEngine-inbox@eclipse.org CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-06-26 08:19 EDT by Henning von Bargen CLA
Modified: 2014-07-01 08:27 EDT (History)
2 users (show)

See Also:


Attachments
Report demonstrating the problem (11.17 KB, application/octet-stream)
2014-06-26 08:19 EDT, Henning von Bargen CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Henning von Bargen CLA 2014-06-26 08:19:19 EDT
Created attachment 244548 [details]
Report demonstrating the problem

Our reports often contain "detail tables".
E.g. based on the ClassicModels demo database, a master-detail report showing customers and their corresponding orders.

For a customer without orders, the report should hide the "orders" table (otherwise it would still show the table header).

The usual way to achieve this is to
- create a COUNT aggregate "AggrCount" on the detail tables binding tab.
- as visibility expression for the table, use !AggrCount.

This works with BIRT 3.7.1 and 4.2.1.

However, with BIRT 4.3.0 and BIRT 4.3.2, the AggrCount contains the value 1 instead of 0, and thus the report output is incorrect (still shows the empty table).

I'll add an example report.
Notify the customer 125 "Havel & Zbyszek Co" on page 2 in the PDF output.
For this customer, there are no orders.
However, the yellow table header is still shown.

This is incorrect behavior in BIRT >= 4.3
Comment 1 Henning von Bargen CLA 2014-06-26 08:24:57 EDT
Note:
The error does not occur if the "expression" field of the COUNT aggregate binding is not empty, e.g. with an expression row["CUSTOMERNUMBER"]

Nevertheless, I think this is an undesired change in behavior and should be fixed.
Searching and modifying hundres of existing reports is not really an option.
Comment 2 Henning von Bargen CLA 2014-06-26 08:38:02 EDT
Another possible workaround is to use this visibility expression instead
(works with 4.3.0 and 4.2.1):

0 != row[0]

// row[0] contains the "row index": 0,1,2,....
// If there are no rows, the value is -1. 

But what is the "official way" to hide a table/list if the data set doesn't contain rows?

And anyway, COUNT should return 0 if there are no rows.
In 4.3, COUNT returns 1 in this case (discovered with our logging framework).
Comment 3 vlad dev CLA 2014-07-01 06:50:51 EDT
It looks like you have to specify an expression in the aggregation binding "Count":
<structure>
	<property name="name">Count</property>
	<property name="dataType">integer</property>
	<property name="aggregateFunction">COUNT</property>
	<list-property name="arguments">
		<structure>
			<property name="name">Expression</property>
			<expression name="value" type="javascript">row["ORDERNUMBER"]</expression>
		</structure>
	</list-property>
	<property name="allowExport">true</property>
</structure>

The COUNT function behaves bad without an expression.
Comment 4 Henning von Bargen CLA 2014-07-01 07:49:39 EDT
Yes, I know (see comment 2).

But this is still different behavior in comparison to BIRT 4.2.1 and to the SQL analogon SELECT COUNT(*) FROM ... which counts just the rows.

Whereas the query SELECT COUNT(COLUMN_X) FROM ... counts the rows where COLUMN_X is not null. I guess this is the same with in BIRT.

This makes a huge difference if there isn't a NOT NULL column in the select list.
Comment 5 vlad dev CLA 2014-07-01 08:01:18 EDT
Sorry, I have overseen your second comment. 

As a workaround for datasets that don't have a not nullable column, you can use an implicit __rownum column in the COUNT function expression:
row.__rownum
Comment 6 Henning von Bargen CLA 2014-07-01 08:27:14 EDT
Well, using row.__rownum is similar to using row[0] (see comment 2 again).

Neither trick seems to be well-documented, and I'm a bit pessimistic here: maybe in one of the next version the developers consider this a bug instead of a feature.

That's why I asked for the official way to do this.

And anyway, it's only a workaround for the regression.