Normally a DDO will inherit constraints from its parent DDOs.
A constraint is built or rebuilt when then message Rebuild_Constraints is sent to a DD object. Rebuild_Constraints creates an internal constraint "expression" that contains all of the rules for record filtering for the DDO. Under normal circumstances Rebuild_Constraints does the following:
Clear the current constraints for the DDO
Send the message Constrain to the DDO. This triggers the OnConstrain event.
Execute all constraint commands within the OnConstrain event. Each constraint is added to the DDO's internal constraint expression.
After sending OnConstrain, the constrain checks to see if a Constrain_File property is non-zero. If so a relates-to constraint is created from the DDO to the file.
This process (steps 2 through 4) is then repeated for every parent DDO and this is repeated for every parent in the DDO structure.
When complete, the DDO contains a constraint expression that consists of all constraint commands defined in the main DDO and all constraint commands defined in all parents DDOs. The main DDO inherits all of the constraints of all of its parents (and grandparents, etc.).
When a record is found and parents are related, the constraint expression is run against these records. If any constraint fails, including parent constraints, the record is considered to be invalid. Therefore if a main record is found and one of its parent records contains an invalid constraint, that main record is considered to be invalid.
Most of the time this method works fine. There are times when the inheritance of constraints gets in the way. Consider an order entry system. In a typical system your detail record will relate to an order header and an Inventory parent. Assume you want to limit inventory records to items that are active (e.g., Constrain Invt.Status eq "A"). This would work perfectly for adding new orders. However, if you loaded an old order that now contains detail items for inactive inventory, those detail items will not appear in your list of order lines. This could be confusing.
In such a case, you can stop DDOs from inheriting constraints by setting the pbInheritConstraints property to false. When this happens all of your order lines would appear (because the parent constraint is not used). However, if you tried to select a different or new inventory record the inventory constraint would be enforced (because the constraint for an inventory find is evaluated by the inventory DDO.)
For example, consider an order DDO structure contains a constraint in the Inventory DDO filtering all records below a certain price. When selecting Invt records only filtered records can be selected. In the Order-detail DDO, constraints are not inherited. Therefore orders will be properly displayed with all detail records - even if the detail points to what is now an invalid Invt parent (we assume it was valid when the order was placed).
Object oVendor_DD is a Vendor_DataDictionary
End_Object // oVendor_DD
Object oInvt_DD is a Invt_DataDictionary
Set DDO_Server to oVendor_DD
Procedure OnConstrain
Constrain invt.Unit_price gt 100
End_Procedure
End_Object // oInvt_DD
Object oCustomer_DD is a Customer_DataDictionary
End_Object // oCustomer_DD
Object oSalesp_DD is a Salesp_DataDictionary
End_Object // oSalesp_DD
Object oOrderhea_DD is a Orderhea_DataDictionary
Set DDO_Server to oCustomer_DD
Set DDO_Server to oSalesp_DD
End_Object // oOrderhea_DD
Object oOrderdtl_DD is a Orderdtl_DataDictionary
Set DDO_Server to oOrderhea_DD
Set DDO_Server to oInvt_DD
Set Constrain_File to Orderhea.File_Number
// Constraints from parent (like Invt) will not be applied
Set pbInheritConstraints to false
End_Object // oOrderdtl_DD
Set Main_DD to oOrderhea_DD
Set Server to oOrderhea_DD
If you choose not to inherit constraints you can still place parent constraints within a child DDO. You must use the Constrain-as filter to do this. For example, your order detail DDO might contain the following:
Set pbInheritConstraints to False
Procedure OnConstrain
// The constrain file MUST be the name of DDO's main file
// but the expression can refer to a parent DDO
Constrain OrderDtl AS (Invt.Active="A")
End_Procedure
Some developers may prefer using this technique because it keeps all constraints for a DDO in one place (i.e., you don't have to search the parent DDOs for additional filters.