Esper: find earliest event within time after a trigger event arrives - esper

My event stream generally contains an open event followed by a close event. Let's call them O and C, correspndingly. However, there are two particulars:
O may be followed by one or more O before C arrives
C may be missing completely (see below)
It is assumed that C should arrive not later than within time T after some O. Otherwise, C is considered missing. When a C eventually arrives, all open Os arrived earlier than T from this C are considered orphans and are of no interest.
I want esper to fire each pair of O followed by C, where earliest O not farther then T from C is selected. Any Os in between as well as before selected O are skipped.
For example,
O1 O2 O3 ... C
should select (O1,C) if datediff(O1, C) < T
should select (O2,C) if above is false and datediff(O2, C) < T
etc.
A lost my temper in approaching this problem. Looks like my mind is not compatible with esper. Your help is very appritiated.

This could be something like below, the idea is that when Event arrives we want to look at the last 1 minute of events and find the first one that matches the time diff. Have a second statement filter out those without matches, if that is desired.
insert into Pair
select , (select window().firstOf(v => v.time - e2.time < T) from Event.win:time(1 min) as e1) as matched
from Event as e2
select * from Pair where matched is not null

Related

Count how many times esper receives different inherit events.

I'm new using Esper and I have been able to manage with it until now. There is something that I can't find solution and I have tried to find everywhere with no success.
I have three Classes extending one to other one.
Using Esper Online:
create schema A(symbol string, price double);
create schema B() inherits A;
create schema C() inherits B;
Now I want to count how many of each events in a time window of 2 seconds I have received, using the next EPL statement:
select COALESCE(a.symbol,b.symbol,c.symbol) as symbol, count(a) as total_a, count(b) as total_b, count(c) as total_c from pattern [every a=A or every b=B or every c=C]#time(2 seconds) group by COALESCE(a.symbol,b.symbol,c.symbol);
And I run the next events:
A={symbol='X', price=1}
B={symbol='X', price=1}
C={symbol='X', price=1}
C={symbol='X', price=1}
The problem is when I send a B event, it counts a B event and an A event due to inheritance , and obviously if I send a C event it counts a C a B and also an A event.
I have used the pattern-level annotation #SuppressOverlappingMatches it works with inheritances, but Time Windows doesn't work with it.
Try this.
select count(*, typeof(a)='A') as cnt_a, count(*, typeof(a)='B') as cnt_b,
count(*, typeof(a)='C') as cnt_c from A#time(2 sec) as a

In a doubly linked list, How many pointers are affected on an insertion operation?

I had an interview yesterday. As it started, the first thing that the interviewer asked was
" In a doubly linked list, How many pointers will be affected on an insertion operation ? "
Since, he didn't specifically asked where to insert I replied that it depends on how many nodes are there in DLL.
As total pointers that will be affected will depend on whether the list is empty or not and where insertion takes place.
But, he didn't say anything whether I had convinced him or not.
Was I correct or maybe I missed something ?
I think the answer depends on whether we are inserting the new node in the middle of the list (surrounded by two nodes), or at the head or tail of the list.
For insertions in the middle of the list, to splice in a new node as follows:
A --- B
^^ splice M in here
A.next = M
M.prev = A
B.prev = M
M.next = B
Hence four pointer assignments take place. However, if the insertion be at the head or tail, then only two pointer assignments would be needed:
TAIL (insert M afterward)
TAIL.next = M
M.prev = TAIL

What would be the most efficient way to shift objects in a Lua table based on choosing a slot?

I have a table of objects, and a user can choose an object in the table at any given order in the table and place it in another slot in the table. When that happens I need the table to shift from the selected dropped slot and fill the empty slot. Not a swap, that's easy, but a shift at the point of placement.
so if I have this as a highly simplified example of my table
t = {a, b, c, d, e, f}
and the user chooses, say e, and wants to drop it into slot b. how best would I
have e take the b slot
have all the values from "b to d shift right and then also fill
the empty e slot?
how would I handle this shift no matter what one is chosen and where
its moved in the table efficiently no matter what size the table
might be?
Here is an implementation of shift using table.move which is efficient and available in Lua 5.3 as #lhf mentioned:
function shift(t, old, new)
local value = t[old]
if new < old then
table.move(t, new, old - 1, new + 1)
else
table.move(t, old + 1, new, old)
end
t[new] = value
end
If you want to move the item at position old to position new as you describe, you can use this:
table.insert(t, new, table.remove(t,old))
Here is your example:
t = {10,20,30,40,50,60}
print(table.concat(t, ','))
old = 5
new = 2
table.insert(t, new, table.remove(t,old))
print(table.concat(t, ','))
As for efficiency, the code above does shift some elements twice when they could have stayed where they were, but this will probably not matter unless the table is huge.
In Lua 5.3, you can probably do something better with table.move.

Can you use the JD Edwards Update command to change a field that is also part of the WHERE clause?

In JD Edward's One World (E1) package, is it possible to use the built in Update table function to update a particular field that is also used in the where clause?
The use case is that I am executing a batch process that loops through a series of "unprocessed" records and after processing them, updates the table to show a "processed" status. There are three statuses (Processed, Unprocessed, and Ignored). During my update, I can't simply update all flags to "Processed" without accidentally updating the ones labeled "Ignored".
If PO cProcessedFlag is equal to "U"
Table1.Select
Table1.Fetch Next
While SV File_IO_Status is equal to CO SUCCESS
...
Table1.Fetch Next
End While
End If
Table1.Update
I need to be able to update the processed field here (Table1.Update) while also being able to specify where the field is not "I".
You can select and update records at the same time. No problem doing this (Assuming that DOCO is the primary key of Table1):
Table1.Select
PO cProcessedFlag = BC cProcessedFlag
Table1.Fetch Next
VA mnOrderNumber[DOCO] <- BC mnOrderNumber[DOCO]
While SV File_IO_Status is equal to CO SUCCESS
...
Table1.Update
VA mnOrderNumber[DOCO] = VA mnOrderNumber[DOCO]
ā€œPā€ -> BC cProcessedFlag
Table1.Fetch Next
VA mnOrderNumber[DOCO] <- BC mnOrderNumber[DOCO]
End While
When you write code in ER, the middleware will actually perform an open, select, close etc. for each tableIO. So the handle for the second Table1.FetchNext is very different to the open, select, update, close generated for the Table1.Update

ISQL Perform instruction: after editadd editupdate of table vs. after add update of table

INFORMIX-SQL 7.3 Perform Screens:
According to documentation, in an "after editadd editupdate of table" control block, its instructions are executed before the row is added or updated to the table, whereas in an "after add update of table" control block, its instructions are executed after the row has been added or updated to the table. Supposedly, this would mean that any instructions which would alter values of field-tags linked to table.columns would not be committed to the table, but field-tags linked to displayonly fields will change?
However, when using "after add update of table", I placed instructions which alter values for field-tags linked to table.columns and their displayed and committed values also changed! I would have thought that an "after add update of table" would only alter displayonly fields.
TABLES
customer
transaction
branch
interest
dates
ATTRIBUTES
[...]
q = transaction.trx_type, INCLUDE=("E","C","V","P","T"), ...;
tb = transaction.trx_int_table,
LOOKUP f1 = ta_days1_f,
t1 = ta_days1_t,
i1 = ta_int1,
[...]
JOINING *interest.int_table, ...;
[...]
INSTRUCTIONS
customer MASTER OF transaction
transaction MASTER OF customer
delimiters ". ";
AFTER QUERY DISPLAY ADD UPDATE OF transaction
if z = "E" then let q = "E"
if z = "C" then let q = "C"
if z = "1" then let q = "E"
[...]
END
Is 'z' a column in the transaction table?
Is the trouble that the value in 'z' is causing a change in the value of 'q' (aka transaction.trx_type), and the modified value is being stored in the database?
Is the value in 'z' part of the transaction table?
Have you verified that the value in the DB is indeed changed - using the Query Language option or a simple (default) form?
It might look as if it is because the instruction is also used AFTER DISPLAY, so when the values are retrieved from the DB, the value displayed in 'q' would be the mapped values corresponding to the value stored in 'z'. You would have to inspect the raw data to hide that mapping.
If this is not the problem, please:
Amend the question to show where 'z' comes from.
Also describe exactly what you do and see.
Confirm that the data in the database, as opposed to on the screen, is amended.
Please can you see whether this table plus form behaves the same for you as it does for me?
Table Transaction
CREATE TABLE TRANSACTION
(
trx_id SERIAL NOT NULL,
trx_type CHAR(1) NOT NULL,
trx_last_type CHAR(1) NOT NULL,
trx_int_table INTEGER NOT NULL
);
Form
DATABASE stores
SCREEN SIZE 24 BY 80
{
trx_id [f000]
trx_type [q]
trx_last_type [z]
trx_int_table [f001 ]
}
END
TABLES
transaction
ATTRIBUTES
f000 = transaction.trx_id;
q = transaction.trx_type, UPSHIFT, AUTONEXT,
INCLUDE=("E","C","V","P","T");
z = transaction.trx_last_type, UPSHIFT, AUTONEXT,
INCLUDE=("E","C","V","P","T","1");
f001 = transaction.trx_int_table;
INSTRUCTIONS
AFTER ADD UPDATE DISPLAY QUERY OF transaction
IF z = "E" THEN LET q = "E"
IF z = "C" THEN LET q = "C"
IF z = "1" THEN LET q = "E"
END
Experiments
[The parenthesized number is automatically generated by IDS/Perform.]
Add a row with data (1), V, E, 23.
Observe that the display is: 1, E, E, 23.
Exit the form.
Observe that the data in the table is: 1, V, E, 23.
Reenter the form and query the data.
Update the data to: (1), T, T, 37.
Observe that the display is: 1, T, T, 37.
Exit the form.
Observe that the data in the table is: 1, T, T, 37.
Reenter the form and query the data.
Update the data to: (1), P, 1, 49
Observe that the display is: 1, E, 1, 49.
Exit the form.
Observe that the data in the table is: 1, P, 1, 49.
Reenter the form and query the data.
Observe that the display is: 1, E, 1, 49.
Choose 'Update', and observe that the display changes to: 1, P, 1, 49.
I did the 'Observe that the data in the table is' steps using:
sqlcmd -d stores -e 'select * from transaction'
This generated lines like these (reflecting different runs):
1|V|E|23
1|P|1|49
That is my SQLCMD program, not Microsoft's upstart of the same name. You can do more or less the same thing with DB-Access, except it is noisier (13 extraneous lines of output) and you would be best off writing the SELECT statement in a file and providing that as an argument:
$ echo "select * from transaction" > check.sql
$ dbaccess stores check
Database selected.
trx_id trx_type trx_last_type trx_int_table
1 P 1 49
1 row(s) retrieved.
Database closed.
$
Conclusions
This is what I observed on Solaris 10 (SPARC) using ISQL 7.50.FC1; it matches what the manual describes, and is also what I suggested in the original part of the answer might be the trouble - what you see on the form is not what is in the database (because of the INSTRUCTIONS section).
Do you see something different? If so, then there could be a bug in ISQL that has been fixed since. Technically, ISQL 7.30 is out of support, I believe. Can you upgrade to a more recent version than that? (I'm not sure whether 7.32 is still supported, but you should really upgrade to 7.50; the current release is 7.50.FC4.)
Transcribing commentary before deleting it:
Up to a point, it is good that you replicate my results. The bad news is that in the bigger form we have different behaviour. I hope that ISQL validates all limits - things like number of columns etc. However, there is a chance that they are not properly validated, given the bug, or maybe there is a separate problem that only shows with the larger form. So, you need to ensure you have a supported version of the product and that the problem reproduces in it. Ideally, you will have a smaller version of the table (or, at least, of the form) that shows the problem, and maybe a still smaller (but not quite as small as my example) version that shows the absence of the problem.
With the test case (table schema and Perform screen that shows the problem) in hand, you can then go to IBM Tech Support with "Look - this works correctly when the form is small; and look, it works incorrectly when the form is large". The bug should then be trackable. You will need to include instructions on how to reproduce the bug similar to those I gave you. And there is no problem with running two forms - one simple and one more complex and displaying the bug - in parallel to show how the data is stored vs displayed. You could describe the steps in terms of 'Form A' and 'Form B', with Form A being Absolutely OK and Form B being Believed to be Buggy. So, add a record with certain values in Form B; show what is displayed in Form B after; show what is stored in the database in Form A after too; show that they are not different when they should be.
Please bear in mind that those who will be fixing the issue have less experience with the product than either you or me - so keep it as simple as possible. Remove as many attributes as you can; leave comments to identify data types etc.

Resources