I have been experimenting with pre-query and post-query and I hope you guys can explain this behaviour.
Either the debugger is not working correct or the pre-query is not working as it should.
Simple master-detail. Order - Order lines. I want to total the order line sale value. So I tried the following

pre-query event executes procedure which does select sum(sale_price) from order_lines where order_no=:order_no.
I have 3 order lines for this order.

Is the pre-query expected to be executed for each row or only once just before the execute_query on the datasource is executed?

The debugger shows that the pre-query event is done twice. Please explain.

Now I tried a post-query. This adds for each row the sale value to a non datasource field on the screen.
1. This does not work as soon as there is more than 1 order line. The debugger shows
The first execution and does add the value. The second execution raises an error "no current row". "Force current row" is not selected in the datasource. There is no post-query for the third row. I did try "force current row" but that makes no difference.

The Pre-Query fires once per query execution. There might be several reasons why it fires more than once. For example, is the Query On Initialize box checked in your datasource? If it is, the datasource will execute its query when it is initialized the first time. This usually happens when a panel which has a component that is bound to the datasource is initialised i.e. referenced the first time (usually by being shown on the screen). Then the datasource will also execute its query the second time because the developer calls the api_datasource.executeQuery API. We recommend developers to uncheck the Query On Initialize checbox when building applications.

But I'd like go beyond debugging this issue. This might be a personal choice but I try to stay away from pre-query and post-query triggers. If there is a piece of code that I want to execute every time I run the api_datasource.executeQuery API then I simply create a wrapper procedure executeQueryOnDatasource1 which both calls the executeQuery API and runs the piece of code that I want to execute.

This makes maintenance of the code much easier down the road. If there is an issue with that part of the application 6 months after the project is over, you or whoever is now responsible of maintenance will probably forget that there is a pre-query event on the datasource and be puzzled by the unexpected behaviour.

If I don't use pre-query triggers or any other stuff that triggers itself behind the scenes. This way when I look at my code, I see everything that is happening right in front me and don't need to worry about code that is executing magically behind the scenes.