=== modified file 'src/com/goldencode/p2j/persist/AbstractQuery.java'
--- src/com/goldencode/p2j/persist/AbstractQuery.java	2023-04-05 18:08:41 +0000
+++ src/com/goldencode/p2j/persist/AbstractQuery.java	2023-04-11 11:35:07 +0000
@@ -233,6 +233,7 @@
 **                           does not match.   Also, buffer match check must include the DMO alias.
 ** 088 CA  20230323          Prevent NPE if the field in EXCEPT/FIELDS can't be resolved in that buffer.
 ** 089 IAS 20230405          Fixed FILL support for recursive DATA-RELATION
+** 090 AL2 20230411          Support query close listeners.
 */
 
 /*
@@ -379,6 +380,9 @@
    /** Registry of listeners who are notified of query is about to (re-)open. */
    private List<QueryOpenListener> openListeners = null;
    
+   /** Registry of listeners who are notified of query is about to close. */
+   private List<QueryCloseListener> closeListeners = null;
+   
    /** Flag to avoid infinite recursion in reposition notification */
    private boolean notificationActive = false;
    
@@ -974,6 +978,25 @@
    }
    
    /**
+    * Adds a listener to be notified when this query is about to close.
+    * <p> 
+    * Note that this method is only called for dynamic queries only (for the moment).
+    *
+    * @param   listener
+    *          The listener to be notified.
+    */
+   @Override
+   public void addQueryCloseListener(QueryCloseListener listener)
+   {
+      if (closeListeners == null)
+      {
+         closeListeners = new LinkedList<>();
+      }
+   
+      closeListeners.add(listener);
+   }
+   
+   /**
     * Notifies the registered QUERY-OPEN listeners that the event is about to happen.
     *  
     * @param    evaluate
@@ -994,6 +1017,22 @@
    }
    
    /**
+    * Notifies the registered QUERY-CLOSE listeners that the event is about to happen.
+    */
+   @Override
+   public void notifyQueryCloseListeners()
+   {
+      if (closeListeners != null)
+      {
+         Iterator<QueryCloseListener> iter = closeListeners.iterator();
+         while (iter.hasNext())
+         {
+            iter.next().onQueryClose();
+         }
+      }
+   }
+   
+   /**
     * Register a listener to receive notifications reposition events for this
     * query.
     *

=== modified file 'src/com/goldencode/p2j/persist/DynamicQueryHelper.java'
--- src/com/goldencode/p2j/persist/DynamicQueryHelper.java	2023-02-28 21:09:24 +0000
+++ src/com/goldencode/p2j/persist/DynamicQueryHelper.java	2023-04-11 11:34:37 +0000
@@ -84,6 +84,7 @@
 **     SVL 20230113 Improved performance by replacing some "for-each" loops with indexed "for" loops.
 **     CA  20230116 Avoid using handle.unwrap, handle.getReference or other BDT usage from within FWD runtime.
 ** 043 OM  20230215 Handled collision of temporary buffers and tables with same name.
+** 044 AL2 20230411 Ensure delayed execute is run only once. The flag is reset on query close. 
 */
 
 /*
@@ -625,22 +626,32 @@
          
          if (processor.delayedExecute() && query0 != null)
          {
+            boolean[] executedOnce = new boolean[1];
             query0.addQueryOpenListener((evaluate) -> 
             {
-               interpreter.processInstancesWith((o) -> 
+               if (!executedOnce[0] || evaluate)
                {
-                  if (o instanceof P2JQuery)
+                  executedOnce[0] = true;
+                  interpreter.processInstancesWith((o) -> 
                   {
-                     ((P2JQuery) o).setDynamicPredicate(query0.isDynamicPredicate());
-                  }
-               });
-               interpreter.interpret("execute");
+                     if (o instanceof P2JQuery)
+                     {
+                        ((P2JQuery) o).setDynamicPredicate(query0.isDynamicPredicate());
+                     }
+                  });
+                  interpreter.interpret("execute");
+               }
                
                if (evaluate)
                {
                   interpreter.evaluateDynamicCalls();
                }
             });
+            
+            query0.addQueryCloseListener(() -> 
+            {
+               executedOnce[0] = false;
+            });
          }
          return query0;
       }

=== modified file 'src/com/goldencode/p2j/persist/P2JQuery.java'
--- src/com/goldencode/p2j/persist/P2JQuery.java	2023-03-28 11:01:11 +0000
+++ src/com/goldencode/p2j/persist/P2JQuery.java	2023-04-11 11:35:49 +0000
@@ -134,6 +134,7 @@
 **                           buffer list).
 **     OM  20220112          Added default implementation for new property 'fillingBrowseRows'.
 ** 062 IAS 20230105          Fixed FILL support for recursive DATA-RELATION
+** 063 AL2 20230411          Added query close listeners.
 */
 
 /*
@@ -2273,6 +2274,16 @@
    public default void addQueryOpenListener(QueryOpenListener qol) {}
    
    /**
+    * Adds a listener to be notified when this query is about to be closed.
+    * <p> 
+    * Note that this method is only called for dynamic queries only (for the moment).
+    *  
+    * @param   qcl
+    *          The listener to be notified.
+    */
+   public default void addQueryCloseListener(QueryCloseListener qcl) {}
+   
+   /**
     * Notifies the registered QUERY-OPEN listeners that the even is about to happen.
     * 
     * @param    evaluate
@@ -2280,6 +2291,11 @@
     *           in the WHERE clause. 
     */
    public default void notifyQueryOpenListeners(boolean evaluate) {}
+   
+   /**
+    * Notifies the registered QUERY-CLOSE listeners that the even is about to happen.
+    */
+   public default void notifyQueryCloseListeners() {}
 
    /**
     * Getter for the BASIC-LOGGING attribute.
@@ -2359,6 +2375,17 @@
       public void onQueryOpen(boolean evaluate);
    }
    
+   /**
+    * Interface for receiving query close events. 
+    */
+   public interface QueryCloseListener
+   {
+      /**
+       * Implement this method to receive the notification that the query IS ABOUT TO close.
+       */
+      public void onQueryClose();
+   }
+   
    /** 
     * Get the recursive DATA-RELATION the query is to FILL for.  
     * @return the recursive DATA-RELATION the query is to FILL for

=== modified file 'src/com/goldencode/p2j/persist/QueryWrapper.java'
--- src/com/goldencode/p2j/persist/QueryWrapper.java	2023-04-05 18:08:41 +0000
+++ src/com/goldencode/p2j/persist/QueryWrapper.java	2023-04-11 11:33:20 +0000
@@ -277,6 +277,7 @@
 **     HC  20230118          Eliminated some of the uses of String.toUpperCase and/or
 **                           String.toLowerCase for performance.
 ** 094 IAS 20230405          Fixed FILL support for recursive DATA-RELATION
+** 095 AL2 20230411          Notify query close listeners.
 */
 
 /*
@@ -3779,6 +3780,11 @@
    {
       boolean success = true;
 
+      if (delegate != null)
+      {
+         delegate.notifyQueryCloseListeners();
+      }
+      
       try
       {
          close();

