Expiring Messages

When rows are deleted from a window, some queries may need to be re-evaluated.

If you have a query that calculates the sum of the prices in a window, then when a row expires, the price in that row should be subtracted from the sum of the prices in the window. Thus if you have a query on a window, each row that arrives in that window may generate two output messages: one for the arriving row and one for the expiring row.

Let's look at an example. Here, two windows are created and a set of queries is created when the output of one window is fed to another window:

CREATE WINDOW StockTradeHistory
SCHEMA ...
KEEP 8 HOURS;
-- Query #1: Insert source data into "history" window.
INSERT INTO StockTradeHistory 
SELECT * 
FROM NYSEStockTrades;
-- Query #2: Process data from "history" window and 
-- generate output.
INSERT INTO OutputStream...
SELECT StockSymbol, AVG(Price)
FROM StockTradeHistory 
KEEP LAST PER StockSymbol GROUP BY StockSymbol;

As you can see, the output of the last query depends upon the contents of the StockTradesHistory window. When a new row arrives in the NYSEStockTrades stream and is put into the StockTradeHistory window, we should calculate a new average price, and when a stock trade's information expires from the StockTradeHistory window, the window will calculate a new average price based on the remaining rows in the window.

If this window directly feeds another window, then when a row from this window expires, the window sends a "delete" message to the second (downstream) window, telling that window to delete its copy of the row.

When one window sends another window a "delete this row" notice, we refer to the notice as a "negative tuple" (because it cancels out the original "positive tuple").

When a User-Defined Function is called from a CCL statement, the function may be passed either a positive tuple or a negative tuple. If you write your own output adapter to subscribe to a stream, your adapter may receive negative tuples and will need to handle them properly. In many cases, all you need to do is determine that the tuple is a negative tuple and then discard it, but in some cases your adapter, like a query, may want to pass on or act upon that negative tuple. To learn how your adapter can recognize that a tuple is negative, see User-Defined Aggregate Functions in the C/C++ SDK chapter.