PK
Q;Aoa, mimetypeapplication/epub+zipPK Q;A iTunesMetadata.plistk
Rules Manager contains one predefined type and a public synonym for this type. Table 7-1 describes the Rules Manager object type.
Tip: See the chapter on Rules Manager Types in Oracle Database PL/SQL Packages and Types Reference for all reference information concerning Rules Manager object types. Use the link in the Object Type Name column in Table 7-1 to see the object type. |
Note: Expression indexing is available only in Oracle Database Enterprise Edition. |
You can define an index on a column storing expressions to quickly find expressions that evaluate to true for a data item. This is most helpful when a large expression set is evaluated for a data item. The SQL EVALUATE
operator determines whether or not to use the index based on its access cost. Expression Filter uses the indextype, EXFSYS.EXPFILTER
, to create and maintain indexes.
If an Expression column is not indexed, the SQL EVALUATE
operator builds a dynamic query for each expression stored in the column and executes it using the values passed in as the data item.
This chapter describes the basic approach to indexing including index representation (Section 12.3), index processing (Section 12.4), and user commands for creating and tuning indexes (Section 12.6).
Expressions in a large expression set tend to have certain commonalities in their predicates. An Expression Filter index, defined on an expression set, groups predicates by their commonalities to reduce processing costs. For example, in the case of two predicates with a common left-hand side, such as Year=1998
and Year=1999
, in most cases, the falseness or trueness of one predicate can be determined based on the outcome of the other predicate. The left-hand side of a predicate includes arithmetic expressions containing one or more elementary attributes and user-defined functions, for example, HORSEPOWER(model, year)
. An operator and a constant on the right-hand side (RHS) completes the predicate, for example, HORSEPOWER(model, year)>=150
.
An Expression Filter index defined on a set of expressions takes advantage of the logical relationships among multiple predicates by grouping them based on the commonality of their left-hand sides. These left-hand sides are arithmetic expressions that consist of one or more elementary attributes and user-defined functions, for example, HORSEPOWER(model,year)
.
The predicates that can be indexed with the Expression Filter indexing mechanism include any predicate with a constant on the right-hand side that uses one of the following predicate operators: =
, !=
, >
, <
, >=
, <=
, BETWEEN
, IS NULL
, IS NOT
NULL
, LIKE
, and NVL
.
The predicates that cannot be indexed are preserved in their original form and they are evaluated by value substitution in the last stage of expression evaluation. Some of the predicates that cannot be indexed include:
Predicates with a variable on the right-hand side.
IN
list predicates.
LIKE
predicates with a leading wild-card character.
Duplicate predicates in an expression with the same left-hand side. At most, two predicates with a duplicate left-hand side, for example Year>1995 and Year<2000,
can be indexed if the index is configured for BETWEEN
operators. A predicate with a BETWEEN
operator is treated as two predicates with binary operators, one with the '>='
operator and another with the '<='
operator. See the section about EXF$INDEXOPER for more information about the BETWEEN
operator.
The Expression Filter index uses persistent database objects internally to maintain the index information for an expression set. A relational table called the predicate table captures the grouping information for all the predicates in an expression set. Typically, the predicate table contains one row for each expression in the expression set. However, an expression containing one or more disjunctions (two simple expressions joined by OR
) is converted into a disjunctive-normal form (disjunction of conjunctions), and each disjunction in this normal form is treated as a separate expression with the same identifier as the original expression. The predicate table contains one row for each such disjunction.
The Expression Filter index can be tuned for better performance by identifying the most-common left-hand sides of the predicates (or discriminating predicate groups) in the expression set. The owner of the expression set (or the table storing expressions) can identify the predicate's left-hand sides or automate this process by collecting statistics on the expression set. For each common left-hand side, a predicate group is formed with all the corresponding predicates in the expression set. For example, if predicates with Model
, Price,
and HorsePower(Model, Year)
attributes are common in the expression set, three predicate groups are formed for these attributes. The predicate table captures the predicate grouping information, as shown in Figure 12-1.
For each predicate group, the predicate table has two columns: one to store the operator of the predicate and the other to store the constant on the right-hand side of the predicate. For a predicate in an expression, Expression Filter stores its operator and the right-hand side constant under the corresponding columns of the predicate group. The predicates that do not fall into one of the preconfigured groups are preserved in their original form and Expression Filter stores them in a VARCHAR2
column of the predicate table as sparse predicates. (For the example in Figure 12-1, the predicates on Mileage
and Year
fall in this category.) Expression Filter implicitly treats the predicates with IN
lists and the predicates with a varying right-hand side (not a constant) as sparse predicates. Expression Filter creates native indexes on the predicate table as described in Section 12.4.
To evaluate a data item for a set of expressions, Expression Filter computes the left-hand side of each predicate group in the data item and compares its value with the corresponding constants stored in the predicate table using an appropriate operator. For example, using the predicate table, if HORSEPOWER('TAURUS',2001)
returns 153, then the predicates satisfying this value are those interested in horsepower equal to 153 or those interested in horsepower greater than a value that is below 153, and so on. If the operators and right-hand side constants of the previous group are stored in the G3_OP
and G3_RHS
columns of the predicate table (in Figure 12-1), then the following query on the predicate table identifies the rows that satisfy this group of predicates:
SELECT Rid FROM predicate_table WHERE G3_OP = '=' AND G3_RHS = :rhs_val or G3_OP = '>' AND G3_RHS < :rhs_val or ... -- where :rhs_val is the value from the computation of the left-hand side --
Expression Filter uses similar techniques for less than (<
), greater than or equal to (>=
), less than or equal to (<=
), not equal to (!=
, <>
), LIKE
, IS NULL
, and IS NOT NULL
predicates. Predicates with the BETWEEN
operator are divided into two predicates with greater than or equal to and less than or equal to operators. Expression Filter can configure duplicate predicate groups for a left-hand side if it frequently appears more than once in a single expression, for example, Year >= 1996 and Year <= 2000
.
The WHERE
clause (shown in the previous query) is repeated for each predicate group in the predicate table, and the predicate groups are all joined by conjunctions. When the complete query (shown in the following example) is issued on the predicate table, it returns the row identifiers for the expressions that evaluate to true with all the predicates in the preconfigured groups. For these resulting expressions, Expression Filter evaluates the corresponding sparse predicates that are stored in the predicate table using dynamic queries to determine if an expression is true for a particular data item.
SELECT Rid, Sparse_predicate FROM predicate_table WHERE --- predicates in group 1 (G1_OP IS NULL OR --- no predicate involving this LHS ((:g1_val IS NOT NULL AND (G1_OP = '=' AND G1_RHS = :g1_val or G1_OP = '>' AND G1_RHS < :g1_val or G1_OP = '<' AND G1_RHS > :g1_val or ...) or (:g1_val IS NULL AND G1_OP = 'IS NULL'))) AND --- predicates in group 2 (G2_OP IS NULL OR ((:g2_val IS NOT NULL AND (G2_OP = '=' AND G2_RHS = :g2_val or G2_OP = '>' AND G2_RHS < :g2_val or G2_OP = '<' AND G2_RHS > :g2_val or ...) or (:g2_val IS NULL AND G2_OP = 'IS NULL'))) AND ...
For efficient execution of the predicate table query (shown previously), Expression Filter creates concatenated bitmap indexes on the {Operator, RHS constant}
columns of selected groups. These groups are identified either by user specification or from the statistics about the frequency of the predicates (belonging to a group) in the expression set. With the indexes defined on preconfigured predicate groups, Expression Filter divides the predicates from an expression set into three classes:
Indexed predicates: Predicates that belong to a subset of the preconfigured predicate groups that are identified as most discriminating. Expression Filter creates bitmap indexes for these predicate groups; thus, these predicates are also called indexed predicates. The previous query performs range scans on the corresponding index to evaluate all the predicates in a group and returns the expressions that evaluate to true with just that predicate. Similar scans are performed on the bitmap indexes of other indexed predicates, and the results from these index scans are combined using BITMAP AND
operations to determine all the expressions that evaluate to true with all the indexed predicates. This enables multiple predicate groups to be filtered simultaneously using one or more bitmap indexes.
Stored predicates: Predicates that belong to groups that are not indexed. Expression Filter captures these predicates in the corresponding {Operator,
RHS constant}
columns of the predicate table, with no bitmap indexes defined on them. For all the expressions that evaluate to true with the indexed predicates, the previous query compares the values of the left-hand sides of these predicate groups with those stored in the predicate table. Although Expression Filter creates bitmap indexes for a selected number of groups, the optimizer may choose not to use one or more indexes based on their access cost. Those groups are treated as stored predicate groups. The query issued on the predicate table remains unchanged for a different choice of indexes.
Sparse predicates: Predicates that do not belong to any of the preconfigured predicate groups. For expressions that evaluate to true for all the predicates in the indexed and stored groups, Expression Filter evaluates last sparse predicates (if any). If the expressions with sparse predicates evaluate to true, Expression Filter considers them true for the data item.
Optionally, you can specify the common operators that appear with predicates on the left-hand side and reduce the number of range scans performed on the bitmap index. See EXF$INDEXOPER
for more information. In the previous example, the Model
attribute commonly appears in equality predicates, and you can configure the Expression Filter index to check only for equality predicates while processing the indexed predicate groups. Expression Filter processes and evaluates sparse predicates along with any other form of predicate on the Model
attribute at the same time.
Once the predicate groups for an expression set are determined, the structure of the predicate table and the query to be issued on the predicate table are fixed. The choice of indexed or stored predicate groups does not change the query. As part of Expression Filter index creation, the predicate table query is determined and a function is dynamically generated for this query. Expression Filter uses the same query (with bind variables) for any data item passed in for the expression set evaluation. This ensures that the predicate table query is compiled once and reused for evaluating any number of data items.
The cost of evaluating a predicate in an expression set depends on the group to which it belongs. The index for an expression set can be tuned by identifying the appropriate predicate groups as the index parameters.
The steps involved in evaluating the predicates in an indexed predicate group are:
One-time computation of the left-hand side of the predicate group
One or more range scans on the bitmap indexes using the computed value
The steps involved in evaluating the predicates in a stored predicate group are:
One-time computation of the left-hand side of the predicate group
Comparison of the computed value with the operators and the right-hand side constants of all the predicates remaining in the working set (after filtering, based on indexed predicates)
The steps involved in evaluating the predicates in a sparse predicate group are:
Parse the subexpression representing the sparse predicates for all the expressions remaining in the working set.
Evaluate the subexpression through substitution of data values (using a dynamic query).
Creating an Index from Default Parameters
In a schema, an attribute set can be used for one or more expression sets, and you can configure the predicate groups for these expression sets by associating the default index parameters with the attribute set. The (discriminating) predicate groups can be chosen with the knowledge of commonly occurring left-hand sides and their selectivity for the expected data.
The following command uses the DBMS_EXPFIL.DEFAULT_INDEX_PARAMETERS
procedure to configure default index parameters with the Car4Sale
attribute set:
BEGIN DBMS_EXPFIL.DEFAULT_INDEX_PARAMETERS('Car4Sale', exf$attribute_list ( exf$attribute (attr_name => 'Model', --- LHS for predicate group attr_oper => exf$indexoper('='), attr_indexed => 'TRUE'), --- indexed predicate group exf$attribute (attr_name => 'Price', attr_oper => exf$indexoper('all'), attr_indexed => 'TRUE'), exf$attribute (attr_name => 'HorsePower(Model, Year)', attr_oper => exf$indexoper('=','<','>','>=','<='), attr_indexed => 'FALSE') --- stored predicate group ) ); END; /
For an expression set, create the Expression Filter index as follows:
CREATE INDEX InterestIndex ON Consumer (Interest) INDEXTYPE IS EXFSYS.EXPFILTER;
The index derives all its parameters from the defaults (Model
, Price
, and HorsePower(Model, Year)
) associated with the corresponding attribute set. If the defaults are not specified, it implicitly uses all the scalar elementary attributes (Model
, Year,Price
, and Mileage
) in the attribute set as its stored and indexed attributes.
You can fine-tune the default parameters derived from the attribute set for each expression set by using the PARAMETERS
clause when you create the index or by associating index parameters directly with the expression set. The following CREATE INDEX
statement with the PARAMETERS
clause configures the index with an additional stored predicate:
CREATE INDEX InterestIndex ON Consumer (Interest) INDEXTYPE IS exfsys.ExpFilter PARAMETERS ('ADD TO DEFAULTS STOREATTRS (CrashTestRating(Model, Year))');
For more information about creating indexes from default parameters, see DEFAULT_INDEX_PARAMETERS
Procedure and "CREATE INDEX" in Chapter 15.
Creating an Index from Exact Parameters
If there is a need to fine-tune the index parameters for each expression set associated with the common attribute set, you can assign the exact index parameters directly to the expression set, using the DBMS_EXPFIL.INDEX_PARAMETERS
procedure.
The following commands copy the index parameters from the defaults and then fine-tunes them for the given expression set. An expression filter index created for the expression set uses these parameters to configure its indexed and stored predicate groups.
BEGIN -- Derive index parameters from defaults -- DBMS_EXPFIL.INDEX_PARAMETERS(expr_tab => 'Consumer', expr_col => 'Interest', attr_list => null, operation => 'DEFAULT'); -- Fine-tune the parameters by adding another stored attribute -- DBMS_EXPFIL.INDEX_PARAMETERS(expr_tab => 'Consumer', expr_col => 'Interest', attr_list => exf$attribute_list ( exf$attribute ( attr_name => 'CrashTestRating(Model, Year)', attr_oper => exf$indexoper('all'), attr_indexed => 'FALSE')), operation => 'ADD'); END; / CREATE INDEX InterestIndex ON Consumer (Interest) INDEXTYPE IS EXFSYS.EXPFILTER;
For more information about creating indexes from exact parameters, see INDEX_PARAMETERS
Procedure and "CREATE INDEX" in Chapter 15.
See Chapter 13 for a discussion on indexing expressions with XPath predicates.
Creating an Index from Statistics
If a representative set of expressions is already stored in the table, the owner of the table can automate the index tuning process by collecting statistics on the expression set, using the DBMS_EXPFIL.GET_EXPRSET_STATS
procedure, and creating the index from these statistics, as shown in the following example:
BEGIN DBMS_EXPFIL.GET_EXPRSET_STATS (expr_tab => 'Consumer', expr_col => 'Interest'); END; / CREATE INDEX InterestIndex ON Consumer (Interest) INDEXTYPE IS EXFSYS.EXPFILTER PARAMETERS ('STOREATTRS TOP 4 INDEXATTRS TOP 2');
For the previous index, four stored attributes are chosen based on the frequency of the corresponding predicate left-hand sides in the expression set, and out of these four attributes, the top two are chosen as indexed attributes. When a TOP
n
clause is used, any defaults associated with the corresponding attribute set are ignored. The attributes chosen for an index can be viewed by querying the USER_EXPFIL_PREDTAB_ATTRIBUTES
view.
For more information about creating indexes from statistics, see GET_EXPRSET_STATS
Procedure and "CREATE INDEX" in Chapter 15.
A query using the SQL EVALUATE
operator on an Expression column can force the use of the index defined on such a column with an optimizer hint. (See the Oracle Database Performance Tuning Guide.) In other cases, the optimizer determines the cost of the Expression Filter index-based scan and compares it with the cost of alternate execution plans.
SELECT * FROM Consumer WHERE EVALUATE (Consumer.Interest, Car4Sale.getVarchar('Mustang',2000,18000,22000)) = 1 and Consumer.Zipcode BETWEEN 03060 and 03070;
For the previous query, if the Consumer
table has an Expression Filter index defined on the Interest
column and a native index defined on the Zipcode
column, the optimizer chooses the appropriate index based on their selectivity and their access cost. Beginning with release 10gR2 (10.2), the selectivity and the cost of an Expression Filter index are computed when statistics are collected on the expression column, the index, or the table storing expressions. These statistics are stored in the Expression Filter dictionary and are used to determine the optimal execution plan for the query with an EVALUATE
operator.
You can use the EXPLAIN PLAN
statement to see if the optimizer picked the Expression Filter index for a query.
The Expression Filter index uses persistent database objects to maintain the index on a column storing expressions. All these secondary objects are created in the schema in which the Expression Filter index is created. There are three types of secondary objects for each Expression Filter index, and they use the following naming conventions:
Conventional table called the predicate table: EXF$PTAB_
n
One or more indexes on the predicate table: EXF$PTAB_
n
_IDX_
m
Package called the Access Function package: EXF$AFUN_
n
To ensure the expression evaluation is valid, a table with an Expression column and the Expression Filter index on the Expression column should belong to the same schema. A user with CREATE INDEX
privileges on a table cannot create an Expression Filter index unless the user is the owner of the table. By default, the predicate table is created in the user's default tablespace. You can specify an alternate storage clause for the predicate table when you create the index by using the PREDSTORAGE
parameter clause. (See the section about the CREATE INDEX statement in Chapter 15.) The indexes on the predicate table are always created in the same tablespace as the predicate table.
An Expression Filter index created for an Expression column is automatically maintained to reflect any changes made to the expressions (with the SQL INSERT
, UPDATE
, or DELETE
statements or SQL*Loader). The bitmap indexes defined on the predicate table could become fragmented when a large number of expressions are modified, added to the set, or deleted. You can rebuild these indexes online to reduce the fragmentation using the DBMS_EXPFIL.DEFRAG_INDEX
procedure, as shown in the following example:
BEGIN DBMS_EXPFIL.DEFRAG_INDEX (idx_name => 'InterestIndex'); END; /
See DEFRAG_INDEX
Procedure for more information about this procedure.
You can rebuild the complete Expression Filter index offline by using the ALTER INDEX...REBUILD
statement. This is useful when the index is marked UNUSABLE following a table maintenance operation. When the default index parameters associated with an attribute set are modified, they can be incorporated into the existing indexes using the ALTER INDEX...REBUILD
statement with the DEFAULT
parameter clause. See the section about ALTER INDEX REBUILD statement in Chapter 15.
Expression Filter and Rules Manager features use schema objects to maintain an Expression column in a user table. Most of these objects are created in the schema of the table with the Expression column. Expression Filter creates objects with the EXF$
prefix and Rules Manager creates objects with the RLM$
prefix (). You can use Expression Filter or Rules Manager APIs to maintain these objects. You should not modify these objects.
The Expression Filter maintains the concept of an attribute set through an object type with a matching name, while Rules Manager maintains the concept of an event structure through an object type with a matching name. The object type used for an attribute set or event structure may not contain any user methods, and it should not be an evolved type (with the use of the SQL ALTER TYPE
command). If the attribute set or event structure is not created from an existing object type, Expression Filter or Rules Manager creates the object type with the matching name and maintains it throughout the life of the attribute set or event structure. It also generates functions for the object type for data item management, dynamic expression evaluation, and expression type checking.
In addition to the object type, Expression Filter and Rules Manager create a nested table type of the object type in the same schema. This nested table type uses a namespace EXF$NTT_
n
, and it is used internally for the expression validation.
The object type created for the attribute set or event structure can be used to create a table storing the corresponding data items. Such tables could include a column of the object type or the table itself could be created from the object type. These tables can be joined with the table storing expressions. This is shown in the following example using the application example in Chapter 11:
-- a table of type -- CREATE TABLE CarInventory OF Car4Sale; INSERT INTO CarInventory VALUES ('Mustang',2000, 18000, 22000); INSERT INTO CarInventory VALUES ('Mustang',2000, 18000, 22000); INSERT INTO CarInventory VALUES ('Taurus',1997, 14000, 24500); SELECT * FROM Consumer, CarInventory Car WHERE EVALUATE (Consumer.Interest, Car.getVarchar()) = 1; -- table with the object type column -- CREATE TABLE CarStock (CarId NUMBER, Details Car4Sale); INSERT INTO CarStock VALUES (1, Car4Sale('Mustang',2000, 18000, 22000)); INSERT INTO CarStock VALUES (2, Car4Sale('Mustang',2000, 18000, 22000)); INSERT INTO CarStock VALUES (3, Car4Sale('Taurus',1997, 14000, 24500)); SELECT * FROM Consumer, CarStock Car WHERE EVALUATE (Consumer.Interest, Car.Details.getVarchar()) = 1;
Note: You should not modify the object type used to maintain an attribute set or event structure with the SQLALTER TYPE or CREATE OR REPLACE TYPE commands. System triggers are used to restrict you from modifying these objects. |
Section C.2.1, Section C.2.2, and Section C.2.3 describe some Expression Filter specific information about Expression Filter internal objects.
When you create an Expression column by assigning an attribute set to a VARCHAR2
column in a user table, a BEFORE ROW
trigger is created on the table. Expression Filter uses this trigger to invoke the expression validation routines when a new expression is added or an existing expression is modified. Expression Filter always creates this trigger in the EXFSYS
schema, and it uses the EXF$VALIDATE_
n
namespace.
The Expression Filter index defined for a column is maintained using database objects created in the schema in which the index is created. These are described in Section 12.8.
Expression Filter uses system triggers to manage the integrity of the system. These include system triggers to:
Restrict the user from dropping an object type created by an attribute set
Drop the attribute set and associated metadata when the user is dropped with a CASCADE
option
Maintain the Expression Filter dictionary through DROP
and ALTER
operations on the table with one or more Expression columns
These triggers are created in the EXFSYS
schema.
This section describes new features of Oracle Database 11g Release 2 (11.2) and provides pointers to additional information.
There are no new features for Rules Manager and Expression Filter in Oracle Database 11g Release 2 (11.2).
Obsolescence Notice: Rules Manager and Expression Filter features of Oracle Database are obsolete in the next major release after Oracle Database 11g Release 2 (11.2). Support will only be available for the life of Oracle Database Release11g Release 2. See My Oracle Support Note ID 1244535.1 for more information. |
Rules Manager is a feature of Oracle Database that uses the Expression Filter and object relational features to provide the features of a special-purpose rules engine with greater scalability and better operational characteristics.
Rules Manager uses the following terminology:
An event structure is an object (abstract) type that you define with a set of attributes that describes the specific features of an event. For example, it is the data structure that captures the customer flight information, using variables, such as Airline, Customer Id, From City, and so forth. The object type definition of the AddFlight event structure is as follows:
TYPE AddFlight AS OBJECT ( CustId NUMBER, Airline VARCHAR2(20), FromCity VARCHAR2(30), ToCity VARCHAR2(30), Depart DATE, Return DATE);
An event is the instantiation of the event structure, so each instance of the event structure is an event. For example, these are three events:
AddFlight (123, 'Abcair', 'Boston', 'Orlando', '01-Apr-2003', '08-Apr-2003'); AddFlight (234, 'Acbair', 'Chicago', 'San Jose', '01-Aug-2003', '10-Aug-2003'); AddFlight (345, 'Acbair', 'New York', 'San Jose', '22-Jun-2003', '24-Jun-2003');
Events are classified into two types:
Primitive event — represents an event that is assumed to be instantaneous and atomic in an application. A primitive event cannot be further broken down into other events and it either occurs completely or not at all. Each primitive event is typically bound to a specific point in time. So Rules Manager can fully evaluate the rules defined for the corresponding event structure with the event. For example, the AddFlight
event is an example of a primitive event:
AddFlight (CustId, Airline, FromCity, ToCity, Depart, Return)
Composite event — represents the combination of two or more primitive events. All primitive events included in the composite event can be bound to a time window and thus generated at different points in time. So Rules Manager cannot fully evaluate the rules defined for the composite event structure until all the corresponding primitive events are generated. For example, adding a second primitive event AddRentalCar to the AddFlight primitive event creates a composite event:
AddFlight (CustId, Airline, FromCity, ToCity, Depart, Return) AddRentalCar (CustId, CarType, Checkout, Checkin, Options)
Because evaluation of rules for composite event structures must be deferred until all parts of a composite event are available, Rules Manager provides several ways of efficiently evaluating composite events.
See Section 2.4 for more information about composite events and complex rule applications.
A rule class is a database table that stores and groups a set of rules that share a common event structure. For example, this rule class of three rules is for the AddFlight event structure:
ON AddFlight (CustId, Airline, FromCity, ToCity, Depart, Return) IF Airline = 'Abcair', and ToCity = 'Orlando' THEN OfferPromtion (CustId, 'RentalCar', 'Acar') ON AddFlight (CustId, Airline, FromCity, ToCity, Depart, Return) IF Airline = 'Acbair', and ToCity = 'Houston' THEN OfferPromtion (CustId, 'RentalCar', 'Bcar') ON AddFlight (CustId, Airline, FromCity, ToCity, Depart, Return) IF ToCity = 'Orlando' and Return-Depart >7 THEN OfferPromtion (CustId, 'ThemePark', 'Ocean World')
Rules are evaluated for an instance of the corresponding event structure. For example, the following event is used to evaluate the rules defined using the AddFlight
event structure:
AddFlight (123, 'Abcair', 'Boston', 'Orlando', '01-Apr-2003', '08-Apr-2003');
A rule is a row in a rule class table that has elements consisting of:
The rule condition is a conditional expression formed using the attributes defined in the event structure. For example, the following rule condition use the attributes: Airline, ToCity, Return, and Depart:
Airline = 'Abcair' and ToCity = 'Orlando' and Return-Depart >= 7
The rule action preferences determine the exact action for each rule and specify the details for the action.
Typically, the actions associated with rules in the rule class are homogenous. For example, if you use a rule class to determine the discount offered during a checkout process, each rule in the class is associated with a specific discount percentage. For rules that match an event instance, these values determine the appropriate action for the rule.
Action preferences can come in different forms, such as:
A list of literals bound as arguments to the common procedure, such as:
'RentalCar', 'Acar', 'Bcar',...
Dynamic PL/SQL commands, such as:
BEGIN OfferRentalPromotion(:1,'Acar'); END;
An action callback procedure is a procedure that acts as an entry point for executing actions for all the rules in a rule class. This procedure is implemented to execute the action for each rule in the rule class based on the action preferences associated with the rule and the event attributes. For the previous example, the action callback procedure can be implemented to invoke the OfferPromotion procedure with the appropriate arguments.
A results view configures a rule class for external action execution when the actions for each matching rule cannot be executed by means of an action callback procedure, such as applications that span multiple tiers.
The rules matching an event are available by querying this preconfigured view. Thus, the component issuing the query executes the corresponding actions. This is useful when the action for certain rules is implemented in the application on multiple tiers. See Section 2.6 for more information.
The results from a rule evaluation are available through the results view until the end of the rule session. By default, the database session (from connect to disconnect) is considered the rule session. Alternatively, you can use the reset session procedure (dbms_rlmgr.reset_session( )
) to end a rule session and start a new session within a database session. Note that at the beginning of a rule session, the results view is empty.
Rule class properties define the event management policies that Rules Manager enforces for each rules application. Two main policies discussed in this chapter are consumption and conflict resolution. Consumption refers to whether an event can be used for multiple rule executions or for just a single rule execution (see Section 3.1). Conflict resolution, or ordering, determines the order in which matching rules with various events are to be executed (see Section 3.2). Section 2.5 and Chapter 3 describe the complete set of event management policies that Rules Manager supports.
Rules Manager uses a relational table to hold the contents of a rule class with each row in the table representing a rule. The rule class table minimally has three columns, one for rule identifiers (rlm$ruleid
), one for rule conditions (rlm$rulecond
), and one for the description of the rule (rlm$ruledesc
). In addition, the rule class table can have one or more columns to store rule action preferences.
Figure 2-1 shows a database representation of the TravelPromotion rule class and its rules for processing the AddFlight event instances.
Figure 2-1 Database Representation of Rule Class and Rules
The TravelPromotion rule class consists of the following columns:
rlm$ruleid
— contains the unique rule identifier that identifies each rule within a rule class.
rlm$rulecond
— contains the rule condition describing each rule; in this case, the rule condition, when satisfied, allows the promotion specified to be offered.
rlm$enabled
— contains a value indicating whether the rule added to the rule class is enabled or disabled. A value of Y
indicates the rule is enabled, a value of N
indicates that it is disabled. By default, a rule created with a missing value for the rlm$enabled
column is considered enabled.
PromoType
— contains one action preference that is used when the rule condition is satisfied, and in each case, the action callback procedure is called that executes the actions for the rules in the rule class; in this case, the Promotype
column stores the type of promotion to be offered, such as a car rental promotion or hotel stay promotion. This value is used by the PromoAction
action callback procedure to invoke the OfferPromotion
procedure with the appropriate arguments.
OfferedBy
— contains another action preference that is associated with the previous action preference column; in this case, it contains the name of the company offering the promotion.
rlm$ruledesc
— contains a description of the rule in plain text provided by the person defining the rule.
Each row of the TravelPromotion
rule class table stores an ECA rule. The event structure, defined as an object type in the database, is associated with the rule condition column and this provides the necessary vocabulary for the rule conditions (stored in the column). The event structure, the rule class table, and the action callback procedure are all created as part of rule class creation.
Once you add all the rules to the rule class, events are ready to be processed and rules evaluated. At runtime, each rule in the rule class is processed against each instance of the event structure. When a rule evaluates to true for a particular event, the PromoAction
action callback procedure calls the designated OfferPromotion
procedure using rule action preferences to execute the prescribed action of offering a specific type of promotion from a particular vendor. Rules Manager enforces various event management policies, such as conflict resolution when an event matches more than one rule, or immediate event consumption when the first match is found and no further evaluation is necessary. These and other event management policies are described in more detail in Chapter 3.
Section 2.3, Section 2.6, and Section 2.4 describe the process of creating rules applications that use a simple event, that span multiple tiers, and that use composite events, respectively. Though the basic five steps are the same for all three cases, the details vary, and some additional steps are necessary for multiple tier applications.
The basic steps to create a rules application that uses a simple or non-composite event are as follows:
Create the event structure as an object type in the database.
Using the AddFlight
example, the event structure is defined as:
CREATE TYPE AddFlight AS OBJECT ( CustId NUMBER, Airline VARCHAR2(20), FromCity VARCHAR2(30), ToCity VARCHAR2(30), Depart DATE, Return DATE);
Create the rule class for the event structure.
Note: For successful creation of a rule class, you should have sufficient privileges to create views, object types, tables, packages, and procedures. |
For this example, create the TravelPromotion
rule class for the AddFlight
event structure and define the PromoType
and OfferedBy
columns as its action preferences. This procedure takes the name of the rule class, the name of the existing event structure created in Step 1, the name of the action callback procedure, and the action preference specification as arguments. The action preferences specification defines the data types of action preferences that are associated with each rule in the rule class.
BEGIN dbms_rlmgr.create_rule_class ( rule_class => 'TravelPromotion', event_struct => 'AddFlight', action_cbk => 'PromoAction', actprf_spec => 'PromoType VARCHAR2(20), OfferedBy VARCHAR2(20)'); END;
Rule class creation creates a table to store the corresponding rule definitions and action preferences. The rule class table uses the same name as the rule class and it is created in the user's schema. The rule class table defines three columns to store the rule identifiers, rule descriptions, and the rule conditions. In this example, the table also creates the rule action preferences columns specified with the previous command to store the action preferences.
TABLE TravelPromotion ( rlm$ruleid VARCHAR2(100), rlm$rulecond VARCHAR2(4000), rlm$enabled CHAR(1) DEFAULT 'Y', rlm$ruledesc VARCHAR2(1000), PromoType VARCHAR2(20), OfferedBy VARCHAR2(20));
You can query the table to see the rules defined in the rule class as well as perform SQL INSERT
, UPDATE
, and DELETE
operations to add, update, and delete rules.
Rule class creation implicitly creates the skeleton for a callback procedure to perform the action. The action callback procedure acts as an entry point for executing actions for all the rules in the rule class. The action callback is called once for every rule that matches an event. The implementation of the action callback procedure can rely on values in the event instance and the action preferences associated with the matching rule.
PROCEDURE PromoAction (rlm$event AddFlight, rlm$rule TravelPromotion%ROWTYPE) is BEGIN null; --- The action for the matching rules can be performed here. --- The appropriate action can be determined from the event --- instance and the action preferences associated with each rule. END;
Rule class creation, in this case, creates the action callback procedure with the name the user provides and has two arguments:
The event as an instance of the corresponding object type.
The action preferences as a ROWTYPE
of the corresponding rule class table. The %ROWTYPE
attribute provides a record type that represents a row in a table.
Replace the system-generated callback procedure with the user implementation to perform the appropriate action for each matching rule. The following action callback procedure can be implemented to invoke the OfferPromotion
procedure with arguments obtained from the event instance and the rule definition:
For this example,
PROCEDURE PromoAction ( rlm$event AddFlight, rlm$rule TravelPromotion%ROWTYPE) is BEGIN OfferPromotion (rlm$event.CustId, rlm$rule.PromoType, rlm$rule.OfferedBy); END;
In this example, the procedure OfferPromotion
performs the action and each matching rule provides the appropriate action preferences. Appendix G shows alternate ways for implementing the action callback procedure for a different choice of action preferences.
Add rules to the rule class.
Adding rules consists of using the SQL INSERT
statement to add a row for each rule. Each row inserted typically contains a rule identifier, a condition, and values for action preferences. Insert the following rule into the TravelPromotion
table:
INSERT INTO TravelPromotion (rlm$ruleid, PromoType, OfferedBy, rlm$rulecond) VALUES
('UN_AV_FL', 'Rental Car', 'Acar',
'Airline= ''Abcair'' and ToCity = ''Orlando'' and Return-Depart >= 7
');
Process the rules for an event.
Use the dbms_rlmgr.process_rules( )
procedure to process the rules in a rule class for an event instance. Processing the rules consists of passing in an event instance as a string of name-value pairs (generated using the getVarchar( )
procedure) or as an AnyData
instance for an event consisting of binary data types as described in Section 11.3. Recall that the Oracle supplied getVarchar( )
method is used to represent the data item as string-formatted name-value pairs when this is possible and that AnyData
is an Oracle supplied object type that can hold instances of any Oracle data type, both Oracle supplied and user-defined.
The following example processes the rules in the TravelPromotion
rule class for an AddFlight
event instance using the getVarchar( )
function.
BEGIN
dbms_rlmgr.process_rules (
rule_class => 'TravelPromotion',
event_inst => AddFlight.getVarchar(987, 'Abcair', 'Boston', 'Orlando', '01-APR-2003', '08-APR-2003')
);
END;
The following example processes the rules in the TravelPromotion
rule class for an AddFlight
event instance using the AnyData.ConvertObject( )
procedure.
BEGIN
dbms_rlmgr.process_rules (
rule_class => 'TravelPromotion',
event_inst => AnyData.convertObject(AddFlight(987, 'Abcair', 'Boston', 'Orlando', '01-APR-2003', '08-APR-2003')));
END;
The previous command processes the rules in the TravelPromotion
rule class for an AddFlight
event instance and performs the action associated with each matching rule through the action callback procedure.
Probably the more common types of rules applications are those that use a composite event structure that combines two or more primitive events. Evaluating rule classes for composite events creates additional requirements. Rules Manager addresses these requirements by:
Aggregating events for rule execution
When two or more primitive events are brought together, each primitive event may be generated by the application at different points in time. This often means a rule cannot be evaluated conclusively until all the primitive events are available. Rules Manager manages the primitive events and joins them together before evaluating the rules. Rules Manager hides the complexity of managing composite events by maintaining the association between the primitive events and the composite event. See Chapter 5 for more information.
Maintaining intermediate state of event processing
When composite events are completely formed in the user application, some parts of rule conditions may need to be evaluated repeatedly with some parts of the composite events. This may lead to multiple evaluations of one primitive event for each instance of a second primitive event, and so forth to find matching rules. This evaluation becomes complex very quickly as the number of primitive events exceeds two. XML tags support incremental evaluation of rules for composite events resulting in Rules Manager improving the performance of the system. Rules Manager maintains the intermediate state of rule evaluation persistently for efficient processing. See Section 5.1 for more information.
Note: The intermediate state maintained for a rule is closely related to the corresponding rule condition (for composite events). So, any modifications made to the rule condition (using theUPDATE command) will discard the intermediate state associated with the rule and the state is maintained only for the events processed subsequently. Effectively, updating a rule condition is equivalent to deleting the corresponding rule and inserting a new one. Modifying the rule's action preferences or the rule identifier has no impact on the rule evaluation state. |
Supporting complex rule constructs
Rules Manager enables you to build complex rules with negation, Any n, and Set semantics in conditional expressions. Using XML tags within rule conditions, Rules Manager can support these complex rule constructs that are commonly used in applications. See Chapter 5 for more information.
Setting event management policies
Rules Manager allows an individual with application domain knowledge to declaratively set event management policies for a rules application. Event policies are specified as properties of a rules class when the rule class is created to control the behavior of simple and composite events in the system, and the performance of composite events.
The policies controlling the ordering of rule executions and the reuse of events for multiple rule executions are applicable to an application with simple as well as composite events. Other composite event-specific policies control the aging of the unused events, ordering of events, and the correlation of primitive events within composite events. The event management policies are summarized in Section 2.5 and described in Section 3.1 through Section 3.8.
Note: The EQUAL property must be specified for a rules class if it is configured for composite events. Domain knowledge is needed to identify common equality join predicates that correlate the primitive events for all the rules in a rule class. |
Designing Rules Applications with Composite Events
Developing a rules application for composite events has some similarities with that of developing a database (SQL) application. The event structure definitions in a rules application are similar to table definitions in a database application. SQL queries operating on these tables are similar to the rule conditions defined in a rule class. In a database application, constraints and indexes specific to each application are created for data integrity and performance. Similarly, in the case of a rules application, properties specified for the rule class enforce the event management policies and improve the performance. These rule class properties are summarized in Section 2.5 and described Chapter 3.
The basic steps to create a rules application with composite events are the same as those described for simple events in Section 2.3, with accommodations for multiple primitive events.
The steps to create a rules application with composite events are as follows:
Create the composite event structure as an object type in the database.
First, create each primitive event structure as an object type. For example:
CREATE or REPLACE TYPE AddFlight AS OBJECT ( CustId NUMBER, Airline VARCHAR2(20), FromCity VARCHAR2(30), ToCity VARCHAR2(30), Depart DATE, Return DATE); CREATE or REPLACE TYPE AddRentalCar AS OBJECT ( CustId NUMBER, CarType VARCHAR2(20), CheckOut DATE, CheckIn DATE, Options VARCHAR2(30));
Next, create all the primitive event structures that constitute the composite event as (first level) embedded types in this object type. For example:
CREATE or REPLACE TYPE TSCompEvent AS OBJECT (Flt AddFlight, Car AddRentalCar);
Use the attribute names, Flt
and Car
, in the rule conditions for identifying the predicates on individual primitive events and for specifying join conditions between primitive events; Flt
and Car
are the primitive event variables used for composite events.
Create the rule class for the composite event structure. Configure the rule class for composite events using an XML properties document that is assigned to the properties argument of the dbms_rlmgr.create_rule_class
procedure.
BEGIN
dbms_rlmgr.create_rule_class (
rule_class => 'CompTravelPromo',
event_struct => 'TSCompEvent',
action_cbk => 'CompPromoAction',
rslt_viewnm => 'CompMatchingPromos',
actprf_spec => 'PromoType VARCHAR2(20),
OfferedBy VARCHAR2(20)',
rlcls_prop => '<composite equal="Flt.CustId, Car.CustId"/>'
);
END;
The previous code example creates the rule class for the composite event structure. The rlcls_prop
argument specifies the XML element <composite>
to configure the rule class for composite events. The properties also include an equal specification that identifies the common equality join predicate in all the rules in the rule class. Other critical rule class properties such as consumption, duration, and ordering of events can be specified using the syntax discussed in Section 3.1 through Section 3.7.
This step re-creates each object type representing a primitive event structure to include a timestamp attribute, rlm$CrtTime
, which captures the corresponding event creation times. This attribute is created with the TIMESTAMP
data type and its value is defaulted to the database timestamp (SYSTIMESTAMP
) at the time of event instantiation. Alternately, an application can explicitly set an event creation time by assigning a valid timestamp value to this attribute.
As previously mentioned, this rule class creation also creates the action callback procedure with the specified name as follows:
PROCEDURE CompPromotion (Flt AddFlight, Car AddRentalCar, rlm$rule CompTravelPromo%ROWTYPE) is BEGIN null; --- The action for the matching rules can be performed here. --- The appropriate action can be determined from the event --- instance and the action preferences associated with each rule. END;
Note: The primitive events within the composite events are passed in as separate arguments to the callback procedure. The action callback procedure includes additional?^ arguments when the rule class is configured for theRULE consumption policy or when the rule class is enabled for one or more collection events. |
Replace the system generated action callback procedure with the user implementation to perform the appropriate action for each matching rule. For example:
PROCEDURE CompPromoAction (Flt AddFlight, Car AddRentalCar, rlm$rule CompTravelPromo%ROWTYPE) is BEGIN OfferPromotion (Flt.CustId, rlm$rule.PromoType, rlm$rule.OfferedBy); END;
Add the rules to the rule class. In this case, add a rule with a conditional expression that uses XML tags. See Section 5.1 for more information about using XML tag extensions in rule conditions to support complex rule constructs.
INSERT INTO CompTravelPromo (rlm$ruleid, PromoType, OfferedBy, rlm$rulecond) VALUES ('UN-HT-FL', 'RentalCar', 'Acar', '<condition> <and join="Flt.CustId = Car.CustId"> <object name="Flt"> Airline=''Abcair'' and ToCity=''Orlando'' </object> <object name="Car"> CarType = ''Luxury'' </object> </and> </condition>');
Process the rules using one primitive event at a time. For example:
BEGIN dbms_rlmgr.process_rules ( rule_class => 'CompTravelPromo', event_inst => AnyData.ConvertObject( AddFlight(987, 'Abcair', 'Boston', 'Orlando', '01-APR-2003', '08-APR-2003'))); dbms_rlmgr.process_rules ( rule_class => 'CompTravelPromo', event_inst => AnyData.ConvertObject( AddFlight(567, 'Abdair', 'Boston', 'Miami', '03-APR-2003', '09-APR-2003'))); dbms_rlmgr.process_rules ( rule_class => 'CompTravelPromo', event_inst => AnyData.ConvertObject( AddRentalCar(987, 'Luxury', '03-APR-2003', '08-APR-2003', NULL))); END;
This command adds three primitive events to the Rules Manager. For the rule defined in Step 4, the first event matches the primitive rule condition for the AddFlight
event and the third event matches the condition for the AddRentalCar
event. Additionally, these two events satisfy the join predicate in the rule condition. So for the previous example, the first and last primitive events together form a composite event that matches the rule condition specified in Step 4. These primitive event instances are passed to the action callback procedure for action execution. The type information for the primitive events that is passed in is embedded in the corresponding AnyData
instance. However, when a string-formatted event is used, the primitive event type information should be explicitly passed in as follows:
BEGIN
dbms_rlmgr.process_rules (
rule_class => 'TravelPromotion',
event_type => 'AddFlight',
event_inst =>
AddFlight.getVarchar(987, 'Abcair', 'Boston', 'Orlando',
'01-APR-2003', '08-APR-2003'));
END;
Rules Manager supports evaluating composite events using complex rule conditions with the following:
Incremental evaluation of rules by allowing predicate joins between and among primitive events
Negation in rule conditions to raise exceptions in processes (that is, when something does not happen, do something)
Sequencing in rule conditions by tracking primitive event creation time and enforcing or detecting sequencing among events
Set semantics in rule conditions to allow instances of primitive events of the same type to be monitored as a group
Any n in rule conditions to allow matching of a subset of primitive events
Rules Manager supports incremental evaluation of rules involving composite events. To support complex rule conditions, the conditional expressions in the SQL WHERE
clause are extended with some XML tags that identify different parts of a conditional expression and adds special semantics to these expressions. Chapter 5 describes more about each type of complex rule condition. Section 5.1 describes implementing incremental evaluation of rules.
Rule class properties define the event management policies that the Rules Manager should enforce for each rules application. Rule class properties include:
Consumption — determines if an event can be used for multiple rule executions or a single rule execution
Conflict resolution or ordering — determines the order in which matching rules with various events are to be executed
Duration — determines the lifetime of unconsumed primitive events
Auto-commit — determines if each interaction with a rule class should be committed automatically
Storage — determines the storage characteristics of the rule class in the database
Equal — specifies the common equality join predicates for all the rules in a rule class, that is, what are the lists of primitive event attributes that are equal in the composite events configured for a rule class
DML Events — specifies when an event structure is created with one or more table alias attributes, that the corresponding rule class should consider the data manipulation language (DML) operations (INSERT
, UPDATE
, DELETE
) on the corresponding tables as the events for which the rules are evaluated
CNF Events — continuous query notification (formerly database change notification) events similar to DML Events except that the rules are processed after the commit of the transaction performing the DML operations.
You specify the rule class properties at the time of rule class creation using an XML properties document that is assigned to the rlcls_prop
argument of the dbms_rlmgr.create_rule_set( )
procedure. For rule classes configured for composite events, specify these properties at the composite event level (for all the primitive events). In addition, you can specify overrides for one or more primitive events in the properties document. Section 3.1 through Section 3.8 describe each of these rules properties in more detail and how each is implemented.
For rules applications that span multiple tiers and where rule management is handled in the database, but the action execution for the rules is handled in the application server, the actions for the rules matching an event cannot be invoked from an action callback procedure. Instead, a results view is populated with the events and the matching rules, both of which are available for external action execution. The results view can be queried to determine the rules that match an event and their corresponding actions can then be executed.
To handle rules applications with certain rules having their action execution occurring on the application server, you must also configure the rule class for external execution (in addition to configuring the action callback procedure). The steps to do this are similar to those described in Section 2.3, but are modified and briefly described as follows (see Chapter 6 for a complete description of each step):
Create the event structure as an object type in the database (same as Step 1 in Section 2.3).
Create the rule class and also define the results view. See Step 2 in Section 6.1 for the details.
Implement the action callback procedure (same as Step3 in Section 2.3).
Add rules to the rule class (same as Step 4 in Section 2.3).
Identify the matching rules for an event. Use the add event procedure (dbms_rlmgr.add_event( )
) that adds each event to the rule class one at a time and identifies the matching rules for a given event that is later accessed using the results view. See Step5 in Section 6.1 for the details.
Find the matching rules by querying the results view. See Step 6 in Section 6.1 for the details.
Consume the event that is used in a rule execution. See Step 7 in Section 6.1 for the details.
For more information about creating rules applications that span multiple tiers, see Section 6.1, and for more information about running rules applications in multitier mode see Section 6.2.
Section 2.7.1 describes using SQL*Loader to load data into a rule class table. Section 2.7.2 describes exporting and importing rules applications.
You can use SQL*Loader to bulk load data from an ASCII file into a rule class table. For the loader operations, SQL*Loader treats the rule conditions stored in the rlm$rulecond
column of the rule class table as strings loaded into a VARCHAR2
column. The data file can hold the XML and SQL based rule conditions in any format allowed for VARCHAR2
data. The values for the action preference columns in the rule class table are loaded using normal SQL*Loader semantics.
Rules Manager automatically validates the data loaded into the rule condition column using the event structure associated with the rule class. The validation is done by a trigger defined on the rule condition column, due to which, a direct load cannot be used while loading rule definitions into a rule class table.
You can export a rules application defined using a set of event structures and a rule class and then import it back to the same database or a different Oracle database. A rule class in a schema is automatically exported when the corresponding rule class table is exported using the export command's (expdp
) tables
parameter or when the complete schema is exported. When you export a rule class, definitions for the associated primitive and composite event structures and the rules defined in the rule class are all placed in the export dump file. However, the internal database objects that maintain the information about event instances and incremental states for partially matched rules are not exported with the rule class. When you use the tables
parameter to export a particular rule class, the implementation for the action callback procedure is not written to the export dump file. The action callback procedure is only exported with the schema export operation.
Note: In the case of a rule class with references to shareable primitive rule conditions, the conditions table storing the conditions are not exported unless the schema is exported or the conditions table is explicitly listed in thetables parameter of the export command. See the note at the end of Section 4.6 for more information. |
You can use the dump file, created with the export of a rule class, to import the rule class and its event structures into the same or a different Oracle database. At the time of import, the internal database objects used for the rule class state maintenance are re-created. Due to the order in which certain objects are created and skipped in an import session, the rule class creation raises some errors and warnings that can be safely ignored. In the case of a schema level import of the rule class, the implementation for action callback procedure is also re-created on the import site However, in the case of a table-level import, only the skeleton for the action callback procedure is created.
Note: In the case of the rule class with references to shareable primitive rule conditions, the rules are validated during the import operation. Any broken references found due to a missing conditions table or the specific primitive condition in the conditions table, returns an ORA-41704 error message. However, the broken references can be fixed as a post-import operation. For this purpose, all the rule conditions with broken references are marked FAILED with the correspondingrlm$enabled column storing the value F . |
This chapter describes a Law Enforcement application and an Order Management application to demonstrate the use of Rules Manager in multiple configurations and to demonstrate the expressiveness of the complex rule conditions.
Note: The complete scripts for these two applications can be found installed at:$ORACLE_HOME/rdbms/demo as ruldemo.sql . |
This Law Enforcement Rules application defines rules to raise security alerts, place a person on the watch list, and so forth based on certain criteria. For this purpose, this application uses some real-world events such as bank transactions, transportation, and field reports to describe the criteria.
The basic steps to create the Law Enforcement rules application with composite events are as follows:
Create the table messagequeue
to hold the messages with a timestamp value:
create table messagequeue (attime timestamp, mesg varchar2(4000));
Create the basic types that represent the event structure:
create or replace type BankTransaction as object (subjectId NUMBER, --- Refer to entity such as personnel --- Could be SSN and so forth tranType VARCHAR2(30), --- DEPOSIT / TRANSFER / WITHDRAW amount NUMBER, --- fundFrom VARCHAR2(30)); --- Location from which it is transfered / create or replace type Transportation as object (subjectId NUMBER, vesselType VARCHAR2(30), --- TRUCK / CAR / PLANE / TRAIN locFrom VARCHAR2(30), --- Starting location locTo VARCHAR2(30), --- Ending location startDate DATE, --- start date endDate DATE); --- end date / create or replace type FieldReport as object (subjectId NUMBER, rptType VARCHAR2(30), --- Tel call / Meeting / Bg Check whoWith NUMBER, --- Identifier of the person with whom --- the subject is in touch rptOrg VARCHAR2(30), --- Organization reporting it rptReg VARCHAR2(30), --- Region rptBody sys.XMLType); --- The actual report /
Create a composite event type that consists of the basic types defined in Step 2:
create or replace type LawEnforcement as object (bank BankTransaction, transport Transportation, fldrpt FieldReport); /
Create a database table for the rules defined on the composite event structure:
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"/>'); END; /
The rule class LawEnforcementRC
is a relational table that acts as the repository for rules. This table uses a set of predefined columns to store the rule identifiers, rule conditions and the descriptions. In addition to these columns, this rule class table defines two columns, actionType
and actionParam
, as specified through the actpref_spec
argument. These columns capture the type of action that should be carried out for each rule. For example:
desc LawEnforcementRC; Name Null? Type --------- -------- ---------------------------------------- RLM$RULEID VARCHAR2(100) ACTIONTYPE VARCHAR2(40) ACTIONPARAM VARCHAR2(100) RLM$RULECOND VARCHAR2(4000) RLM$RULEDESC VARCHAR2(1000) RLM$ENABLED CHAR(1) DEFAULT 'Y'
This step also creates the skeleton for an action callback procedure with the specified name. For example:
select text from user_source where name = 'LAWENFORCEMENTCBK' order by line; TEXT ------------------------------------------------------------------------------- procedure "LAWENFORCEMENTCBK" ( "BANK" "BANKTRANSACTION", "TRANSPORT" "TRANSPORTATION", "FLDRPT" "FIELDREPORT", rlm$rule "LAWENFORCEMENTRC"%ROWTYPE) is begin null; --- The action for the matching rules can be carried here. --- The appropriate action can be determined from the --- event and action preferences associated with each rule. end; 10 rows selected.
Implement the callback procedure to perform the appropriate action for each matching rule, based on event instances that match the rule and the action preferences associated with the rule. For this use case, the callback procedure considers the action for the rules to be the insertion of a detailed message into the message queue table. For example:
CREATE OR REPLACE PROCEDURE LAWENFORCEMENTCBK ( bank banktransaction, transport transportation, fldrpt fieldreport, rlm$rule LawEnforcementRC%ROWTYPE) IS mesg VARCHAR2(4000); msgl VARCHAR2(100); begin msgl := 'Rule '||rlm$rule.rlm$ruleid||' matched following primitive events'; dbms_output.put_line(msgl); mesg := msgl||chr(10); if (bank is not null) then msgl := '->Bank Transaction by subject ('||bank.subjectId||') of type ['||bank.tranType||']'; dbms_output.put_line(msgl); mesg := mesg||msgl||chr(10); end if; if (transport is not null) then msgl := '->Transportation by subject('||transport.subjectId||') use vessel ['||transport.vesselType||']'; dbms_output.put_line(msgl); mesg := mesg||msgl||chr(10); end if; if (fldrpt is not null) then msgl := '->Field report refer to('||fldrpt.subjectId||' and '||fldrpt.whowith||')'; dbms_output.put_line(msgl); mesg := mesg||msgl||chr(10); end if; msgl := '=>Recommended Action : Action Type ['||rlm$rule.actionType|| '] Action Parameter ['||rlm$rule.actionParam||']'; dbms_output.put_line(msgl||chr(10)); mesg := mesg||msgl||chr(10); insert into messagequeue values (systimestamp, mesg); end; /
The rules you define in the rule class can make use of user-defined functions in the database schema. The commands in the following list create some dummy functions that are later used in the rule conditions.
For the value of the region passed in, query the restricted areas table and return 1
if the current region is a restricted area:
CREATE OR REPLACE FUNCTION IsRestrictedArea(region VARCHAR2) RETURN NUMBER IS BEGIN -- User can expand this function and implement a logic -- that relies on other relational tables. RETURN 1; END; /
Check to see if the subject chosen is on the watch list and return 1
if True:
CREATE OR REPLACE FUNCTION OnWatchList(subject NUMBER) RETURN NUMBER IS BEGIN -- User can expand this function and implement a logic -- that relies on other relational tables. RETURN 1; END; /
Check to see if the two parties are associates and return 1
if the two subjects passed in are associates according to the registry:
CREATE OR REPLACE FUNCTION AreAssociates(subjectA NUMBER, subjectB NUMBER) RETURN NUMBER IS BEGIN -- User can expand this function and implement a logic -- that relies on other relational tables. RETURN 1; END; /
Add all three user-defined functions to the composite event LawEnforcement
:
EXEC DBMS_RLMGR.ADD_FUNCTIONS('LawEnforcement', 'OnWatchList'); EXEC DBMS_RLMGR.ADD_FUNCTIONS('LawEnforcement', 'IsRestrictedArea'); EXEC DBMS_RLMGR.ADD_FUNCTIONS('LawEnforcement', 'AreAssociates');
Define the rules that suggest some actions:
Rule: Add a person to the NYPD watch list if he receives a money transfer for more than $10,000 and he rents a truck, one way, to one of the restricted areas. Note that the rule specifies the join predicate at the rule class level.
INSERT INTO LawEnforcementRC (rlm$ruleid, actionType, actionParam, rlm$rulecond) VALUES ('1', 'ADD2WATCHLIST','NYPD', '<condition> <and> <object name="bank"> tranType = ''TRANSFER'' AND amount > 10000 AND fundFrom != ''USA'' </object> <object name="transport"> vesselType = ''TRUCK'' AND locFrom != locTo AND IsRestrictedArea(locTo)=1 </object> </and> </condition>');
Rule: Add a person to the NYPD watch list if the rule meets two of the following three conditions. The person gets a money transfer for over $10,000 from outside the United States, he rents a truck, one-way, into one of the restricted areas, and he makes a phone conversation with a person already on the watch list. The following rule demonstrates the use of the <ANY>
element where it considers a rule condition to be true if m out of n events are detected.
INSERT INTO LawEnforcementRC (rlm$ruleid, actionType, actionParam, rlm$rulecond) VALUES ('2', 'ADD2WATCHLIST','NYPD', '<condition> <any count="2"> <object name="bank"> tranType = ''TRANSFER'' AND amount > 10000 AND fundFrom != ''USA'' </object> <object name="transport"> vesselType = ''TRUCK'' AND locFrom != locTo AND IsRestrictedArea(locTo)=1 </object> <object name="fldrpt"> rptType = ''TELCALL'' AND OnWatchList(whoWith) = 1 </object> </any> </condition>');
Rule: Start a background check on a person if he receives a large sum of money from outside the United States, he rents a truck one-way into one of the restricted areas, and there is no field report with his background information. The following rule demonstrates the use of negation where it considers a rule condition to be true if some of the specified events are detected and other events are not detected:
INSERT INTO LawEnforcementRC (rlm$ruleid, actionType, actionParam, rlm$rulecond) VALUES ('3','STARTBACKGROUNDCHECK','RENTAL_DESTINATION', '<condition> <and> <object name="bank"> tranType = ''TRANSFER'' AND amount > 10000 AND fundFrom != ''USA'' </object> <object name="transport"> vesselType=''TRUCK'' AND locFrom != locTo AND IsRestrictedArea(locTo)=1 </object> <not> <object name="fldrpt"/> </not> </and> </condition>');
Rule: If a subject receives over $10,000 from outside the United States, he rents a truck for a one way trip into a restricted area, and a field report saying that the subject was never arrested before was not submitted within a "certain" (0.001 fraction of a day; this could be days, but it uses seconds to demonstrate the use of a deadline) period, add the destination of the truck to high-risk areas. This rule demonstrates Negation with a deadline:
INSERT INTO LawEnforcementRC (rlm$ruleid, actionType, actionParam, rlm$rulecond) VALUES ('4','ADD2HIGH_RISK_AREA','RENTAL_DESTINATION', '<condition> <and> <object name="bank" tranType = ''TRANSFER'' AND amount > 10000 AND fundFrom != ''USA'' </object> <object name="transport"> vesselType = ''TRUCK'' AND locFrom != locTo AND IsRestrictedArea(locTo)=1 </object> <not by="systimestamp+0.001"> <object name="fldrpt"> rptType = ''BACKGROUNDCHECK'' and extract(rptBody, ''/history/arrests[@number=0'') is not null </object> </not> </and> </condition>');
Browse the rules. This is optional. The following example demonstrates this task:
select rlm$ruleid, rlm$rulecond from LawEnforcementRC order by 1; RLM$R RLM$RULECOND ----- -------------------------------------------------------------------- 1 <condition> <and> <object name="bank"> tranType = 'TRANSFER' AND amount > 10000 AND fundFrom != 'USA' </object> <object name="transport"> vesselType = 'TRUCK' AND locFrom != locTo AND IsRestrictedArea(locTo)=1 </object> </and> </condition> . . .
Process the rules for the primitive events.
Add two primitive events that each partially match one or more rules and together match one rule, such that it executes the rules action (it prints the message to the screen as well as inserts it into the messagequeue
table):
set serveroutput on size 10000; BEGIN dbms_rlmgr.process_rules ( rule_class => 'LawEnforcementRC', event_inst => sys.anydata.convertobject( fieldreport(123302122, 'TELCALL',123302123, 'NSA', 'NE', null))); END; /
BEGIN dbms_rlmgr.process_rules ( rule_class => 'LawEnforcementRC', event_inst => sys.anydata.convertobject( banktransaction(123302122, 'TRANSFER', 100000, 'USSR'))); END; / Rule 2 matched following primitive events ->Bank Transaction by subject (123302122) of type [TRANSFER] ->Field report refer to(123302122 and 123302123) =>Recommended Action : Action Type [ADD2WATCHLIST] Action Parameter [NYPD]
The following Transportation event, in combination with the Bank Transaction event, evaluates some of the rules to true and thus calls the action call-back procedure with appropriate arguments:
BEGIN dbms_rlmgr.process_rules ( rule_class => 'LawEnforcementRC', event_inst => sys.anydata.convertobject( transportation(123302122, 'TRUCK', 'WIS', 'MD', sysdate, sysdate + 7))); END; / Rule 1 matched following primitive events ->Bank Transaction by subject (123302122) of type [TRANSFER] ->Transportation by subject(123302122) use vessel [TRUCK] =>Recommended Action : Action Type [ADD2WATCHLIST] Action Parameter [NYPD] Rule 2 matched following primitive events ->Transportation by subject(123302122) use vessel [TRUCK]->Field report refer to(123302122 and 123302123) =>Recommended Action : Action Type [ADD2WATCHLIST] Action Parameter [NYPD] Rule 2 matched following primitive events ->Bank Transaction by subject (123302122) of type [TRANSFER] ->Transportation by subject(123302122) use vessel [TRUCK] =>Recommended Action : Action Type [ADD2WATCHLIST] Action Parameter [NYPD] Rule 3 matched following primitive events ->Bank Transaction by subject (123302122) of type [TRANSFER] ->Transportation by subject(123302122) use vessel [TRUCK] =>Recommended Action : Action Type [STARTBACKGROUNDCHECK] Action Parameter [RENTAL_DESTINATION]
Check the message queue:
SQL> select mesg from messagequeue order by attime; MESG -------------------------------------------- Rule 2 matched following primitive events ->Bank Transaction by subject (123302122) of type [TRANSFER] ->Field report refer to(123302122 and 123302123) =>Recommended Action : Action Type [ADD2WATCHLIST] Action Parameter [NYPD] Rule 1 matched following primitive events ->Bank Transaction by subject (123302122) of type [TRANSFER] ->Transportation by subject(123302122) use vessel [TRUCK] =>Recommended Action : Action Type [ADD2WATCHLIST] Action Parameter [NYPD] Rule 2 matched following primitive events ->Transportation by subject(123302122) use vessel [TRUCK] ->Field report refer to(123302122 and 123302123) =>Recommended Action : Action Type [ADD2WATCHLIST] Action Parameter [NYPD] Rule 2 matched following primitive events ->Bank Transaction by subject (123302122) of type [TRANSFER] ->Transportation by subject(123302122) use vessel [TRUCK] =>Recommended Action : Action Type [ADD2WATCHLIST] Action Parameter [NYPD] Rule 3 matched following primitive events ->Bank Transaction by subject (123302122) of type [TRANSFER] ->Transportation by subject(123302122) use vessel [TRUCK] =>Recommended Action : Action Type [STARTBACKGROUNDCHECK] Action Parameter [RENTAL_DESTINATION]
Truncate the table messagequeue:
SQL> truncate table messagequeue;
Now lets assume you sleep past the deadline for rule 4. The scheduler process picks up this rule and executes its action. The result is a new message in the message queue.
SQL> exec dbms_lock.sleep(180);
Rule 4 executes the following action after the deadline time elapses:
SQL> select mesg from messagequeue; MESG -------------------------------------------- Rule 4 matched following primitive events ->Bank Transaction by subject (123302122) of type [TRANSFER] ->Transportation by subject(123302122) use vessel [TRUCK] =>Recommended Action : Action Type [ADD2HIGH_RISK_AREA] Action Parameter [RENTAL_DESTINATION]
This Order Management rules application demonstrates the use of Rules Manager for the event data that is stored in relational tables.
The basic steps to create the Order Management rules application with composite events are as follows:
Create the three relational tables to store the information about the purchase orders, shipping information, and payment information, as follows:
create table PurchaseOrders (orderId NUMBER, custId NUMBER, itemId NUMBER, itemType VARCHAR2(30), quantity NUMBER, shipBy DATE); create table ShipmentInfo (orderId NUMBER, destState VARCHAR2(2), address VARCHAR2(50), shipTime DATE, shipType VARCHAR2(10)); create table PaymentInfo (orderId NUMBER, payType VARCHAR2(10), -- Credit Card / Check -- amountPaid NUMBER, pymtTime DATE, billState VARCHAR2(2));
Create the event structure. You cannot create the event structures from object types if they refer to the existing tables using table alias constructs. Instead, model such event structures as Expression Filter attribute sets, as follows:
begin DBMS_RLMGR.CREATE_EVENT_STRUCT (event_struct => 'OrderMgmt'); DBMS_RLMGR.ADD_ELEMENTARY_ATTRIBUTE( event_struct => 'OrderMgmt', attr_name => 'po', tab_alias => RLM$TABLE_ALIAS('PurchaseOrders')); DBMS_RLMGR.ADD_ELEMENTARY_ATTRIBUTE( event_struct => 'OrderMgmt', attr_name => 'si', tab_alias => RLM$TABLE_ALIAS('ShipmentInfo')); DBMS_RLMGR.ADD_ELEMENTARY_ATTRIBUTE( event_struct => 'OrderMgmt', attr_name => 'py', tab_alias => RLM$TABLE_ALIAS('PaymentInfo')); end; /
Create the rule class (database table for rules) for the OrderMgmt
composite event. Also, specify the DMLEVENTS
property to process the rules for each inserted row into the event data tables, as follows:
BEGIN DBMS_RLMGR.CREATE_RULE_CLASS ( rule_class => 'OrderMgmtRC', event_struct => 'OrderMgmt', action_cbk => 'OrderMgmtCBK', actprf_spec => 'actionType VARCHAR2(40), actionParam VARCHAR2(100)', rslt_viewnm => 'MatchingOrders', rlcls_prop => '<composite equal="po.orderId, si.orderId, py.orderId" dmlevents="I"/>'); END; /
This step also creates the skeleton for an action callback procedure with the specified name, as follows:
desc OrderMgmtCBK; PROCEDURE OrderMgmtCBK Argument Name Type In/Out Default? ------------------------------ ----------------------- ------ -------- PO ROWID IN SI ROWID IN PY ROWID IN RLM$RULE RECORD IN RLM$RULEID VARCHAR2(100) IN ACTIONTYPE VARCHAR2(40) IN ACTIONPARAM VARCHAR2(100) IN RLM$RULECOND VARCHAR2(4000) IN RLM$RULEDESC VARCHAR2(1000) IN RLM$ENABLED CHAR(1) DEFAULT 'Y' IN
Implement the callback procedure to perform the appropriate action for each matching rule, based on event instances that match the rule and action preferences associated with the rule. In this case, consider one action to be a message displayed to the screen, as shown in the following example:
CREATE OR REPLACE PROCEDURE OrderMgmtCBK ( po ROWID, -- rowid from the PurchaseOrders table si ROWID, -- rowid from the ShipmentInfo table py ROWID, -- rowid from the PaymentInfo table rlm$rule OrderMgmtRC%ROWTYPE) IS ordId NUMBER; msg VARCHAR2(2000); begin -- the rowid arguments represent the primitive events that are -- rows inserted into the corresponding tables. Use the rowids -- to fetch necessary values. if (po is not null) then select orderId into ordId from PurchaseOrders where rowid = po; elsif (si is not null) then select orderId into ordId from ShipmentInfo where rowid = si; elsif (py is not null) then select orderId into ordId from PaymentInfo where rowid = py; end if; msg := 'Order number: '||ordId||' Matched rule: ' ||rlm$rule.rlm$ruleid||chr(10)|| '-> Recommended Action : '||chr(10)|| ' Action Type ['||rlm$rule.actionType|| ']'||chr(10)|| ' Action Parameter ['|| rlm$rule.actionParam||']'; dbms_output.put_line (msg||chr(10)); end; /
Add user-defined functions that may be useful in rule conditions:
create or replace function getCustType(custId number) return VARCHAR2 is begin -- the actual function implementation can rely on other -- relational tables to derive the customer type information return 'GOLD'; end; / exec DBMS_RLMGR.ADD_FUNCTIONS('OrderMgmt','getCustType');
Add some rules:
Rule 1: If the order is for more than 100 routers and payment is by check, contact the customer to update the status of the order. Note that the rule specifies the join predicate across event types at the rule class level. For example:
INSERT INTO OrderMgmtRC (rlm$ruleid, actionType, actionParam, rlm$rulecond) VALUES (1, 'CALL_CUSTOMER','UPDATE_ORDER_STATUS', '<condition> <and> <object name="po"> itemType = ''ROUTER'' and quantity > 100 </object> <object name="py"> payType = ''CHECK'' </object> </and> </condition>');
Rule 2: If a Gold customer places an order and items ship before receiving payment, adjust the customer's credit. For example:
INSERT INTO OrderMgmtRC (rlm$ruleid, actionType, actionParam, rlm$rulecond) VALUES (2, 'UPDATE_CUST_PROFILE', 'DECR_AVAILABLE_CREDIT', '<condition> <and> <object name="po"> getCustType(custid) = ''GOLD'' </object> <object name="si"/> <not> <object name="py"/> </not> </and> </condition>');
Rule 3: If a Gold customer places an order and items ship within 1 day prior to the shipby date, increment the quality of service statistics. For example:
INSERT INTO OrderMgmtRC (rlm$ruleid, actionType, actionParam, rlm$rulecond) VALUES (3, 'UPDATE_STATISTICS', 'INCREMENT QOS', '<condition> <and join="po.shipby > si.shiptime-1"> <object name="po"> getCustType(custid) = ''GOLD'' </object> <object name="si"/> </and> </condition>');
Process rules for some primitive events by inserting rows into corresponding data tables, as shown in the following list:
The following event partially matches some of the rules in the rule class and does not result in any action:
insert into PurchaseOrders (orderId, custId, itemId, itemType, quantity, shipBy) values (1, 123, 234, 'ROUTER', 120, '01-OCT-2004');
The following event in combination with the previous added events matches two rules and fires the corresponding actions:
insert into ShipmentInfo (orderId, deststate, address, shipTime, shipType) values (1, 'CA','1 Main street, San Jose','29-SEP-2004','1 Day Air'); Order number: 1 Matched rule: 2 -> Recommended Action : Action Type [UPDATE_CUST_PROFILE] Action Parameter [DECR_AVAILABLE_CREDIT] Order number: 1 Matched rule: 3 -> Recommended Action : Action Type [UPDATE_STATISTICS] Action Parameter [INCREMENT QOS]
The following event matches one more rule:
insert into PaymentInfo (orderId, paytype, amountpaid, pymttime, billstate) values (1, 'CHECK', 100000, '30-SEP-2004', 'CA'); Order number: 1 Matched rule: 1 -> Recommended Action : Action Type [CALL_CUSTOMER] Action Parameter [UPDATE_ORDER_STATUS]
Now, consider a similar application without the use of the DMLEVENTS
property. This implies that the user explicitly invokes the Rules Manager APIs to process the rules for some data stored in relational tables. This rule class shares the event structure with the OrderMgmtRC
rule class.
Create the rule class (database table for rules) for the OrderMgmtRC2
composite event, as follows:
BEGIN DBMS_RLMGR.CREATE_RULE_CLASS ( rule_class => 'OrderMgmtRC2', event_struct => 'OrderMgmt', action_cbk => 'OrderMgmtCBK2', actprf_spec => 'actionType VARCHAR2(40), actionParam VARCHAR2(100)', rslt_viewnm => 'MatchingOrders2', rlcls_prop => '<composite equal="po.orderId, si.orderId, py.orderId"/>'); END; /
Implement the callback procedure to perform the appropriate action for each matching rule, based on the event instances that matched the rule and the action preferences associated with the rule, as follows:
--- Implement the action callback procedure -- CREATE OR REPLACE PROCEDURE OrderMgmtCBK2 ( po ROWID, -- rowid from the PurchaseOrders table si ROWID, -- rowid from the ShipmentInfo table py ROWID, -- rowid from the PaymentInfo table rlm$rule OrderMgmtRC2%ROWTYPE) IS ordId NUMBER; msg VARCHAR2(2000); begin -- the rowid argument represent the primitive events that are -- rows inseted into the corresponding tables. Use the rowids -- to fetch necessary values. if (po is not null) then select orderId into ordId from PurchaseOrders where rowid = po; elsif (si is not null) then select orderId into ordId from ShipmentInfo where rowid = si; elsif (py is not null) then select orderId into ordId from PaymentInfo where rowid = py; end if; msg := 'Order number: '||ordId||' Matched rule: ' ||rlm$rule.rlm$ruleid||chr(10)|| '-> Recommended Action : '||chr(10)|| ' Action Type ['||rlm$rule.actionType|| ']'||chr(10)||' Action Parameter ['|| rlm$rule.actionParam||']'; dbms_output.put_line (msg||chr(10)); end; /
Insert the same set of rules into the new rule class, as follows:
insert into OrderMgmtRC2 (select * from OrderMgmtRC); commit;
Process the rules for the rows in the data tables as shown in the code that follows. Because the rules do not configure DML events for this rule class, the application must explicitly process the rules for the rows in the data table. To process the rules, it uses the ROWIDS of the rows inserted into the data tables as references to the events and passes these ROWIDs to the PROCESS_RULES
procedure.
var datarid varchar2(40);
insert into PurchaseOrd5ers (orderId, custId, itemId, itemType, quantity, shipBy) values (2, 123, 234, 'ROUTER', 120, '01-OCT-2004') returning rowid into :datarid; BEGIN dbms_rlmgr.process_rules (rule_class => 'OrderMgmtRC2', event_type => 'PurchaseOrders', event_inst => :datarid); END; /
insert into ShipmentInfo (orderId, deststate, address, shipTime, shipType) values (2, 'CA','1 Main street, San Jose','29-SEP-2004','1 Day Air') returning rowid into :datarid; BEGIN dbms_rlmgr.process_rules (rule_class => 'OrderMgmtRC2', event_type => 'ShipmentInfo', event_inst => :datarid); END; / Order number: 2 Matched rule: 2 -> Recommended Action : Action Type [UPDATE_CUST_PROFILE] Action Parameter [DECR_AVAILABLE_CREDIT] Order number: 2 Matched rule: 3 -> Recommended Action : Action Type [UPDATE_STATISTICS] Action Parameter [INCREMENT QOS]
insert into PaymentInfo (orderId, paytype, amountpaid, pymttime, billstate) values (2, 'CHECK', 100000, '30-SEP-2004', 'CA') returning rowid into :datarid; BEGIN dbms_rlmgr.process_rules (rule_class => 'OrderMgmtRC2', event_type => 'PaymentInfo', event_inst => :datarid); END; / Order number: 2 Matched rule: 1 -> Recommended Action : Action Type [CALL_CUSTOMER] Action Parameter [UPDATE_ORDER_STATUS]
Now, try the session oriented evaluation of rules where the results from matching rules are available in the results view to be queried, as shown in the following list:
A description of the result view table follows:
set linesize 80; desc MatchingOrders2; Name Null? Type ----------------------------------------- -------- ---------------------------- RLM$EVENTID ROWID PO ROWID SI ROWID PY ROWID RLM$RULEID VARCHAR2(100) ACTIONTYPE VARCHAR2(40) ACTIONPARAM VARCHAR2(100) RLM$RULECOND VARCHAR2(4000) RLM$RULEDESC VARCHAR2(1000) RLM$ENABLED CHAR(1) DEFAULT 'Y' select count(*) from MatchingOrders2; COUNT(*) ---------- 0
Process the rules for the rows in the data tables. Note the use of the ADD_EVENT
procedure instead of the PROCESS_RULES
procedure in the previous example. This ensures the rule class results view stores the results from the matching of events with the rules. For example:
insert into PurchaseOrders (orderId, custId, itemId, itemType, quantity, shipBy) values (3, 123, 234, 'ROUTER', 120, '01-OCT-2004') returning rowid into :datarid; --- Use ADD_EVENT API in the place of PROCESS_RULES --- BEGIN dbms_rlmgr.add_event (rule_class => 'OrderMgmtRC2', event_type => 'PurchaseOrders', event_inst => :datarid); END; /
insert into ShipmentInfo (orderId, deststate, address, shipTime, shipType) values (3, 'CA','1 Main street, San Jose','29-SEP-2004','1 Day Air') returning rowid into :datarid; BEGIN dbms_rlmgr.add_event (rule_class => 'OrderMgmtRC2', event_type => 'ShipmentInfo', event_inst => :datarid); END; /
insert into PaymentInfo (orderId, paytype, amountpaid, pymttime, billstate) values (3, 'CHECK', 100000, '30-SEP-2004', 'CA') returning rowid into :datarid; BEGIN dbms_rlmgr.add_event (rule_class => 'OrderMgmtRC2', event_type => 'PaymentInfo', event_inst => :datarid); END; /
Because table aliases configure the event structure, ROWIDS from the corresponding tables represent events, as follows:
column rlm$ruleid format a7; column actiontype format a25; column actionparam format a25; select po, si, py, rlm$ruleid, actionType, actionParam from MatchingOrders2; PO SI PY RLM$RUL ------------------ ------------------ ------------------ ------- ACTIONTYPE ACTIONPARAM ------------------------- ------------------------- AAAOBxAAEAAAAHPAAC AAAOByAAEAAAAHXAAC 2 UPDATE_CUST_PROFILE DECR_AVAILABLE_CREDIT AAAOBxAAEAAAAHPAAC AAAOByAAEAAAAHXAAC 3 UPDATE_STATISTICS INCREMENT QOS AAAOBxAAEAAAAHPAAC AAAOBzAAEAAAAHfAAC 1 CALL_CUSTOMER UPDATE_ORDER_STATUS
Use ROWIDS to derive the actual event values from the data tables, as follows:
select (select orderId from purchaseOrders where rowid = po) as OrderId, rlm$ruleid, actionType, actionParam from MatchingOrders2; ORDERID RLM$RUL ACTIONTYPE ACTIONPARAM ---------- ------- ------------------------- ------------------------- 3 2 UPDATE_CUST_PROFILE DECR_AVAILABLE_CREDIT 3 3 UPDATE_STATISTICS INCREMENT QOS 3 1 CALL_CUSTOMER UPDATE_ORDER_STATUS
The following Order Management application demonstrates the use of collection events for identifying complex event scenarios and acting on them. This application uses the object types in the database as the event structure and the basic steps in creating this application are similar to those discussed in Section 10.1.
Create the object types that represent the primitive event structures and the composite event structure.
create or replace type PurchaseOrder as object ( orderid number, customerid number, itemid number, itemcount number, amount number, exptddate date); / create or replace type ShipItem as object ( itemid number, itemtype varchar2(30), orderid number, truckid number); / create or replace type TruckAtDock as object ( truckid number, loadid date, status varchar2(30), capacity number); / create or replace type OrderMgmt as object ( porder PurchaseOrder, sitem ShipItem, truck TruckAtDock ); /
Create the rule class. Set the rule class properties such that events based on PurchaseOrder
and ShipItem
types are enabled for collections.
BEGIN DBMS_RLMGR.CREATE_RULE_CLASS( rule_class => 'OrderMgmtRC', event_struct => 'OrderMgmt', action_cbk => 'OrderMgmtCBK', actprf_spec => 'actionType VARCHAR2(40), actionParam VARCHAR2(100), poAggrRet VARCHAR2(20) default null', rslt_viewnm => 'MatchedScenarios', rlcls_prop => '<composite equal="(porder.orderid, sitem.orderid) | (sitem.truckid, truck.truckid)" ordering="rlm$rule.rlm$ruleid, porder.orderid, porder.itemid, truck.loadid"> <collection type="PurchaseOrder" groupby="orderid, customerid, itemid"/> <collection type="ShipItem" groupby="itemid, truckid"/> </composite>'); END; /
Implement the action callback procedure. Note that for each primitive event type enabled for collections, the action callback procedure uses one additional ROWID argument that binds in the identifier for the collection event. It then uses this event identifier to obtain any aggregate values computed for a given rule.
create or replace procedure "ORDERMGMTCBK" ( PORDER PURCHASEORDER, PO_EVTID ROWID, SITEM SHIPITEM, SI_EVTID ROWID, TRUCK TRUCKATDOCK, rlm$rule ORDERMGMTRC%ROWTYPE) is mesg VARCHAR2(100); aggrval VARCHAR2(100); begin mesg := ' Rule "'||rlm$rule.rlm$ruleid|| '" matched '|| case when porder.orderid is not null then 'Purchase Order' ||porder.orderid when porder.customerid is not null then 'Customer' ||porder.customerid when sitem.truckid is not null then '||Truck '||sitem.truckid end; if (porder is not null and rlm$rule.poAggrRet is not null) then aggrval := dbms_rlmgr.get_aggregate_value ('OrderMgmtRC', po_evtid, rlm$rule.poAggrRet); aggrval := ' with '||rlm$rule.poAggrRet||' equal to '||aggrval; end if; dbms_output.put_line (mesg||aggrval); end; /
Create any user-defined function that may be used in the rule class.
create or replace function CustomerType (custId int) return VARCHAR2 is begin return 'GOLD'; end; / exec dbms_rlmgr.add_functions('OrderMgmt','CustomerType');
Add rules to the rule class.
Rule: Offer an elite status to a customer if he submits a large number of orders, each with a minimum of 10000 dollars.
insert into OrderMgmtRC (rlm$ruleid, actionType, actionParam, rlm$ruledesc, rlm$rulecond) values ('Large number of orders promo', 'PROMOTION','ELITE_STATUS', 'Offer an elite status to a customer if he submited a large number of orders, each with a minimum of 10000 dollars', '<condition> <collection name="porder" groupby="customerid" having="count(*) > 10"> amount > 10000 </collection> </condition>');
Rule: Offer a promotion for ordering in bulk if the average value of the last 10 orders is over 20000 dollars.
insert into OrderMgmtRC (rlm$ruleid, actionType, actionParam, rlm$ruledesc, rlm$rulecond) values ('Expanding customer', 'PROMOTION', 'LARGE_ORDER', 'Offer a promotion for ordering in bulk if the average size of the last 10 orders is over 20000 dollars', '<condition> <collection name="porder" groupby="customerid" windowsize="10" having="avg(amount) > 20000"/> </condition>');
Rule: Offer an elite status to a customer if he submits a large number of orders, each with a minimum of 1000 dollars, within a 30 day period.
insert into OrderMgmtRC (rlm$ruleid, actionType, actionParam, rlm$ruledesc, rlm$rulecond) values ('Promo on Total size of orders in 10 days ', 'PROMOTION','ELITE_STATUS', 'Offer an elite status to a customer if he submitted a large number of orders, each with a minimum of 1000 dollars, in a 30 day period', '<condition> <collection name="porder" groupby="customerid" windowlen="30" having="sum(amount) > 50000"/> amount > 1000 </collection> </condition>');
Rule: Compare the number of items ordered and the items shipped to mark the order complete.
insert into OrderMgmtRC (rlm$ruleid, actionType, actionParam, rlm$ruledesc, rlm$rulecond) values ('Completed order', 'UPDATE_ORDER_STATUS','COMPLETE', 'Compare the number of items ordered and the items shipped to mark the order complete', '<condition> <and equal="porder.orderid, sitem.orderid" having="count(sitem.*) = porder.itemcount"> <object name="porder"/> <collection name="sitem" groupby="orderid" compute="count(*)"> itemtype != ''Reusable Container'' </collection> </and> </condition>');
Rule: Signal readiness to ship when the truck is at least 90% full.
insert into OrderMgmtRC (rlm$ruleid, actionType, actionParam, rlm$ruledesc, rlm$rulecond) values ('Ready to ship', 'READY_TO_SHIP', 'LOADED_TRUCK', 'Signal readiness to ship when the truck is at least 90% full', '<condition> <and equal="sitem.truckid, truck.truckid" having="count(sitem.*) >= truck.capacity*0.9" > <object name="truck"> status = ''Loading'' </object> <collection name="sitem" groupby="truckid" compute="count(*)"> itemtype = ''Reusable Container'' </collection> </and> </condition>');
Process the rules for the instances of PurchaseOrder
, ShipItem
, and TruckAtDock
events.
Rules Manager and Expression Filter Developer's Guide
11g Release 2 (11.2)
E14919-04
August 2011
Obsolescence Notice - see My Oracle Support Note ID 1244535.1
Oracle Database Rules Manager and Expression Filter Developer's Guide, 11g Release 2 (11.2)
E14919-04
Copyright © 2003, 2011, Oracle and/or its affiliates. All rights reserved.
Primary Authors: Aravind Yalamanchi, Rod Ward
Contributors: William Beauregard, Timothy Chorma, Dieter Gawlick, Helen Grembowicz, Lory Molesky, Deborah Owens, Jagannathan Srinivasan
This software and related documentation are provided under a license agreement containing restrictions on use and disclosure and are protected by intellectual property laws. Except as expressly permitted in your license agreement or allowed by law, you may not use, copy, reproduce, translate, broadcast, modify, license, transmit, distribute, exhibit, perform, publish, or display any part, in any form, or by any means. Reverse engineering, disassembly, or decompilation of this software, unless required by law for interoperability, is prohibited.
The information contained herein is subject to change without notice and is not warranted to be error-free. If you find any errors, please report them to us in writing.
If this is software or related documentation that is delivered to the U.S. Government or anyone licensing it on behalf of the U.S. Government, the following notice is applicable:
U.S. GOVERNMENT RIGHTS Programs, software, databases, and related documentation and technical data delivered to U.S. Government customers are "commercial computer software" or "commercial technical data" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations. As such, the use, duplication, disclosure, modification, and adaptation shall be subject to the restrictions and license terms set forth in the applicable Government contract, and, to the extent applicable by the terms of the Government contract, the additional rights set forth in FAR 52.227-19, Commercial Computer Software License (December 2007). Oracle America, Inc., 500 Oracle Parkway, Redwood City, CA 94065.
This software or hardware is developed for general use in a variety of information management applications. It is not developed or intended for use in any inherently dangerous applications, including applications that may create a risk of personal injury. If you use this software or hardware in dangerous applications, then you shall be responsible to take all appropriate fail-safe, backup, redundancy, and other measures to ensure its safe use. Oracle Corporation and its affiliates disclaim any liability for any damages caused by use of this software or hardware in dangerous applications.
Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners.
Intel and Intel Xeon are trademarks or registered trademarks of Intel Corporation. All SPARC trademarks are used under license and are trademarks or registered trademarks of SPARC International, Inc. AMD, Opteron, the AMD logo, and the AMD Opteron logo are trademarks or registered trademarks of Advanced Micro Devices. UNIX is a registered trademark of The Open Group.
This software or hardware and documentation may provide access to or information on content, products, and services from third parties. Oracle Corporation and its affiliates are not responsible for and expressly disclaim all warranties of any kind with respect to third-party content, products, and services. Oracle Corporation and its affiliates will not be responsible for any loss, costs, or damages incurred due to your access to or use of third-party content, products, or services.
Rules applications can be run in multitier mode. For rules applications that span multiple tiers where rule management is handled in the database, but the action execution for the rules is handled in the application server, the actions for the rules matching an event cannot be invoked from an action callback procedure. Instead, a results view is populated with the information about the events and matching rules; both of which are available for external action execution. You can query the results view to determine the rules that match an event and their corresponding actions can then be executed.
To handle rules applications with certain rules having their action execution occurring on the application server, you must configure the rule class for external execution (in addition to configuring the action callback procedure). The steps to do this are similar to those described in Section 2.3, but are modified as follows:
Create the event structure as an object type in the database (same as Step 1 in Section 2.3).
Create the TravelPromotion
rule class. Also define the results view, even though you may not use it initially. The results view can be used, for example, to create the TravelPromotion
rule class, such that for each rule session (that processes some events for a rule class), the action execution can switch at runtime between either the action callback procedure (calling dbms_rlmgr.process_rules( )
as shown in Step 5 in Section 2.3) or external action execution (calling dbms_rlmgr.add_event( )
, as shown in Step 5 in this section). For this purpose, the rule class is configured with an action callback procedure and a results view, as shown in the following example:
BEGIN
dbms_rlmgr.create_rule_class (
rule_class => 'TravelPromotion',
event_struct => 'AddFlight',
action_cbk => 'PromoAction',
rslt_viewnm => 'MatchingPromos',
actprf_spec => 'PromoType VARCHAR2(20),
OfferedBy VARCHAR2(20)');
END;
Note that this command creates the following MatchingPromos
results view to hold the results from the rule evaluation. This view uses a fixed set of columns to list the system generated event identifier (rlm$eventid
), the event instance (rlm$event
for a (simple) primitive event), the rule identifier for the matching rules (rlm$ruleid
), the rule condition (rlm$rulecond
), the rule description (rlm$ruledesc
), and a variable set of columns to represent the action preferences associated with the rules (PromoType
and OfferedBy
columns in this example). For an event matching a set of rules in the rule class, the information about the event and the matched rules can be obtained by querying this view.
VIEW MatchingPromos ( rlm$eventid ROWID, rlm$event AddFlight, rlm$ruleid VARCHAR2(100), PromoType VARCHAR2(20), OfferedBy VARCHAR2(20)), rlm$rulecond VARCHAR2(4000), rlm$ruledesc VARCHAR2(1000, rlm$enabled CHAR(1) DEFAULT 'Y'); );
The results view in the case of a rule class configured for a composite event is structured to hold the results from evaluating the rules using one or more primitive events. For this purpose, this view is created with separate columns for each primitive event within the composite event. For example, the following results view is created for the rule class defined in Section 2.4.1:
VIEW CompMatchingPromos ( rlm$eventid ROWID, Flt AddFlight, Car AddRentalCar, rlm$ruleid VARCHAR2(100), PromoType VARCHAR2(20), OfferedBy VARCHAR2(20), rlm$rulecond VARCHAR2(4000), rlm$ruledesc VARCHAR2(1000) rlm$enabled CHAR(1) DEFAULT 'Y');
Implement the action callback procedure (same as Step 3 in Section 2.3).
Add rules to the rule class (same as Step 4 in Section 2.3).
Identify the matching rules for an event. This step replaces the use of the process rules procedure (dbms_rlmgr.process_rules( )
) that identifies the matching rules and executes the corresponding actions with an add event procedure (dbms_rlmgr.add_event( )
) that adds the event to the rule class one at a time and identifies the matching rules for a given event that are later accessed using the MatchingPromos
results view.
BEGIN
dbms_rlmgr.add_event (
rule_class => 'TravelPromotion',
event_inst => AddFlight.getVarchar(987, 'Abcair', 'Boston', 'Orlando', '01-APR-2003', '08-APR-2003')
);
END;
Find the matching rules by querying the results view. For example, the following query returns a list of all the events added in the current session and their corresponding matching rules (and their action preferences):
SELECT rlm$eventid, rlm$ruleid, PromoType, OfferedBy FROM MatchingPromos;
Use the results from this query to execute the appropriate action in the application server. In the case of a rule class defined for a single event structure, this view implicitly has a rlm$eventid
column that returns a system generated event identifier and rlm$event
column to return the actual event as the (primitive event structure's) object instance.
When you need to identify one candidate rule from the result set (conflict resolution), you can use ORDER BY
, GROUP BY
, and HAVING
clauses. Note that the callback mechanism for action execution can only use ORDER BY
semantics for conflict resolution. See Section 3.2 for more information. For example, if the Travel Services application offers only one promotion of each type, the following analytical query can be used to identify the appropriate rules to be fired:
SELECT rlm$eventid, rlm$ruleid, PromoType, OfferedBy FROM (SELECT rlm$eventid, rlm$ruleid, PromoType, OfferedBy, ROW_NUMBER( ) over (PARTITION BY PromoType ORDER BY rlm$ruleid) rnum FROM MatchingPromos) WHERE rnum=1;
In this example, the rule identified as the one to be fired is the first one (rnum=1
) returned from the query of the result set for the set of rules that evaluated to be true, partitioned by the type of promotion and ordered in ascending order by the rlm$ruleid
column value.
The results from a rule evaluation are available until the end of the rule session. By default, the database session (from connect to disconnect) is considered the rule session. Alternatively, you can use the reset session procedure (dbms_rlmgr.reset_session( )
) to end a rule session and start a new session within a database session. Note that at the beginning of a rule session, the results view is empty.
Consume the event that is used in a rule execution. You can mark an event for exclusive or shared execution of rules by specifying the consumption policy for the events. Previously, in Section 2.3, if the TravelPromotion
rule class was configured for exclusive consumption of events, then an event used for the execution of a rule was immediately deleted from the system and it could not be used for any other (matching) rules. Because the action callback procedure is used, Rules Manager automatically handles the consumption of the exclusive events. However, when you use external action execution, the application should explicitly consume the event chosen for an action execution by using the consume event procedure (dbms_rlmgr.consume_event( )
). This procedure ensures that when multiple concurrent sessions try to consume the same event, only one of them succeeds. So, you should execute the action for a particular rule if the event is successfully consumed, as follows:
DECLARE consumed number; BEGIN consumed := dbms_rlmgr.consume_event ( rule_class => 'TravelPromotion', event_ident => :eventIdBind); IF (consumed = 1) THEN OfferPromotion(…); -- offer the promotion only if the event -- consumption is successful END IF; END;
Obtain the event identifier from the value listed in the rlm$eventid
column of the MatchingPromos
results view. If the consumption policy (see Section 3.2) for all events is shared, then the CONSUME_EVENT
call always returns 1
and the event is still available. Note that only the events you configure for exclusive consumption are consumed and the corresponding rows from the results view are deleted.
Designing a rule-based application using Rules Manager involves a varying number of steps, depending on its mode of operation. Almost all the steps in both cases, single tier and multitier, are one-time implementations. Once these implementations are in place, you no longer need to deal with the Rules Manager APIs. You add new rules using the SQL INSERT
statement against the rule class table and the run-time calls that are embedded in larger applications automatically process these new rules.
A rule class stored in the database can operate in either of the following two modes:
Single tier mode -- the rule evaluation, identification of the candidate rules or action for execution, execution of action, and optional consumption of events all happen in the database with a single PROCESS_RULES
call (which passes in the event instance). Note that this is the most common case even for applications running outside the database.
Multitier mode -- the rule evaluation happens in the database and the remaining steps described in single-tier mode can be done in any tier with appropriate database calls (with a maximum of four steps, which are described in Section 6.2.2).
See either Section 2.3 or Section 2.4 for an example of a rule class stored in the database that uses a single tier mode of operation.
The main reasons for a rules application to operate in the multitier mode are:
The action suggested by the rules cannot be implemented as a database function or package (PL/SQL or Java) in the database.
The conflict resolution criterion for the rule class is complex and it cannot be specified using a SQL ORDER BY
clause. In situations when a single event processing a set of rules matches two or more rules, conflict resolution criterion is used to identify a subset of rules or determine an exact order of rules that should be fired, or both. Using a simple SQL ORDER BY
clause is usually sufficient for most applications. However, multitier mode can make use of any SQL operator (including analytical operators) for the conflict resolution criterion.
The four steps to use Rules Manager in the multitier mode are:
Tell the database about the event by calling the dbms_rlmgr.add_event
procedure.
Ask the database which rules apply (query a view, possibly with a complex query with a SQL ORDER BY
clause, and so forth).
Based on the applications conflict-resolution criteria, identify a subset of the matched rules that should be fired and prepare for executing the action by consuming the event with a dbms_rlmgr.consume_event
function call.
Upon success in Step 3, make calls to the (local, middle tier resident) routines that the programmer maps to the actions that are defined.
If the only reason for using the multitier mode is to execute the actions in the application server, then you can use single tier mode with a few modifications (thereby reducing the number of steps involved to two). You can implement the action callback procedure in the single-tier mode to enqueue the actions and continue with the rest of the operations (consumption). The application server can subscribe to this action queue and execute the actions. This configuration requires a minimum of two database calls (PROCESS_RULES
call and DEQUEUE
call).
Rules Manager, as a database feature, works in multiuser and concurrent session environments. It allows two concurrent sessions to process the same set of rules and call for deletion of a common event that matched the rules and ensures that only one of the sessions succeeds. When the rules application is operating in the single-tier mode, this happens by specifying an EXCLUSIVE
consumption policy for the event type. The PROCESS_RULE
procedure controls the event consumption logic and avoids deadlocks between various sessions. When the rule application is operating in multitier mode, the middle tier application must signal its intent to execute the action of a rule by calling the CONSUME_EVENT
function (because the user application is controlling the conflict resolution criterion). This call returns 0
if any one of the events required by the action has already been consumed by another concurrent session. So, the application should execute the action only if this call returns 1
. Note that this step can be skipped if all the events are configured for SHARED
consumption (implying that the events are shared for multiple rule executions).
Because one of the main reasons for using the multitier mode is to implement complex conflict resolution criteria, the results from matching an event with the rules is exposed (to the application) as a relation that can be queried using complex SQL. You can also use this view to specify different resolution criteria based on some external factors (for example, use one conflict-resolution criterion between the times 9AM-5PM and other criterion for the rest of the day).
Rules Manager rule classes can store any form of data (scalar, XML, Raw, BLOB, and so forth) along with the rule definition. This data is returned back to the action-callback procedure or the application when the corresponding rule matches an event.
For example, a rule application may choose to store Simple Object Access Protocol (SOAP) messages in their full form (in an XMLType
column) as actions for each rule. So, when a rule matches an event, it returns this SOAP message to the application. The application in the middle tier could interpret the data accordingly and perform the required action (post the SOAP message). See Appendix G for additional information on action execution.
In another application, the exact call for the action may be fixed, for example, using the OfferDiscount2Customer
function. In this case, the rule definitions may just store the percentage of discount that should be offered. When this discount value is returned to the application, it can be bound as an argument to the OfferDiscount2Customer
function call.
This chapter provides reference information about the SQL EVALUATE
operator and SQL statements used to index expression data. Table 15-1 lists the statements and their descriptions. For complete information about SQL statements, see Oracle Database SQL Language Reference.
Table 15-1 Expression Filter Index Creation and Usage Statements
Statement | Description |
---|---|
|
Matches an expression set with a given data item or table of data items |
|
Rebuilds an Expression Filter index |
|
Changes the name of an Expression Filter index |
|
Creates an Expression Filter index on a column storing expressions |
|
Drops an Expression Filter index |
The EVALUATE
operator is used in the WHERE
clause of a SQL statement to compare stored expressions to incoming data items.
The expressions to be evaluated are stored in an Expression column, which is created by assigning an attribute set to a VARCHAR2
column in a user table.
Format
EVALUATE (expression_column, <dataitem>) <dataitem> := <varchar_dataitem> | <anydata_dataitem> <varchar_dataitem> := attribute_name => attribute_value {, attribute_name => attribute_value} <anydata_dataitem> := AnyData.convertObject(attribute_set_instance)
Keywords and Parameters
Name of the column storing the expressions
Name of an attribute from the corresponding attribute set
Value for the attribute
Instance of the object type associated with the corresponding attribute set
Returns
The EVALUATE
operator returns a 1
for an expression that matches the data item, and returns a 0
for an expression that does not match the data item. For any null values stored in the Expression column, the EVALUATE
operator returns NULL
.
Usage Notes
You can use the EVALUATE
operator in the WHERE
clause of a SQL statement. When you define an Expression Filter index on a column storing expressions, the EVALUATE
operator on such a column may use the index for the expression set evaluation based on its usage cost. You can use the EVALUATE
operator as a join predicate between a table storing expressions and a table storing the corresponding data items.
If you can represent the values of all elementary attributes in the attribute set as readable values, such as those stored in VARCHAR
, DATE
, and NUMBER
data types and the constructors formatted as a string, then you can format the data item as a string of attribute name-value pairs. If a data item does not require a constructor for any of its elementary attribute values, then you can format a list of values provided for the data item as a string of name-value pairs using two getVarchar methods (a STATIC
method and a MEMBER
method) in the object type associated with the attribute set.
You can format any data item using an AnyData
instance. An attribute set with one or more binary typed attributes must use the AnyData
form of the data item.
See Section 11.3 for more information about the EVALUATE
operator.
Related views: USER_EXPFIL_ATTRIBUTE_SETS View
, USER_EXPFIL_ATTRIBUTES View
, and USER_EXPFIL_EXPRESSION_SETS View
Examples
The following query uses the VARCHAR
form of the data item generated by the getVarchar()
function:
SELECT * FROM Consumer WHERE EVALUATE (Consumer.Interest, Car4Sale('Mustang', 2000, 18000, 22000).getVarchar() ) = 1;
For the previous query, the data item can be passed in the AnyData
form with the following syntax:
SELECT * FROM Consumer WHERE EVALUATE (Consumer.Interest, AnyData.convertObject ( Car4Sale ('Mustang', 2000, 18000, 22000) )) = 1;
When a large set of data items are stored in a table, the table storing expressions can be joined with the table storing data items with the following syntax:
SELECT i.CarId, c.CId, c.Phone FROM Consumer c, Inventory i WHERE EVALUATE (c.Interest, Car4Sale(i.Model, i.Year, i.Price, i.Mileage).getVarchar()) = 1 ORDER BY i.CarId;
The ALTER INDEX REBUILD
statement rebuilds an Expression Filter index created on a column storing expressions. The Expression Filter index DOMIDX_OPSTATUS
status in the USER_INDEXES
view must be VALID
for the rebuild operation to succeed.
Format
ALTER INDEX [schema_name.]index_name REBUILD [PARAMETERS ('DEFAULT')]
Keywords and Parameters
The list of stored and indexed attributes for the Expression Filter index being rebuilt are derived from the default index parameters associated with the corresponding attribute set.
Usage Notes
When you issue the ALTER INDEX...REBUILD
statement without a PARAMETERS
clause, the Expression Filter index is rebuilt using the current list of stored and indexed attributes. You can also use this statement for indexes that failed during IMPORT
operation due to missing dependent objects.
You can modify the default index parameters associated with an attribute set without affecting the existing Expression Filter indexes. You can rebuild these indexes to use the new set of defaults by using the DEFAULT
parameter with the ALTER INDEX...REBUILD
statement. When you rebuild an index using the defaults, index parameters assigned to the expression set are cleared.
The bitmap indexes defined for the indexed attributes of an Expression Filter index get fragmented as the expressions stored in the corresponding column are frequently modified (using INSERT
, UPDATE
, or DELETE
operations). Rebuilding those indexes could improve the performance of the query using the EVALUATE
operator. The bitmap indexes can be rebuilt online using the DBMS_EXPFIL.DEFRAG_INDEX
procedure.
See Section 12.8 for more information about rebuilding indexes.
Related views: USER_EXPFIL_INDEXES View
and USER_EXPFIL_PREDTAB_ATTRIBUTES View
Examples
The following statement rebuilds the index using its current parameters:
ALTER INDEX InterestIndex REBUILD;
The following statement rebuilds the index using the default index parameters associated with the corresponding attribute set:
ALTER INDEX InterestIndex REBUILD PARAMETERS('DEFAULT');
The ALTER INDEX RENAME TO
statement renames an Expression Filter index.
Format
ALTER INDEX [schema_name.]index_name RENAME TO new_index_name;
Keywords and Parameters
None.
Usage Notes
None.
Examples
The following statement renames the index:
ALTER INDEX InterestIndex RENAME TO ExprIndex;
The CREATE INDEX
statement creates an Expression Filter index for a set of expressions stored in a column. You should configure the column being indexed to store expressions (with an attribute set assigned to it), and the index should be created in the same schema as the table (storing expressions).
Format
CREATE INDEX [schema_name.]index_name ON [schema_name.].table_name (column_name) INDEXTYPE IS EXFSYS.EXPFILTER [ PARAMETERS (' <parameters_clause> ' ) ...; <parameters_clause>:= [ADD TO DEFAULTS | REPLACE DEFAULTS] [<storeattrs_clause>] [<indexattrs_clause>][<predstorage_clause>] <storeattrs_clause> := STOREATTRS [ ( attr1, attr2, ..., attrx ) | TOP n ] <indexattrs_clause> := INDEXATTRS [ ( attr1, attr2, ..., attry ) | TOP m ] <predstorage_clause> := PREDSTORAGE (<storage_clause>)
Keywords and Parameters
The name of the index type that implements the Expression Filter index.
When you specify this parameter, the attributes listed in the STOREATTRS
and INDEXATTRS
clauses are added to the defaults associated with the corresponding attribute set. This is the default behavior.
When you specify this parameter, the index is created using only the list of stored and indexed attributes specified after this clause. In this case, the default index parameters associated with the corresponding attribute set are ignored.
Lists the stored attributes for the Expression Filter index.
Lists the indexed attributes for the Expression Filter index.
You can use this parameter for both STOREATTRS
and INDEXATTRS
clauses only when expression set statistics are collected. (See the section about GET_EXPRSET_STATS Procedure.) The number after the TOP
parameter indicates the number of (the most-frequent) attributes to be stored or indexed for the Expression Filter index.
Storage clause for the predicate table. See Oracle Database SQL Language Reference for the <storage_clause>
definition.
Usage Notes
When the index parameters are directly assigned to an expression set (column storing expressions), the PARAMETERS
clause in the CREATE INDEX
statement cannot contain STOREATTRS
or INDEXATTRS
clauses. In this case, the Expression Filter index is always created using the parameters associated with the expression set. (See the INDEX_PARAMETERS
Procedure and XPINDEX_PARAMETERS
Procedure sections in Chapter 18 and the "USER_EXPFIL_INDEX_PARAMS View" in Chapter 19.)
When the PARAMETERS
clause is not used with the CREATE INDEX
statement and the index parameters are not assigned to the expression set, the default index parameters associated with the corresponding attribute set are used for the Expression Filter index. If the default index parameters list is empty, all the scalar attributes defined in the attribute set are stored and indexed in the predicate table.
For an Expression Filter index, all the indexed attributes are also stored. So, the list of stored attributes is derived from those listed in the STOREATTRS
clause and those listed in the INDEXATTRS
clause. If you do not specify the REPLACE DEFAULTS
clause, this list is merged with the default index parameters associated with the corresponding attribute set.
If you do not specify the REPLACE DEFAULTS
clause, the list of indexed attributes for an Expression Filter index is derived from the INDEXATTRS
clause and the default index parameters associated with the corresponding attribute set. If this list is empty, the system picks at most 10 stored attributes and indexes them.
If an attribute is listed in the PARAMETERS
clause as well as the default index parameters, its stored versus indexed property is decided by the PARAMETERS
clause specification.
Predicate statistics for the expression set should be available to use the TOP
clause in the parameters of the CREATE INDEX
statement. (See the GET_EXPRSET_STATS
Procedure for more information.) When you use the TOP
clause for the STOREATTRS
parameter, the INDEXATTRS
parameter (if specified) should also use the TOP
clause. Also, the number you specify for the TOP
clause of the INDEXATTRS
parameter should be less than or equal to the one you specify for the STOREATTRS
parameter. When you use a TOP
clause, REPLACE DEFAULTS
usage is implied. That is, the stored and indexed attributes are picked solely based on the predicate statistics available in the dictionary.
The successful creation of the Expression Filter index creates a predicate table, one or more bitmap indexes on the predicate table, and a package with access functions in the same schema as the base table. By default, the predicate table and its indexes are created in the user default tablespace. You can specify an alternate tablespace and other storage parameters for the predicate table using the PREDSTORAGE
clause. The indexes on the predicate table are always created in the same tablespace as the predicate table.
See Chapter 12 for information about indexing expressions.
Related views: USER_EXPFIL_INDEXES View
, USER_EXPFIL_INDEX_PARAMS View, USER_EXPFIL_DEF_INDEX_PARAMS View
, USER_EXPFIL_EXPRSET_STATS View
, and USER_EXPFIL_PREDTAB_ATTRIBUTES View
Examples
When you do not directly assign index parameters to the expression set, you can create an Expression Filter index using the default index parameters specified for the corresponding attribute set as follows:
CREATE INDEX InterestIndex ON Consumer (Interest) INDEXTYPE IS EXFSYS.EXPFILTER;
You can create an index with one additional stored attribute using the following statement:
CREATE INDEX InterestIndex ON Consumer (Interest) INDEXTYPE IS EXFSYS.EXPFILTER PARAMETERS ('STOREATTRS (CrashTestRating(Model, Year)) PREDSTORAGE (tablespace tbs_1) ');
You can specify the complete list of stored and indexed attributes for an index with the following statement:
CREATE INDEX InterestIndex ON Consumer (Interest) INDEXTYPE IS EXFSYS.EXPFILTER PARAMETERS ('REPLACE DEFAULTS STOREATTRS (Model, CrashTestRating(Model, Year)) INDEXATTRS (Model, Year, Price) PREDSTORAGE (tablespace tbs_1) ');
You can use the TOP
clause in the parameters clause when statistics are computed for the expression set. These statistics are accessible from the USER_EXPFIL_EXPRSET_STATS
view.
BEGIN DBMS_EXPFIL.GET_EXPRSET_STATS (expr_tab => 'Consumer', expr_col => 'Interest'); END; / CREATE INDEX InterestIndex ON Consumer (Interest) INDEXTYPE IS EXFSYS.EXPFILTER PARAMETERS ('STOREATTRS TOP 4 INDEXATTRS TOP 3');
The DROP INDEX
statement drops an Expression Filter index.
Format
DROP INDEX [schema_name.]index_name;
Keyword and Parameters
None.
Usage Notes
Dropping an Expression Filter index automatically drops all the secondary objects maintained for the index. These objects include a predicate table, one or more indexes on the predicate table, and an access function package.
Examples
DROP INDEX InterestIndex;
The rule class properties you specify at the time you create the rule class include the event management policies that the Rules Manager should enforce for each rules application. In the case of rules defined for composite event structures, the primitive events are added to the system one at a time. These events are later combined with other primitive events to form composite events that match one or more rule conditions. Depending on the join conditions between primitive events, a primitive event can participate in a 1 to 1, 1 to N, or N-to-M relationship with other events to form one or more composite events. Rules Manager supports application-specific requirements for reusing primitive events and for handling duplicate composite events using rule event management policies and they are broadly classified as follows:
Consumption — determines if an event can be used for multiple rule executions or a single rule execution
Conflict resolution or ordering — determines the order in which matching rules with various events are to be executed
Duration — determines the lifetime of unconsumed primitive events
Auto-commit — determines if each interaction with a rule class should be committed automatically
Storage — determines the storage characteristics of the rule class in the database
Equal — specifies the common equality join predicates for all the rules in a rule class, that is, what are the lists of primitive event attributes that are equal in the composite events configured for a rule class
DML Events — specifies when you create an event structure with one or more table alias attributes, that you can configure the corresponding rule class to consider the DML operation (INSERT, UPDATE, DELETE
) on the corresponding tables as the events for which the rules are evaluated. The DML Events specification uses DML events from uncommitted transactions to process the rules. Whereas, in the case of continuous query notification (formerly database change notification) (CNF) events (see Section 2.5 and Section 3.7 for more information), the rules are processed for the DML operations within a transaction after the transaction commit operation.
The event management policies duration
and equal
are only applicable to rule classes configured for composite events. All other policies are applicable to rule classes configured for simple events as well as rule classes configured for composite events. In addition to the event management policies, the rule class properties allow the specifications for collection of events. A collection specification enables a primitive event to be used in rule conditions involving collections of events as opposed to individual events. For such events, rule conditions can compute aggregate values over a finite but potentially large number of primitive events of the same type and specify predicates on the resulting aggregates. Primitive events of a specific type are grouped based on certain event attributes and aggregate operators, such as SUM
, AVG
, MIN
, MAX
, and COUNT
on the other event attributes are used to apply predicates.
The rule class properties are all specified in an XML properties document, which is used as one of the arguments (rlcls_prop
) to the rule class creation procedure (dbms_rlmgr.create_rule_class
). Section 4.8 discusses the rule class property for enabling collections. All other rule class properties are described in the sections that follow.
A primitive event used to form a composite event can be combined with other primitive events to form a different composite event. For example, you can combine two instances of the AddFlight
event with one instance of AddRentalCar
event to form two different composite events (that could match two different rules). Some rule applications require that once a primitive event matches a rule on its own or in combination with other primitive events, it should not be used with any more rule executions. This implies that a primitive event used to form a composite event is consumed or removed from the system. The consumption
property for a rule class determines the policy regarding the reuse of primitive events in the system. The consumption policy is applicable to both the rules defined for simple events and the rules defined for composite events. Two modes of event consumption are possible:
EXCLUSIVE
— when the consumption mode is EXCLUSIVE
, a primitive event can be used to match only one rule (which ever matches first). Once the corresponding rule action is executed, this event is removed from the system, irrespective of the event duration specification (TRANSACTION
, SESSION
, or Elapsed time
).
SHARED
— when the consumption mode is SHARED
, a primitive event can be used to match any number of rules and execute their actions. The primitive event is removed from the system only when its duration specification is met. The default consumption policy for a rule class created with no consumption property is SHARED
.
Following the same example used previously, if two AddFlight
events are already added to the system, the next AddRentalCar
event could form two composite events that could match two or more rules. If the rule class is configured for EXCLUSIVE
consumption of events, only one of the rule actions can be executed using one of the composite events. This rule can be chosen deterministically if appropriate conflict resolution techniques are employed (see Section 3.2).
The EXCLUSIVE
consumption policy for a rule class created for a simple event structure implies that, at most, one rule is executed for any event instance passed to the dbms_rlmgr.process_rules
procedure. If the event matches more than one rule, the rule that is chosen for execution is determined using the ordering property of the rule class (see Section 3.2 that describes ordering). You can configure the rule class created for a primitive event structure with the EXCLUSIVE
event consumption policy using the following XML properties document (as the rlcls_prop
argument to the dbms_rlmgr.create_rule_class
procedure).
<simple consumption="exclusive"/>
Other valid forms of consumption specification within the rule class properties include the following:
<composite consumption="exclusive"/> <composite consumption="shared"/>
Rule applications can have different policies regarding the reuse of primitive events for a subset of primitive events used in a composite event. For such applications, the consumption policy can be specified for each primitive event type as a child element of the <composite>
element, such as the following:
<composite consumption="shared"> <object type="AddFlight" consumption="shared"> <object type="AddRentalCar" consumption="exclusive"> </composite>
The value for the consumption
attribute of the <composite>
element is used as the default value for all the primitive events in the composite event. This default value is overridden for a primitive event type by specifying it as the child element of the <composite>
element and specifying the consumption attribute for this element.
Specifying Custom Logic for Event Consumption
In addition to EXCLUSIVE
and SHARED
consumption policies, a rule class for composite events can be configured with a RULE
consumption policy, which allows individual rules in the rule class to use some custom logic for event consumption. The RULE
consumption policy can only be specified at the composite event level and when specified, the consumption policy for the primitive event type cannot be set to EXCLUSIVE
. When you configure the rule class for RULE
consumption policy, the action callback procedure and the rule class results view are created to return the identifiers for the individual primitive events matching a rule. You use these identifiers to selectively consume some or all of the primitive events atomically. See the DBMS_RLMGR.CONSUME_PRIM_EVENTS
function for more information.
When an event matches a rule on its own or in combination with other primitive events, by default, the order of rule (action) executions is not deterministic. Some rule applications may need the matching rules to execute in a particular order, which is determined by some conflict resolution criteria. Additionally, in the case of exclusive consumption of events, only one of the matching rules is executed. Unless some conflict resolution criterion is specified, this rule is chosen randomly. One of the common techniques of conflict resolution is to order the resulting composite events and matching rules based on the event attribute values and the rule action preferences.
Conflict resolution among composite events
The composite events resulting from the addition of a primitive event can be ordered based on the attributes of the corresponding primitive events. For example, the travel services application may decide to resolve among a set of composite events, consisting of AddFlight
and AddRentalCar
primitive events, based on the primitive event creation times. So, the conflict resolution criterion for this composite event structure is represented as [Flt.rlm$CrtTime
, Car.rlm$CrtTime
], implying that an event with earliest creation time is consumed before the others. This notation is similar to that of an ORDER BY
clause in a SQL query. Optionally, the DESC
keyword can be used with some of the attributes to sort the events in descending order (see information later in this section for complete syntax). When the rule class is configured for exclusive consumption of events, only the top-most event in this sorted list is chosen for rule execution.
Conflict resolution among matching rules for simple and composite events
A composite or a simple event can match one or more rules in a rule class. If more than one rule is matched, by default, their actions are executed in a non-deterministic order. If the order of the rule action executions is important, you can use the rule identifiers and the action preferences associated with the rules to sort the matching rules. For example, the travel services application can resolve among matching rules by using the conflict resolution criterion – [rlm$rule.PromoType
, rlm$rule.OfferedBy
, rlm$rule.rlm$ruleid
]. In this case, sorting the matching rules is done in ascending order and ordered first by the action preference PromoType
, then by the action preference OfferedBy
, then by the rule identifier rlm$ruleid
. As shown in this example, the rule identifier rlm$rule
is used to refer to any rule-specific attribute. The notation and semantics used for specifying conflict resolution criteria are similar to that of an ORDER BY
clause in a SQL query. Optionally, you can use the DESC
keyword with some of the attributes to sort the rules in the descending order (see information later in this section for complete syntax). When you configure the rule class for exclusive consumption of events, only the top-most rule in the sorted list is chosen for execution.
When a set of composite events matches a set of rules, the exact order of rule executions can be specified by combining the conflict resolution criterion for the composite events with that of the matching rules. The syntax for specifying the conflict resolution criteria is described using the ORDERING
property.
The ORDERING
property of the rule class determines the order in which a set of rules that match a set of composite events or a simple event are executed. When the consumption policy for a composite event type or for some primitive event types is set to EXCLUSIVE
, the ORDERING
property also determines the subset of rules that are executed. (The rest of the matching rules are ignored, because the exclusive events that are required to execute the rules are deleted after the first rule execution). The ORDERING
property is applicable to both the rules defined for simple events and the rules defined for composite events.
In the case of a rule class created for a composite event structure, the addition of a primitive event to the system could form multiple composite events that could match multiple rules. So, you can specify the ordering of the resulting events and the matching rules using the attributes in the events, the action preferences associated with the rules, and the rule identifiers. For the travel services rule class example, you can specify the ordering of the events and the matching rules as follows:
<composite ordering="Flt.rlm$CrtTime, Car.rlm$CrtTime, rlm$rule.PromoType, rlm$rule.OfferedBy, rlm$rule.rlm$ruleid"/>
In this ascending column, attribute ranked, ordering specification, you use the rule identifier rlm$rule
to refer to the attributes associated with the rule class (action preferences PromoType
and OfferedBy
and the rule identifier rlm$ruleid
); and you use the variables declared for the primitive events in the composite event structure (Flt
for AddFlight
and Car
for AddRentalCar
) to access the primitive events' attribute values.
The ORDERING
property can be combined with some other policies, such as consumption and duration. Other valid forms of ordering specification within the rule class properties include:
<composite consumption="exclusive" ordering="Flt.rlm$CrtTime, rlm$rule.PromoType, rlm$rule.rlm$ruleid DESC"/> <simple ordering="rlm$rule.PromoType, rlm$rule.OfferedBy, rlm$rule.rlm$ruleid/>
In the case of a rule class created for a simple event structure, as there is only one event at any point in time, the ordering is only based on the matched rules. So Rules Manager only allows in the ordering clause, the rule identifier and action preferences associated with the rules.
It is common for applications to generate events that will never trigger a rule firing, thus never consuming these events. The duration policy for primitive events determines the maximum lifetime of the events. When you add a primitive event to Rules Manager for incremental evaluation of rules, the event and the evaluation results are stored in the database. These events are later combined with other matching primitive events to form a composite event that conclusively satisfies one or more rule conditions. However, there may not be a matching event to form a composite event. For example, the travel services rule discussed in Section 2.6 may detect an AddFlight
event for a rule, but the corresponding AddRentalCar
event may not occur (or the AddRentalCar
event occurring may not be for a luxury car). So, the duration (or the life) of the primitive events should be set such that the incomplete (composite) events and the results from the incremental rule evaluations are deleted after a certain period.
The duration of a primitive event depends on the rule application and it can be classified into one of following four scenarios.
TRANSACTION: In this scenario, the primitive events added to the system during a database transaction are preserved until the end of the transaction (COMMIT
or ROLLBACK
). So, a rule for the composite event evaluates to true only if Rules Manager detects all the required primitive events within a database transaction.
SESSION: In this scenario, the primitive events added during a database session are preserved until the end of the session (CONNECT
or DISCONNECT
). So, a rule for the composite event evaluates to true only if Rules Manager detects all the required primitive events within a database session.
CALL: In some rule applications, a subset of primitive events are truly transient in that an event is considered for a possible match with the rules only at the instance at which the event is added. Such events do not contribute to the event history and they are not considered for any future rule matches. Hence, these events are said to be valid only for the duration of the call (PROCESS_RULES
or ADD_EVENT
) that processes the rules. You can configure a subset of primitive events within a composite event for the CALL
duration. A CALL
duration event contributes to a rule execution only if the event, in combination with other events in the system, evaluates a rule condition to true at the time of the call. Such events are not considered for rule matches after the call regardless of any rule executions during the call.
Elapsed time: In this scenario, the duration of a primitive event added to the system is determined by an event timeout associated with the rule class. You specify the event timeout as elapsed time (for example 10 hours, 3 days) and this is added to the creation time (determined by its rlm$CrtTime
attribute) to determine the exact time of event deletion.
The duration policy dictates the life span of the primitive events in the system. In the case of a rule class created for simple events, Rules Manager does not store the events in the system (as the rules are evaluated conclusively for each event). So, the duration policy is applicable only for the rule classes created for composite event structures. A rule class configured to reset all the primitive events at the end of each (database) transaction uses the following XML properties document:
<composite duration="transaction"/>
While specifying the duration as elapsed time, the value for the duration
attribute can be specified in {[int] minutes | hours | days} format, such as shown here:
<composite duration="20 minutes"/> <composite duration="2 hours"/> <composite duration="10 days"/>
These specifications apply to all the primitive events that constitute the composite event. If different duration specifications are required for some primitive event types, you can specify them as child elements of the <composite>
element, such as shown here:
<composite duration="10 days"> <object type="AddFlight" duration="3 days"/> <object type="AddRentalCar" duration="call"/> </composite>
In this case, you use the value of 10 days for the duration
attribute of the <composite>
element as the default value for all the primitive events in the composite event. This default value is overridden for a primitive event type by specifying it as the child element of the <composite>
element and specifying the duration
attribute for this element, for example, as shown by the duration property call
specified for the AddRentalCar
event type. So these AddRentalCar
events would be discarded if they did not match a rule during either a PROCESS_RULES
or ADD_EVENT
call.
A restriction on the duration policy is that the TRANSACTION
or SESSION
values for the duration policy can only be specified at the composite event level. When specified, these values cannot be overridden at the primitive events level.
In the case of a rule class for composite events, identifying the most-common equality join predicates in all rule conditions and specifying those using the EQUAL
rule class property is important for performance. All rules in a rule class use one or more common (equality) join predicates to relate the primitive events that form a composite event with each other. You define these join predicates using the attributes of the corresponding primitive event types. For example, in the travel services application, the AddFlight
and AddRentalCar
events in a composite event are related through the customer identifiers in these primitive events (Flt.CustId = Car.CustId
). You can configure the rule class to optimize a limited number of distinct equality join predicates used in its rule conditions using the EQUAL
property.
Note: Use of theEQUAL property at the rule class level is mandatory for better performance. |
The EQUAL
property used for a rule class may be of two types depending on the homogeneity of the join conditions in its rules. In the case of a rule class with a homogenous set of rules using the same equality join predicate for all its rule conditions, the equal specification for the rule class can be uniquely identified and there is only a single equal specification. On the other hand, when different subsets of rules use different join predicates, you can configure the rule class with a limited number of alternate equal specifications. Each equal specification may be based on a single attribute from each contributing primitive event or it could be based on multiple attributes from each primitive event (concatenated keys) as discussed in this section.
A single equal specification for a rule class identifies the equality join predicates that are used by all rules in the rule class. For example, if all the rules in the travel services applications relate the primitive events based on the customer identifiers (Flt.CustId = Car.CustId)
, then you can configure this join predicate as a single equal specification for the rule class's EQUAL
property.
In this case, you specify the EQUAL
property as a comma-delimited list of attributes, one from each primitive event structure configured for the rule class and it is used as the join predicate for all the rules in the rule class. This list identifies the primitive event attributes that must be equal to form a composite event. For example:
<composite equal="Flt.CustId, Car.CustId"/>
When the composite event has more than two primitive events, the corresponding rule conditions may employ conjunctions of two of more equality join predicates. For example, if reading1
, reading2
, and reading3
are three primitive events representing RFID readings, the join condition in a rule relating these three events could be reading1.ReaderId = reading2.ReaderId
and reading2.ReaderId = reading3.readingId
(to check for all three readings to occur at the same reader). The corresponding equal specification is a comma-delimited list of attributes from each primitive event (reading1.readerId
, reading2.readerId
, reading3.readerId
).
In the case of single equal specification, since each rule condition is guaranteed to use the same equality join predicate, the equal specification in the rule class properties obviate the need for the same join predicate in each rule condition. Hence, the rules in the rule class may skip the equality join predicates involving the same set of attributes, as demonstrated with the following examples.
The following rule condition explicitly specifies the equality join predicate in conjunction with other (possible inequality) join predicates. This specification uses the SQL WHERE
clause syntax for join predicates.
<condition>
<and join="Flt.CustId = Car.CustId
and Car.rlm$CrtTime > Flt.rlm$CrtTime ">
<object name="Flt"> Airline='Abcair' and ToCity='Orlando' </object>
<object> CarType = 'Luxury' </object>
</and>
</condition>
The following rule condition demonstrates the use of the EQUAL clause in the place of the equality join predicate in the previous example. The EQUAL clause specification for a rule condition acts as a short representation of equality join predicates especially when the rule condition has negation (see Section 5.3) or Any n (see Section 5.5) constructs.
<condition> <and equal="Flt.CustId, Car.CustId" join="Car.rlm$CrtTime > Flt.rlm$CrtTime"> <object name="Flt"> Airline='Abcair' and ToCity='Orlando' </object> <object> CarType = 'Luxury' </object> </and> </condition>
When the EQUAL
property for the rule class is specified as equal="Flt.CustId, Car.CustId"
, use of the corresponding join predicate or the EQUAL clause in a rule condition (as shown with the previous two examples) is redundant. In this case, the single equal specification associated with the rule class is enforced for all rules in the rule class. Hence, the following rule condition is equivalent to the previous two examples when the rule class is created with the previous EQUAL
property.
<condition> <and join="Car.rlm$CrtTime > Flt.rlm$CrtTime"> <object name="Flt"> Airline='Abcair' and ToCity='Orlando' </object> <object name="Car"> CarType = 'Luxury' </object> </and> </condition>
Equal Specification with Concatenated Keys
Often the equality join predicates between primitive events may involve more than one attribute from each primitive event. For example, in the travel services application, the AddFlight
and AddRentalCar
events may be related to each other based on their itineraries (equality predicate on Depart
and CheckOut
dates from respective events), in addition to the equality of the customer identifiers. A sample rule using such join predicates is as follows.
<and join="Flt.CustId = Car.CustId and Flt.Depart = Car.CheckOut"
>
<object name="Flt"> Airline = 'Abcair' and ToCity = 'Orlando' </object>
<object name="Car"> CarType = 'Luxury' </object>
</and>
If the equality predicates involving multiple attributes from each primitive event are common across all the rules in the rule class, you can configure the rule class with an EQUAL
property specification with concatenated keys for optimal performance.
<composite equal="(Flt.CustId, Car.CustId), (Flt.Depart, Car.CheckOut)"/>
Note: A maximum of three key concatenations can be specified with the rule class's EQUAL property. |
With the previous specification, the combination of [Flt.CustId
, Flt.Depart
] attributes acts as a concatenated key for each Flt
event and it should match the concatenated key from a Car
event for any rule in the rule class to be true. Since you enforce the previous equal specification for all rules in the rule class, a similar equal specification for each rule may be skipped.
Another form of EQUAL
property specification for a rule class identifies a list of the most common equality join predicates in its rules. For this purpose, each single equal specification is grouped using parentheses and alternate equal specifications are separated using a vertical bar ( '|') character. For example, if you create MTa rule class with two primitive events of the same RFIDRead
type, a subset of rules in the rule class may join the primitive events on their ItemId
attributes (reading1.ItemId = reading2.ItemId
). Another subset of the rules in the same rule class may relate the primitive events on their ReaderId
attributes (reading1.ReaderId = reading2.ReaderId
). You can optimize the rule class to process both types of these rules efficiently using the following EQUAL
property:
<composite equal="(reading1.ItemId, reading2.ItemId) | (reading1.ReaderId, reading2.ReaderId)"/>
Note: At most, you can define five alternate equal specifications for a rule class'sEQUAL property. |
The alternate equal specifications provide a means for optimizing the rule evaluation for the most common join predicates in a rule class and the rule class does not automatically enforce any equality join predicates for its rules. For optimal performance, each rule condition in the rule class must specify one of the alternate equal specifications for its EQUAL clause. For example, the following rule's EQUAL clause matches one of the alternate equal specifications at the rule class level and hence, this rule is optimized:
<condition> <and equal="reading1.ItemId, reading2.ItemId"/> <object name="reading1"/> <object name="reading2"/> </and> </condition>
Hence, the EQUAL clause for individual rules in a rule class not only acts as a short representation for the equality join predicate, but also helps map it into one of the alternate EQUAL
property specifications.
The alternate equal specification may include one or more specifications involving concatenated keys. For example, if the travel services application uses some rules, which just relate the AddFlight
and AddRentalCar
events based on their customer identifiers and some other rules on the identifiers as well as the dates in their itineraries, you can configure the rule class with the following equal property for optimal performance.
<composite equal="(Flt.CustId, Car.CustId) | (Flt.CustId, Car.CustId), (Flt.Depart, Car.CheckOut)"/>
With this specification at the rule class level, individual rules in the rule class may use either of these two alternate EQUAL
property specifications.
<condition> <and equal="(Flt.CustId, Car.CustId), (Flt.Depart, Car.CheckOut)"> <object name="Flt"> Airline='Abcair' and ToCity='Orlando' </object> <object> CarType = 'Luxury' </object> </and> </condition>
Note that while matching an EQUAL clause specified for a rule with one of the alternate equal specifications, the order of attributes is irrelevant.
Use the STORAGE
attribute of the <simple>
or <composite>
element to specify the storage properties for the rule class table and the internal objects created for the rule class. By default, the database objects used to manage the rules in a rule class are created using user defaults for the storage properties (Example: tablespace specification). The value assigned for this attribute can be any valid storage properties that you can specify in a typical SQL CREATE TABLE
statement. The following XML properties document shows how to use it (as the argument to the dbms_rlmgr.create_rule_class
procedure) to create a rule class for simple events that resides in a tablespace TBS_1
and uses exclusive consumption policy:
<simple storage="tablespace TBS_1" consumption="exclusive"/>
Another example of specifying storage attributes in the rule class properties is as shown:
<composite storage="tablespace TBS_1"/>
In most cases, all the Rules Manager procedures commit immediately after each add rule, delete rule, and process rule operation. You can configure the rule class to follow transaction boundaries by turning off the auto-commit functionality. For this purpose, you can specify the AUTOCOMMIT
property in the rule class properties document. For example:
<simple autocommit="NO"/>
You can specify the AUTOCOMMIT
property for the rule class created for simple as well as composite events. Other valid forms of specifying the AUTOCOMMIT
property include:
<composite autocommit="NO" consumption="shared"/> <composite autocommit="YES"/>
When the AUTOCOMMIT
property is set to NO
, the set of Rules Manager operations (add rule, delete rule, and process rule) performed in a transaction can be rolled back by issuing a ROLLBACK
statement. An exception to this rule is when the action callback procedure (implemented by the end user) performs an irreversible operation (sending a mail, performing a data definition language (DDL) operation, commit, rollback, and so forth). A DDL operation within an action callback operation automatically commits all the operations performed in that transaction. To avoid this situation, you should perform any DDL operations in an autonomous transaction.
Turning off the AUTOCOMMIT
property for a rule class can limit the concurrent operations on the rule class. This is especially the case when you create the rule class for composite events that is configured for exclusive consumption policy. (In a transaction, the consumed events are locked until the transaction is committed and the other sessions may wait for these events to be released.)
The default value for the AUTOCOMMIT
property is dependent on other event management policies (see Table 3-1). The default value for this policy is NO
for a rule class configured for simple (non-composite) rules and a composite rule class configured with the SESSION
or TRANSACTION
duration policy. (These configurations do not pose issues with sharing of events across sessions). For all other configurations, a default value of YES
is used for the AUTOCOMMIT
property. Note that the AUTOCOMMIT
property cannot be set to YES
when the duration policy is set to TRANSACTION
. Also, the AUTOCOMMIT
property cannot be set to NO
when one or more primitive event types are configured for EXCLUSIVE
or RULE
consumption policy.
When you define the event structure with one or more table alias constructs and you configure the corresponding rule class for DML events (see Section 3.7), the AUTOCOMMIT
property is always set to NO
. Note that this could result in deadlocks while working with EXCLUSIVE
or RULE
consumption policies.
A rule class with the AUTOCOMMIT
property set to NO
cannot contain rules involving negation and a deadline (See Section 5.3).
When you create an event structure with one or more table alias attributes (see Section 4.1), then you can configure the corresponding rule class to consider the SQL INSERT
and SQL*Loader operations on the corresponding tables as the events for which the rules are evaluated. You can enable this rule class behavior using the DMLEVENTS
or CNFEVENTS
property for the rule class:
<simple dmlevents="I"/> <simple cnfevents="I"/>
You can specify either of these properties for a rule class configured for simple and composite events. Events for UPDATE
and DELETE
operations on the underlying tables are only applicable for the rule classes configured for composite events.
<composite dmlevents="IUD"/> <composite cnfevents="IUD"/>
When a row in a table is deleted, the state information for the rules matching this row are marked for deletion. Similarly, when the row is updated, the existing state information is marked for deletion and the new state information is computed for the updated row. The deleted row (or the old image of the updated row) does not have an effect on the past rule states. That is, the delete operation does not cause existing rule states to automatically become true due to the retraction of the event. This scenario pertains to the rule conditions with negative constructs, in which the event matched the negative portion of the rule before it is deleted.
With the DMLEVENTS specification, Rules Manager uses the events generated from a DML operation to process the rules in the rule class as part of the same DML command. This is achieved with the use of row level triggers on the underlying tables. On the other hand, when you use the CNFEVENTS specification, the rules are processed after the commit of the DML transaction using the net data changes (within the transaction) as the events. In effect, if a row is inserted into a table and then updated within the same transaction, with the CNFEVENTS specification, the rules are processed once for the newly inserted row (with committed data). Whereas, when you use the DMLEVENTS specification, the rules are processed twice for the same row - once synchronously with the INSERT
operation and again with the UPDATE
operation. See Section 4.7 for additional information on the use of CNFEVENTS.
When you specify the DMLEVENTS
policy, the AUTOCOMMIT
policy for the rule class should be NO
. In this case, the AUTOCOMMIT
policy of NO
is allowed even when the consumption policy is set to EXCLUSIVE
or RULE
(which is considered an invalid combination when the DMLEVENTS
policy is not used). Note that the use of the EXCLUSIVE
or RULE
consumption policy with the DMLEVENTS
policy could result in application deadlocks.
You can mix and match most of the rule class properties (or event management policies) described in this section while defining a rule class. However, Table 3-1 shows some of the combinations of these properties that are considered invalid. For example, if the rule classes' AUTOCOMMIT
property is set to YES
, setting the DURATION
policy to TRANSACTION
is invalid. This is because the events are deleted from the system as soon as they are added and they cannot be combined with other events to form composite events. The DMLEVENTS
policy has no direct influence on the valid and invalid combination of event management policies. This policy only effects the default value for the AUTOCOMMIT
policy.
Table 3-1 Valid and Invalid Rule Class Property Combinations
AUTOCOMMIT | CONSUMPTION | DURATION | |
---|---|---|---|
Invalid |
Yes |
-- |
Transaction |
Valid |
Yes |
-- |
Session |
Valid |
Yes |
-- |
[n] Units |
Valid |
No |
Shared |
-- |
Valid |
No |
Exclusive |
TransactionFoot 1 |
Valid |
No |
Exclusive |
SessionFootref 1 |
Invalid |
No |
Exclusive |
[n] UnitsFoot 2 |
Valid |
No |
RuleFoot 3 |
TransactionFootref 1 |
Valid |
No |
Rule |
SessionFootref 1 |
Invalid |
No |
Rule |
[n] UnitsFootref 2 |
Footnote 1 A rule class operating in SESSION
or TRANSACTION
mode has no concurrency issues across the database session, as each session gets a private copy of the events and incremental results.
Footnote 2 A rule class with the EXCLUSIVE
consumption policy locks some rows in order to mark them "consumed" and may not actually consume the rows. Such rows are kept from being consumed by other database sessions and thus result in deadlocks. So, it is recommended that the locked rows be released with AUTOCOMMIT="YES" property.
Footnote 3 RULE
is a special form of the EXCLUSIVE
consumption policy where the consumption of certain events is initiated by the end-user.
The default values for various event management policies for a rule class configured for simple events are as follows:
CONSUMPTION : Shared DURATION : Infinite Duration (NULL) AUTOCOMMIT : No
The default values for the event management policies for a rule class configured for a composite event is sometimes dependent on other event management policies, as follows:
CONSUMPTION : Shared DURATION : Infinite Duration (NULL) AUTOCOMMIT IF DMLEVENTS = IUD : NO ELSE IF DURATION = TRANSACTION / SESSION : NO ELSE : YES
The action callback procedure configured for a rule class acts as a common entry point for executing the actions for all the rules in the rule class. This procedure is called once for each rule matching an event (primitive or composite). At the time of execution, this procedure has access to the events that matched the rule and the complete list of action preferences associated with the matched rule. The user implementing the action callback procedure can rely on this information to determine the appropriate action for each rule. Rules Manager provides maximum flexibility by not restricting the types of action preferences used for a rule class. In the simplest case, the action preferences associated with a rule can be one or more scalar values that are used as arguments to a common procedure (OfferPromotion
from the example in Section 2.4) that executes the appropriate action for each rule. Table G-1 represents one such rule class that is created with three types of action preference - PromoType
, OfferedBy
, and Discount
.
Table G-1 TravelPromotion Rule Class Table
rlm$ruleId | rlm$rulecond | rlm$enabled | PromoType | OfferedBy | Discount | rlm$ruledesc |
---|---|---|---|---|---|---|
AB_AV_ORL |
Airline='Abcair' and ToCity='Orlando' |
'Y' |
RentalCar |
Acar |
10 |
Additional info |
AC_HT_SJC |
Airline='Acbair' and ToCity='San Jose' |
'Y' |
Hotel |
Ahotel |
5 |
Additional info |
... |
... |
... |
... |
... |
... |
... |
If you implement a single PL/SQL procedure in the database to offer all types of discounts by accepting appropriate arguments, the action callback procedure for the preceding rule class can make use of this procedure to execute appropriate actions, as follows:
CREATE or REPLACE PROCEDURE PromoAction (rlm$event AddFlight, rlm$rule TravelPromotion%ROWTYPE) is BEGIN OfferPromotion(rlm$event.CustId, rlm$rule.PromoType, rlm$rule.OfferedBy, rlm$rule.Discount); END;
However, if you do not implement the action for all the rules with a single procedure but with a handful of procedures, the action callback procedure can be implemented to choose the appropriate procedure using one of the action preference values. For example, if the procedures used to offer hotel and rental car promotions are different, the preceding action callback procedure can be implemented as follows:
CREATE or REPLACE PROCEDURE PromoAction (rlm$event AddFlight, rlm$rule TravelPromotion%ROWTYPE) is BEGIN CASE rlm$rule.PromoType WHEN 'RentalCar' then OfferRentalCarPromotion(rlm$event.CustId, rlm$rule.OfferedBy, rlm$rule.Discount); WHEN 'Hotel' then OfferHotelPromotion (rlm$event.CustId, rlm$rule.OfferedBy, rlm$rule.Discount); ELSE OfferPromotion(rlm$event.CustId, rlm$rule.PromoType, rlm$rule.OfferedBy, rlm$rule.Discount); END CASE; END;
For complex rule applications requiring different actions for each rule, the PL/SQL commands that model the actions can be stored as the rule action preferences. For this purpose, the preceding rule class table can be configured to store the anonymous PL/SQL code blocks as the rule action preferences as described in Table G-2.
Table G-2 Modified TravelPromotion Rule Class Table
rlm$ruleId | rlm$rulecond | rlm$enabled | ActionCommands | rlm$ruledesc |
---|---|---|---|---|
AB_AV_ORL |
Airline='Abcair' and ToCity='Orlando' |
'Y' |
begin OfferAcarPromotion(:1,10); end; |
Additional info |
AC_HT_SJC |
Airline='Acbair' and ToCity='San Jose' |
'Y' |
begin OfferAhotelPromotion (:1, 5); end; |
Additional info |
... |
... |
... |
... |
... |
For the preceding rule class configuration, you can implement the action callback procedure to execute the anonymous PL/SQL code blocks using the EXECUTE IMMEDIATE
command shown as follows.
CREATE or REPLACE PROCEDURE PromoAction (rlm$event AddFlight, rlm$rule TravelPromotion%ROWTYPE) is BEGIN EXECUTE IMMEDIATE rlm$rule.ActionCommands USING rlm$event.CustId; END; /
A rules application in the database can use a combination of the previous three procedures to model complex action execution logic. For this purpose, the rule class can be created with as high as 997 action preference columns, each with any valid SQL data type (including RAW
, CLOB
, and XML
).
Rules Manager uses the DBMS_RLMGR
package, which contains various procedures, to create and manage rules and rule sessions. The following table describes the procedures in the DBMS_RLMGR
package.
None of the values and names passed to the procedures defined in the DBMS_RLMGR
package are case insensitive, unless otherwise mentioned. To preserve the case, enclose the values with double quotation marks.
Tip: See the chapter on the DBMS_RLMGR package in Oracle Database PL/SQL Packages and Types Reference for all reference information concerning Rules Manager package procedures. Use the links in the Procedures column in Table 8-1 to see each procedure. |
Table 8-1 DBMS_RLMGR Procedures
Procedure | Description |
---|---|
Adds the specified attribute to the event structure and the Expression Filter attribute set | |
Adds an event to a rule class in an active session | |
Adds a function, a type, or a package to the approved list of functions with an event structure and to the Expression Filter attribute set | |
Adds a rule to the rule class | |
Retrieves the primitive rule condition reference from a rule condition for composite events | |
Consumes an event using its identifiers and prepares the corresponding rule for action execution | |
Consumes one or more primitive events with all or none semantics | |
Creates a repository for the primitive rule conditions that can be shared by multiple rules from the same or different rule classes | |
Creates an event structure | |
Creates expression filter indexes for the rule class if the default indexes have been dropped | |
Creates a rule class interface package to directly operate on the rule class | |
Creates a rule class | |
Deletes a rule from a rule class | |
Drops the conditions table | |
Drops an event structure | |
Drops Expression Filter indexes for the rule conditions | |
Drops the rule class interface package | |
Drops a rule class | |
Adds an attribute to the primitive event structure | |
Retrieves the aggregate value computed for a collection event | |
Grants a privilege on a rule class to another user | |
Processes the rules for a given event | |
Resets the rule class by removing all the events associated with the rule class and purging any state information pertaining to rules matching some events | |
Starts a new rule session within a database session | |
Revokes a privilege on a rule class from a user | |
Synchronizes the indexes defined to process the predicates involving the |
Expression Filter defines views containing metadata using the xxx_EXPFIL
prefix, where xxx
can be the string USER
or ALL
. Expression Filter procedures create and maintain these read-only views.
Table 19-1 lists the names of the views and their descriptions.
Table 19-1 Expression Filter Views
View Name | Description |
---|---|
USER_EXPFIL_ASET_FUNCTIONS View |
List of functions and packages approved for the attribute set |
|
List of elementary attributes of the attribute set |
USER_EXPFIL_ATTRIBUTE_SETS View |
List of attribute set |
USER_EXPFIL_DEF_INDEX_PARAMS View |
List of default index parameters |
USER_EXPFIL_EXPRESSION_SETS View |
List of expression sets |
USER_EXPFIL_EXPRSET_STATS View |
List of predicate statistics for the expression sets |
|
List of index parameters assigned to the expression set |
|
List of expression filter indexes |
USER_EXPFIL_PREDTAB_ATTRIBUTES View |
List of stored and indexed attributes for the indexes |
|
List of all the expression privileges of the current user |
|
Maps any errors with the text indexes to the expression column values in which the error exists |
The USER_EXPFIL_ASET_FUNCTIONS
view lists all the functions and packages that are allowed in the expressions using a particular attribute set. The following table describes the columns in this view:
Column Name | Data Type | Description |
---|---|---|
ATTRIBUTE_SET_NAME | VARCHAR2 | Name of the attribute set |
UDF_NAME | VARCHAR2 | Name of the user-defined function or package (or type) as specified by the user (with or without the schema extension) |
OBJECT_OWNER | VARCHAR2 | Owner of the function or package (or type) |
OBJECT_NAME | VARCHAR2 | Name of the function or package (or type) |
OBJECT_TYPE | VARCHAR2 | Type of the object at the time the object was added to the attribute set:
|
The USER_EXPFIL_ATTRIBUTES
view lists all the elementary attributes of the attribute sets defined in the user's schema. The following table describes the columns in this view:
Column Name | Data Type | Description |
---|---|---|
ATTRIBUTE_SET_NAME | VARCHAR2 | Name of the attribute se |
ATTRIBUTE | VARCHAR2 | Name of the elementary attribut. |
DATA_TYPE | VARCHAR2 | Data type of the attribute |
ASSOCIATED_TABLE | VARCHAR2 | Name of the corresponding table for the table alias attribute. NULL for all other types of attributes |
TEXT_PREFERENCES | VARCHAR2 | Preferences for an attribute configured for text predicates |
The USER_EXPFIL_ATTRIBUTE_SETS view lists the attribute sets defined in the user's schema. The following table describes the columns in this view:
Column Name | Data Type | Description |
---|---|---|
ATTRIBUTE_SET_NAME | VARCHAR2 | Name of the attribute set |
The USER_EXPFIL_DEF_INDEX_PARAMS view lists the default index parameters (stored and indexed attributes) associated with the attribute sets defined in the user's schema. The following table describes the columns in this view:
Column Name | Data Type | Description |
---|---|---|
ATTRIBUTE_SET_NAME | VARCHAR2 | Name of the attribute set |
ATTRIBUTE | VARCHAR2 | Name of the stored attribute |
DATA_TYPE | VARCHAR2 | Data type of the attribute |
ELEMENTARY | VARCHAR2 | YES , if the attribute is also the elementary attribute of the attribute set; otherwise, NO |
INDEXED | VARCHAR2 | YES , if the stored attribute is also the indexed attribute; otherwise, NO |
OPERATOR_LIST | VARCHAR2 | String representation of the common operators configured for the attribute |
XMLTYPE_ATTR | VARCHAR2 | Name of the corresponding XMLType elementary attribute when the stored or indexed attribute is an XML tag |
The USER_EXPFIL_EXPRESSION_SETS view lists the expression sets defined in the user's schema. The following table describes the columns in this view:
Column Name | Data Type | Description |
---|---|---|
EXPR_TABLE | VARCHAR2 | Name of the table storing expressions |
EXPR_COLUMN | VARCHAR2 | Name of the column (in the table) storing expressions |
ATTRIBUTE_SET | VARCHAR2 | Name of the corresponding attribute set |
LAST_ANALYZED | DATE | Date on which the predicate statistics for this expression set were recently computed. NULL if statistics were not collected |
NUM_EXPRESSIONS | NUMBER | Number of expressions in the set when the set was last analyzed |
PREDS_PER_EXPR | NUMBER | Average number of predicates for each expression (when last analyzed) |
NUM_SPARSE_PREDS | NUMBER | Number of sparse predicates in the expression set (when last analyzed) |
The USER_EXPFIL_EXPRSET_STATS view lists the predicate statistics for the expression sets in the user's schema. The following table describes the columns in this view:
Column Name | Data Type | Description |
---|---|---|
EXPR_TABLE | VARCHAR2 | Name of the table storing expressions |
EXPR_COLUMN | VARCHAR2 | Name of the column (in the table) storing expressions |
ATTRIBUTE_EXP | VARCHAR2 | The arithmetic expression that represents a common left-hand side (LHS) in the predicates of the expression set |
PCT_OCCURRENCE | NUMBER | Percentage occurrence of the attribute in the expression set |
PCT_EQ_OPER | NUMBER | Percentage of predicates (of the attribute) with equality (= ) operator |
PCT_LT_OPER | NUMBER | Percentage of predicates (of the attribute) with the less than (< ) operator |
PCT_GT_OPER | NUMBER | Percentage of predicates (of the attribute) with the greater than (> ) operator |
PCT_LTEQ_OPER | NUMBER | Percentage of predicates (of the attribute) with the less than or equal to (<= ) operator |
PCT_GTEQ_OPER | NUMBER | Percentage of predicates (of the attribute) with the greater than or equal to (>= ) operator |
PCT_NEQ_OPER | NUMBER | Percentage of predicates (of the attribute) with the not equal to (!=) operator |
PCT_NUL_OPER | NUMBER | Percentage of predicates (of the attribute) with the IS NULL operator |
PCT_NNUL_OPER | NUMBER | Percentage of predicates (of the attribute) with the IS NOT NULL operator |
PCT_BETW_OPER | NUMBER | Percentage of predicates (of the attribute) with the BETWEEN operator |
PCT_NVL_OPER | NUMBER | Percentage of predicates (of the attribute) with the NVL operator |
PCT_LIKE_OPER | NUMBER | Percentage of predicates (of the attribute) with the LIKE operator |
The USER_EXPFIL_INDEX_PARAMS view lists the index parameters associated with the expression sets defined in the user's schema. The following table describes the columns in this view:
Column Name | Data Type | Description |
---|---|---|
EXPSET_TABLE | VARCHAR2 | Name of the table storing the expressions |
EXPSET_COLUMN | VARCHAR2 | Name of the column storing the expressions |
ATTRIBUTE | VARCHAR2 | Name of the stored attribute |
DATA_TYPE | VARCHAR2 | Data type of the attribute |
ELEMENTARY | VARCHAR2 | YES if the attribute is also the elementary attribute of the attribute set; otherwise, NO |
INDEXED | VARCHAR2 | YES if the stored attribute is also the indexed attribute; otherwise, NO |
OPERATOR_LIST | VARCHAR2 | String representation of the common operators configured for the attribute |
XMLTYPE_ATTR | VARCHAR2 | Name of the corresponding XMLType elementary attribute when the stored or indexed attribute is an XML tag |
The USER_EXPFIL_INDEXES view lists the Expression Filter indexes defined in the user's schema. The following table describes the columns in this view:
Column Name | Data Type | Description |
---|---|---|
INDEX_NAME | VARCHAR2 | Name of the index |
PREDICATE_TABLE | VARCHAR2 | Name of the predicate table used for the index |
ACCESS_FUNC_PACKAGE | VARCHAR2 | Name of the package that defines the functions with queries on the predicate table |
ATTRIBUTE_SET | VARCHAR2 | Name of the corresponding attribute set |
EXPRESSION_TABLE | VARCHAR2 | Name of the table on which the index is defined |
EXPRESSION_COLUMN | VARCHAR2 | Name of the column on which the index is defined |
STATUS | VARCHAR2 | Index status:
|
The USER_EXPFIL_PREDTAB_ATTRIBUTES view shows the exact list of stored and indexed attributes used for expression filter indexes in the user's schema. The following table describes the columns in this view:
Column Name | Data Type | Description |
---|---|---|
INDEX_NAME | VARCHAR2 | Name of the index |
ATTRIBUTE_ID | NUMBER | Attribute identifier (unique for an index) |
ATTRIBUTE_ALIAS | VARCHAR2 | Alias given to the stored attribute |
SUBEXPRESSION | VARCHAR2 | The arithmetic expression that represents the stored attribute (also the LHS of predicates in the set) |
DATA_TYPE | VARCHAR2 | Derived data type for the stored attribute |
INDEXED | VARCHAR2 | YES , if the stored attribute is also the indexed attribute; otherwise, NO |
OPERATOR_LIST | VARCHAR2 | String representation of the common operators configured for the attribute |
XMLTYPE_ATTR | VARCHAR2 | Name of the corresponding XMLType elementary attribute when the stored or indexed attribute is an XML tag |
XPTAG_TYPE | VARCHAR2 | Type of the XML tag:
|
XPFILTER_TYPE | VARCHAR2 | Type of filter configured for the XML tag: POSITIONAL or [CHAR|INT|DATE] VALUE |
The USER_EXPFIL_PRIVILEGES view lists the privileges of the current user on expression sets belonging to other schemas and the privileges of other users on the expression sets owned by the current user. The following table describes the columns in this view:
Column Name | Data Type | Description |
---|---|---|
EXPSET_OWNER | VARCHAR2 | Owner of the expression set |
EXPSET_TABLE | VARCHAR2 | Name of the table storing expressions |
EXPSET_COLUMN | VARCHAR2 | Name of the column storing the expressions |
GRANTEE | VARCHAR2 | Grantee of the privilege |
INSERT_PRIV | VARCHAR2 | Y if the grantee has the INSERT EXPRESSION privilege on the expression set; otherwise, N |
UPDATE_PRIV | VARCHAR2 | Y if the grantee has the UPDATE EXPRESSION privilege on the expression set; otherwise, N |
The USER_EXPFIL_TEXT_INDEX_ERRORS view maps any errors with the text indexes to the expression column values in which the error exists. The following table describes the columns in this view:
Column Name | Data Type | Description |
---|---|---|
EXPRESSION_TABLE | VARCHAR2 | Table with the expression column |
EXPRESSION_COLUMN | VARCHAR2 | Name of the column storing expressions |
ERR_TIMESTAMP | VARCHAR2 | Time at which the error was noticed |
ERR_EXPRKEY | VARCHAR2 | Key to the expression with the text predicate |
ERR_TEXT | VARCHAR2 | Description of the text predicate error |
An Expression column can store expressions defined on one or more database tables. These expressions use special elementary attributes called table aliases. The elementary attributes are created using the EXF$TABLE_ALIAS
type, and the name of the attribute is treated as the alias to the table specified through the EXF$TABLE_ALIAS
type.
For example, there is a set of expressions defined on a transient variable HRMGR
and two database tables, SCOTT.EMP
and SCOTT.DEPT
.
hrmgr='Greg' and emp.job='SALESMAN' and emp.deptno = dept.deptno and dept.loc = 'CHICAGO'
Create the attribute set for this type of expression as shown in the following example:
BEGIN -- Create the empty Attribute Set -- DBMS_EXPFIL.CREATE_ATTRIBUTE_SET('hrdb'); -- Add elementary attributes to the Attribute Set -- DBMS_EXPFIL.ADD_ELEMENTARY_ATTRIBUTE('hrdb','hrmgr','VARCHAR2(20)'); -- Define elementary attributes of EXF$TABLE_ALIAS type -- DBMS_EXPFIL.ADD_ELEMENTARY_ATTRIBUTE('hrdb','emp', EXF$TABLE_ALIAS('scott.emp')); DBMS_EXPFIL.ADD_ELEMENTARY_ATTRIBUTE('hrdb','dept', EXF$TABLE_ALIAS('scott.dept')); END; /
The table HRInterest
stores the expressions defined for this application. Configure the Expression column in this table as shown in the following example:
CREATE TABLE HRInterest (SubId number, Interest VARCHAR2(100)); BEGIN DBMS_EXPFIL.ASSIGN_ATTRIBUTE_SET('hrdb','HRInterest','Interest'); END; / -- insert the rows with expressions into the HRInterest table --
You can index the expressions that use one or more table alias attributes similar to those not using the table alias attributes. For example, the following CREATE INDEX
statement configures stored and indexed attributes for the index defined on the Expression column:
CREATE INDEX HRIndex ON HRInterest (Interest) INDEXTYPE IS EXFSYS.EXPFILTER PARAMETERS ('STOREATTRS (emp.job, dept.loc, hrmgr) INDEXATTRS (emp.job, hrmgr)');
When you evaluate the expression, the values for the attributes defined as table aliases are passed by assigning the ROWIDs from the corresponding tables. You can evaluate the expressions stored in the HRInterest
table for the data (rows) stored in EMP
and DEPT
tables (and a value of HRMGR
) with the following query:
SELECT empno, job, sal, loc, SubId, Interest FROM emp, dept, HRInterest WHERE emp.deptno = dept.deptno AND EVALUATE(Interest, hrdb.getVarchar('Greg',emp.rowid,dept.rowid)) = 1;
You can add additional predicates to the previous query if the expressions are evaluated only for a subset of rows in the EMP
and DEPT
tables:
SELECT empno, job, sal, loc, SubId, Interest FROM emp, dept, HRInterest WHERE emp.deptno = dept.deptno AND emp.sal > 1400 AND EVALUATE(Interest, hrdb.getVarchar('Greg',emp.rowid,dept.rowid)) = 1;
Oracle Database Rules Manager and Expression Filter Developer's Guide provides usage and reference information about Rules Manager, a feature in the Oracle Database that offers interfaces to define, manage, and enforce complex rules in the database and Expression Filter, a feature of Oracle Database and component of Rules Manager that stores, indexes, and evaluates conditional expressions in relational tables.
Oracle Database Rules Manager and Expression Filter Developer's Guide is intended for application developers and DBAs who perform the following tasks:
Use Event-Condition-Action (ECA) rules to integrate processes and automate workflows
Use the database to store and evaluate large sets of conditional expressions
Use the database to define, manage, and enforce complex rules
This manual assumes a working knowledge of application programming and familiarity with SQL, PL/SQL, XML, and basic object-oriented programming to access information in relational database systems.
For information about Oracle's commitment to accessibility, visit the Oracle Accessibility Program website at http://www.oracle.com/pls/topic/lookup?ctx=acc&id=docacc
.
Access to Oracle Support
Oracle customers have access to electronic support through My Oracle Support. For information, visit http://www.oracle.com/pls/topic/lookup?ctx=acc&id=info
or visit http://www.oracle.com/pls/topic/lookup?ctx=acc&id=trs
if you are hearing impaired.
For more information, see these Oracle resources:
The following text conventions are used in this document:
Convention | Meaning |
---|---|
boldface | Boldface type indicates graphical user interface elements associated with an action, terms defined in text or the glossary, or important parts of an example. |
italic | Italic type indicates book titles, emphasis, or placeholder variables for which you supply particular values. |
monospace | Monospace type indicates commands within a paragraph, URLs, code in examples, text that appears on the screen, or text that you enter. |