For a rule application, the types of data you include in an event structure and the event sources are application dependent. Rules Manager makes use of the Oracle rich type system to support rules applications involving complex data types such as XML, Spatial, and Text. Similarly, it leverages from its integration with the database to capture transactional and non-transaction modifications to the data as the source of events.
This chapter discusses various event and rule class configurations that provide the ultimate flexibility in designing rules applications in the database.
The rule applications considered so far use rule conditions that you define on some application data. That is, the concept of an event instance exists in the application and it may or may not be stored in the database. Often however, the data in the event instances correspond to some rows stored in relational tables. For such applications, you can use the row identifiers (ROWIDs) of these rows to pass the data by reference to the Rules Manager procedures, for example, using the
event_inst parameter to represent an event instance of the
PROCESS_RULES call (
event_inst => :FlightDataRowid). For this purpose, you should model the corresponding event structure using Expression Filter's table alias constructs. See the
ADD_ELEMENTARY_ATTRIBUTE procedure for more information. See Section 10.2 and Appendix A for more examples.
For the travel services application considered in Section 2.4, if you store the
AddRentalCar primitive events in two relational tables
RentalCarData respectively, you can create the corresponding composite event structure to refer to rows in these tables as follows:
BEGIN DBMS_RLMGR.CREATE_EVENT_STRUCTURE (event_structure => 'TSCompEvent'); DBMS_RLMGR.ADD_ELEMENTARY_ATTRIBUTE ( event_structure => 'TSCompEvent', attr_name => 'Flt', --- Prim event name tab_alias => rlm$table_alias('FlightData')); DBMS_RLMGR.ADD_ELEMENTARY_ATTRIBUTE ( event_structure => 'TSCompEvent', attr_name => 'Car', --- Prim event name tab_alias => rlm$table_alias('RentalCarData')); END;
Now you can use the composite event structure
TSCompEvent to configure a rule class (Same as step 2 in Section 2.4.1). The representation of the rules in the rule class does not vary with this event structure. However, within the action callback procedure, the primitive event instances that match a rule are each passed in as ROWIDs from the corresponding tables and you use these ROWIDs to obtain the original event data. Also, with this new event structure, the primitive event instances, for which the rules are processed, are passed in by reference using the ROWIDs for the corresponding table rows.
BEGIN dbms_rlmgr.process_rules ( rule_set_nm => 'TravelPromotion', event_type => 'FlightData', event_inst => :FlightDataRowid); -- rowid of a row --- END;
Note that you evaluate the conditions corresponding to a primitive event when the
dbms_rlmgr.process_rules procedure is invoked with the appropriate ROWID. However, Rules Manager does not keep track of any changes to the original row through an
Optionally, you can eliminate the
PROCESS_RULES call by configuring the preceding rule class to consider all the DML (
DELETE) operations on the corresponding tables as events. This is done using the
CNFEVENTS property at the time of rule class creation. (See Section 3.7 and Section 3.8).
When the duration and consumption policies are set for the primitive events derived from relational data, it is the references to the table rows that are consumed or deleted from the rule class. The original rows are not affected by these event management policies.A composite event structure can be formed using a combination of table alias constructs and embedded abstract data types (ADTs) (for various primitive events). The rule conditions defined for a composite event structure consisting of one or more table alias constructs may not use the (short form of) the
SEQUENCE property to enforce sequencing among primitive events (see Section 5.2). This is because the implicit attribute
rlm$crttime may not exist for the rows stored in the relational tables. You can enforce partial sequencing using the join property in the rule conditions.
You can use the
XMLType data type supplied by Oracle Database to create attributes in the event structures and rule classes that can process rules defined on XML documents. For this purpose, a primitive event structure can be created with one or more
XMLType attributes (along with some non-XML attributes), such as the following:
CREATE or REPLACE TYPE AddFlight AS OBJECT ( CustId NUMBER, Airline VARCHAR(20), FromCity VARCHAR(30), ToCity VARCHAR(30), Depart DATE, Return DATE, Details sys.XMLType)
If a primitive event is just an XML document, then the preceding object type can be created with just one attribute, that is of
XMLType. You specify the predicates on the
XMLType attributes using the
EXISTSNODE operators supplied by Oracle, as shown in the following example.
<condition> <!-- optional for conditions on primitive events --> Airline='Abcair' and ToCity='Orlando' and EXTRACT(doc, '/preferences/seat[@class="economy"]') is not null </condition>
You can form a composite event structure for XML events by including two or more primitive event types that contain an
XMLType attribute. So, you create the composite event structure as an object type with embedded primitive event types (as described in Section 2.4). Once you create the event structures with
XMLType attributes, all the other concepts described in Section 2.2 apply to the XML data that is part of the events.
For a better understanding of how XPath predicates are handled and how they are indexed, see Chapter 13.
Note:The Oracle Spatial or the Locator components must be installed in order to use spatial predicates in stored expressions.
SDO_GEOMETRY data type supplied by Oracle Database can be used to create event structures and rule classes that can process rules defined on spatial geometries. For this purpose, you can create a primitive event structure with one or more attributes of the
MDSYS.SDO_GEOMETRY type, as follows:
CREATE or REPLACE TYPE AddHotel AS OBJECT ( CustId NUMBER, Type VARCHAR(20), CheckIn DATE, CheckOut DATE, Location MDSYS.SDO_GEOMETRY)
In order to specify predicates on the spatial attributes and index them for efficiency, you should associate the geometry metadata describing the dimension, lower and upper bounds, and tolerance in each dimension with each spatial geometry attribute. You can insert this metadata information into the
USER_SDO_GEOM_METADATA view using the event structure name in the place of the table name. For more information on the
USER_SDO_GEOM_METADATA view and its semantics, see Oracle Spatial Developer's Guide.
INSERT INTO user_sdo_geom_metadata VALUES ('ADDHOTEL','LOCATION', mdsys.sdo_dim_array( mdsys.sdo_dim_element('X', -180, 180, 0.5), mdsys.sdo_dim_element('Y', -90, 90, 0.5)), 8307);
When you use the event structure with spatial attribute to create a rule class, the rule conditions stored in the rule class table can include predicates in these attributes using
SDO_RELATE operators, as shown in the following examples:
<condition> Type = 'Luxury' and CheckOut-CheckIn > 3 and SDO_WITHIN_DISTANCE (Location, SDO_GEOMETRY(2001, 8307, SDO_POINT_TYPE(-77.03644, 37.89868, NULL), NULL, NULL), 'distance=0.5 units=mile') = 'TRUE' </condition>
<condition> Type = 'Luxury' and CheckOut-CheckIn > 3 and SDO_RELATE (Location, SDO_GEOMETRY(2001, 8307, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 3), SDO_ORDINATE_ARRAY(-77.03644, 37.89868, -75, 39), 'mask=anyinteract') = 'TRUE' </condition>
You can form a composite event structure involving spatial attributes by including two or more primitive event structures that contain
SDO_GEOMETRY attributes. In the case of rules specified for composite events, the spatial predicates involving
SDO_RELATE operators are not allowed in the join clause of the rule condition. If needed, you can use functions defined in the
MDSYS.SDO_GEOM package to achieve this functionality. See Oracle Spatial Developer's Guide for additional information.
You can configure the event structure associated with a rule class for one or more text attributes such that the corresponding rule conditions may include text predicates on these attributes. You specify the text predicates in the rule conditions using the Oracle Text
CONTAINS operator. The
CONTAINS operator refers to the text attribute defined in the event structure and applies a text query expression on the documents bound to this attribute.
You can define the text attributes in an event structure to be of CLOB or VARCHAR data type with associated text preferences. You can create such attributes using the
DBMS_RLMGR.ADD_ELEMENTARY_ATTRIBUTE procedure. You specify the text preferences for an attribute using an instance of
EXF$TEXT type, which accepts the text preferences in string format, for example: (LEXER hotelreserv_lexer WORDLIST hotelreserv_wordlist). Use the preferences specified through this argument for parsing the document bound to the attribute and for indexing the text query expressions within the rule conditions. Alternately, you can assign an
EXF$TEXT instance with an empty preferences string to use default preferences.
For the travel services application considered in Section 2.4, if each hotel reservation includes some addition information, you can model the
AddHotel event structure as follows.
BEGIN DBMS_RLMGR.CREATE_EVENT_STRUCT (EVENT_STRUCT => 'AddFlight'); DBMS_RLMGR.ADD_ELEMENTARY_ATTRIBUTE ( EVENT_STRUCT => 'AddHotel', ATTR_NAME => 'CustId', ATTR_TYPE => 'NUMBER'); DBMS_RLMGR.ADD_ELEMENTARY_ATTRIBUTE ( EVENT_STRUCT => 'AddHotel', ATTR_NAME => 'Type', ATTR_TYPE => 'VARCHAR2(20)'); . . . DBMS_RLMGR.ADD_ELEMENTARY_ATTRIBUTE ( EVENT_STRUCT => 'AddHotel', ATTR_NAME => 'AddlInfo', ATTR_TYPE => 'CLOB', TEXT_PREF => EXF$TEXT('LEXER hotelreserv_lexer')); END;
The rule conditions specified for the previous event structure can now include text predicates on the
AddlInfo attribute shown as follows.
Type = 'Luxury' and CONTAINS (AddlInfo, 'Disney World') = 1
The event structure created with one or more text attributes could be part of composite event structure so that you can specify the text predicates on the individual primitive events as follows.
<condition> <and equal="Car.CustId, Hotel.CustId"> <object name="Car"> carType = 'Luxury' </object> <object name="Hotel"> Type = 'Luxury' and CONTAINS (AddlInfo, 'Disney World') = 1 </object> </and> </condition>
In the case of rules specified for composite events, the predicates involving text attributes are not allowed in the join clauses of the rule condition. The use of
CONTAINS operator is only valid within the primitive event conditions. The text predicates in the rule conditions are processed using the
CTXRULE index that is implicitly created for each text attribute. Unlike other forms of indexes, the
CTXRULE index is not transactional in nature. That is, any modifications made to the rule conditions are not automatically reflected in the corresponding
CTXRULE indexes. This could result in incorrect matching of events with rule conditions until you synchronize the text indexes with the updated rule conditions. You can synchronize all the text indexes associated with a rule class with the following command.
BEGIN DBMS_RLMGR.SYNC_TEXT_INDEXES (rule_class => 'CompTravelPromo'); END;
The user must have the
EXECUTE privilege on the
CTX_DDL package in order to run the previous command.
Often there is a need to add rules to the rule class and keep them disabled. Such rules still belong to the rule class and they can be enabled at a later point in time. For this purpose, you can create a rule class table with
DBMS_RLMGR.CREATE_RULE_CLASS procedure that implicitly has an
rlm$enabled column in which to store the status of each rule. In the case of a rule class resulting from an upgrade of an Oracle 10g database, this column does not exist and thus the rules in such rule classes cannot be disabled. The
rlm$enabled column in the rule class table defaults to a value of
Y to indicate that a rule by default is always enabled. Optionally, a value
N can be assigned to this column during the insert of a new rule or update of an existing rule. A rule with
N assigned to the
rlm$enabled column is disabled and it cannot match any incoming events. Any modification to the
rlm$enabled column (to enable or disable the rule) or a modification to the rule condition itself discards any intermediate state information associated with the rule. In effect, when an existing rule is enabled after being disabled, it is equivalent to a new rule with no prior state information.
The rules defined for composite events have conditions on individual primitive events and a join condition that relates these primitive events. In many rule-based applications, multiple rule conditions involving composite events use the same conditional expressions on the primitive events. For example, in the Travel Services application described in Section 2.4, a vacation in Orlando is defined as a round trip to Orlando with a minimum stay of 4 days (ToCity = 'Orlando' and Return-Depart >= 4). The same vacation in the Orlando scenario can be combined with a primitive event condition capturing a Luxury car rental and another condition capturing a car rental with a child seat option to form two different rule conditions. For such applications, Rules Manager has provisions to share parts of the rule condition across rules by using references into primitive rule condition repositories. Within a repository, each primitive rule condition has a unique identifier that can be referenced from one or more rules sharing the primitive condition. The ability to share primitive conditions simplifies the construction of the rule conditions for composite events and also allows managing them as one logical unit for any modifications made to the shared primitive rule condition.
The shareable rule conditions are associated with a primitive events structure and they do not belong to a particular rule class. So, a common list of rule conditions defined for a primitive event structure can be shared across multiple rules in a rule class as well as rules defined in multiple rule classes (configured with the same primitive event structure).
In addition to the basic steps for creating the event structure, the rule class, and the action callback procedure, a rules application with sharable primitive rule conditions has the following steps:
BEGIN dbms_rlmgr.create_conditions_table( cond_table => 'FlightConditions', pevent_struct => 'AddFlight'); END;
The previous step creates a relational table to store the primitive rule conditions. This table is created with the user-specified name (
FlightConditions) and it has a set of columns to store the unique identifier (primary key) for each rule condition (
rlm$condid), the rule conditions (
rlm$condition), and their descriptions in plain text (
rlm$conddesc).At the time of operation, if the primitive event structure specified for the primitive event argument is just an object type in the database and thus not associated with a rule class, the object type is converted into an event structure and it is later assigned as expression metadata to the
Note:There can only be at most one primitive rule conditions table associated with an event structure.
Insert a primitive rule condition into the table created in Step 1. The values stored in the condition column (
rlm$condition) are automatically validated using the event structure associated with it.
INSERT INTO FlightConditions (rlm$condid, rlm$conddesc, rlm$condition) VALUES ('OrlandoVacation', 'Vacation in Orlando', 'ToCity = ''Orlando'' and Return-Depart >= 4');
Once you create one or more rule classes using the primitive event structure (
AddFlight), the rules added to the rule classes can refer to the conditions in the corresponding primitive rule conditions table (
FlightConditions). This is done by assigning the primary key of a shared primitive rule condition to the ref attribute of the corresponding object element within the rule condition.
INSERT INTO CompTravelPromo (rlm$ruleid, promoType, offeredBy, rlm$rulecond) VALUES ('PARKS_PROMO', 'TICKETS','THEME_PARKS_ASSOC', '<condition> <and join="Flt.CustId = Car.CustId"> <object name="Flt" ref="OrlandoVacation"/> <object name="Car" ref="LuxuryCarRental"/> </and> </condition>');
In the previous rule definition, the primitive rule condition references OrlandoVacation and LuxuryCarRental are resolved through the event structure names (
AddRentalCar respectively) to the corresponding primitive rule condition tables and the primary keys within those tables. Multiple rules in the
CompTravelPromo table can refer to the same primitive rule condition.
The primitive rule condition references within a rule condition for composite event are resolved at the time of rule definition. The runtime characteristics of such rules are similar to those of rules with in-place primitive rule conditions and the steps involved in evaluating the rules remain unchanged.
Note:When a primitive condition that is shared by one or more rules is updated, the changes are propagated to all the rules referring to it. Effectively, the rules themselves are considered updated and any intermediate state associated with these rules is discarded.
A primitive rule condition cannot be deleted when one or more rules in one or more rule classes refer to it. You cannot use a
SQL DROP TABLE command to drop the primitive rule conditions table. You must use the
DBMS_RLMGR.DROP_CONDITIONS_TABLE procedure instead. A primitive conditions table may not be truncated (with
SQL TRUNCATE TABLE command) if a rule class is configured with the corresponding primitive event structure.
The list of rule conditions that have references to conditions defined in a conditions table can be obtained by joining the rule class table with the condition table using a join predicate with the
DBMS_RLMGR.CONDITION_REF function. Given a rule condition and a primitive event name, this function returns the identifier (key) for the condition reference. This function returns
NULL if the rule condition does not use a reference for that primitive event. The following query identifies all the rule conditions that refer to any shared conditions stored in the
select ctp.rlm$ruleid from CompTravelPromo ctp, FlightConditions fc where dbms_rlmgr.condition_ref(ctp.rlm$rulecond, 'FLT') = fc.rlm$condid;
The previous query uses a functional index defined to retrieve rows from the rule class table based on the condition references they use. Note that if the rule class is configured for duplicate primitive events of the same type, the previous query should include multiple join predicates (combined with disjunctions). Also note that the primitive event name passed to the
CONDITION_REF function must be case-sensitive for the previous query to benefit from the functional index. When a primitive event name requires quotes to preserve the case or special characters in the name, the quoted name must be passed to the
Note:When a rule class with one or more condition references is exported, the corresponding conditions tables are not automatically exported. The conditions table can be explicitly exported using the tables clause of the EXPORT command. The conditions tables are implicitly included in a schema export. During an IMPORT operation, all the references in the rule conditions are resolved using the conditions table that existed prior to import or that are exported with the rule class. The import of a rule class fails with an ORA-41704 error message when one of its rules refers to a missing conditions table or a condition. In such cases, the rules with invalid references are marked invalid by storing the value
Funder the corresponding
When the event structure used for a rule class is defined with one or more table alias attributes, the rule class can be configured to treat all INSERT, UPDATE, and DELETE operations on the underlying tables as the events for which the rules are evaluated (see Section 3.7 and Section 4.1). You specify this using the
DMLEVENTS property at the time of rule class creation. In this case, the row level triggers on the relational tables capture the events and invoke the
PROCESS_RULES procedure from within the trigger body. As the rules are processed as part of DML operations, this configuration poses some restrictions on the types of rule actions possible (for example, rule actions cannot commit) and the
AUTOCOMMIT policy for the rule class. Also, a long running transaction holding some locks on the matching rules in a rule class can often lead to deadlocks.
Identifying the events after committing the DML operations is often desirable to avoid the side effects of
DMLEVENTS configuration. Rules Manager provides an option to process the rules for the net data changes within a transaction after the end of the transaction. In this case, Rules Manager makes use of the continuous query notification (formerly database change notification) feature (see Oracle Database Advanced Application Developer's Guide) to receive notifications of net data changes (within a transaction) after the end of each transaction. These notifications are used to capture the modified rows or the event data and match them with the rules in the rule class.
A rule class using an event structure with one or more table alias attributes can be configured for continuous query notification (CNF) events with the
CNFEVENTS property at the time of rule class creation. The rule class can be configured to treat just INSERT notifications or all INSERT, UPDATE, and DELETE notifications as events with CNFEVENTS="I" or CNFEVENTS="IUD" specifications respectively. The configuration CNFEVENTS="I" is ideal for append-only databases. The user creating a rule class with the
CNFEVENTS property should be granted the
CHANGE NOTIFICATION privilege and the execute privilege on the
DBMS_CHANGE_NOTIFICATION package. A rule class cannot be configured for both DML events and CNF events. Using a combination of table alias and embedded primitive event types in the composite event structure, a rule class can be configured to obtain a subset of the events automatically through continuous query notification while others are explicitly added by the application.
Unlike in the case of
DMLEVENTS, where the rules are processed synchronously with a DML operation, a
CNFEVENTS configuration processes the rules asynchronously after the commit of a transaction. Since the order in which the continuous query notifications for a set of transactions are processed is not guaranteed, rules that are sensitive to the order of events may yield inconsistent results. Also, the version of the row picked up at the time of rule evaluation could be different from the version of the row at the end of transaction (with potential race conditions). By picking the latest version of the row for rule evaluation, it is ensured that the rule class with CNFEVENTS="IUD" configuration has the correct persistent state information after all the events (notifications) are processed.
A class of rule-based applications requires support for conditional expressions on collections of events as opposed to individual events. The rule conditions in such applications compute aggregate values over a finite but potentially large number of primitive events of the same type and specify predicates on the resulting aggregates. For this purpose, primitive events of a specific type are grouped based on certain event attributes and aggregate operators such as
COUNT on the other event attributes are used to apply predicates. For example, a rule condition may test the sum of amounts transferred from a particular account. In this scenario, if each bank transaction is an individual event, these events are grouped based on the account identifier and the predicate is specified on the sum of the amounts (
SUM(amount) > 10000).
Rules Manager supports aggregate operators in rule conditions with the use of collection events. A collection event consists of one or more primitive events of a specific type grouped by one or more event attributes and optionally satisfying user-specified conditions described with the having clause and/or a text node within the collection element. For example, a collection event could represent a set of BankTransaction events that share a common account identifier attribute and for a withdrawal type. The items needed to define a collection event include at least one primitive event structure, a composite rule class enabled for collection events, a composite event, and a named collection specified by a
<collection> element in a rule condition as follows:
<condition> <collection name="bank" groupby = "subjectId" having = "SUM(amount) > 10000"> tranType = 'Withdrawal' </collection> </condition>
name attribute of the
<collection> element restricts the type of primitive events considered for the collection and the value specified for the
groupby attribute combined with predicates on the other event attributes define the properties that are common across all the primitive events in the collection. The
having attribute specifies the aggregate predicates that should be evaluated for the events in the collection. A rule condition involving a
<collection> element can be viewed as operating as a standard SQL query with WHERE, GROUP BY and HAVING clauses. For example, the preceding rule condition can be mapped to the following SQL query on the conceptual Transactions table.
SELECT DISTINCT subjectId FROM Transaction WHERE tranType = 'Withdrawal' GROUP BY subjectId HAVING SUM(amount) > 10000
In the preceding rule condition, each bank transaction primitive event is tested for the
Withdrawal transaction type and the matching primitive events are grouped based on their
subjectId attribute resulting in one collection event for each distinct
The primitive events participating in a particular collection may be further restricted using moving window semantics. Rules Manager supports two types of moving windows with collection events:
Fixed window length: The window length for a collection is specified as
n units of time (fraction of a day). A collection with a fixed window length only consists of the primitive events that are generated within the last
n units of time. Any primitive event generated prior to this time are not considered for evaluating the aggregate conditions. With a
windowlen="1" specification in the following example, the SUM is computed only for the bank transactions that are generated within 24 hours of the last event in the collection. This rule identifies the situation where over $10,000 is withdrawn from an account within the past 24 hours.
<condition> <collection name="bank" groupby = "subjectId" having = "SUM(amount) > 10000" windowlen ="1"> tranType = 'Withdrawal' </collection> </condition>
Fixed window size: The window size for a collection is specified as
n number of primitive events. A collection with a fixed window size specification only consists of the most recent
n primitive events that belong in that collection. With a
windowsize="10" specification in the place of the
windowlen specification in the preceding example would compute the SUM for the last 10 withdrawal transactions for each account.
With some restrictions, a rule condition can combine a collection event with other collection events or primitive events to form composite events involving collections (see Section 5.6). You can use the basic rule condition syntax for composite events to relate one collection with other events within a composite event.
Unlike in the case of rule conditions involving set semantics (see Section 5.4), the number of primitive events participating in the rule conditions through collections is not restricted by the event structure definition. A subset of the primitive event types within a composite event are configured for collections and each rule condition in the corresponding rule class can consider varying number of primitive events using varying window specifications. Consider a Law enforcement application that relates BankTransaction, Transportation, and FieldReport events to raise some security alerts (see Section 10.1). In this application, if there is a need to specify aggregate predicates on BankTransaction events, the rule class created with the LawEnforcement composite event structure should be configured as follows.
BEGIN DBMS_RLMGR.CREATE_RULE_CLASS( rule_class => 'LawEnforcementRC', event_struct => 'LawEnforcement', action_cbk => 'LawEnforcementCBK', actprf_spec => 'actionType VARCHAR2(40), actionParam VARCHAR2(100)', rslt_viewnm => 'MatchedCriteria', rlcls_prop => '<composite equal="bank.subjectId, transport.subjectId, fldrpt.subjectId" ordering="rlm$rule.rlm$ruleid, bank.subjectId, transport.subjectId"> <collection type = "BankTransaction" groupby = "subjectId, tranType"/> </composite>'); END; /
For each primitive event type participating in collections, the rule class properties should include a
<collection> element with the name of the type and a
groupby specification. The
groupby specification lists all possible
groupby attributes expected with this primitive event. The rule class created with the preceding command can include rule conditions that group bank transactions just on the
transType attributes or a combination of these two attributes, (
transType). Note that grouping of events could also be based on some expression involving the attributes in the event structure. For example, if some rules need to group the events based on the region from which the events originated, a user defined function, which maps a country to a broader region can be included in the
groupby specification. (Example:
groupby = "subjectId, tranType, regionOf(fundFrom)" ).
The use of a
<collection> element in the place of an
<object> element in rule class properties enables the specific event type for collections. The
<collection> element can also include the attributes that are allowed with the
<object> elements such as
duration. A rule class configured for collection events internally uses some additional database objects to maintain the incremental state information pertaining to collections. Such rule classes can store and manage rule conditions involving individual events as well as those involving collection events.
When a rule class is configured for collections involving specific primitive event type, the corresponding rules can create collection events out of individual primitive event instances using the
<collection> element within the rule condition syntax for composite events. The rule condition syntax for collection events has provisions for grouping a set of primitive events to form collection events and for testing aggregate predicates on these events. The attributes over which the primitive events are grouped is a subset of the attributes listed in the rule class properties for the given event type. Each rule in the rule class may use a different
groupby specification for the collection event. The aggregate predicates for the collection events are specified using the SQL operators
COUNT for counting the number of events,
AVG for computing the average value for an attribute,
SUM for computing the sum of certain attribute,
MIN for computing the minimum values for an attribute, and
MAX for computing the maximum values for an attribute. The aggregate predicates expressed in SQL-HAVING clause syntax are assigned to the
having attribute of the
<condition> <collection name="bank" groupby = "subjectId" having = "SUM(amount) > 10000 or COUNT(*) > 10" windowlen ="1"> tranType = 'Withdrawal' </collection> </condition>
Unlike the primitive events that are shared across multiple rules that match the event, a collection event is specific to the rule matching it. Based on the number of unique combinations of the attributes the primitive events are grouped on, one rule condition may have multiple collection events associated with it. These collection events are maintained as some primitive events are added to the collection or (dropped for the collection owing to window specification). Each collection event and the corresponding aggregate values are computed incrementally and the resulting state is stored persistently in the database. Note that the aggregate values are computed only upon the arrival of a new event and a primitive event dropping out of a window due to elapsed time does not force the computation.
When a rule condition involving collections evaluates to true, the corresponding action can be executed using the action callback mechanism or the results views as discussed in Section 2.4 and Section 2.6. For the action execution, an instance of the collection event is passed into the callback procedure. The collection event is of the same type as the primitive events of which it consists. However, in the collection event, only the attributes on which the events are grouped (native attributes from the collections's
GROUP BY clause) are initialized, while the rest are each set to
NULL. For example, a collection event matching the previous rule condition will be an instance of BankTransaction type that only has the
subjectId (known to be common across all primitive events in the collection) initialized. In order to provide access to the aggregate values computed for the collection event, the action callback procedure (and the results view) is created with an additional argument for passing in the collection event identifier (
ROWID type). This event identifier is passed into the
DBMS_RLMGR.GET_AGGREGATE_VALUE call to fetch the computed values for an aggregate function such as
CREATE OR REPLACE PROCEDURE LawEnforcementCBK ( bank BankTransaction, bank_evtid ROWID, -- event identifier for the "bank" collection events -- transport Transportation, fldrpt FieldReport, rlm$rule LawEnforcementRC%ROWTYPE) IS BEGIN .. dbms_rlmgr.get_aggregate_value(rule_class => 'LawEnforcementRC', event_ident => bank_evtid, aggr_func => 'SUM(amount)'); END;
Note that the
DBMS_RLMGR.GET_AGGREGATE_VALUE call returns a non-null value only if the signature of the aggregate function passed in matches one of the aggregate operators computed for that collection.
Since the collection event is created over a period of time, there is no precise timestamp associated with such an event. A null value is stored in its
rlm$CrtTime (timestamp) attribute and thus operations involving this attribute (such as
SEQUENCE) are invalid. For the same reason, a duration policy that is specified as elapsed time has no impact on collection events. Note that when you configure the rule class with
TRANSACTION event duration policies, the collection events are also expired at the end of
TRANSACTION respectively. Since a collection event is private to a rule, consuming such an event (using an
RULE consumption policy) will reset the collection (empty the collection) and does not impact the number of rules that are executed. Recall that when multiple rules evaluate to true with a primitive event (no use of collections), consuming the event by one or more of these matching rules will automatically stop the action execution for the other rules.
When the rule conditions with collection constructs coexist with the rule conditions with individual primitive events (no collections), the consumption of the primitive events owing to the
RULE consumption policy does not drop the primitive event from the existing collection events. Similarly, when the primitive events expire due to an elapsed time duration policy, the collection events depending on this event are not impacted.
A rule class can be configured for multiple primitive event types that are collections. However, in this release, the primitive events modeled as table aliases to some relational table cannot be configured as collections. Also, the composite event structure used for the rule class may not have multiple primitive events of the same type.
Tuning a rule class for optimal performance falls into three broad areas:
Choosing the appropriate
In the case of a rule class for composite events, identifying the most-common equality join predicates in all the rule conditions and specifying them using the
EQUAL rule class property is important for performance. Different forms of
EQUAL property specifications and their syntax is discussed in Section 3.4.
Tuning Expression Filter indexes
The indexes used to identify the candidate rules that match a given event can be tuned for better performance.
Creating Rule Class Interface package
A rule class specific interface package helps reduce the overhead involved with the generic interfaces.
A rule class created for simple or composite events implicitly creates one or more Expression Filter indexes to process the rule conditions for incoming events. These default indexes, created at the time of rule class creation, assume that predicates with all scalar attributes in the event structures are equally likely in the rule conditions and this assumption may not hold true for most applications. The performance of a rules application can be improved by tuning the indexes to the specific workload. This is possible either with the domain knowledge or by analyzing a representative workload from the rules application.
When using the domain knowledge to tune the Expression Filter indexes created for a rule class, treat the primitive event structures (or a simple event structure) as the Expression Filter attribute sets (see Section 11.2).
The default index parameters associated with an attribute set can be obtained by querying the
USER_EXPFIL_DEF_INDEX_PARAMS view and they can be changed using the
DBMS_EXPFIL.DEFAULT_INDEX_PARAMETERS call (see Section 12.6). These default index parameters are used any time a corresponding Expression Filter index is created. The default indexes created for a rule class can be dropped using the
DBMS_RLMGR.DROP_EXPFIL_INDEXES call and they can be recreated to use the user assigned index parameters using the
When using a workload to tune Expression Filter indexes created for a rule class, the most common predicate constructs in the rule conditions can be identified by collecting statistics on a representative set of rules already defined in the rule class. The Expression Filter indexes are created from these statistics by setting the
coll_stats argument of the
DBMS_RLMGR.CREATE_EXPFIL_INDEXES call to
When the event structure used for a rule class has one or more XMLType attributes, the default Expression Filter indexes and the indexes created from statistics are not optimized for the XPath predicates on these attributes. Hence, the XPath index parameters should be explicitly assigned to the event structure using the
DBMS_RLMGR.DEFAULT_XPINDEX_PARAMETERS call as discussed in Section 13.2.4.
A way to improve the runtime performance of a rules application is to create a rule class interface package that is specific to the rule class. This avoids the overhead involved in using the generic
DBMS_RLMGR package. The
DBMS_RLMGR procedures used for the run time operations such as processing the rules for some events, consuming the events and resetting the session make use of the rule class name passed in as one of the arguments and map them to the corresponding operations on the rule class. This step can be avoided by creating a rule class interface package that is used to directly operate on the rule class. The rule class interface package is most effective when the rules in the rule class are selective or they often do not match any incoming events. This package is created using the
DBMS_RLMGR.CREATE_INTERFACE call and this has a set of procedures to perform all runtime operations on the rule class. See the
DBMS_RLMGR.CREATE_INTERFACE call in Oracle Database PL/SQL Packages and Types Reference for additional information.
The predicates in a rule condition may use user-defined functions, references to database table data, and database state information. In the case of a condition specified for a simple or a primitive event, the corresponding predicates are evaluated using the state information at the time the event is added to the rule class (using either the
PROCESS_RULES or the
ADD_EVENT call. This is the case even for conditions specified for individual primitive events within a composite event. So, when multiple primitive events are used to capture a composite event, the predicates associated with individual primitive events are evaluated at different times, corresponding to the occurrences of their respective event. Only the predicates specified in the join attribute of the composite condition are evaluated at the time of composite event creation. So, this aspect should be considered when using database state or schema object references in the rule conditions.
When developing rule applications using Rules Manager, rules defined in the rule class can be tested using some hypothetical events. Because these events could match some rules in the rule class partially, they could contribute to the incremental states stored in the database. So before you deploy your application in a production environment, you must purge this partial state information so as not to cause any unexpected rule actions. Use the
DBMS_RLMGR.PURGE_EVENTS procedure call to purge any state information and the events from the database prior to deploying the application in a production environment.